feat(core): add the Sandbox resource type and its capability contract - #387
Merged
Conversation
Greptile SummaryAdds the Sandbox resource contract, platform capability matrix, plan-time validation, binding vocabulary, and capability-token types. The follow-up makes file transfer an explicit capability and correctly reports it as unavailable on Azure.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| crates/alien-core/src/resources/sandbox.rs | Defines the Sandbox resource, capability matrix, validation contract, and explicit Azure file-transfer limitation. |
| crates/alien-bindings/src/traits.rs | Adds the provider-neutral Sandbox session and operation trait surface, with file methods tied to the published files capability. |
| crates/alien-core/src/sandbox_capability.rs | Defines operation classes and session-scoped capability claims with exact session, generation, expiry, and operation checks. |
| crates/alien-core/src/sandbox_capability_token.rs | Adds feature-gated Ed25519 signing and signature-first verification for sandbox capability tokens. |
| crates/alien-preflights/src/compile_time/sandbox_platform_support.rs | Enforces platform capability compatibility during planning rather than silently degrading declarations. |
| packages/core/src/sandbox.ts | Adds the TypeScript Sandbox builder corresponding to the Rust resource contract. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
Declaration["Sandbox declaration"] --> Preflight["Plan-time preflight"]
Platform["Target platform"] --> Capabilities["Platform capability matrix"]
Capabilities --> Preflight
Preflight -->|All requirements supported| Plan["Continue planning"]
Preflight -->|Unsupported requirement| Refusal["Typed refusal"]
Capabilities --> Caller["Application capability query"]
Caller -->|files = false on Azure| Avoid["Skip file operations"]
Caller -->|files = true elsewhere| Files["Use file operations"]
Reviews (44): Last reviewed commit: "docs(core): correct the capability notes..." | Re-trigger Greptile
ItamarZand88
force-pushed
the
itamar/alien-75-sandbox-1-core
branch
29 times, most recently
from
August 12, 2026 07:22
a13b427 to
e03d8a5
Compare
ItamarZand88
force-pushed
the
itamar/alien-75-sandbox-1-core
branch
11 times, most recently
from
August 17, 2026 22:14
bca19ef to
79b3147
Compare
ItamarZand88
force-pushed
the
itamar/alien-75-sandbox-1-core
branch
from
August 19, 2026 09:19
79b3147 to
61698a6
Compare
Azure's data plane exposes exec and lifecycle and no file transfer, so readFile, writeFiles and mkdir are refused there. The floor claimed otherwise, and with no field for it a caller could not branch: it found out by calling and failing, which is the outcome this type exists to prevent.
No platform supports a hostname egress allowlist — domainEgressRules is false on all five — and Azure additionally has no file transfer. The comment named Azure as the one platform that could.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
alien.Sandbox— a declaration for an isolated environment that runs untrustedcode, typically code an LLM just wrote. This layer is the type and its rules only: no
backend, no package emitters, no runtime.
What happens when a stack declaring a sandbox is planned:
deadline — is refused here, rather than accepted and quietly ignored.
This PR changes a sandbox from something you cannot express to something the platform
either honours exactly or rejects with the reason.
What I did
Sandboxresource: where its filesystem comes from, its cpu/memory/diskceilings, its outbound network policy, and its session lifetime.
supports instead of discovering a gap through a failure. Backends differ more than
you would expect — one cannot reconnect to a session at all, and only one can
restrict egress to a list of hostnames.
platform with no backend, a GCP sandbox is refused without a workload to host it,
and a declared ceiling a platform cannot enforce is refused rather than dropped.
operation class and expiry, all verified after the signature.
linked from a worker.
Files touched
crates/alien-core/src/resources/sandbox.rs— the type, its limits, egress andsession policy, and the per-platform capability matrix
crates/alien-core/src/sandbox_capability{,_token}.rs— the operation classes andthe claims an agent verifies
crates/alien-core/src/{ownership,gateability,resource_links}.rs— registrationcrates/alien-preflights/src/compile_time/sandbox_*.rs— the plan-time refusalspackages/core/src/sandbox.ts— the TypeScript builderHow I tested
alien buildagainst each target.A ceiling GCP cannot enforce, and a session deadline only Kubernetes has, are both
refused at plan time naming the capability they needed — not accepted and dropped.
alien-core32 sandbox tests (the per-platform capability matrix, thelimit/egress/session refusals, quantity parsing);
alien-preflightsdrives theplatform gate through the runner rather than calling the check directly;
@alienplatform/core90 tests including the builder and its gateability.this layer. Runtime behaviour is exercised in the layers that add it.
I also ran a security review on the diff. What it checked:
session id and the generation it started under, and both are checked after the
signature (
sandbox_capability_token.rs).claims, so a replaced session voids them.
deliberately coarse (execute vs manage), so a new method cannot fall inside one
already granted.
it — refused at plan time instead, which the preflight test drives through the runner.
Nothing turned up.
What changed since the last review
Azure's sandbox data plane carries exec and lifecycle but no file transfer, so
readFile,writeFilesandmkdirare refused there. The capability contract called files part of theguaranteed floor, which meant a caller had no way to find that out except by calling and failing.
When an application asks what a sandbox can do:
SandboxCapabilities::for_platformreturns the set for the platform it is running on.files: false, and every other backendfiles: true— this is theanswer that was previously unavailable, because the floor was assumed rather than published.
The floor is now create, exec and terminate; files moved out of it and became a capability.
Files touched
crates/alien-core/src/resources/sandbox.rs— thefilesfield, its per-platform values, theSandboxCapability::Filesvariant, and the corrected floor in the struct doccrates/alien-bindings/src/traits.rs—Requiresfiles`` on the three file operationspackages/core/src/generated/**— regenerated, four filesHow I tested
cargo test -p alien-core— 523 pass, including two new assertions incapability_sets_are_per_platformfiles: trueand confirmed the test fails on "the Azure data plane has nofile transfer", then restored it
pnpm -C packages/core generatea second time produces no further diff, so the committedartifacts match the source