Skip to content

feat: add sandbox_environment table, CRUD and update agent_spec with environment - #810

Open
thesujai wants to merge 2 commits into
feat/add-provider-namefrom
feat/sandbox-environments
Open

thesujai wants to merge 2 commits into
feat/add-provider-namefrom
feat/sandbox-environments

Conversation

@thesujai

@thesujai thesujai commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes AGE-2287

Changes

  • feat: add sandbox_environment table, CRUD and update agent_spec with environment

How was this tested?

NA, next PR will be tested

Checklist

  • I have read the contributing guidelines
  • pnpm build, pnpm test, pnpm typecheck, pnpm lint:ci, and pnpm format:check pass locally
  • Tests added/updated where it makes sense
  • No hand-edits to generated code (packages/trueforge-sdk, python/trueforge_sdk, .github/fern/openapi/openapi.json, docs/openapi.json) — fork PRs omit SDK regen; maintainers regenerate after merge
  • Docs / .env.example updated if configuration or behavior changed

Note

Medium Risk
New sandbox provisioning paths and agent spec wiring affect runtime isolation and outbound network/secrets config, with external Daytona validation on write.

Overview
Adds caller-owned Daytona sandbox environments with full CRUD at /api/v1/sandbox-environments, plus OpenAPI and SDK surface (client.sandboxEnvironments).

Each environment is stored with a Daytona manifest (image variants, lifecycle, networking, resources, org secrets) and is scoped to the creating subject on list/get/update/delete. Create/update validate against the tenant sandbox provider (snapshot existence, secret names, trueforge-default when the provider is ready). Delete returns 409 if any agent still references the environment by name.

AgentSpec gains optional config.sandbox.environment so agents can pin a named environment instead of tenant defaults; agent and session flows now validate that the name exists, is owned by the caller, and matches the configured provider. Tenant permissions expose sandbox-environment → CREATE alongside agents.

Minor version bumps in the changeset for @truefoundry/trueforge and @truefoundry/trueforge-core.

Reviewed by Cursor Bugbot for commit b6eef3c. Bugbot is set up for automated code reviews on this repo. Configure here.

@changeset-bot

changeset-bot Bot commented Sep 18, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b6eef3c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@truefoundry/trueforge Minor
@truefoundry/trueforge-core Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b6eef3c. Configure here.

): Promise<SandboxEnvironmentRecord | undefined>;
deleteSandboxEnvironment(input: DeleteSandboxEnvironmentInput, transaction?: TTransaction): Promise<boolean>;
getOwnedIds(input: GetOwnedIdsInput, transaction?: TTransaction): Promise<readonly string[]>;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing dual-backend store contract tests

Medium Severity

ISandboxEnvironmentStore has both Postgres and SQLite implementations, but there is no shared contract suite covering uniqueness, creator-scoped list, get-by-id/name, description patching, or delete. IAgentStore.listAgentIdsUsingSandboxEnvironment is also new and uses dialect-specific JSON lookups with no contract coverage, so Postgres/SQLite drift can ship untested.

Additional Locations (1)
Fix in Cursor Fix in Web

Triggered by learned rule: Dual-backend stores and dispatch need contract tests

Reviewed by Cursor Bugbot for commit b6eef3c. Configure here.

message: 'Daytona denied access while verifying the snapshot',
cause: error,
});
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Daytona 403 mapped to 422

Medium Severity

isDaytonaPermissionError (Daytona HTTP 403) is turned into HTTPException(422) when verifying snapshots and organization secrets. Invalid API keys correctly become 422, but an authenticated key missing grants is supposed to stay 403 so operators can distinguish credential failure from missing write:sandboxes / write:snapshots permissions.

Additional Locations (1)
Fix in Cursor Fix in Web

Triggered by learned rule: HTTP 401 is platform-auth only; split Daytona 401/403

Reviewed by Cursor Bugbot for commit b6eef3c. Configure here.

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