Drop async from validate::run after the preflight refactor removed all
awaits, replace absolute paths and a one-liner helper in
manifest_validation, swap a redundant to_path_buf for clone in a test,
and regenerate cli.mdx so docs check stays green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace remaining expensive CLI lifecycle checks with seeded fixtures or focused unit coverage so the concurrent suite spends less time on duplicate full-process setup.
Seed read-only CLI tests from run-store fixtures, remove duplicate expensive lifecycle coverage, and keep machine-dependent gh tests offline so the suite no longer probes local credentials.
Replace per-file sandbox metadata git writes with one fast-import stream per metadata commit while preserving the push-after-each-commit contract. Cover binary files, quoted paths, parent linkage, and per-snapshot push behavior in the metadata writer regression test.
Add a validation-only API response and route while keeping fabro validate local so it does not start or contact the server for structural workflow checks.
Eliminate four parallel-type duplications between fabro-api generated
DTOs and fabro-types canonical types. The wire shape is owned by
OpenAPI; canonical types are reused via fabro-api/build.rs
with_replacement so the adapter functions and silent unwrap_or_default
defaults disappear.
- SecretType moves to fabro-types (was fabro-vault); deletes
secret_type_from_api adapter.
- DiffLineStats renamed to DiffStats, moved to fabro-types, switched
u64 -> i64 to match the OpenAPI integer; deletes line_stats_to_api.
- ManifestPreRunPushOutcome rewritten as a oneOf+discriminator
PreRunPushOutcome over five variant schemas, deleting both
pre_run_push_outcome_from_manifest and build_manifest_push_outcome.
- ManifestGit and PreRunGitContext unify as GitContext: dirty:
DirtyStatus replaces clean: bool (preserving the Unknown state
previously truncated on the wire), sha becomes Option<String>, and
origin_url/branch fold into the unified context. RunSpec and
RunCreatedProps flatten three fields (repo_origin_url, base_branch,
pre_run_git) into a single git: Option<GitContext>.
Each replacement gets a fabro-api parity test (TypeId equality plus
JSON roundtrip) modeled on run_summary_round_trip.rs. TS client
regenerated.
Greenfield app, no production deployments — wire contract changed
directly without backwards-compat shims.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Set debug = "line-tables-only" and split-debuginfo = "off" for the dev
and test profiles. Keeps backtraces with file/line info but trims local
variable metadata and split-debug artifacts that drive APFS metadata
churn during cargo clean and incremental rebuilds on macOS.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The persisted bool described user intent (\"the user opted into the
in-place execution mode\"), not a literal consequence -- SlateDB and
event-sourced checkpoints flow regardless of the flag, only git
checkpoints are skipped. Renaming aligns the name with intent and
decouples it from any future implementation that allows git
checkpoints in-place.
The fork validator still consults this bool to bail out with a clear
error before searching for git checkpoints that won't exist.
Two queries: per-test p50/p90 regression ordered by largest median delta,
plus a per-package roll-up of total wall-time and quantile shifts. Filters
to passed tests so flakes don't skew medians. Run with `duckdb < test/
analysis/bench-tests-diff.sql` against two CSVs produced by `cargo dev
bench-tests`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
WorkdirStrategy was structurally redundant with the existing
LocalSandboxLayer.worktree_mode config — Local sandboxes always picked
LocalWorktree, everything else picked Cloud, and the LocalDirectory arm
was only ever reachable via the parallel checkpoints_disabled bool.
resolve_worktree_plan now reads worktree_mode directly: Cloud sandboxes
return None with a pre_run_git base sha; Local + Never returns None
with no base sha; Local + non-Never builds the WorktreePlan as before.
RunOptions.checkpoints_disabled drops out: the lifecycle gate becomes
has_run_branch (git: None alone is the canonical "no git checkpoints"
signal), and tests/fixtures stop carrying the field.
Runs the workspace test suite N times via `cargo nextest run --no-fail-fast`
and appends one row per testcase to a CSV (git_sha, run_index, started_at,
binary, package, classname, test_name, status, duration_ms). Group ≈ package
is derived from the JUnit testsuite name.
The lenient `[profile.bench]` (with junit.path) is synthesized at runtime to
target/bench-tests/nextest-tool.toml and passed via `--tool-config-file`, so
nothing needs to be added to .config/nextest.toml.
Intended use: collect samples on the current checkout, switch SHAs, collect
again, then diff/aggregate externally to hunt slowdowns.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop --allow-no-checkpoints and the paired ManifestArgs in_place /
allow_no_checkpoints fields. The CLI now translates --in-place into a
single ManifestArgs.worktree_mode = "never" signal that flows through
the existing args→layer pipeline as run.sandbox.local.worktree_mode =
Never. The server computes prepared.in_place from the resolved settings
once, replacing the trio of bail!s and the sandbox-default fixup.
Skip worktree checkpoint setup when a local sandbox is not backed by a git repository, and keep the API contract aligned with RunSpec serialization for omitted labels.
Ensure local runs use the worktree checkpoint path by default, expose source and sandbox paths in API/web surfaces, and remove dead fork/rewind push controls. Update docs for clone-based sandboxes and durable checkpoint timelines.
Add shared sandbox git validation for checkpoint paths, preserve forked run projection state, and record CLI remote mismatches explicitly. Refresh the API/client docs for durable run-store timeline and structured run specs.
- Reuse fabro_sandbox::shell_quote in sandbox_metadata.rs and sandbox_git.rs
(CLAUDE.md mandates the shared helper, not local reimplementations).
- Skip git_diff call on first checkpoint when prev SHA equals new SHA;
previously diffed a SHA against itself, costing one sandbox round-trip.
- Drop tuple-match theatre in write_snapshot cleanup.
- Type LEVEL_COLOR as Record<LogLevel, string> so the lookup is exhaustive.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add GET /api/v1/runs/{id}/graph/source returning text/vnd.graphviz so
the run graph can be inspected as the original Graphviz DOT in addition
to the rendered SVG. Refactor get_graph to share DOT loading with the
new handler. The web run-graph view gains a Graph | Source toggle that
lazy-loads and displays the DOT with a copy button.
The span name "run" already namespaces the field, so `run{id=...}` reads
cleaner than `run{run_id=...}` in log output.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Parse each tracing line in the run logs panel and tint the timestamp,
level, target, and message separately. Errors and warnings now stand
out at a glance (coral/amber) while debug/trace and the surrounding
chrome recede. Original whitespace is preserved so the formatter's
column alignment is intact.
Hide the Steer action on board cards outside demo mode so the action
list reflects what the operator can actually do. Hide the lifecycle
status pill on cards in the Initializing column since the column header
already conveys the state. Shorten the install wizard top nav label
"Object store" to "Storage".
Operators choose Docker (default, zero-config) or Daytona (validated
via Daytona SDK) during browser install. Selection is captured in
settings.toml under [run.sandbox] -- explicitly even for Docker, so the
choice is locked in. Daytona keys land in the vault as DAYTONA_API_KEY
(Environment secret). Step always runs after object_store and before
the LLM step.
Server adds POST /install/sandbox/test (validates Daytona key via
client.list) and PUT /install/sandbox; both reuse the install-token
auth and InstallSecret redaction patterns established by object-store.
A resolve_install_sandbox_state helper preserves a saved Daytona key
when the operator revisits the step without re-entering it. The
in-memory api_key is dropped from PendingInstall after finish, matching
the manual_credentials cleanup for S3 access keys.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extract a fail_init helper on DockerSandbox/DaytonaSandbox to collapse
~15 copy-pasted 8-line InitializeFailed emit-and-return blocks. Convert
Error::message(format!(\"...{e}\")) to Error::context for the .map_err
sites whose source implements std::error::Error, preserving cause
chains. Drop the redundant no_store_default middleware (security_headers
already sets the default) and skip path allocation in
http_log_middleware for /assets/ requests.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Update test sites to call .to_string() before .contains() since the
sandbox Error enum no longer dereferences to String, add use statements
to satisfy clippy::absolute_paths, and inline the redundant
sandbox_error helpers in fabro-agent to clear needless_pass_by_value.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When the packaged container starts as root, map the mounted Docker socket's group into the container and add the unprivileged fabro user before dropping privileges. This lets Docker sandboxes work with socket mounts from OrbStack, Docker Desktop, and Linux daemons whose socket GID varies by host.
Keep demo dispatch scoped to API requests, add no-store defaults for install responses, and update the server test sandbox mock for typed sandbox errors.
The ubuntu-*-arm-32-cores runner images don't ship with unzip, so
oven-sh/setup-bun fails when extracting the bun release zip. x86
runner images include it, which is why only the aarch64-unknown-linux
compile jobs failed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The references previously read `docs/CONTRIBUTING.md` and `docs/AGENTS.md`,
which never existed at those paths. The actual style references live at
the repo root.