Commit graph

3169 commits

Author SHA1 Message Date
Fabro
36a2ef7b73 fabro(01KQRF98KVJANMHY45N67NTKPC): fmt (succeeded)
Fabro-Run: 01KQRF98KVJANMHY45N67NTKPC
Fabro-Completed: 11

⚒️ Generated with [Fabro](https://fabro.sh)
2026-05-04 04:28:14 +00:00
Fabro
5a241848dd fabro(01KQRF98KVJANMHY45N67NTKPC): verify (succeeded)
Fabro-Run: 01KQRF98KVJANMHY45N67NTKPC
Fabro-Completed: 10

⚒️ Generated with [Fabro](https://fabro.sh)
2026-05-04 04:28:09 +00:00
Fabro
e7606063ab fabro(01KQRF98KVJANMHY45N67NTKPC): fixup (succeeded)
Fabro-Run: 01KQRF98KVJANMHY45N67NTKPC
Fabro-Completed: 9

⚒️ Generated with [Fabro](https://fabro.sh)
2026-05-04 04:27:48 +00:00
Fabro
080841e13f fabro(01KQRF98KVJANMHY45N67NTKPC): verify (failed)
Fabro-Run: 01KQRF98KVJANMHY45N67NTKPC
Fabro-Completed: 8

⚒️ Generated with [Fabro](https://fabro.sh)
2026-05-04 04:24:19 +00:00
Fabro
29b1f593e2 fabro(01KQRF98KVJANMHY45N67NTKPC): simplify_gpt (failed)
Fabro-Run: 01KQRF98KVJANMHY45N67NTKPC
Fabro-Completed: 7

⚒️ Generated with [Fabro](https://fabro.sh)
2026-05-04 04:22:40 +00:00
Fabro
f9932156b1 fabro(01KQRF98KVJANMHY45N67NTKPC): simplify_opus (succeeded)
Fabro-Run: 01KQRF98KVJANMHY45N67NTKPC
Fabro-Completed: 6
Fabro-Checkpoint: 37593d6a48f30e1b7a9c5a46beebb7380e401fda

⚒️ Generated with [Fabro](https://fabro.sh)
2026-05-04 04:22:32 +00:00
Fabro
5a082539a8 fabro(01KQRF98KVJANMHY45N67NTKPC): implement (succeeded)
Fabro-Run: 01KQRF98KVJANMHY45N67NTKPC
Fabro-Completed: 5
Fabro-Checkpoint: 6e74f28cb8

⚒️ Generated with [Fabro](https://fabro.sh)
2026-05-04 04:10:37 +00:00
Fabro
0af60ac835 fabro(01KQRF98KVJANMHY45N67NTKPC): preflight_lint (succeeded)
Fabro-Run: 01KQRF98KVJANMHY45N67NTKPC
Fabro-Completed: 4
Fabro-Checkpoint: d71b82ee9c

⚒️ Generated with [Fabro](https://fabro.sh)
2026-05-04 03:12:06 +00:00
Fabro
4c9153ab09 fabro(01KQRF98KVJANMHY45N67NTKPC): preflight_compile (succeeded)
Fabro-Run: 01KQRF98KVJANMHY45N67NTKPC
Fabro-Completed: 3
Fabro-Checkpoint: 235ab4b8bd

⚒️ Generated with [Fabro](https://fabro.sh)
2026-05-04 03:09:59 +00:00
Fabro
ec2d437e18 fabro(01KQRF98KVJANMHY45N67NTKPC): toolchain (succeeded)
Fabro-Run: 01KQRF98KVJANMHY45N67NTKPC
Fabro-Completed: 2
Fabro-Checkpoint: 9f6d6590ab

⚒️ Generated with [Fabro](https://fabro.sh)
2026-05-04 03:07:57 +00:00
Bryan Helmkamp
253af11508
refactor(billing): simplify run-billing post-review cleanups
Use BilledTokenCounts::default() for the non-LLM branch, hoist the
by-model stage count and hasLlmStages predicate out of JSX, and drop
the in-test for-loop in favor of iterator-based assertions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 23:01:04 -04:00
Bryan Helmkamp
95eb13750a
fix(billing): render non-LLM run stages
Include completed stages without LLM usage in run billing responses so command-only runs still show runtime rows. Keep token and model aggregates scoped to billed LLM usage, and render placeholder values in the web billing table.
2026-05-03 22:49:33 -04:00
Bryan Helmkamp
6780dff63f
fix(workflow): retain exec output tails on failures
Keep sandbox exec failures structured until event emission so git push, checkpoint, notice, and retro failures can expose redacted output tails without expanding their terse error strings.

Also add log rendering that appends sanitized tail content for exec-backed errors while preserving the existing safe Display behavior.
2026-05-03 21:30:34 -04:00
Bryan Helmkamp
446c7cc065
fix(sandbox): surface snapshot lifecycle progress
Emit snapshot slow-path events only when Docker or Daytona actually performs image or snapshot work, replace retired completion markers with snapshot.ready, and render the lifecycle in attach/log output.
2026-05-03 20:44:16 -04:00
Bryan Helmkamp
fe342a4bd7
fix(redact): skip name fields to preserve sandbox identifiers
ULID-derived sandbox names like fabro-01KQR3V9D4VPFFWMNTVH09J48G tripped
the entropy detector and rendered as REDACTED in CLI run output.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 19:57:55 -04:00
Bryan Helmkamp
93f255c6c4
fix(web): preserve run-overview exit-node color after archive
Use the archived status's prior terminal kind so the Exit node keeps
its succeeded/failed fill instead of falling back to the default
transparent server fill.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 19:42:07 -04:00
Bryan Helmkamp
57dad3a11f
chore(daytona): preinstall pinned nightly toolchain in snapshot
The smoke workflow's Lint Rust stage runs `cargo +nightly-2026-04-14
fmt`/`clippy`. The previous fabro-v7 snapshot only had stable, so rustup
silently synced the nightly channel on every run. Bump to fabro-v8 and
add `rustup toolchain install nightly-2026-04-14` with clippy+rustfmt so
lint starts immediately.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 19:33:28 -04:00
Bryan Helmkamp
a425724719
refactor(server): reuse canonical_origin in run_web_url
Delegate to the existing AppState::canonical_origin helper instead of
re-resolving server.web.url and re-checking emptiness inline. The helper
already validates the URL via validate_public_url, so a misconfigured
non-http(s) origin no longer leaks through into run_web_url's output.

Also pass web_url into create_run_input directly rather than constructing
with None and immediately patching the field at the call site.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 18:27:34 -04:00
Bryan Helmkamp
649b57c185
feat(api): expose web_url on run responses and run.created event
So that CLI and other API consumers can surface a clickable link to the
run's web UI page instead of guessing route shapes or probing settings.
The server populates `web_url` from `server.web.enabled` and
`server.web.url`, returns it on `RunStatusResponse` (create plus all
lifecycle transitions), and persists it on the `run.created` event so
attach replays the same link without re-deriving it.

CLI: prints `Web UI: <url>` as a run-header info line, driven off the
replayed event so fresh runs and `attach` share one code path. Absent
when the UI is disabled.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 18:18:19 -04:00
Bryan Helmkamp
e5c5feaa8d
fix(workflows): pin clippy and fmt to nightly-2026-04-14
The smoke and implement-plan workflows ran cargo clippy without a
toolchain prefix, so on the Daytona snapshot they fell through to the
baked-in stable toolchain. clippy.toml now uses allow-unwrap-types
(added in clippy 1.95), which the stable in fabro-v7 doesn't recognize.
Pin every fmt and clippy invocation to nightly-2026-04-14 so they match
.github/workflows/rust.yml. Also update the public repl-handoff example
to keep the documented template consistent.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 17:32:46 -04:00
Bryan Helmkamp
2d7c79de1e
feat(server): validate Daytona API key scopes
Probe the Daytona API at install, `fabro secret set DAYTONA_API_KEY`,
and `fabro doctor` time to confirm the configured key carries the
snapshot/sandbox scopes Fabro needs. Operators now see a precise scope
error against the control plane instead of a generic sandbox-create
failure at first run.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 17:09:01 -04:00
Bryan Helmkamp
5c60fe8182
chore: plans 2026-05-03 13:10:04 -04:00
Bryan Helmkamp
bfb6bdb25c
fix(cli): bound server readiness probes
Use HTTP health checks with short deadlines for managed server readiness and add finite control-plane request timeouts for CLI/server clients. Keep stream bodies uncapped so SSE attach flows can remain long-lived.
2026-05-02 20:13:18 -04:00
Bryan Helmkamp
6f1d87c878
refactor(web): simplify interview-dock
Drop a resync useEffect that healed activeIndex back to safeIndex —
safeIndex already clamped reads, so the effect only triggered an
extra render. Reuse the shared ErrorMessage from ui.tsx instead of
the inline copy. Drop a useMemo over a tiny per-render array.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 15:59:07 -04:00
Bryan Helmkamp
66f06950ba
refactor: simplify Rust review cleanup
Centralize shared test setup and graph vocabularies, remove stringly event checks, and make server handler dependencies explicit.
2026-05-02 15:41:17 -04:00
Bryan Helmkamp
7247fd6b7c
feat(web): add interview dock for answering blocked runs from the UI
Replaces the read-only BlockedRunNotice with a viewport-fixed dock that
lets users answer pending human-in-the-loop questions without dropping
to the CLI. Supports YesNo, Confirmation, MultipleChoice, MultiSelect,
and Freeform question types, plus the allow_freeform fallback for
choice-with-write-in. Multiple pending questions surface a "+N more"
pill so a parallel-handler run can be drained from one place.

The dock subscribes to interview.* SSE events for auto-refresh and
posts answers via the existing /runs/{id}/questions/{qid}/answer
endpoint. Cancel is consolidated into the page header (now shown for
blocked runs) so the dock chrome stays focused on the conversation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 15:39:01 -04:00
Bryan Helmkamp
a479db981f
chore(validate): remove stale rule section dividers
Leftover from when rules.rs was a single 3500-line file. Numbering
was stale (Rule 23 and Rule 24 each appeared twice after the split)
and duplicated info already in the filename.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 15:19:06 -04:00
Bryan Helmkamp
ae5ccb5ce2
refactor(workflow): split event module by responsibility
Keep fabro_workflow::event as the public facade while moving event conversion, names, redaction, sink, emitter, stored-field helpers, and StageScope into focused modules. Co-locate the existing event tests with the moved code and update the events strategy docs for the new module layout.
2026-05-02 14:52:10 -04:00
Bryan Helmkamp
b1d560faf7
refactor(validate): split lint rules into modules 2026-05-02 13:44:55 -04:00
Bryan Helmkamp
343407bb83
Merge branch 'mechanical-server-handler-split' 2026-05-02 13:33:10 -04:00
Bryan Helmkamp
50bc9a4fcf
Merge remote-tracking branch 'origin/main' 2026-05-02 13:33:07 -04:00
Bryan Helmkamp
10555a292d
refactor(server): split HTTP handlers into modules 2026-05-02 13:32:49 -04:00
Bryan Helmkamp
0723ca068c
refactor(server): move server tests out of main module 2026-05-02 13:10:31 -04:00
Bryan Helmkamp
33848b8759
docs(agents): document test support boundaries 2026-05-02 13:05:15 -04:00
Bryan Helmkamp
886173f5ad
refactor(server): gate test app state helpers
Move test-only app state constructors into the gated test_support module
so release builds do not expose or link fixture helpers and secrets.
2026-05-02 13:02:41 -04:00
fabro-releases[bot]
5de3dc89d6 Bump version to 0.221.0-nightly.1
Some checks are pending
Rust / Format (push) Waiting to run
Rust / Clippy (push) Waiting to run
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
2026-05-02 16:45:20 +00:00
Bryan Helmkamp
f219987f2a
fix(test): align worker token fixtures with auth routing
Share CLI integration worker-token issuance through the auth test helper so test tokens carry the same worker kid header as production-issued tokens.
2026-05-02 12:08:00 -04:00
Bryan Helmkamp
d10e0f5c56
refactor: simplify auth and actor handling
Tighten auth state to remove impossible identity branches and stringly error codes.
Route worker JWTs by header metadata, avoid unnecessary auth context cloning, and reuse shared helpers across tests and Slack payload handling.
Carry typed timeout actor metadata through failures instead of deriving it from display text.
2026-05-02 11:44:17 -04:00
Bryan Helmkamp
2c595d5939
refactor: dedupe auth helpers and tidy principal tests
Replace hand-built RequestAuthContext literals in github_webhook with the
existing ::invalid()/::authenticated() constructors, collapse the duplicate
demo/real principal layers into a single cloneable layer, and forward the
_with_anyhow error constructors to their _with_source twins to drop the
duplicated cause-collection bodies. refresh_credential_from_headers now
reuses jwt_auth::bearer_token_from_headers for Authorization parsing.
test_support shares one TEST_DEV_TOKEN-derived bearer header instead of a
hand-pasted literal. Replace for-loops in principal/cli_flow tests with
per-variant cases to honor the no-loops-in-tests rule.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 11:14:59 -04:00
Bryan Helmkamp
b499a17796
fix(error): preserve remaining error context
Carry structured error sources through workflow, server, tracker, and CLI paths instead of flattening them into strings before the render boundary.
2026-05-02 10:51:15 -04:00
Bryan Helmkamp
43f03087e6
Merge remote-tracking branch 'origin/main' 2026-05-02 10:06:25 -04:00
Bryan Helmkamp
f6b8d1acdb
Fix principal auth gap regressions 2026-05-02 10:02:12 -04:00
Bryan Helmkamp
29c45498b0
Fix run principal attribution gaps 2026-05-02 09:14:02 -04:00
Bryan Helmkamp
de10825ce1
Merge remote-tracking branch 'origin/main' 2026-05-02 08:51:47 -04:00
fabro-releases[bot]
349200f056 Bump version to 0.221.0-nightly.0 2026-05-02 09:39:00 +00:00
Bryan Helmkamp
8f4c12580c
refactor: dedupe artifact entry adapters, retry URL helper, query-param check
Extract run_artifact_entry_from / artifact_entry_from in fabro-server so
the two list-artifact handlers share a single conversion site. Push the
?retry=... query append into stage_artifacts_url in fabro-client so
upload callers don't repeat it. Replace required_filename and
required_retry with one generic required_query_param<T> helper.

(From impls were the cleaner shape but the orphan rule blocks them:
NodeArtifact lives in fabro-store, RunArtifactEntry in fabro-api,
neither is in fabro-server. Free fns achieve the same dedup without
adding a fabro-store -> fabro-api coupling.)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 01:16:10 -04:00
Bryan Helmkamp
f628b91c04
Merge origin/main
Reconcile parallel refactors that converged on stage vocabulary from
opposite directions. Origin's vocabulary wins everywhere it conflicts:
StageProjection (struct), StageState (status enum, kept), StageCompletion
(record). Local's artifact-retries feature, OpenAPI typing of JSON-blob
fields, parallel awaits in build_conclusion_from_store, and shared
RETRY_SEGMENT_PREFIX constant carry forward on top.

Origin's stage_at_visit reducer helpers (8 arms) supersede the local
stage_entry_with_current_visit (5 arms); same intent, broader coverage.
Origin's iter_stages_mut and first_event_seq helper unification are
preserved unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 22:05:41 -04:00
Bryan Helmkamp
8d7b9a804a
Unify run event principals 2026-05-01 21:56:47 -04:00
Bryan Helmkamp
5393b12beb
refactor: skip linear scans and serial awaits in run state and finalize
Defer current_visit_for to the fallback branch in stage_entry_with_current_visit
so events that already carry stage_id avoid an O(N stages) scan per event.
Run state() and list_events() concurrently in build_conclusion_from_store, and
share a single retry- segment prefix between encode and decode.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 21:33:39 -04:00
Bryan Helmkamp
cc81f538f4
refactor(api): type StageState JSON-blob fields so the TS client stops emitting any
provider_used, script_invocation, and script_timing become object | null;
parallel_results becomes Array<object> | null. The Rust StageState type is
unaffected because fabro-api/build.rs replaces it with fabro_types::StageState.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 21:16:56 -04:00