Skip to content

[codex] Add Crownest provider#681

Merged
steipete merged 20 commits into
openclaw:mainfrom
tristanmanchester:codex/crownest-provider
Jul 2, 2026
Merged

[codex] Add Crownest provider#681
steipete merged 20 commits into
openclaw:mainfrom
tristanmanchester:codex/crownest-provider

Conversation

@tristanmanchester

@tristanmanchester tristanmanchester commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds a Crownest delegated-run provider with archive sync, Workspace Run execution, provider docs, matrix/category updates, config/env handling, and a live smoke script.
  • Hardens Crownest lifecycle behavior around claim cleanup, failed setup, cancellation, kept sandboxes, status waits, cleanup command scoping, stream failures, per-lease operation locking, and redaction of presigned upload errors.
  • Preserves and cleans sandbox IDs from malformed partial create responses, sends the exact archive Content-Length to staged upload targets, and keeps live-smoke reuse and cleanup in the original provider scope.
  • Adds focused Go coverage for provider/client/CLI behavior plus script coverage for live smoke classification.

Why / impact

This lets Crabbox run workloads on Crownest while keeping the core provider-neutral and avoiding secret persistence or secret forwarding. The provider treats the Crownest API key as runtime-only configuration, does not pass it on the command line, rejects unsupported delegated-run surfaces, and documents the current environment-forwarding limitation.

Review comment addressed

  • Removed unrelated worker/package-lock.json drift from the branch.
  • Added Crownest per-lease operation locking for retained run reuse, stop, and cleanup paths so concurrent local processes cannot race over the same retained sandbox.
  • Made retained-session cleanup commands carry the Crownest selector scope (--crownest-url, --crownest-project-id, --crownest-template) so custom-scoped retained sandboxes can be stopped from the printed command.
  • Addressed Codex review on one-shot cleanup: when Crownest owns cleanup with keepSandbox=false, Crabbox removes only the local claim and does not call DeleteSandbox; retained sandboxes still use explicit delete when Crabbox requested retention and later cleans up.
  • Addressed maintainer autoreview findings by making archive uploads non-chunked and carrying the explicit Crownest template through status, reuse, stop, and trap cleanup.

Repo guidance checked

  • AGENTS.md: provider-neutral core, no generated outputs edited by hand, verification commands included in the PR, and no provider/broker tokens in code/docs.
  • SECURITY.md: no live credentials or private infrastructure details are published here.
  • .github/: no pull request template is present; CI target is the repository default branch, main.
  • Crownest API docs referenced for provider integration context: https://docs.crownest.dev/docs

Validation

  • go test ./internal/providers/crownest ./internal/cli
    Passed.
  • go test -race ./...
    Passed on the final current-main merge.
  • go vet ./...
    Passed.
  • Filtered core coverage used by CI
    90.1% after focused Crownest config-path tests; threshold is 90.0%.
  • go build -trimpath -o bin/crabbox ./cmd/crabbox
    Passed. macOS linker emitted only: ld: warning: ignoring duplicate libraries: '-lobjc'.
  • scripts/check-docs.sh
    Passed: checked 51 command docs, provider matrix with 69 providers, 202 markdown files, and built dist/docs-site.
  • node --test scripts/live-crownest-smoke.test.js
    Passed: 1 test.
  • Full Worker format/lint/typecheck/test/build gate
    Passed: 752 tests and Wrangler dry-run build.
  • git diff --exit-code origin/main -- worker/package-lock.json
    Passed: worker lockfile is no longer part of this PR.
  • Whole-branch autoreview plus focused post-fix autoreview
    Two actionable findings fixed; final review clean with no accepted/actionable findings.

Live Crownest evidence

Using a Crownest API key from the shell environment only, I ran bin/crabbox doctor --provider crownest and a real remote workload against a temporary repo containing six files. The remote command ran Node tests, analyzed a CSV dataset, wrote a summary artifact, and verified the aggregate output.

Key output:

ok      provider provider=crownest timeout=10s auth=ready api=ready mutation=false runtime=ready
sync candidate: 6 files, 8.7 KiB
leased [redacted] slug=[redacted] provider=crownest sandbox=[redacted]
v22.22.3
# pass 3
analysis complete {"totalEvents":240,"totalFailures":34,"totalCostCents":6582}
verification complete {"totalEvents":240,"totalFailures":34,"totalCostCents":6582,"teams":[{"team":"alpha","count":60,"failures":8,"failureRate":0.1333,"p95DurationMs":851,"totalCostCents":1680},{"team":"beta","count":60,"failures":9,"failureRate":0.15,"p95DurationMs":838,"totalCostCents":1606},{"team":"delta","count":60,"failures":8,"failureRate":0.1333,"p95DurationMs":820,"totalCostCents":1628},{"team":"gamma","count":60,"failures":9,"failureRate":0.15,"p95DurationMs":783,"totalCostCents":1668}]}
crownest run summary sync=58ms command=4.898s total=17.073s exit=0

I also ran the live smoke script with CRABBOX_BIN=bin/crabbox scripts/live-crownest-smoke.sh. It exercised doctor, one-shot run, keep, status, reuse, and stop:

released lease=[redacted] sandbox=[redacted]
classification=live_crownest_smoke_passed

Config / secrets

  • Crownest requires CRABBOX_CROWNEST_API_KEY or CROWNEST_API_KEY to be supplied at runtime.
  • The API key is intentionally not persisted in Crabbox config and is not passed as a command-line argument.
  • Provider docs cover the current delegated-run behavior and note that command environment forwarding is not supported yet.

@clawsweeper

clawsweeper Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs changes before merge. Reviewed July 2, 2026, 2:00 PM ET / 18:00 UTC.

Summary
The PR adds a built-in Crownest delegated-run provider with CLI config/env handling, provider registration, docs, tests, and a live smoke script.

Reproducibility: yes. for the review findings by source inspection: client.go still probes /v1/sandboxes?limit=1, and backend.go publishes a claim before acquiring the operation lock. I did not run live Crownest credentials in this read-only review.

Review metrics: 2 noteworthy metrics.

  • Provider scope: 1 provider added across 23 files. A built-in provider addition changes CLI config, docs, provider registration, runtime behavior, and live smoke coverage rather than a narrow local fix.
  • Diff size: 3704 added, 3 removed. The amount of new provider code makes lifecycle and permission-boundary review important beyond green CI.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦞 diamond lobster
Patch quality: 🦐 gold shrimp
Result: needs maintainer review before merge.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Fix the doctor probe to match least-privilege Workspace Run credentials.
  • Acquire the Crownest operation lock before publishing a newly created local claim.

Risk before merge

  • [P1] Merging adds Crownest as a built-in third-party provider, so maintainers need to accept ongoing docs, config, lifecycle, credential-scope, and support ownership for the Workspace Run API.
  • [P1] Normal CI cannot prove Crownest account permission boundaries, quota behavior, staged upload behavior, event streaming, or retained-sandbox lifecycle; the PR body's live proof is strong but does not replace maintainer provider acceptance.

Maintainer options:

  1. Fix the two Crownest blockers (recommended)
    Update doctor to validate a supported Workspace Run/auth surface and acquire the per-lease operation lock before publishing any new local claim, with focused regression tests.
  2. Pause provider acceptance
    If maintainers are not ready to own Crownest as a built-in provider, keep the PR waiting or close it until the support direction is confirmed.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Fix Crownest doctor so least-privilege Workspace Run credentials are not rejected by a sandbox-list probe, and fix newly acquired Crownest runs so the per-lease operation lock is held before the local claim/slug is published; add focused regression tests for both paths.

Next step before merge

  • The remaining blockers are narrow code/test repairs in the Crownest provider rather than an unclear product decision, although final provider acceptance remains maintainer-owned.

Security
Cleared: The diff adds provider HTTP calls, secret env handling, and a live smoke script, but I found no concrete credential persistence, argv secret, or supply-chain regression in the inspected patch.

Review findings

  • [P2] Probe Workspace Run auth in doctor — internal/providers/crownest/client.go:159-160
  • [P2] Acquire the operation lock before publishing new claims — internal/providers/crownest/backend.go:216-219
Review details

Best possible solution:

Keep the Crownest implementation behind the provider adapter, but fix the doctor permission boundary and claim/operation-lock ordering before final maintainer provider acceptance.

Do we have a high-confidence way to reproduce the issue?

Yes for the review findings by source inspection: client.go still probes /v1/sandboxes?limit=1, and backend.go publishes a claim before acquiring the operation lock. I did not run live Crownest credentials in this read-only review.

Is this the best way to solve the issue?

No; the provider shape is close, but the current implementation needs the doctor probe and claim/lock ordering fixed before it is the narrow maintainable solution.

Full review comments:

  • [P2] Probe Workspace Run auth in doctor — internal/providers/crownest/client.go:159-160
    doctor still calls Probe, and Probe performs GET /v1/sandboxes?limit=1. A Crownest key that can create/read/cancel Workspace Runs but cannot list sandboxes can run the delegated workload but will fail doctor as an auth/API failure, so the probe should exercise the Workspace Run surface or treat sandbox-list denial as non-fatal.
    Confidence: 0.88
  • [P2] Acquire the operation lock before publishing new claims — internal/providers/crownest/backend.go:216-219
    claimAcquiredSandbox writes the local claim and makes the slug resolvable before this process holds the per-lease operation lock. Another crabbox stop --provider crownest <slug> can acquire the lock first, delete the sandbox, and remove the claim while the active run is still uploading/finalizing/starting; hold the lock before making the claim visible.
    Confidence: 0.9

Overall correctness: patch is incorrect
Overall confidence: 0.9

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against c0363ba1ba3b.

Label changes

Label changes:

  • add merge-risk: 🚨 compatibility: The doctor probe can reject valid Crownest run-only credentials if sandbox-list permission is not granted.
  • add merge-risk: 🚨 availability: A local stop racing a newly published claim can delete the sandbox while the active run is still starting.
  • remove merge-risk: 🚨 other: Current PR review merge-risk labels are merge-risk: 🚨 compatibility, merge-risk: 🚨 availability.

Label justifications:

  • P2: This is a normal-priority provider addition with concrete pre-merge correctness blockers but no shipped-user regression.
  • merge-risk: 🚨 compatibility: The doctor probe can reject valid Crownest run-only credentials if sandbox-list permission is not granted.
  • merge-risk: 🚨 availability: A local stop racing a newly published claim can delete the sandbox while the active run is still starting.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (terminal): The PR body includes redacted live terminal output for doctor, a real remote workload, and the live smoke script covering doctor, one-shot run, keep, status, reuse, and stop.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes redacted live terminal output for doctor, a real remote workload, and the live smoke script covering doctor, one-shot run, keep, status, reuse, and stop.
Evidence reviewed

Acceptance criteria:

  • [P1] go test ./internal/providers/crownest ./internal/cli.
  • [P1] go vet ./...

What I checked:

  • AGENTS.md policy applied: Read the full target AGENTS.md and applied the provider-neutral adapter boundary and secret-handling guidance to the review. (AGENTS.md:1, c0363ba1ba3b)
  • Doctor probes sandbox list: Crownest Doctor delegates to api.Probe, and Probe performs GET /v1/sandboxes?limit=1 instead of validating the Workspace Run surface. (internal/providers/crownest/client.go:159, ed1e87e9bedb)
  • Claim is published before the operation lock: Run calls claimAcquiredSandbox before lockAcquiredLease, so the new slug can become visible before the creating process owns the per-lease lock. (internal/providers/crownest/backend.go:216, ed1e87e9bedb)
  • Operation-lock tests miss new-claim publication: Existing lock tests cover reuse, stop, cleanup, and lock cancellation, but not the newly acquired run path where the claim is first published. (internal/providers/crownest/backend_test.go:298, ed1e87e9bedb)
  • Live behavior proof in PR body: The PR body includes redacted terminal output for doctor, a real Crownest remote workload, and a live smoke script covering doctor, one-shot run, keep, status, reuse, and stop. (ed1e87e9bedb)
  • Area history sampled: Current main and branch history show recent provider catalog, provider mutation, and Crownest hardening work by Peter Steinberger plus adjacent built-in provider addition work by Momo. (c0363ba1ba3b)

Likely related people:

  • steipete: Current main history shows recent provider mutation and provider catalog work, and this PR branch includes Crownest hardening commits by the same contributor. (role: recent provider and claim-path contributor; confidence: medium; commits: a28b457ccdeb, 185162630e43, 2e5d6dfd559f; files: internal/cli/config.go, internal/providers/all/all.go, internal/providers/crownest/backend.go)
  • Momo: Added the recent Tencent Cloud provider across the same provider registration, config, metadata, docs, and backend surfaces on current main. (role: adjacent provider contributor; confidence: medium; commits: f18f0ce35887; files: internal/cli/config.go, internal/providers/all/all.go, docs/providers/provider-metadata.json)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 automation 🚨 Merging this PR could break CI, automerge, proof capture, label sync, or automation. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. merge-risk: 🚨 automation 🚨 Merging this PR could break CI, automerge, proof capture, label sync, or automation. labels Jun 25, 2026
@tristanmanchester tristanmanchester marked this pull request as ready for review June 25, 2026 05:28

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3f2a8bfbb3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/providers/crownest/backend.go Outdated
*shouldStop = false
cleanupCtx, cancel := context.WithTimeout(context.WithoutCancel(ctx), cleanupTimeout)
defer cancel()
if err := api.DeleteSandbox(cleanupCtx, sandboxID); err != nil && !isNotFound(err) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid deleting one-shot Workspace Run sandboxes

For normal crabbox run --provider crownest without --keep, the Workspace Run is created with keepSandbox=false, so Crownest owns cleanup; the public Workspace Runs docs describe the run lifecycle as requiring workspace_run:create/read/cancel and keepSandbox as the cleanup control. This unconditional DeleteSandbox makes an otherwise successful run fail during cleanup for least-privilege keys that can run Workspace Runs but cannot delete sandboxes (403 is not treated like 404), flipping the local exit code to 1 after the remote command succeeded.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in e418223. One-shot Crownest Workspace Runs now respect keepSandbox=false: Crabbox removes the local claim but does not call DeleteSandbox, so least-privilege Workspace Run keys do not fail after a successful remote command. Retained paths still delete when Crabbox explicitly requested retention and then needs to clean up.

Validation: go test ./internal/providers/crownest ./internal/cli, go vet ./..., go build -trimpath -o bin/crabbox ./cmd/crabbox, live scripts/live-crownest-smoke.sh, and autoreview clean.

@tristanmanchester tristanmanchester force-pushed the codex/crownest-provider branch from 3f2a8bf to e418223 Compare June 25, 2026 13:48
@clawsweeper clawsweeper Bot added the merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. label Jun 25, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 185162630e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

func (c *httpClient) BaseURL() string { return c.baseURL }

func (c *httpClient) Probe(ctx context.Context) error {
return c.doJSON(ctx, http.MethodGet, "/v1/sandboxes?limit=1", nil, nil, "")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Probe the Workspace Run surface in doctor

For a least-privilege Crownest key that has only the documented Workspace Run lifecycle scopes (workspace_run:create/read/cancel), normal one-shot crabbox run --provider crownest can succeed, but this doctor probe hits the sandbox-list endpoint and fails with 403 before exercising the delegated-run surface. That makes crabbox doctor --provider crownest incorrectly report auth/API failure for valid run-only credentials; probe a Workspace Run read endpoint instead, or make sandbox-list denial non-fatal for doctor.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 2, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ed1e87e9be

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +216 to +219
if err := b.claimAcquiredSandbox(ctx, api, req, leaseID, sandboxID, slug, &leaseID, &slug); err != nil {
return RunResult{}, err
}
if err := lockAcquiredLease(); err != nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Acquire the operation lock before publishing new claims

For newly created Crownest runs, claimAcquiredSandbox writes the local claim and prints the slug before this process holds the per-lease operation lock. In the window before lockAcquiredLease succeeds, another crabbox stop --provider crownest <slug> process can resolve the just-published claim, acquire the lock first, delete the sandbox, and remove the claim while this run is still uploading/finalizing/starting, causing the active run to fail or race against a deleted sandbox. Hold the operation lock before making the claim visible (the same pattern matters when the sandbox ID is first reported after start).

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. and removed merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. labels Jul 2, 2026
@steipete steipete merged commit 30f09ed into openclaw:main Jul 2, 2026
8 checks passed
@tristanmanchester tristanmanchester deleted the codex/crownest-provider branch July 2, 2026 18:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants