Commit graph

221 commits

Author SHA1 Message Date
Bryan Helmkamp
5d9d4f8b35 Add publish = false to all crates to prevent accidental crates.io publish
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 13:08:19 -04:00
Bryan Helmkamp
5d53ad6dbd Make metadata rebuild recovery robust 2026-03-29 09:35:13 -04:00
Bryan Helmkamp
a6da73ecd1 Rebuild metadata branches from the run store 2026-03-29 09:10:50 -04:00
Bryan Helmkamp
27f13e7957 Fix store migration gaps: retro agent, finalize commit, engine failure, and hydration tolerance
- retro_agent::upload_data_files reads from RunStore first with filesystem
  fallback for progress.jsonl, checkpoint, run record, and start record
- write_finalize_commit reads retro.json from store before falling back to disk
- persist_terminal_engine_failure uses build_conclusion_from_store instead of
  disk-only build_conclusion
- open_or_hydrate_run tolerates malformed checkpoint/conclusion/retro/sandbox
  JSON files during hydration (warns and skips instead of failing)
- Box<DbReader> in SlateRunDb fixes clippy large_enum_variant warning
- Fix tests that called open_or_hydrate_run on dirs without run.json
- Nextest test-groups replace global thread cap for better parallelism
- opt-level=1 for dev dependencies shrinks test binary sizes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 08:22:15 -04:00
Bryan Helmkamp
9c66dcb6f0 Fix remaining CLI store migration gaps 2026-03-28 23:23:38 -04:00
Bryan Helmkamp
f6f5c25498 Wire workflows and CLI to fabro-store 2026-03-28 22:57:49 -04:00
Bryan Helmkamp
fb3527e896 Replace mockito with httpmock in fabro-hooks, fabro-openai-oauth, and fabro-tracker
mockito's Server::new_async() triggers macOS SCDynamicStoreCreateWithOptions
via hyper-util (~300ms per test), which serializes on configd under workspace
concurrency and causes 4s+ timeouts. httpmock avoids this path entirely.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 20:39:14 -04:00
Bryan Helmkamp
a2ab2f8528 Return graphs from workflow transforms 2026-03-28 19:02:22 -04:00
Bryan Helmkamp
0db3856445 Consolidate integration tests under tests/it 2026-03-28 18:39:52 -04:00
Bryan Helmkamp
ab39f728c4 Replace mockito with HttpClient trait in fabro-github and detect import self-loops
Introduce an HttpClient trait abstraction over reqwest::Client so tests
use a lightweight MockHttpClient instead of spawning a TCP server via
mockito. This removes the mockito dev-dependency entirely and makes
tests faster and more deterministic.

Also add self-loop detection in ImportTransform to poison placeholders
that have edges pointing back to themselves.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:35:22 -04:00
Bryan Helmkamp
2fa91fe6cb Fix import transform edge cases 2026-03-28 17:44:41 -04:00
Bryan Helmkamp
847c0481d0 Add file-based workflow imports 2026-03-28 17:28:37 -04:00
Bryan Helmkamp
007fb54286 Fix unreachable_pub and unsafe_code warnings in test code
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 17:22:27 -04:00
Bryan Helmkamp
533ebc3f87 Fix clippy type_complexity lints with OnNodeCallback type alias
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 17:11:40 -04:00
Bryan Helmkamp
20f2a3b8bb Add detached engine process titles 2026-03-28 16:44:56 -04:00
Bryan Helmkamp
8a03928db6 Fix sandbox spec feature gating 2026-03-28 16:38:57 -04:00
Bryan Helmkamp
8b3ca5ef01 Centralize sandbox variant handling 2026-03-28 16:34:27 -04:00
Bryan Helmkamp
4cb56de9ec Remove legacy runtime IPC fallbacks 2026-03-28 15:26:32 -04:00
Bryan Helmkamp
2eb39d368c Rename *config* variables/params that hold *Settings types
Local variables and function parameters named with "config" but holding
*Settings types (FabroSettings, TlsSettings, ApiSettings, LlmSettings)
are renamed to use "settings" for consistency with the type system.
Module paths (cli_config::) and struct fields are unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 15:15:15 -04:00
Bryan Helmkamp
52d0478a47 Enable 7 additional pedantic clippy lints
Enables char_lit_as_u8, collapsible_else_if, collapsible_if,
map_unwrap_or, match_same_arms, used_underscore_binding, and
if_not_else. Fixes all violations: combines duplicate match arms,
renames underscore-prefixed bindings that are actually used, rewrites
if-not-else patterns, and applies map_or where appropriate.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:57:48 -04:00
Bryan Helmkamp
4901e0ec8f Enable additional pedantic clippy lints and fix violations
Enables cast_possible_truncation, cast_sign_loss, items_after_statements,
needless_pass_by_value, return_self_not_must_use, uninlined_format_args,
unreadable_literal, and unnested_or_patterns. Keeps doc_markdown disabled.

Replaces unsafe `as` casts with try_from().unwrap() throughout, using
#[allow] only for f64-to-integer casts which have no try_from equivalent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:31:11 -04:00
Bryan Helmkamp
13eca22f5a Enable clippy pedantic lints and restriction lints workspace-wide
Adopts uv's clippy lint configuration: pedantic group at warn priority,
with noisy lints allowed, plus restriction lints for print/dbg/exit/use_self.
Fixes all violations across the workspace.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:37:57 -04:00
Bryan Helmkamp
bd97e76fe5 Apply rustfmt 2024 style edition across workspace
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 12:56:30 -04:00
Bryan Helmkamp
e6d865e29f Enforce no-inline-qualified-paths via clippy absolute_paths lint
Add clippy.toml with absolute-paths-max-segments = 2 (allowing std/core/alloc)
and enable the absolute_paths = "warn" lint workspace-wide. Fix all ~300
violations across the codebase: replace 3+-segment inline paths with use
statements so call sites read as operations::create() rather than
fabro_workflows::operations::create(). The demo module gets an allow
attribute since it constructs many API types by design.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 12:42:02 -04:00
Bryan Helmkamp
9e5d77bb0b Enforce no-wildcard-imports via clippy workspace lint
Configure clippy `wildcard_imports = "warn"` at the workspace level and
opt all 28 crates in via `[lints] workspace = true`. Fix the three
production glob imports that triggered warnings: fabro-sandbox
read_guard, fabro-cli main, and fabro-api demo module (allowed via
attribute since it constructs many API types by design). Document the
import style convention in CLAUDE.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:14:34 -04:00
Bryan Helmkamp
b314742eb8 Extract RunSession from run_engine to eliminate intermediary option types
Replace four private types (InternalStartOptions, StartRetroOptions,
StartFinalizeOptions, StartPullRequestConfig) with a single RunSession
struct. Convert derive_start_options and run_engine into RunSession::new
and RunSession::run methods, flattening the nested config fields.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 01:39:43 -04:00
Bryan Helmkamp
c6c48b2e5e Extract push_run_branches helper from rewind.rs and fork.rs
Both rewind_to_entry and fork_from_entry had nearly identical 25-line
blocks resolving the repo path, checking for a remote tracking branch,
and pushing run+meta refspecs. Extract Store::repo_dir() and a shared
push_run_branches() helper to eliminate the duplication.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 01:34:24 -04:00
Bryan Helmkamp
cf9dcbde10 Remove unused goal_override and base_dir from PersistCreateOptions
These fields were only consumed by create_from_source before calling
persist_validated, which immediately destructured them to _. Pass them
as explicit parameters to create_from_source instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 01:16:57 -04:00
Bryan Helmkamp
cc381f2bf5 Create RuntimeState for run runtime and cache paths 2026-03-28 01:14:14 -04:00
Bryan Helmkamp
127e0211cc Deduplicate timeline resolution and test helpers in operations
Move resolve_target into RunTimeline::resolve() method and extract
shared test helpers (temp_repo, test_sig, make_checkpoint_json) into
a test_support module used by both fork.rs and rewind.rs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 00:50:35 -04:00
Bryan Helmkamp
46737b7728 Fix Slate store fencing and restore status shape 2026-03-28 00:42:45 -04:00
Bryan Helmkamp
6460c95751 Add fabro-store with in-memory and SlateDB backends 2026-03-28 00:13:25 -04:00
Bryan Helmkamp
7f127a9402 Split validate.rs and resume.rs out of operations
Extract validate() into its own file from create.rs and resume() into
its own file from start.rs, maintaining one public operation per file.
Shared helpers (preprocess_and_validate, execute_persisted_run) become
pub(super) so the new modules can call them.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 21:35:30 -04:00
Bryan Helmkamp
1944af5e54 Create fabro-types and rewire shared types 2026-03-27 21:15:03 -04:00
Bryan Helmkamp
75b5aa35b9 Refactor workflow operations and config resolution 2026-03-27 17:58:05 -04:00
Bryan Helmkamp
f8cc95e97d Tighten workflows request context and launcher cleanup 2026-03-27 17:04:45 -04:00
Bryan Helmkamp
3c3cefb452 Thin CLI run commands and move execution into workflows operations 2026-03-27 16:27:55 -04:00
Bryan Helmkamp
022e0cc54f Clean up resolved settings interfaces 2026-03-27 15:32:06 -04:00
Bryan Helmkamp
b1642a93ef Refactor config layering into combine plus settings 2026-03-27 14:52:11 -04:00
Bryan Helmkamp
ace13ac848 Rename --run-dir to --storage-dir, unify with data_dir
Replace the per-run `--run-dir` CLI flag with `--storage-dir` which sets
the base storage directory (default ~/.fabro). Runs are now created under
`<storage-dir>/runs/` automatically. This unifies the server's `data_dir`
config with the CLI by renaming `FabroConfig.data_dir` to `storage_dir`
and adding a `storage_dir()` convenience method.

Key changes:
- FabroConfig: `data_dir` → `storage_dir` (serde alias preserves compat)
- CLI: `--run-dir` → `--storage-dir` on `fabro run`
- `__detached`: now takes `--storage-dir` + `--run-id` instead of `--run-dir`
- All ~20 CLI commands derive runs base from config instead of hardcoded default
- Added parameterized `runs_base(storage_dir)` and `make_run_dir()` helpers
- Updated OpenAPI spec, docs, and all tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 13:20:01 -04:00
Bryan Helmkamp
b970fdef2b fix(operations): thread git checkpoint options through RunOptions
RunOptions.git was hardcoded to None in run_engine(), relying on
initialize to overwrite it from InitOptions.git. Pass options.git
directly for consistency — initialize still owns the final decision
(clearing it on worktree failure).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 23:17:42 -04:00
Bryan Helmkamp
8e51d9c29b Fix verification regressions after runtime init refactor 2026-03-26 22:48:47 -04:00
Bryan Helmkamp
bb791e98b0 Refactor workflow runtime initialization 2026-03-26 22:18:07 -04:00
Bryan Helmkamp
571ac0e1f3 Guard resume against completed runs 2026-03-26 13:53:12 -04:00
Bryan Helmkamp
13e394fa5b refactor: clean CREATE/START/RESUME separation
Resume now follows the same subprocess pattern as run: look up run
directory by ID prefix, validate checkpoint exists, clean stale
artifacts, reset status to Submitted, spawn _run_engine --resume, and
attach. This eliminates ~1600 lines of duplicated env/sandbox setup
from resume.rs.

Key changes:
- operations::start() and operations::resume() take run_dir instead
  of Persisted, loading state from disk internally
- run_engine() builds RunOptions from RunRecord on disk, so callers
  no longer extract record fields manually
- StartOptions flattened (no more nested InitOptions)
- FabroError::Precondition variant for start/resume guard checks
- _run_engine accepts --resume flag to dispatch to resume path
- operations::restore removed (no longer needed)
- Resume CLI stripped to just <RUN_ID> + --detach

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 12:58:47 -04:00
Bryan Helmkamp
97e2ff7882 Add restore operation for resumed runs 2026-03-26 10:30:30 -04:00
Bryan Helmkamp
e6e913eabc refactor: rename local variables/fields to align with Options suffix
Follow-up to fafc0a3c. Renames local variables, function parameters,
and struct fields that hold renamed types (ExecutorOptions, RunCreateOptions,
RunOptions) from config/settings to options/run_options for consistency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 09:24:11 -04:00
Bryan Helmkamp
fafc0a3c39 refactor: rename Settings/Config structs to Options suffix
Standardize naming so all "bag of options" structs use the Options
suffix: ExecutorSettings→ExecutorOptions, RunSettings→RunOptions,
GitCheckpointSettings→GitCheckpointOptions, LifecycleConfig→LifecycleOptions,
RunCreateSettings→RunCreateOptions, StartRetroConfig→StartRetroOptions,
StartFinalizeConfig→StartFinalizeOptions, AutoMergeConfig→AutoMergeOptions.
Also renames the run_settings module to run_options.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 08:52:15 -04:00
Bryan Helmkamp
c81e61bd12 Add pull_request pipeline stage 2026-03-26 08:38:23 -04:00
Bryan Helmkamp
89ad849208 refactor(operations): make create own the full create lifecycle
operations::create now handles the full pipeline: var expansion, parse,
goal override, transform, validate, config normalization, and persist.
This eliminates duplicated RunRecord construction and pipeline::persist
calls across CLI and API callers.

Key changes:
- Rename operations::create → validate, CreateOptions → ValidateOptions
- New operations::create returns Persisted, with RunCreateSettings
- Add ValidationFailed error variant with diagnostics
- Move normalize_config, default_run_dir into operations
- Delete prepare_workflow, PreparedWorkflow, CliFlags from CLI
- Make pipeline::persist and types module pub(crate)
- API catches both Parse and ValidationFailed as 400
- CLI prints diagnostics directly from error (no re-validation)
- ExecutionOverrides struct replaces 9-param function

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 23:09:16 -04:00