Commit graph

766 commits

Author SHA1 Message Date
Bryan Helmkamp
80fbeb5fcd Auto-PR on Successful Workflow Run (#3)
* arc(01KK6WHJ904CXGN0MCQFGWKMKS): implement (success)

Arc-Run: 01KK6WHJ904CXGN0MCQFGWKMKS
Arc-Completed: 2
Arc-Checkpoint: 4c3a9115be9074c7e23792c0ef9b1f0525ffc10d

* arc(01KK6WHJ904CXGN0MCQFGWKMKS): simplify (success)

Arc-Run: 01KK6WHJ904CXGN0MCQFGWKMKS
Arc-Completed: 3
Arc-Checkpoint: 7d8e8413e70eb198e14fcb676903dcc91bd21b76

* Fix merge conflicts: add pull_request to OpenAPI spec, fix clippy warning, cargo fmt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: arc <arc@local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 16:32:55 -04:00
Bryan Helmkamp
7f6f356bae TOML Config Format for MCP Servers (#2)
* arc(01KK6WHD2MEDZ0JVYTHEK9HFNF): implement (success)

Arc-Run: 01KK6WHD2MEDZ0JVYTHEK9HFNF
Arc-Completed: 2
Arc-Checkpoint: 25f71de745f9001a09e566706d62a6ac2ea6f827

* arc(01KK6WHD2MEDZ0JVYTHEK9HFNF): simplify (success)

Arc-Run: 01KK6WHD2MEDZ0JVYTHEK9HFNF
Arc-Completed: 3
Arc-Checkpoint: fed4325308110df4799171944ddb5170de59044c

* Fix Rust formatting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: arc <arc@local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 16:26:46 -04:00
Bryan Helmkamp
ff053e1e4a Fix ReadBeforeWriteSandbox (#1)
* arc(01KK60MHXX1G7Y2H0YN6HAWWZH): start (success)

Arc-Run: 01KK60MHXX1G7Y2H0YN6HAWWZH
Arc-Completed: 1
Arc-Checkpoint: be0355a55571c147ac954b15ac0d5605d63539e8

* arc(01KK60MHXX1G7Y2H0YN6HAWWZH): implement (success)

Arc-Run: 01KK60MHXX1G7Y2H0YN6HAWWZH
Arc-Completed: 2
Arc-Checkpoint: b67ee066bf67ce3c36bbdf31833e4303065de311

* arc(01KK60MHXX1G7Y2H0YN6HAWWZH): simplify (success)

Arc-Run: 01KK60MHXX1G7Y2H0YN6HAWWZH
Arc-Completed: 3
Arc-Checkpoint: 69fbd818f537771b9d7f8b43339e31fe4fa63321

* Fix formatting in cli.rs and tools.rs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix clippy warnings after merging main

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: arc <arc@local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 16:19:22 -04:00
Bryan Helmkamp
d002aa0b51 Rename arc run startarc run (#5)
* arc(01KK7524KNGTPS4090QMF87FJN): implement (success)

Arc-Run: 01KK7524KNGTPS4090QMF87FJN
Arc-Completed: 2
Arc-Checkpoint: 1ff03c704805dfe8e7c37b37f97bd06dfa0e5dc5

* Fix: restore trailing newlines stripped by previous commit

* arc(01KK7524KNGTPS4090QMF87FJN): simplify (success)

Arc-Run: 01KK7524KNGTPS4090QMF87FJN
Arc-Completed: 3
Arc-Checkpoint: 21771adfd26283a1d1e6b8a123a83a0c4277db48

---------

Co-authored-by: arc <arc@local>
Co-authored-by: Arc Assistant <assistant@arc.dev>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 16:14:50 -04:00
Bryan Helmkamp
c3d23d72e9 Extract raise_on_errors helper to deduplicate diagnostic error filtering
The pattern of filtering Error-severity diagnostics, collecting messages,
and returning ArcError::Validation appeared in three places. Extract it
into validation::raise_on_errors and use prepare_from_file in run_from_branch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:52:37 -04:00
Bryan Helmkamp
8ee27278dd Add conformance test to detect ServerConfig ↔ OpenAPI spec drift
Recursively compares serialized ServerConfig keys against the
OpenAPI ServerConfiguration schema properties. Also fixes 7 fields
that were missing from the spec: log, checkpoint, git.slug,
git.author, git.webhooks, sandbox.exe, sandbox.env.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:44:59 -04:00
Bryan Helmkamp
3c476772e7 Add prepare_with_file_inlining API to prevent validate/run divergence
FileInliningTransform was treated as a "custom" transform that every
caller had to remember to register manually. This caused arc validate
to break and left latent bugs in run_from_branch and SubWorkflowHandler.

Add prepare_with_file_inlining() and prepare_from_file() to WorkflowBuilder
so file inlining is a built-in concern. Rename prepare_workflow to
prepare_from_source for clarity. Fix the SubWorkflowHandler to use
prepare_from_file when reading from stack.child_dotfile paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:37:54 -04:00
Bryan Helmkamp
3fdd1ec746 Add commit watermark to /changelog skill for precise change tracking
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:37:52 -04:00
Bryan Helmkamp
5a720ddb26 Rename /runs/{id}/compare to /runs/{id}/files with pagination
Replace the RunCompare envelope (checkpoints + files + stats) with a
standard PaginatedRunFileList response containing FileDiff items,
matching the existing pagination pattern used by other endpoints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:37:30 -04:00
Bryan Helmkamp
e73f2ab00e Add pause/unpause run endpoints
Add POST /runs/{id}/pause and POST /runs/{id}/unpause endpoints
following the cancel endpoint conventions, with paused RunStatus variant,
demo stubs, and regenerated TypeScript client.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:36:36 -04:00
Bryan Helmkamp
be358944c0 Reorganize API Reference nav: remove unused sections, nest under More
Remove Verification, Insights, and Retros groups. Move Sessions, Models,
and Administration as sub-groups under More. Add unlisted Test Model
endpoint. Hide Run Verification endpoint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:20:35 -04:00
Bryan Helmkamp
09a2166324 Update changelog and docs for webhook listener, verbose config, optional goal
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:15:52 -04:00
Bryan Helmkamp
3e47d85b16 Fix arc validate not resolving @file references
Register FileInliningTransform in validate_command so @file references
(e.g. @prompts/simplify.md) are resolved during validation, matching
the behavior in run.rs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 13:58:56 -04:00
Bryan Helmkamp
95be0206e5 Add implement-and-simplify workflow with full preflight checks
Run cargo check, clippy, and tests in preflight before starting implementation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 13:40:30 -04:00
Bryan Helmkamp
839cbc28b8 Fix stale test: goal is now optional in run config
The missing_required_fields test was not updated when goal was changed
from String to Option<String> in c143d2c8.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 13:11:39 -04:00
Bryan Helmkamp
0ca9a309c0 Fix clippy await_holding_lock: drop RwLock guard before await in webhook setup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 13:03:37 -04:00
Bryan Helmkamp
2355cd573d Simplify webhook module: deduplicate PEM decoding, extract delivery_id, remove redundant state
- Reuse jwt_auth::decode_pem_env in read_github_private_key instead of duplicating base64/PEM logic
- Extract delivery_id once at top of webhook_handler instead of 3 separate times
- Remove redundant funnel_port field from WebhookManager (derive from listener.port())
- Gate parse_event_metadata behind debug log level to avoid full JSON parse on every webhook

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 12:45:38 -04:00
Bryan Helmkamp
d838fda004 Add GitHub webhook listener via Tailscale funnel
Adds a webhook subsystem that receives GitHub App webhooks when configured
in server.toml with [git.webhooks] strategy = "tailscale_funnel". On startup,
it binds a local HTTP listener on a random port, exposes it via `tailscale funnel`,
and patches the GitHub App webhook URL. Incoming webhooks are verified with
HMAC-SHA256 before processing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 12:37:56 -04:00
Bryan Helmkamp
46d170468e Add PostToolUse hook to auto-format Rust files with cargo fmt
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 12:03:09 -04:00
Bryan Helmkamp
18aaa75ae7 Support verbose = true in cli.toml to default verbose output on
Adds a top-level `verbose` bool to CliConfig so `arc run start` and
`arc doctor` pick it up without requiring `-v` every invocation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 12:01:05 -04:00
Bryan Helmkamp
ad058e604a Fix demo data to wrap goal values in Some() after making goal optional
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:59:50 -04:00
Bryan Helmkamp
c143d2c873 Make goal optional in run config TOML so it can be provided via CLI --goal
Precedence: CLI --goal > TOML goal > DOT graph attribute. Previously
the TOML goal field was required but never applied to the graph.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:56:41 -04:00
Bryan Helmkamp
1cd3be878a Track .claude directory and add docs skill watermark
Remove .claude from .gitignore and commit the docs skill watermark
so future /docs runs know where to start.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:23:07 -04:00
Bryan Helmkamp
014ff0595b Update changelog and docs for March 7-8 changes
Regenerate March 7 changelog with sandbox.env, CLI renames, and missing
accordion items. Add March 8 changelog for sandbox reliability and @file
validation. Update reference docs for --goal, --mode flags, sandbox.env,
checkpoint exclude globs, [log] config, [git.author], and project_memory.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:22:26 -04:00
Bryan Helmkamp
f4c2014026 Add custom Dockerfile and simplify imagegen workflow
Bake the imagegen script into a Daytona snapshot so the agent
can just run `imagegen <prompt> <output>` instead of manually
calling the Gemini API with curl/jq.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:20:07 -04:00
Bryan Helmkamp
aa8aab6588 Remove unused base64::Engine import in daytona integration tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:14:37 -04:00
Bryan Helmkamp
d8cd4f0c21 Upgrade CI runners to 16-core for faster Rust builds
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:14:18 -04:00
Bryan Helmkamp
fb19251e9c Fix CI: clippy warnings, formatting, and mTLS test cert version
Rust 1.94.0 introduced new clippy lints and rustls now rejects X.509 v1
certificates. This fixes all three CI jobs:

- Format: cargo fmt across the workspace
- Clippy: unnecessary_unwrap, useless_format, derivable_impls,
  type_complexity, too_many_arguments, redundant_closure, map_or
  simplification, and other new lints
- Tests: generate v3 certs (with extensions) for mTLS tests so newer
  rustls accepts them

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:07:33 -04:00
Bryan Helmkamp
97a0a9be32 Fix clippy warnings in arc-agent
- Collapse nested if statements in heredoc stripping (v4a_patch.rs)
- Pass ToolCall directly to execute_one_tool to reduce argument count (tool_execution.rs)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 10:15:25 -04:00
Bryan Helmkamp
f4481e5287 Render Run ID line through progress system for consistent styling
The Run: line was using raw eprintln! without indentation or dimming,
making it visually inconsistent with the Logs: and Sandbox: lines.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 10:13:39 -04:00
Bryan Helmkamp
736f6dec57 Reduce Daytona sandbox timeout grace period from 5s to 2s 2026-03-08 10:06:52 -04:00
Bryan Helmkamp
7af7fb30d6 Update docs to reflect new stream read timeout and backoff defaults
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 10:05:48 -04:00
Bryan Helmkamp
ad226440fb Fix daytona exec tests to load github app credentials
Tests were failing locally because the Daytona sandbox needs GitHub App credentials to clone a private repository, but the exec tests were passing . This updates the tests to load the credentials and supply them during initialization.
2026-03-08 10:05:02 -04:00
Bryan Helmkamp
ae1f13402b Add 5-minute stream read timeout and increase retry backoff to 5s
A stalled Anthropic SSE stream caused a run to hang for 10 minutes
until the stall watchdog killed it. The HTTP connection succeeded but
no SSE events arrived, and with stream_read_timeout defaulting to None
the read blocked indefinitely.

- Set AdapterTimeout default stream_read to 300s (5 min), matching
  the idle timeout used by OpenAI Codex
- Increase BackoffConfig default initial_delay_ms from 200ms to 5s
  so transient LLM failures get meaningful recovery time before retry

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 10:03:50 -04:00
Bryan Helmkamp
a019082dfc Print only first line of goal in arc run start output
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 10:01:36 -04:00
Bryan Helmkamp
2b8da8f15b Add tests for Daytona execute_command timeout and cancellation
Adds two new tests to the Daytona integration suite:
1. `daytona_exec_command_cancelled`: verifies that an active token cancellation properly aborts a running command and yields a correct exit code/message.
2. `daytona_exec_command_local_timeout`: tests the recent fix that prevents commands from hanging indefinitely by enforcing a local timeout fallback.
2026-03-08 10:01:06 -04:00
Bryan Helmkamp
6280a822eb Fix subagent/system prompt empty handling with TDD 2026-03-08 09:59:56 -04:00
Bryan Helmkamp
59634a3936 Increase default stall watchdog timeout from 10 minutes to 30 minutes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 09:52:07 -04:00
Bryan Helmkamp
3dce68d664 cargo fmt 2026-03-08 09:51:10 -04:00
Bryan Helmkamp
445050dc57 Enforce local timeout and cancellation for Daytona execute_command
The Daytona SDK HTTP client can sometimes hang indefinitely if the connection
drops or the server stops responding. Since `daytona_sandbox.rs` was awaiting
the `execute_command` call directly, this could cause the entire workflow engine
to stall, eventually triggering the stall watchdog.

This wraps the `execute_command` call in a `tokio::select!` block, enforcing
the requested `timeout_ms` locally (with a 5s grace period) and respecting
the `cancel_token`.

Co-Authored-By: Gemini CLI <noreply@google.com>
2026-03-08 09:49:51 -04:00
Bryan Helmkamp
5967c3783e Fix v4a patch parser/applier to match canonical OpenAI codex spec
- Forward-order hunk application with cursor tracking (fixes duplicate line matching)
- Accept `@@ context` without trailing ` @@` (backward compat preserved)
- Stacked `@@` anchors collapse to single hunk using last context
- `*** End of File` marker for backward search from end of file
- `*** Move to:` for file renames during update
- 4-pass fuzzy matching: exact → trim_end → trim → unicode normalization
- Heredoc wrapper stripping (<<EOF / <<'EOF' / <<"EOF")
- Update system prompt to use canonical `@@ context` format

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 09:45:14 -04:00
Bryan Helmkamp
58e08bec60 Cache start node ID before main loop to avoid repeated O(n) lookup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 03:09:39 -04:00
Bryan Helmkamp
a3abbaf191 Skip git checkpoint commit for start node
The start node is a no-op (StartHandler returns success immediately), so its
git checkpoint commit is always empty. Skipping it reduces noise in git history
without losing any data — the checkpoint JSON is still saved to disk, and the
next node's diff falls back to base_sha correctly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-08 03:02:57 -04:00
Bryan Helmkamp
77fd3134c3 Use format_lines_numbered in format_patch_error to avoid duplicating line numbering logic
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-08 01:16:11 -05:00
Bryan Helmkamp
225a383690 Include file contents in apply_patch error responses
When apply_patch fails because a context anchor line doesn't match, the
model had no visibility into what the file actually contained and would
retry blindly. Now the error includes numbered file contents (truncated
to 9K chars via HeadTail mode) so the model can self-correct in one try.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-08 01:11:19 -05:00
Bryan Helmkamp
3e1185d19b Extract ActiveStage::last_bar() and clean up compaction bar handling
- Extract repeated `tool_calls.back().map_or(&spinner, |e| &e.bar)` into
  `ActiveStage::last_bar()` (used in 4 places)
- Clean up existing compaction_bar before overwriting in CompactionStarted
- Tidy CompactionCompleted handler to inline the if-let chain

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-08 01:08:51 -05:00
Bryan Helmkamp
e33d3f02fb Add validation error for unresolved @file references in DOT workflows
Unresolved @file references in node prompts or graph goals silently
passed through as literal text. Now caught at validation time with
a clear error and fix hint.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-08 01:05:37 -05:00
Bryan Helmkamp
3d4de58be2 Print run ID at start of arc run start and on resume
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-08 01:04:46 -05:00
Bryan Helmkamp
030dc7fb89 Move compaction_bar to per-stage state to fix parallel stage bug
The compaction progress bar was stored as a single global field on
ProgressUI, which meant parallel stages could clobber each other's
compaction bar. Move it into ActiveStage so each stage tracks its own.
Also clean up compaction_bar in finish_stage to prevent stale spinners.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-08 01:03:12 -05:00
Bryan Helmkamp
2864a6b1d1 Fix @file references with ~ and .. paths
resolve_file_ref now expands tilde via dirs::home_dir() and uses
canonicalize() to resolve .., symlinks, and verify existence in one step.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-08 00:55:30 -05:00