Context
This picks up a thread that stalled on #517 and is the gating question for #567.
Goal: turn "More soon" into a concrete, scoped list of preconditions, so we can either align #567 against them or take the refactor on as a prerequisite PR.
What #567 already conforms to
To save a re-read, the current submission does not propose any new abstractions — it deliberately conforms to the existing contracts:
- Implements the current
Sandbox trait and provider registry as-is; no trait changes.
- Follows the clone-based provider contract (
is_clone_based(), run-manifest GitHub origin metadata, skip_clone semantics) exactly as the Docker / Daytona providers do.
- All shell interpolation goes through
shell_quote(); the one env-var export path is guarded by an identifier-only allowlist.
- Config resolution mirrors the Daytona provider shape (
FORKD_URL / FORKD_TOKEN / FORKD_SNAPSHOT_TAG from environment, token redacted in Debug).
- Fully feature-gated behind a
forkd feature, default off. Default builds compile byte-compatible with main; every always-compiled match over SandboxProviderKind pairs a gated arm with a graceful-error arm.
- Clippy-clean under
--features forkd -D warnings; cargo fmt --check clean; live-tested against a forkd v0.5.2 controller and currently running on our own gate infrastructure at fabro 0.290.
So if the preconditions are "the provider should fit the existing shape," we're already there. If they're "the existing shape itself should change before we add a fourth provider," that's a different conversation and we'd like to see it on the page.
What we need from you (@brynary, or whoever picks up the maintainer review)
A scoped list of the preconditions you flagged on #517. Even a partial list is useful — we can iterate. Concrete categories we'd like to know about one way or the other:
- Provider registry shape — current
SandboxProviderKind enum + match arms. Any cleanup you want before N=3 (forkd) lands? Trait-object dispatch, boxed providers, registration via inventory/linkme, plugin model, etc.?
Sandbox trait split — is the current trait granularity right, or do you want it broken into narrower responsibilities (e.g. Workspace / Exec / Files / Lifecycle)? Async/Sync split? Associated types vs generics?
- Clone-source contract — today, clone-based providers read the GitHub origin from the run manifest and
is_clone_based() gates the clone step. Is that the contract you want kept, or is there a richer "workspace source" abstraction you'd like introduced first (e.g. pluggable source resolvers, non-GitHub origins, fork detection)?
- Anything else — config-loading shape, feature-gating conventions, telemetry hooks, error type surface, server-side registration at
fabro server boot, etc.
If a precondition turns out to be a substantive refactor, we're happy to take it on as a prerequisite PR (or co-author with a maintainer), with the forkd provider rebased on top.
References
Context
This picks up a thread that stalled on #517 and is the gating question for #567.
main. The PR body already raises this and offers to move the conversation here per CONTRIBUTING's "align on approach first" guidance for larger features.Goal: turn "More soon" into a concrete, scoped list of preconditions, so we can either align #567 against them or take the refactor on as a prerequisite PR.
What #567 already conforms to
To save a re-read, the current submission does not propose any new abstractions — it deliberately conforms to the existing contracts:
Sandboxtrait and provider registry as-is; no trait changes.is_clone_based(), run-manifest GitHub origin metadata,skip_clonesemantics) exactly as the Docker / Daytona providers do.shell_quote(); the one env-var export path is guarded by an identifier-only allowlist.FORKD_URL/FORKD_TOKEN/FORKD_SNAPSHOT_TAGfrom environment, token redacted inDebug).forkdfeature, default off. Default builds compile byte-compatible withmain; every always-compiled match overSandboxProviderKindpairs a gated arm with a graceful-error arm.--features forkd -D warnings;cargo fmt --checkclean; live-tested against a forkd v0.5.2 controller and currently running on our own gate infrastructure at fabro 0.290.So if the preconditions are "the provider should fit the existing shape," we're already there. If they're "the existing shape itself should change before we add a fourth provider," that's a different conversation and we'd like to see it on the page.
What we need from you (@brynary, or whoever picks up the maintainer review)
A scoped list of the preconditions you flagged on #517. Even a partial list is useful — we can iterate. Concrete categories we'd like to know about one way or the other:
SandboxProviderKindenum + match arms. Any cleanup you want before N=3 (forkd) lands? Trait-object dispatch, boxed providers, registration via inventory/linkme, plugin model, etc.?Sandboxtrait split — is the current trait granularity right, or do you want it broken into narrower responsibilities (e.g.Workspace/Exec/Files/Lifecycle)? Async/Sync split? Associated types vs generics?is_clone_based()gates the clone step. Is that the contract you want kept, or is there a richer "workspace source" abstraction you'd like introduced first (e.g. pluggable source resolvers, non-GitHub origins, fork detection)?fabro serverboot, etc.If a precondition turns out to be a substantive refactor, we're happy to take it on as a prerequisite PR (or co-author with a maintainer), with the forkd provider rebased on top.
References