Commit graph

5105 commits

Author SHA1 Message Date
Bryan Helmkamp
cfa4afd58c Normalize attach JSON snapshot ordering 2026-04-01 22:57:27 -07:00
Bryan Helmkamp
adf7807619 Use store-backed run summaries and attach replay 2026-04-01 22:57:27 -07:00
Bryan Helmkamp
aa369a8bf4 Rebuild metadata branches from store-backed node state 2026-04-01 22:57:27 -07:00
Bryan Helmkamp
0002ba3095 Export checkpoint metadata from the run store 2026-04-01 22:57:27 -07:00
Bryan Helmkamp
50ca4e4498 Use store-backed run discovery for asset commands 2026-04-01 22:57:27 -07:00
Bryan Helmkamp
c7317c35f5 Persist provider metadata from LLM handlers 2026-04-01 22:57:27 -07:00
Bryan Helmkamp
157f805117 Persist command and diff artifacts in the run store 2026-04-01 22:57:27 -07:00
Bryan Helmkamp
9049ac606b Require store persistence for pull request records 2026-04-01 22:57:27 -07:00
Bryan Helmkamp
1f631498c1 Use store-backed status for attach and run lookup 2026-04-01 22:57:27 -07:00
Bryan Helmkamp
d0a3a0a092 Remove run hydration from production paths 2026-04-01 22:57:27 -07:00
Bryan Helmkamp
156e211bd4 Persist run creation directly into the store 2026-04-01 22:57:27 -07:00
Bryan Helmkamp
4f73aac043 Cut more CLI control-plane reads over to the store 2026-04-01 22:57:27 -07:00
Bryan Helmkamp
1db1387469 Rehydrate rewound runs before resume 2026-04-01 22:57:27 -07:00
Bryan Helmkamp
aa1e955b47 Move attach and logs to store-backed event history 2026-04-01 22:57:27 -07:00
Bryan Helmkamp
b127c025c2 Cut PR and diff readers over to the run store 2026-04-01 22:57:27 -07:00
Bryan Helmkamp
c83cf3a577 Expand store-backed run metadata and detached startup
Add the missing run-store records for node metadata, final patches, and pull
request state, and extend the store snapshots/backends to round-trip them.

Also cut the detached startup path over to explicit run IDs and store-backed
status loading so start and detached execution no longer require run.json for
bootstrap.
2026-04-01 22:57:26 -07:00
Bryan Helmkamp
96359f95cb Fix login route collision after SPA cutover
Move the browser sign-in page off the backend /auth namespace so direct
navigation works, update Rust and frontend redirects to /login, and add
tests that lock the split between SPA login UI and backend OAuth endpoints.
2026-04-01 21:55:30 -07:00
Bryan Helmkamp
b56b82d34b Cut over Fabro web app to a server-backed SPA
Replace the old React Router SSR setup with a static SPA build served by
fabro-server, move setup and GitHub auth handling into Rust, and update the
default local web URL and stale Arc-era references to match the Fabro name.
2026-04-01 21:36:01 -07:00
Bryan Helmkamp
70bfa53255 Simplify: fix buggy JSON sorting, deduplicate event filtering, clean up wait loop
- Replace no-op sort_json_value (IndexMap→IndexMap) in create.rs with
  normalize_json_value (IndexMap→BTreeMap→Map) from event.rs, fixing
  RunCreated events having non-deterministic key order
- Add AgentEvent::is_streaming_noise() to centralize the 6-variant
  streaming filter used in api.rs, retro.rs, and subagent.rs
- Extract load_file_status closure and merge Ok(None)|Err(_) arms in
  wait.rs to remove triple-repeated RunStatusRecord::load expression

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 20:13:15 -04:00
Bryan Helmkamp
d95dedf711 Persist run.created events in the run store
Hydrate the durable run store immediately after create-time event emission so
store-backed readers see the initial run.created event instead of only the
on-disk progress log. Add a regression test covering create-time store
visibility and wire in the object_store dependency needed by that test.
2026-04-01 20:13:14 -04:00
Bryan Helmkamp
d8b07add7b Expand workflow event payloads and stabilize CLI logs
Add richer run, stage, prompt, command, retro, and agent session event
metadata so progress output and stored workflow events carry the context
needed by the new plan. Normalize event serialization and update CLI log
handling to prefer progress.jsonl with consistent redaction, and fix the
detached wait/log race covered by the updated integration and snapshot
tests.
2026-04-01 20:13:14 -04:00
Bryan Helmkamp
12dc5557d8 Consolidate unsafe process code into fabro-proc crate
Rename fabro-proctitle to fabro-proc and add safe wrappers for all
process management primitives (signals, pre-exec hooks). This contains
all unsafe proc code behind a safe API so downstream crates no longer
need #[allow(unsafe_code)] or direct libc dependencies.

New modules: signal (process_alive, sigterm, sigkill, sigterm_process_group),
pre_exec (pre_exec_setsid, pre_exec_setpgid, pre_exec_pdeathsig),
title (existing proctitle code). Eliminates three duplicate process_alive
definitions and removes libc as a direct dep of fabro-cli and fabro-sandbox.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 17:49:29 -04:00
Bryan Helmkamp
46e9e8d096 smoke 2026-04-01 17:31:51 -04:00
Bryan Helmkamp
afd1b52527 Deny unsafe_code workspace-wide, remove unsafe pointer cast from tests
Promote unsafe_code lint from warn to deny so new unsafe code is a
compile error. Add #![allow(unsafe_code)] to the two sleep_inhibitor
modules that were missing it. Replace the unsafe trait-object pointer
cast in CliMockSandbox tests with a shared Arc<Mutex<Vec<String>>>.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 17:17:59 -04:00
Bryan Helmkamp
ee173403e9 docs 2026-04-01 16:25:41 -04:00
Bryan Helmkamp
a30f06b5cb docs 2026-04-01 14:37:06 -04:00
Bryan Helmkamp
905206f63d Fix attach hanging on Linux CI when engine exits before attach starts
The attach loop's PID liveness fallback used `last_seq > 0` (store path)
and `!progress_file_is_empty` (file path) to keep the engine "alive" when
no launcher record could be found. These conditions are always true once
events exist, so the loop never exited via the PID path after the launcher
record was cleaned up by start_run or active_launcher_record_for_run.

The store-based terminal status check (the other exit path) only read from
the SlateDB DbReader, which may not see data still in the WAL or not yet
visible via manifest poll. Adding a disk fallback to read status.json
ensures the check works even when the store reader has a stale view.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:32:16 -04:00
Bryan Helmkamp
d9e111a632 docs 2026-04-01 14:31:58 -04:00
Bryan Helmkamp
09341ef7ac Replace max_retries=0 with goal_gate=true in smoke workflow
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:38:30 -04:00
Bryan Helmkamp
07a8e76b9d Fix missing create_app_state import in mTLS e2e tests
The mtls_e2e module is gated with #[cfg(target_os = "linux")], so the
wrong import (create_app_state_with_options instead of create_app_state)
was never caught on macOS. Fixes CI compilation failure on Linux.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:38:29 -04:00
Bryan Helmkamp
e31d762e98 Fix flaky SSE event stream integration test 2026-04-01 11:11:45 -04:00
Bryan Helmkamp
77773acacb test(devcontainer): disable flaky OCI fetch integration
Temporarily short-circuit fetch_feature_oci_integration unless FABRO_ENABLE_FETCH_FEATURE_OCI_INTEGRATION is set.

The test depends on live oras and ghcr.io access and is timing out under the current nextest ignored-test invocation, so keep it visible but disabled until the root cause is addressed.
2026-04-01 11:11:38 -04:00
Bryan Helmkamp
77d1495603 Move hook twin coverage to CLI workflow tests
Replace in-process workflow E2E hook tests with fabro-cli workflow
integration tests that run fabro as a subprocess and pass OpenAI twin
env only to the child process. Remove the unsafe env-var mutation helper
from fabro-workflow integration tests.
2026-04-01 11:03:44 -04:00
Bryan Helmkamp
c6cb9c6e7e Expand OpenAI twin coverage across integration tests
Add shared twin scenario helpers and use them to cover OpenAI-backed
CLI, agent parity, workflow, and exec integration paths. This brings the
worktree implementation back into the main checkout as a single commit.
2026-04-01 11:03:34 -04:00
Bryan Helmkamp
63b97710d3 Add missing Arc import in mTLS e2e tests
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 10:38:50 -04:00
Bryan Helmkamp
2898efa1cb Expand smoke workflow into discrete sequential stages
Replace the single prompt-based stage with six command stages:
toolchain, compile-rust, compile-typescript, lint-rust, test-rust,
test-typescript. Each stage fails fast (max_retries=0).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 10:10:57 -04:00
Bryan Helmkamp
c22845e548 Integrate twin-github for fabro-github tests
Add the stripped twin-github test server to the workspace, wire it through
fabro-test, and cover fabro-github's real HTTP auth and pull-request flows
with twin-backed integration tests. This also refactors the GitHub helper
entry points to take explicit base URLs so tests and callers share the same
request path.
2026-04-01 09:48:33 -04:00
Bryan Helmkamp
9f5cf7bb77 Remove auto dry-run when LLM providers are missing
Previously, workflows silently fell back to dry-run mode when no LLM
providers were configured or client init failed. This caused command-only
workflows to skip execution entirely. Now missing LLM providers produce
a hard error when the graph has LLM nodes, and are ignored when it doesn't.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 00:34:20 -04:00
Bryan Helmkamp
55181537c3 Suppress unreachable_pub warnings in twin-openai test helpers
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 22:41:36 -04:00
Bryan Helmkamp
c3df5220c3 Optimize slow Docker and real CLI tests
- Move real_cli_claude/codex/gemini tests from fabro-workflow to fabro-cli,
  which has a 20s nextest timeout (vs 6s default), and add poll_interval(10ms)
- Reduce DockerSandbox stop_container grace period from 5s to 1s
- Reduce timeout_handling test sleep from 60s to 2s

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 22:19:51 -04:00
Bryan Helmkamp
6b47cd980b Increase nextest timeout for fabro-cli integration tests
These tests invoke the CLI binary and take longer than unit tests,
so flag SLOW at 5s and hard-kill at 20s.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 20:36:48 -04:00
Bryan Helmkamp
5b7eabee8f Add twin test mode for OpenAI E2E tests
Integrate twin-openai (fake OpenAI server) into the workspace and wire
it into the e2e_test macro so OpenAI tests can run without real API
credentials. The twin server starts in-process via OnceLock on first use
and provides per-test isolation through bearer-token namespacing.

Changes:
- Add Twin as default TestMode, replacing Off (gating now via #[ignore])
- Extend #[e2e_test] macro with `twin` requirement for twin-only,
  live-only, and dual-mode (twin + live) test gating
- Add e2e_openai!() macro returning (base_url, api_key)
- Convert openai_complete and openai_gpt_5_3_codex_complete to dual-mode
- Add new openai_server_error twin-only test with scripted 500 error
- Standardize axum 0.8 as workspace dependency across all crates
- Relax twin-openai ResponsesRequest to accept unknown fields via flatten

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 20:36:48 -04: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
0ffa3e23b0 Replace compact_progress_event with raw event snapshots
The compact_progress_event test helper cherry-picked fields and flattened
the properties wrapper, making snapshots misleadingly show a format that
doesn't match the actual fabro attach --json / progress.jsonl output.
Now snapshots show the real RunEventEnvelope structure with volatile
fields (id, ts, run_id, duration_ms) redacted via insta filters.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 20:31:13 -04:00
Bryan Helmkamp
507f5ddcde Prune stale git worktrees before branch creation in WorktreeSandbox
Stale worktree references from deleted temp directories kept branches
locked, causing "cannot force update the branch" errors on subsequent
runs with the same branch name.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 13:44:01 -04:00
Bryan Helmkamp
c27f72005a Fix rewind snapshot filtering for short SHAs 2026-03-31 13:34:26 -04:00
Bryan Helmkamp
892f98022f Fix workspace clippy issues in fabro-test 2026-03-31 13:33:20 -04:00
Bryan Helmkamp
699691b468 Rename fabro-openai-oauth to fabro-oauth 2026-03-31 13:23:43 -04:00
Bryan Helmkamp
564479291c tweak test timeout again 2026-03-31 13:19:06 -04:00
Bryan Helmkamp
1f39a55ef2 tighten slow test limit 2026-03-31 13:12:57 -04:00