Commit graph

299 commits

Author SHA1 Message Date
Bryan Helmkamp
f568688154
Move the sandbox-driver pin to the supervisor kind fix
The plugin supervisor now answers to the configured kind, which fabro's
plugin test expects of the provider it holds.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 13:52:52 -06:00
Bryan Helmkamp
d27897c39f
Move the sandbox-driver pin to the follow-up commit
The driver branch gained equality on statuses and events, a git failure
that says when a command timed out, and lost the misleading
GitAttempt::succeeded; nothing in fabro used the method.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 13:24:37 -06:00
Bryan Helmkamp
454ad13d69
Pin sandbox-driver at the Section 4 branch
The driver's section-4-driver-items branch (lithoscomputer/sandbox-driver#20)
carries the provider-owned scopes, the supervisor as provider, Host attach
by directory, the BASH_ENV launch rule, git retry and verbs, the status
image/snapshot/network split, Daytona snapshot caching in create, the
services port verbs, and RFC 3339 wire timestamps. This commit only moves
the pin and follows the two API changes that no longer compile: the status
projection reads image and snapshot instead of source, and the plugin
supervisor is launched rather than constructed. The deletion rounds follow
one item per commit.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 12:29:22 -06:00
Bryan Helmkamp
346dba6e50
Pin sandbox-driver at the ambient credentials facet
The driver branch adds `Git::set_ambient_credentials`, classifies a
missing `git` executable as `GitFailureKind::GitUnavailable`, and runs
Daytona's pinned clones through the derived clone after a new
conformance check caught the toolbox pin failing. The project notes
follow the last change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 09:50:18 -06:00
Bryan Helmkamp
2e8d6b8a3d
Merge origin/main into the sandbox-driver adoption
Both sides rewrote the same crates. This branch replaced fabro's sandbox
layer with the sandbox driver: one RunSandbox, no Sandbox trait, driver
events consumed directly, MockSandbox over the driver's doubles. Main
replaced fabro's LLM layer with lithos-llm: fabro-model deleted, the
catalog and provider ids from lithos, credentials through the lithos
CredentialProvider, clients built with build_client.

Every conflict was one of those two renames meeting in an import list or
a signature, so the rule was mechanical: sandbox names resolve to this
branch, LLM names to main. Where main's newer code still used the old
sandbox API — new session tests over Arc::new(MockSandbox), the SDK
example's LocalSandbox, test fakes typed as Arc<dyn Sandbox> — it is
ported to RunSandbox and the mock helper. Where this branch still used
fabro-model or Client::from_source, main's replacement stands. One
combined future in the CLI runner crossed clippy's size budget and is
boxed at its call.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 13:37:11 -06:00
Bryan Helmkamp
3e2f00b423
Pin the sandbox driver to main with the git facet options merged
Pull request #18 on the driver is merged as a merge commit, so the
commit fabro was pinned to is an ancestor of main. Follow main.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 13:24:05 -06:00
Bryan Helmkamp
14875c2fdf
Set up and push the run branch through the driver's git facet
Fabro's run-branch setup and its pushes were the last git it assembled
by hand: two rev-parse calls, a checkout -B, and a push built as shell
and run through exec. Because those failures never passed through the
driver, fabro kept a second classifier that read git's stderr for the
same auth and not-found shapes the driver already classifies for a
clone.

Both now call the facet. Setup reads the current branch and head commit
from the driver's status and creates or moves the run branch at that
base; a push sends its refspec with what remains of the retry plan's
attempt budget as the push timeout. The retry plan, the credential
lease, and the drift repair stay as they were — they are fabro's
policy — but the decision they act on comes from the driver's failure
class, the same way the clone's does. The output-shaped classifiers and
the auth hint matchers are deleted; the message classifier remains for
the host-side repository probe and metadata push, which never run
inside a sandbox. A git failure's captured output now renders as the
attempt's output tail, as an exec failure's did.

The driver pin moves to lithoscomputer/sandbox-driver#18, which adds the
push refspec and timeout, the checkout start point, and the status head
this relies on.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 13:16:16 -06:00
Bryan Helmkamp
87e1e3a00f
Replace fabro-llm helper modules with lithos-llm equivalents
Delete fabro-llm's attachments, reasoning, and structured modules and
the LlmError newtype and ErrorFacts trait. lithos-llm now provides all
of them: InlineLocalFiles under the local-files feature, ReasoningOutput
with Response::reasoning(), Client::complete_object, and the retry,
auth, cancel, and failover predicates directly on Error and ErrorData.
fabro-llm keeps only failure_signature_hint, which is Fabro's own loop
detection policy.

Store ErrorData directly in the agent and workflow error enums, boxed
where the variant would otherwise dominate the enum size. Repin
lithos-llm to a1e3fd3 for these additions.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 09:41:20 -06:00
Bryan Helmkamp
6eb9ee8cd9
Pin lithos-llm at the Rust boundary revision
lithos-llm ba2f418 adds provider readiness, catalog queries, error policy
predicates, one-call structured output, local-file inlining, the reasoning
normalizer, the nearest supported effort, and built-in provider ids. Every
addition is additive, so this pin changes nothing yet; the commits that
follow adopt each one and delete Fabro's copy.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 09:09:21 -06:00
Bryan Helmkamp
c9bfd5edaa
Pin the sandbox driver to the merged main
The second-wave driver work — the tag pin, classified git failures, the
stop ladder, snapshot ensure, owner scoping, and the testing crate — is
merged as pull requests #10 through #15, so fabro follows the merge
commit on main instead of the head of the open stack. The content is
the same; the commits were rebased, so every hash changed.

CI installs the driver's plugin executables at the rev it reads from
Cargo.toml, so this also moves the executables the plugin scenarios run.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 08:33:43 -06:00
Bryan Helmkamp
6e874aff5b
Retire the fabro Sandbox trait for one concrete RunSandbox
Fabro carried its own Sandbox trait long after every implementation
became a thin layer over the sandbox driver: one production type
implemented it, a delegation macro forwarded it, and each consumer crate
kept hand-written fakes of its thirty methods for tests. The trait
existed to be mocked, and the mocks pinned behavior that no provider
had — canned walk listings that ignored the traversal root, opaque
provider paths, activation failures with no lifecycle behind them.

There is now one sandbox type. RunSandbox keeps fabro's semantics — path
resolution against the run's working directory, the Bash exec policy,
git setup and push, credential refresh — as inherent methods over the
driver's exec, filesystem, search, and git facets, and every consumer
takes Arc<RunSandbox>. The directory, grep, and walk types are the
driver's own, re-exported from fabro-sandbox. The exec policy reports
the provider's measured duration rather than its own clock.

Tests script a sandbox through fabro-sandbox's MockSandbox: a struct of
fields (seeded files, the result every command returns, the platform,
a runtime directory) that hands out a RunSandbox over the driver's
scripted doubles and reads back what the code did — commands, timeouts,
environment, term stops, writes, deletes, existence probes. The
hand-written fakes in fabro-agent, fabro-acp, fabro-hooks,
fabro-workflow, and fabro-server are gone; the one wrapper a git
integration test still needs sits at the driver level, hiding a path
from a real Host sandbox. The refresh-ahead loop takes the refresh as a
closure so its schedule is tested without a sandbox at all.

The driver pin moves to the testing-crate stack head, which gained the
double behavior these ports needed: retention caps on scripted output,
canned walks narrowed to the requested base, upload and download on the
memory filesystem, and recorders for deletes, existence probes, and
term stops. One test that modelled a provider handing back opaque object
paths from a walk is removed: the driver contract has no such thing.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 00:14:42 -06:00
Bryan Helmkamp
331935904a
Adopt the driver's tag pins, git classes, stop ladder, ensure, and ownership
The sandbox-driver stack fabro pins now carries five things fabro used
to do itself, so fabro stops doing them. A tag pin is a clone option,
so the exec-based init, fetch, and checkout path for tags is gone and
every pin goes through the driver's clone; the shell command builders
and the hermetic git proofs that only served that path go with it. The
driver classifies every git failure it produces, so the retry module
keeps only the decision (a rejected credential is retried while a fresh
App token may still be replicating; an unreachable remote is retried
whatever the credential; everything else is permanent) and its hint
tables are gone. The provider runs the TERM, grace, KILL ladder for the
timeout and for the caller's cancellation, so the exec wrapper sets the
grace on the spec, passes the cancellation token as the term stop, and
reads the driver's verdict instead of racing its own timer. Daytona's
snapshot is ensured by the driver, so the list, activate, create, and
poll sequence and its back-off loop are gone. Every provider is
connected through the driver's ownership scope, narrowed to the run when
one is known, so creates carry fabro's labels and attaches to anything
else are refused by the driver; the label module keeps only the label
names, and the inventory provider reads the scope's answers instead of
checking labels itself.

The pin moves to the stack head with the driver's fix for a command
that honours the TERM inside the grace, which fabro's own tests caught
as a timeout reported as a cancellation. The Docker checkpoint
integration tests now create their container through the driver, since
the driver attaches only to containers it created; they were reaching
for a hand-run container since the Docker cutover.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 23:00:56 -06:00
Bryan Helmkamp
ff231e890b
Pin the driver PR stack and run its own plugin executables
The plugin scenarios launched two executables fabro built itself,
`fabro-sandbox-host` and `fabro-sandbox-docker`, that only wrapped the
driver's providers in a stdio server the driver already ships as
`sandbox-driver-host` and `sandbox-driver-docker`. Fabro now finds the
driver's executables on PATH: CI installs them at the rev the workspace
pins, read from Cargo.toml so the plugins and the in-process providers
are one build, and a developer installs them the same way. The plugin
proof in fabro-sandbox skips without the executable unless the CI
environment forbids skipping; it was also never running in CI, which
ran it under `--run-ignored only` although it is not ignored, so the
job now runs it on its own.

The pin moves to the head of the sandbox-driver PR stack #9 through
#15: tag pins, classified git failures, the stop grace ladder, snapshot
ensure, the ownership scope, and the testing doubles, which the next
commits adopt. The `sandbox-driver-testing` crate joins the workspace
dependencies for them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 22:19:26 -06:00
Bryan Helmkamp
f2695b96c7
Pin lithos-llm at the catalog convergence revision
lithos-llm 38ccb14 moves the catalog policy Fabro carried under
metadata.fabro into core fields (enabled, stands_in_for, api_key_url,
family, cutoffs, estimated_output_tps, small_default, probe), ships the
openai-codex provider, reads the shared metadata.agent namespace, and
derives conventional secret names for operator-defined providers.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 22:11:21 -06:00
Bryan Helmkamp
5b035d3f75
Name plugins by their configured kind and drop out-of-process bundled kinds
sandbox-driver PR #9 removes the check that a plugin's declared kind match
the configured one: an operator who configures a path and pins its
checksum has already chosen the executable, so the configured kind is
fabro's name for whatever it serves. With that in the driver, fabro no
longer needs plugin settings on a bundled kind to reach Docker over the
wire. Bundled kinds reject plugin keys again, `connect_provider` links a
bundled kind in-process and launches everything else, and the CLI
scenarios run the Docker executable under the non-bundled `docker-plugin`
kind. The driver pin moves to the PR head until it merges.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 20:13:50 -06:00
Bryan Helmkamp
28d4242df0
Route Daytona sandboxes through the sandbox driver
The `daytona` provider kind now maps onto the sandbox-driver Daytona
provider instead of fabro's own SDK client. Fabro keeps what is its own:
the HMAC-named snapshot built from the environment's image or Dockerfile,
the explicit 120 minute auto-stop default, the managed labels that gate
destructive operations, the clone decision and layout, and push
credentials. The driver creates the sandbox, clones natively, and serves
exec, files, search, terminal, SSH, preview, and VNC through its facets.

- `daytona.rs` builds the driver `SandboxSpec` (snapshot source,
  `/home/daytona/workspace`, labels, timers, network policy, run name),
  ensures the snapshot through the driver `SnapshotProvider`, attaches by
  persisted id with fabro's label guard, and probes credentials through
  the provider health check under fabro's 20 second budget.
- `DriverSandbox` gains a create plan that settles the spec right before
  the provider call, records the snapshot a sandbox came from, and
  reports the provider console URL on `Ready`.
- Terminals use the driver `Pty` facet; the server's SSH, preview, and
  VNC endpoints use the `SshAccess`, `PreviewUrls`, and `Vnc` facets
  through the driver-typed reconnect. The preview endpoint now answers
  for every provider with a preview facet, so the local sandbox returns
  its loopback URL.
- Daytona credentials travel as `DaytonaCredentials` built from the
  vault key plus configured URL and organization; nothing reads the
  process environment implicitly. The inventory registry uses the shared
  `DriverInventoryProvider`.
- The SDK-based `daytona/mod.rs`, `provider/daytona.rs`, the Daytona
  terminal, the `daytona` cargo feature, and the direct daytona-sdk,
  git2 (in fabro-sandbox), tungstenite, and rustls dependencies are
  gone. The live Daytona tests run against the driver-backed sandbox.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 19:14:13 -06:00
Bryan Helmkamp
580bb85f5b
Depend on lithos-llm and the published twin-openai crate
Add lithos-llm as a pinned git dependency and replace the in-repo
`test/twin/openai` crate with the published `twins` revision that
lithos-llm verifies its codecs against. Move the Fabro policy overlay
(`fabro-policy.toml`) into fabro-llm so Fabro owns its own catalog
policy layer.

Drop the twin-openai nextest overrides and CI package filter now that the
crate is no longer a workspace member.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 17:26:57 -06:00
Bryan Helmkamp
3d33935fba
Route Docker sandboxes through the sandbox driver
Fabro's Docker provider kind now maps onto the sandbox-driver Docker
provider instead of its own bollard implementation. Fabro keeps what is
its own: the clone decision and repository layout, the GitHub App push
credentials embedded in origin, git retry classification, the managed
labels that gate destructive operations, and the run-facing events.

- `clone.rs` performs fabro's clone over the driver `Git` and `Exec`
  facets. An exact commit goes through the driver's pinned clone; a tag
  pin runs fabro's init/fetch/attach sequence through `Exec` so the
  fully qualified tag ref is the only revision consulted. Network
  failures retry through `git_retry`, which now classifies driver errors
  (exec output, provider retryability) and never replays an operation
  whose outcome is unknown.
- `DriverSandbox` gains a pending-create state, a `RepoWorkspace` with
  push-credential state, path resolution against the cloned working
  directory, git lifecycle methods, image-pull progress mapped from
  driver events, and an embedded terminal over the driver `Pty` facet.
- `docker.rs` builds the driver `SandboxSpec` (image, `/workspace`,
  fabro labels, env, cpu/memory, network policy, run name) and attaches
  by persisted container id, refusing containers without fabro's labels.
- Inventory, details, diagnostics, terminal, and reconnect run over the
  driver: a `DriverInventoryProvider` lists by fabro's managed label and
  projects `SandboxStatus` into fabro's inventory and details shapes.
- The bollard-based `docker.rs`, `provider/docker.rs`, Docker terminal,
  Docker error variants, the `docker` cargo feature, and the bollard and
  tar dependencies are gone. The Docker integration tests, the agent
  shell test, the workflow artifact test, and the driver benchmark run
  against the driver-backed sandbox.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 17:07:51 -06:00
Bryan Helmkamp
07c52b07ca
Depend on the sandbox-driver crates by git revision
Fabro pins the sandbox-driver workspace the same way it pins the
Daytona SDK: every crate at one commit on main. The bundled Host,
Docker, and Daytona provider libraries link in-process, and the
protocol crate reaches third-party providers over stdio. Nothing uses
the crates yet; the following commits move fabro onto them one layer
at a time.

The driver pins tracing-subscriber exactly, so the lockfile settles on
that version for the whole workspace.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 14:18:58 -06:00
Bryan Helmkamp
aa8b919f1c
Pin daytona-sdk-rust to the merged main commit
Both fabro and sandbox-driver now pin the same daytona-sdk-rust commit
on main. The newer SDK adds region and sandbox class fields to snapshot
creation; fabro leaves both unset and keeps its current behavior.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 13:45:44 -06:00
fabro-releases[bot]
2f326a13c4 Bump version to 0.348.0-nightly.0
Some checks failed
Rust / Format (push) Has been cancelled
Rust / Clippy (push) Has been cancelled
Rust / Generated Docs (push) Has been cancelled
Rust / Test (Linux) (push) Has been cancelled
Rust / Test (macOS) (push) Has been cancelled
2026-09-06 09:29:10 +00:00
fabro-releases[bot]
efa0d16588 Bump version to 0.347.0-nightly.0 2026-09-05 09:31:42 +00:00
fabro-releases[bot]
86101748da Bump version to 0.346.0-nightly.0 2026-09-04 09:35:05 +00:00
fabro-releases[bot]
a468125ab3 Bump version to 0.345.0-nightly.0 2026-09-03 09:33:32 +00:00
fabro-releases[bot]
2bf41d908b Bump version to 0.344.0-nightly.0 2026-09-02 09:36:17 +00:00
fabro-releases[bot]
285d485de7 Bump version to 0.343.0-nightly.0 2026-09-01 09:36:51 +00:00
fabro-releases[bot]
3a5c683fbf Bump version to 0.342.0-nightly.0 2026-08-31 09:41:11 +00:00
fabro-releases[bot]
775b62b500 Bump version to 0.339.0-nightly.1 2026-08-28 20:41:40 +00:00
fabro-releases[bot]
f87ece704b Bump version to 0.339.0-nightly.0 2026-08-28 13:11:14 +00:00
fabro-releases[bot]
88185f0bd9 Bump version to 0.338.0-nightly.0 2026-08-27 12:48:55 +00:00
fabro-releases[bot]
ff29795dd8 Bump version to 0.337.0-nightly.1 2026-08-26 13:41:21 +00:00
fabro-releases[bot]
1289144f03 Bump version to 0.337.0-nightly.0 2026-08-26 09:31:24 +00:00
fabro-releases[bot]
e74f3c6c4b Bump version to 0.336.0-nightly.1 2026-08-25 13:26:02 +00:00
fabro-releases[bot]
7ae7ca9ead Bump version to 0.336.0-nightly.0 2026-08-25 09:31:30 +00:00
fabro-releases[bot]
330d0f8984 Bump version to 0.335.0-nightly.1 2026-08-24 18:48:34 +00:00
fabro-releases[bot]
2bf86327c0 Bump version to 0.335.0-nightly.0 2026-08-24 09:36:45 +00:00
fabro-releases[bot]
7200d437e9 Bump version to 0.333.0-nightly.0
Some checks failed
Rust / Format (push) Has been cancelled
Rust / Clippy (push) Has been cancelled
Rust / Generated Docs (push) Has been cancelled
Rust / Test (Linux) (push) Has been cancelled
Rust / Test (macOS) (push) Has been cancelled
TypeScript / Typecheck (push) Has been cancelled
TypeScript / Test (push) Has been cancelled
TypeScript / Build (push) Has been cancelled
2026-08-22 04:04:57 +00:00
Bryan Helmkamp
438bab29f0
feat: support shallow sandbox clones 2026-08-21 17:11:24 -04:00
fabro-releases[bot]
346e81f400 Bump version to 0.332.0-nightly.1 2026-08-21 11:40:10 +00:00
fabro-releases[bot]
f8879d13c4 Bump version to 0.332.0-nightly.0
Some checks are pending
Rust / Generated Docs (push) Waiting to run
Rust / Test (Linux) (push) Waiting to run
Rust / Test (macOS) (push) Waiting to run
TypeScript / Typecheck (push) Waiting to run
TypeScript / Test (push) Waiting to run
TypeScript / Build (push) Waiting to run
Rust / Format (push) Waiting to run
Rust / Clippy (push) Waiting to run
2026-08-21 02:31:24 +00:00
fabro-releases[bot]
03c3412e51 Bump version to 0.331.0-nightly.0 2026-08-20 09:26:14 +00:00
fabro-releases[bot]
519e456b28 Bump version to 0.330.0-nightly.0 2026-08-19 09:28:39 +00:00
fabro-releases[bot]
400be9f2dc Bump version to 0.329.0-nightly.0 2026-08-18 09:28:05 +00:00
fabro-releases[bot]
535e333970 Bump version to 0.325.0-nightly.0
Some checks failed
Rust / Format (push) Has been cancelled
Rust / Clippy (push) Has been cancelled
Rust / Generated Docs (push) Has been cancelled
Rust / Test (Linux) (push) Has been cancelled
Rust / Test (macOS) (push) Has been cancelled
2026-08-14 09:41:55 +00:00
fabro-releases[bot]
d5b3da87fc Bump version to 0.324.0-nightly.0 2026-08-13 09:41:35 +00:00
fabro-releases[bot]
0abf2297c0 Bump version to 0.316.0-nightly.0
Some checks failed
Rust / Format (push) Has been cancelled
Rust / Clippy (push) Has been cancelled
Rust / Generated Docs (push) Has been cancelled
Rust / Test (Linux) (push) Has been cancelled
Rust / Test (macOS) (push) Has been cancelled
2026-08-05 10:08:51 +00:00
fabro-releases[bot]
f5ed1bd0c9 Bump version to 0.315.0-nightly.0 2026-08-04 10:11:51 +00:00
fabro-releases[bot]
77e7704e81 Bump version to 0.313.0-nightly.0
Some checks are pending
Rust / Generated Docs (push) Waiting to run
Rust / Test (Linux) (push) Waiting to run
Rust / Test (macOS) (push) Waiting to run
Rust / Format (push) Waiting to run
Rust / Clippy (push) Waiting to run
2026-08-02 09:55:44 +00:00
fabro-releases[bot]
d16cd75c56 Bump version to 0.312.0-nightly.1 2026-08-01 14:42:21 +00:00
Bryan Helmkamp
20d3aa5cdd
Merge pull request #705 from fabro-sh/feat/download-all-artifacts
Download latest artifacts as a ZIP
2026-08-01 09:28:16 -04:00