Commit graph

43 commits

Author SHA1 Message Date
Bryan Helmkamp
5eeacd7864 fmt 2026-04-11 11:27:46 -04:00
Bryan Helmkamp
2d8dea3454 Merge origin/main into main
Brings in the events schema v2 work (RunEvent envelope fields, ActorRef,
parallel branch ids, flattened EventEnvelope wire JSON) on top of the
local Stage 6 settings TOML redesign.

Conflict resolutions:
- fabro-types/src/lib.rs: keep new ParallelBranchId re-export from
  origin; drop the legacy Settings/ArtifactStorage* re-exports (the
  flat Settings struct was deleted in Stage 6.3b).
- fabro-server/src/server.rs: keep new ActorRef import from origin;
  drop the unused legacy Settings import that came along with it.
- fabro-api-client/src/models/web-settings.ts: keep our deletion. The
  remote modification was an incidental TS-client regeneration that
  Stage 6.6 already invalidated by collapsing settings DTOs to a
  freeform v2 shape.
- fabro-workflow/src/event.rs: rewrite the run_created actor test to
  use SettingsFile::default() instead of the deleted Settings type.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 21:11:55 -04:00
Bryan Helmkamp
3eabc013d1 test(migration): land final Stage 4 fixes — 100% workspace tests green
Close out consumer migration with targeted behavior fixes and the
remaining integration-test fixture rewrites. The full workspace
nextest run now reports 3,760 passed / 0 failed / 182 skipped.

Runtime fixes:
- effective_settings::apply_server_defaults now propagates the full
  server-side Settings shape (llm, sandbox, setup, checkpoint,
  pull_request, artifacts, hooks, mcp_servers, github, slack, fabro)
  into the resolved CLI settings, matching the pre-Stage-3 'merge
  everything server' behavior for RemoteServer/LocalDaemon modes
- fabro-cli commands/run/overrides: route --verbose through
  cli.output.verbosity = verbose instead of a run.metadata stash,
  so it resolves to settings.verbose via the bridge
- fabro-server run_manifest manifest_args_layer: same — emit a
  CliLayer with cli.output.verbosity rather than stuffing the flag
  into run.metadata
- fabro-test settings_storage_dir: detect the managed marker and
  return None instead of parsing the injected server.storage.root,
  so isolated_server correctly spins up a new storage dir
- fabro-server run_manifest_local_daemon test now passes with full
  server-side settings snapshot propagation

Test fixture + assertion updates:
- cmd::config::settings_local_explicit_workflow_path_uses_workflow_project_layers:
  assertion updated for v2 R30 whole-list replacement of
  run.prepare.steps across layers (only workflow-setup survives)
- cmd::config::create_explicit_workflow_path_uses_project_config_relative_to_workflow:
  same correction for the persisted run.settings.setup.commands
- cmd::attach::attach_json_errors_without_prompting_for_human_input
  and cmd::run::json_run_implies_auto_approve_for_human_gates: strip
  the bridge-emitted settings.server and settings.version fields from
  the JSON snapshot so the randomised unix-socket path does not flap
  the insta snapshot
- cmd::server_start::concurrent_autostart_converges_on_one_shared_daemon_and_cleans_up:
  rewrite the injected settings.toml to v2 shape with
  [server.storage] root and [cli.target] type = unix path
- scenario::smoke::attach_smoke_covers_arg_validation_and_remote_server_behaviors:
  two [server] target fixtures rewritten to [cli.target]
  type = http url

Accepted insta snapshots for attach and run JSON outputs. Workspace
build + clippy both clean under -D warnings.
2026-04-09 11:07:18 -04:00
Bryan Helmkamp
58f400c70c feat(api): flatten EventEnvelope wire JSON (schema v2)
Wire EventEnvelope now inlines the RunEvent payload fields alongside
seq at the top level of the JSON object. The internal Rust
EventEnvelope { seq, payload } stays structurally unchanged; only the
API/SSE serialization layer flattens for clients.

- OpenAPI spec: add stage_id, parallel_group_id, parallel_branch_id,
  tool_call_id, actor to RunEvent; model EventEnvelope as allOf(seq,
  RunEvent); introduce ActorRef/ActorKind schemas.
- fabro-server: rewrite api_event_envelope_from_store to merge seq
  into the payload JSON value before returning the generated flat
  type; remove the now-unused nested ApiRunEvent conversion helper.
- fabro-cli server_client: add wire_event_envelope_into_store helper
  that turns flat wire JSON back into fabro_store::EventEnvelope
  { seq, payload } for internal consumers.
- Regenerate progenitor Rust types and typescript-axios client.
- Update demo stubs, SSE tests, CLI test helpers, and insta
  snapshots to expect the flattened shape and the new stage_id field.

Incidental: the typescript regeneration also picked up prior-merged
spec fields (ApiQuestion stage/timeout/context, upload manifest
batches, web-settings) that were stale in the TS client.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 10:40:21 -04:00
Bryan Helmkamp
c33deedb34 fix(test): eliminate recovery, cancel, and label flakes
Stabilize the recovery scenario around rebuilt metadata timing and node
ordinals, make in-process run cancellation converge on a cancelled
reason, and keep the label assertion unit test out of the shared
TestContext session lifecycle.
2026-04-08 10:13:17 -04:00
Bryan Helmkamp
0928620904 perf(cli): reduce slow integration test overhead
Collapse expensive CLI smoke coverage into scenario tests, replace the
slow doctor no-color integration check with a unit-level render test,
and remove duplicate attach coverage. Also fix local Unix-socket
autostart so missing daemons don't spend the full 5s readiness wait
before startup.

The commit includes the measured slow-test report updates for the work
landed here.
2026-04-07 22:57:45 -04:00
Bryan Helmkamp
4dc31192b8 refactor(scratch): remove stale scratch file refs
Drop scratch-only compatibility paths and legacy test scaffolding now that
SlateDB-backed state is authoritative. This removes scratch file fallbacks,
updates docs and UI labels, and moves tests onto durable store-backed helpers.
2026-04-07 20:40:06 -04:00
Bryan Helmkamp
0eca7d94d6 fix(run): make attach stream terminal-authoritative
Replay persisted run events for attach requests, keep the SSE stream live
only while the run is active, and close on terminal run events instead of
returning 410 for completed runs.

The CLI now treats premature attach EOF as an error, and the affected
integration tests were stabilized around store-backed event ordering and
recovered rewind timelines.
2026-04-07 14:32:23 -04:00
Bryan Helmkamp
23231eb1ae refactor(cli): separate local socket and storage defaults
Keep local server targeting based on explicit server targets instead of
implicitly deriving a socket from storage_dir. This makes ~/.fabro/fabro.sock
the default local socket again, keeps storage under ~/.fabro/storage, threads
FABRO_CONFIG through server autostart paths, and updates the CLI test harness
for the new split.
2026-04-06 11:57:14 -04:00
Bryan Helmkamp
bd8f0fe5ee refactor(storage): unify scratch paths and key schema
- centralize FABRO_HOME and storage path resolution in fabro-config
- rename store types, extract ArtifactStore, and simplify run key layout
- switch run scratch to scratch/, remove RuntimeState, and refresh docs/clients
2026-04-06 10:13:37 -04:00
Bryan Helmkamp
9c61608d96 refactor(cli): make run-adjacent commands server-only 2026-04-06 06:12:16 -04:00
Bryan Helmkamp
a1e0762eb0 refactor(workspace): satisfy clippy all-targets warnings 2026-04-05 14:37:32 -04:00
Bryan Helmkamp
824fb66d51 refactor(cli): simplify run lifecycle around server ownership
Rename the hidden detached worker command to __runner, remove launcher
bookkeeping, and resolve runs through a shared server-backed lookup.
This leaves attach, resume, logs, and related commands using the server
as the source of truth and updates the integration coverage around the
new lifecycle.
2026-04-05 12:11:55 -04:00
Bryan Helmkamp
a19aef2e3c test(cli): consolidate artifact integration coverage 2026-04-05 11:26:32 -04:00
Bryan Helmkamp
2b6ba07f36 fix(cli): restore green server-backed test checkpoint 2026-04-05 03:41:10 -04:00
Bryan Helmkamp
2889d5b2c2 fix(tests): isolate shared-daemon scenario helpers 2026-04-05 03:18:46 -04:00
Bryan Helmkamp
bf2b6ba701 refactor(cli): route run state through the shared server daemon
Move durable run access and execution control onto the server-backed client,
canonicalize run APIs under /api/v1/runs, and switch CLI integration tests
to a shared test daemon/storage model with shared-state-safe assertions.
2026-04-05 00:15:33 -04:00
Bryan Helmkamp
cba8de4d94 Refactor assets into blob-backed artifacts 2026-04-04 12:08:15 -04:00
Bryan Helmkamp
b40b145424 merge: resolve conflicts from origin/main
Merged origin/main incorporating:
- db_prefix threading in SlateRunStore for run isolation
- matches_run validation in active run cache
- NodeVisitRef type in fabro-store types
- ListRunsQuery parameter for list_runs API
- HashSet dedup in catalog listing
- Updated snapshot tests for new run directory format

Preserved from feature branch:
- NodeAsset struct and exports
- StageId-based node references in run state
- make_run_dir as pub for cross-crate access
- Thread-spawn approach in handler test_default for tokio safety
- parse_run_id handles YYYYMMDD-ULID directory format

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 20:46:09 -07:00
Bryan Helmkamp
b0e6117122 Derive run metadata from RunId 2026-04-03 17:46:44 -07:00
Bryan Helmkamp
d490dbe4fa refactor: simplify run storage and retire sqlite metadata 2026-04-03 17:24:51 -07:00
Bryan Helmkamp
4c4d8482e3 Rename fabro_store::RunState to RunProjection
Clarifies that this type is an event-sourced projection of run history,
distinct from fabro_core::ExecutionState which tracks live execution.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 16:37:19 -07:00
Bryan Helmkamp
0e1798a69f Remove dead code, double-Arc, and back-compat shims
- Remove RunStoreHandle type alias (double-Arc); use SlateRunStore directly
- Remove RunState::list_node_ids (test-only, inline in tests)
- Remove SlateRunStore::list_assets and scan_prefix (test-only)
- Remove RuntimeState::ensure_runtime_dir/ensure_artifact_values_dir (test-only)
- Remove read_dot_source and its 4 tests (reads files no longer written)
- Remove back-compat modules transform/vars/stylesheet; update integration test
- Remove unused InvalidTransition/ParseRunStatusError re-exports
- Fix crate::vars import to crate::transforms::variable_expansion

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 16:24:44 -07:00
Bryan Helmkamp
ffee4688eb Remove InMemoryStore, RunSnapshot, and NodeSnapshot; use RunState directly
InMemoryStore duplicated SlateStore's interface and was unused in
production. RunSnapshot/NodeSnapshot were intermediate projections that
tests consumed — replaced with RunState to eliminate the indirection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:59:24 -07:00
Bryan Helmkamp
32ce949d8f Merge remote-tracking branch 'origin/main' 2026-04-03 10:34:48 -07:00
Bryan Helmkamp
563a9eeb49 Remove server feature flag from fabro-cli, always compile server in
The server subcommand and related code were gated behind
cfg(feature = "server"). This removes the feature flag entirely,
making fabro-server a required dependency so the server command
is always available.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 10:09:56 -07:00
Bryan Helmkamp
abe0e49688 Gate server test imports behind cfg(feature = "server")
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 07:57:32 -07:00
Bryan Helmkamp
6874d0c76e Merge remote-tracking branch 'origin/main' into feat/event-sourced-run-state 2026-04-03 06:44:58 -07:00
Bryan Helmkamp
180cca046c Collapse store handles onto Slate 2026-04-02 23:16:05 -07:00
Bryan Helmkamp
031d4cdbb6 Require a durable run store throughout execution
Make run lookup fail with RunNotFound instead of returning Option, thread a required RunStore through workflow and retro paths, and update CLI, server, and test callers to match. Also treat null optional event properties as absent during store-backed replay so event-sourced state stays robust.
2026-04-02 15:08:21 -07:00
Bryan Helmkamp
696f481103 Clean up server integration tests
Remove empty server.rs, redundant comments, redundant server.json
existence check (already covered by status check), unnecessary
String allocation, and unnecessary final filters.clone().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:25:06 -07:00
Bryan Helmkamp
4e84152c39 Add integration tests for server daemon management
- cmd/server_start: help snapshot, start-already-running error
- cmd/server_stop: help snapshot, stop-when-not-running error
- cmd/server_status: help snapshot, status-when-not-running error
- scenario/server_lifecycle: full start → status → status --json → stop cycle
- Remove stale server.rs help test (replaced by per-command files)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:18:05 -07:00
Bryan Helmkamp
7f0f014bfb Reduce slatedb timers 2026-04-02 06:43:58 -07:00
Bryan Helmkamp
345d6cd357 Stabilize workspace tests and clean warnings
Make the full workspace nextest run reliable after the run-store migration,
restore legacy test-harness projections needed by workflow integration tests,
and clear the remaining fmt/clippy issues in the touched paths.
2026-04-02 06:33:22 -07:00
Bryan Helmkamp
c71722d797 Default TestContext::command() working directory to temp_dir
Tests were flaky because command() inherited the real repo as the
working directory. When the repo was clean, detached runs attempted
git worktree creation against it, sometimes failing and injecting
extra warning lines into snapshots.

Now command() defaults to the non-git temp_dir, eliminating this
class of flakiness. Tests needing a specific directory override with
.current_dir(). Also canonicalizes fixture paths and adds a
[FIXTURES] snapshot filter via test_context!() macro.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 20:36:48 -04:00
Bryan Helmkamp
1c6c160e08 Centralize E2E test env var handling 2026-03-31 09:30:38 -04:00
Bryan Helmkamp
798f1990f6 Fix envelope event verification regressions 2026-03-30 17:38:57 -04:00
Bryan Helmkamp
cac8f386f9 Rename fabro-git-storage to fabro-checkpoint 2026-03-30 16:17:39 -04:00
Bryan Helmkamp
a40bf50b6d fmt 2026-03-30 16:17:39 -04:00
Bryan Helmkamp
c4aa3439fc Reorganize CLI integration tests and document testing strategy 2026-03-30 16:17:39 -04:00
Bryan Helmkamp
a66b65bfc3 Move cp, ssh, preview under fabro sandbox namespace
These commands all operate on a run's sandbox environment. Grouping them
under `fabro sandbox` makes the mental model clear and avoids confusion
with `fabro asset cp`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 12:00:37 -04:00
Bryan Helmkamp
fab59a8298 Extract workflow E2E tests into workflow/ directory
Move the 6 parametrized workflow scenarios from scenario/workflows.rs
into a new workflow/ directory with one file per test. Move fixture
.fabro files from test/scenario/ to workflow/fixtures/ co-located with
the tests.

Rename the scenario_tests! macro to sandbox_tests! in the new module
for clarity. Slim scenario/ down to just lifecycle and exec tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 11:41:18 -04:00
Bryan Helmkamp
b0e1b5054a Split scenario.rs into scenario/ directory
Break the monolithic scenario.rs into three focused files:
- scenario/workflows.rs — 6 parametrized E2E workflow scenarios
- scenario/lifecycle.rs — run lifecycle (ps, inspect, logs, assets, rm)
- scenario/exec.rs — exec creates file scenario
- scenario/mod.rs — shared helpers, macro, and timeout_for

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 11:41:15 -04:00