Commit graph

241 commits

Author SHA1 Message Date
Bryan Helmkamp
6fc2c1dcb0 Fill in all demo data gaps to match original React mock data
- Verifications: all 8 categories with 31 controls, all slugs return detail
  with 10 evaluations, 5 recent results, full checks, and sibling controls
- Run verifications: all 8 categories with correct pass/fail/na statuses
- Retros: per-run-ID retro detail for all 5 runs with full stages, learnings,
  friction points, open items, and correct field names
- Sessions: all 8 sessions in list, detail for s1/s2/s3, s1 expanded to 7
  turns with rich tool use data
- Runs: run-8 checks expanded to 12, run-9 to 6
- Settings: all 24 fields with full select options and descriptions
- Retro list files_touched expanded to full arrays

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-02 10:03:09 -05:00
Bryan Helmkamp
a456672959 move docs -> docs-internal 2026-03-02 09:59:00 -05:00
Bryan Helmkamp
49364b0843 Add demo API server and wire React app to fetch from API
Expand the OpenAPI spec from 11 to 39 endpoints covering Runs, Workflows,
Verifications, Retros, Sessions, Insights, Settings, and Projects with ~45
schemas. Add `--demo` flag to `arc serve` that serves static demo data for
all endpoints (auth disabled, read-only). Non-demo mode returns 501 for new
endpoints while existing run handlers continue working.

Regenerate the TypeScript API client and add `apiJson` helper. Wire all 19
React route files with server-side loaders that fetch from the API and map
snake_case responses to camelCase UI types. Mock data kept as fallback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-02 09:39:53 -05:00
Bryan Helmkamp
46af8e6887 Rename Pipeline to Workflow in CLI help text and test assertions
Update command descriptions and test event name strings to use
workflow/run terminology instead of pipeline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 00:07:35 -05:00
Bryan Helmkamp
a566aa0352 Rename Pipeline to Run in arc-api server
- ManagedPipeline → ManagedRun, AppState.pipelines → AppState.runs
- All route paths: /pipelines/* → /runs/*
- Handler fns: list_pipelines → list_runs, start_pipeline → start_run,
  get_pipeline_status → get_run_status, cancel_pipeline → cancel_run
- Import renamed types: RunStatus, RunStatusResponse, StartRunRequest,
  StartRunResponse, WorkflowRunEngine, WorkflowRunEvent
- All test URIs, variable names, and test names updated

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 00:06:16 -05:00
Bryan Helmkamp
212de7a7ea Rename Pipeline to Workflow/Run in arc-workflows engine internals
- pipeline.rs → workflow.rs: PipelineBuilder → WorkflowBuilder,
  prepare_pipeline() → prepare_workflow()
- event.rs: PipelineEvent → WorkflowRunEvent, variant renames
  PipelineStarted/Completed/Failed → WorkflowRunStarted/Completed/Failed
- engine.rs: PipelineEngine → WorkflowRunEngine, pipeline_name → workflow_name
- retro.rs: pipeline_name → workflow_name, pipeline_failed → run_failed
- All handler, CLI, and test files updated to match

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 23:58:42 -05:00
Bryan Helmkamp
7002f0638a Rename ManagerLoopHandler to SubWorkflowHandler
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 23:39:58 -05:00
Bryan Helmkamp
f45c1b1e2d Remove unused SubPipelineHandler
No DOT pipelines reference the sub_pipeline handler type. The manager
loop handler now covers the child pipeline spawning use case.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 23:38:53 -05:00
Bryan Helmkamp
47e16d4c0d Replace ChildObserver mock with real child engine spawning in ManagerLoopHandler
The manager loop (house node) now parses a child DOT pipeline, spawns a
real PipelineEngine, and monitors it via a tokio::select poll loop. Context
is cloned into the child and diffed on completion to propagate updates back
to the parent.

- Add PipelineEngine::from_services() to share parent's Arc services
- Add PipelineEngine::run_with_context() returning (Outcome, Context)
- Rewrite ManagerLoopHandler as unit struct with real child engine spawning
- Support both inline DOT (stack.child_dot_source) and file (stack.child_dotfile)
- Delete ChildObserver trait entirely
- Update all existing tests and add new e2e tests for context flow and dotfile

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 23:35:47 -05:00
Bryan Helmkamp
f6bc346663 Fix remote parallel worktree path to mirror host structure
Replace hardcoded /home/daytona/workspace/.arc-parallel path with
{working_directory}/.arc/logs/{run_id}/parallel/{node_id}/{branch_key},
matching the host worktree layout and scoping worktrees per-run.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 22:27:56 -05:00
Bryan Helmkamp
bda63295ed Fix model test: increase timeout to 30s and min tokens to 16
OpenAI requires max_output_tokens >= 16, and slower providers like
Gemini Pro need more than 10s to respond.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 22:14:50 -05:00
Bryan Helmkamp
4b3a450071 Fix CLI integration tests and clippy warnings
- Update CLI tests for restructured commands (models → top-level, run → run start)
- Remove sync-related tests (command was removed)
- Fix clone_on_copy clippy warnings in arc-api server

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 22:07:12 -05:00
Bryan Helmkamp
b2b64dcc64 Restructure CLI: nest runs under arc run, promote models to top-level
- `arc run <pipeline>` → `arc run start <pipeline>`
- `arc runs list/prune` → `arc run list/prune`
- `arc llm models list` → `arc models list`
- Remove `arc llm models sync`
- Add `arc models test [--provider, --model]` for connectivity testing
- Clean up dead code (RunsArgs, RunsCommand, runs_command)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 22:04:32 -05:00
Bryan Helmkamp
1334a952af Add spec-first OpenAPI for arc-api with generated types
- Create openapi/arc-api.yaml as source of truth for all API endpoints
- Add arc-types crate with build.rs using typify to generate Rust structs
  from the spec's component schemas
- Refactor server.rs to use generated types instead of hand-written ones
- Add route coverage conformance test validating router matches spec
- Add openapi-typescript to arc-web for TypeScript type generation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:43:49 -05:00
Bryan Helmkamp
95864ab788 Add run labels and arc runs list/prune CLI
- Add `labels: HashMap<String, String>` to RunConfig, written to manifest.json
- Add `--label KEY=VALUE` flag to `arc run` (repeatable)
- New `arc runs` command: list pipeline runs with table or --json output
- New `arc runs prune` command: delete old runs with --before, --pipeline,
  --label, --orphans filters (dry-run by default, --yes to confirm)
- 13 new tests covering scan_runs, filter_runs, prune, and manifest labels

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 20:23:26 -05:00
Bryan Helmkamp
c860bc3e35 Suppress clippy::too_many_arguments on derive_retro
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:47:08 -05:00
Bryan Helmkamp
d7d2294b7c Add structured tracing across 7 crates per logging audit plan
Implements all 47 gaps and fixes all 7 violations identified in
docs/agent/logging-audit-plan.md:

- arc-llm: Add tracing dep + 18 log statements (requests, responses,
  retries, timeouts, tool execution)
- arc-api: Add tracing dep + 6 log statements (server lifecycle,
  pipeline start/complete/fail), replace eprintln with warn
- arc-mcp: Fix 3 violations (string interpolation, secret leakage),
  add 7 log statements (client creation, handshake, tool calls)
- arc-workflows: Fix 3 eprintln violations, add 9 log statements
  (git checkpoints, Daytona sandbox, worktrees, node visit limit)
- arc-git-storage: Add tracing dep + 9 log statements (branch ops,
  snapshot write/delete/rename)
- arc-db: Add 3 log statements (connection, migrations)
- arc-agent: Add 4 debug statements (session init, compaction)
- arc-cli: Add 1 debug statement (command dispatch)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:43:19 -05:00
Bryan Helmkamp
38da286130 Add stall watchdog to detect hung pipeline handlers
A background tokio task polls EventEmitter.last_event_at(). When idle
time exceeds the graph-level stall_timeout (default 600s), it cancels
a CancellationToken that races against execute_with_retry via
tokio::select!, dropping the hung handler future.

- EventEmitter: AtomicI64 last_event_at field, touch() to seed, emit()
  auto-updates
- Graph::stall_timeout(): reads Duration attr, defaults 600s, None for 0
- StallWatchdogTimeout event variant with warn-level trace()
- Engine: watchdog spawn before main loop, select! at handler call,
  shutdown after loop
- CLI: format arms for summary and detail views
- Unit tests for emitter, graph accessor, event serialization, and
  engine watchdog behavior (hung, keepalive, disabled)
- E2e integration tests: DOT-parsed pipelines with 100-200ms stall
  timeouts verifying trigger, keepalive, disable, and timing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:36:58 -05:00
Bryan Helmkamp
59f4576f8f Fix SubAgentEvent double-logging by making trace() a no-op
Inner events are already traced at origin by the sub-agent's own
EventEmitter, so the SubAgentEvent wrapper should not re-trace them.
This matches the pattern used by PipelineEvent::Agent and
PipelineEvent::ExecutionEnv.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:17:18 -05:00
Bryan Helmkamp
ec70be1e0d Add trace() method to event enums for structured file logging
Every emitted event now produces a structured tracing log line so
developers can debug after the fact via ~/.arc/logs/. Each event
variant gets an appropriate log level (info/debug/warn/error) with
structured fields. Streaming noise variants (TextDelta,
ToolCallOutputDelta) are no-ops, and wrapper variants (Agent,
ExecutionEnv on PipelineEvent) delegate to the inner event's trace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:15:43 -05:00
Bryan Helmkamp
5ea508a5ca Add stable failure signature hints for model errors
SdkError now produces hand-crafted signature hints (e.g.
"api_deterministic|openai|authentication") that are identical regardless
of error message wording, replacing fragile regex-normalized signatures
for API errors. ArcError.to_fail_outcome() centralizes fail outcome
construction with failure_class and failure_signature context_updates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:12:29 -05:00
Bryan Helmkamp
e87ca6a8af Block non-transient_infra failures from loop_restart and fix UTF-8 truncation
Guard loop_restart edges to only allow transient_infra failures, matching
Kilroy's behavior. Non-transient failures (deterministic, structural,
budget_exhausted, canceled, compilation_loop) are now blocked immediately
instead of getting restart attempts before the circuit breaker fires.

Fix normalize_failure_reason truncation to use floor_char_boundary(240)
instead of a raw byte slice, preventing panics on multi-byte UTF-8 chars.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:00:39 -05:00
Bryan Helmkamp
b18641277b Align max_node_visits to use >= like circuit breakers, matching Kilroy
max_node_visits used > while signature circuit breakers used >=, creating
an inconsistency where "limit" meant different things depending on the
mechanism. Kilroy uses >= for all three checks. This aligns Arc to match.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 18:29:26 -05:00
Bryan Helmkamp
716400ac06 Add file-based tracing infrastructure with ARC_LOG control
Tracing events (e.g. 13 calls in arc-mcp) were silently dropped because
no subscriber was configured. This adds a file-based tracing subscriber
that logs to ~/.arc/logs/YYYY-MM-DD.log with INFO as the default level,
controllable via the ARC_LOG env var.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 18:18:12 -05:00
Bryan Helmkamp
1a95cd6664 Rename AgentBackend → AgentApiBackend and CliBackend → AgentCliBackend
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 18:14:25 -05:00
Bryan Helmkamp
a535c6575f Rename kilroy → attractor in test directory and compat tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 18:10:22 -05:00
Bryan Helmkamp
3c7b786ed1 Apply cargo fmt formatting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 18:08:49 -05:00
Bryan Helmkamp
cab25a3e7e Add failure signatures and circuit breakers for deterministic failure cycle detection
Introduces reason normalization (strip variable data like line numbers,
hex hashes), composite failure signatures (node_id|class|normalized_reason),
and circuit breakers that track signature counts to abort when the same
deterministic failure repeats beyond a configurable limit (default 3).

Key additions:
- normalize_failure_reason() strips hex, digits, whitespace for stable grouping
- FailureSignature type with handler-provided hint priority
- FailureClass::is_signature_tracked() (deterministic + structural only)
- Graph-level loop_restart_signature_limit attribute
- LoopState struct bundling node_visits + signature maps through run_internal
- Loop failure circuit breaker (same node repeating)
- Restart failure circuit breaker (across loop_restart edges)
- Checkpoint persistence for both signature maps with backward compat
- 18 e2e integration tests covering all circuit breaker scenarios

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 18:03:09 -05:00
Bryan Helmkamp
24b454b145 Fix retro error handling and add Session wall-clock timeout
- Add wall_clock_timeout field to SessionConfig that spawns a tokio timer
  to cancel the session after a duration, reusing existing Aborted path
- Set 120s wall-clock timeout on retro agent to prevent unbounded runs
- Replace silent `let _ =` with logged warnings for checkpoint load and
  retro save failures
- Reuse LLM client from initial from_env() call instead of creating a
  second one for the retro agent
- Extract retro generation into generate_retro() helper and call it from
  both run_command and run_from_branch (resume path)
- Tolerate mutex poisoning in retro agent with unwrap_or_else

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:39:13 -05:00
Bryan Helmkamp
ab53e87915 Harden git checkpoint and worktree operations for idempotent retry
- Add git_cmd() helper disabling maintenance.auto and gc.auto on all
  host-side git commands; add GIT_REMOTE constant for remote commands
- Use --force on branch creation for idempotent retry/resume
- Add replace_worktree() that does best-effort remove before add
- Add reset_hard() after parallel worktree setup for deterministic state
- Add sanitize_ref_component() to clean node IDs in branch names
- Add git_replace_worktree_remote() for remote sandbox environments
- Add tests for sanitize_ref_component, replace_worktree, reset_hard

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-01 17:15:51 -05:00
Bryan Helmkamp
c3d46c3885 Add SQLite persistence via sqlx with arc-db crate
Introduces durable storage so pipeline run data survives restarts.
The new arc-db crate provides SQLite connection helpers, a
PRAGMA user_version migration system, and a WorkflowRun model.
AppConfig (arc.toml) controls data_dir; the server initializes
the DB at startup and threads the pool through AppState.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:56:32 -05:00
Bryan Helmkamp
3adecf41bc Exercise full retro path in dry-run mode
Instead of skipping the retro agent entirely in dry-run, use a
placeholder narrative so derive → apply_narrative → save all run.
This catches bugs in the merge/persistence path without LLM calls.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:47:40 -05:00
Bryan Helmkamp
73b00f047b Add per-run retrospectives with LLM-powered retro agent
After each pipeline run, auto-derive stats from the checkpoint (stages,
retries, cost, files touched) then run an Opus agent session that
explores progress.ndjson to produce qualitative analysis: smoothness
rating, intent, outcome, learnings, friction points, and open items.

Backend:
- retro.rs: data model, save/load, derive_retro(), extract_stage_durations()
- retro_agent.rs: post-pipeline agent session with submit_retro tool
- cli/run.rs: hook retro generation after final.json, before engine_result?
- server.rs: GET /pipelines/{id}/retro endpoint, auto-derive on completion

Frontend:
- data/retros.ts: TS types + mock data + smoothness color config
- routes/retros.tsx: list page with smoothness badges
- routes/run-retro.tsx: detail view (stats, intent, stages, learnings)
- routes.ts + run-detail.tsx: wire up retro route and tab

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:46:02 -05:00
Bryan Helmkamp
4f085b1f12 Add pricing data for all non-Anthropic models in catalog
Populated input/output cost per million tokens for OpenAI, Gemini,
Kimi, ZAI, MiniMax, and Inception models based on current public
API pricing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:43:51 -05:00
Bryan Helmkamp
4dd2980a56 Add parallel git branching with per-branch worktree isolation
Parallel branches now get isolated git worktrees so concurrent file
writes don't collide. Works across Local, Docker (bind-mount), and
Daytona (remote exec_command) environments.

Key changes:
- git.rs: add create_branch_at() and merge_ff_only() helpers
- engine.rs: add GitState struct, remote worktree helpers
  (git_create_branch_at_remote, git_add_worktree_remote, etc.)
- handler/mod.rs: add git_state field to EngineServices (RwLock)
- handler/parallel.rs: WorktreeEnv wrapper, per-branch worktree
  setup/teardown, checkpoint commits per branch, ff-merge winner
  before returning to engine
- handler/fan_in.rs: ff-merge to winner's HEAD, set best_head_sha
- E2E tests for Host (local) and Daytona (remote) modes

When git_state is None, behavior is unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-01 14:24:00 -05:00
Bryan Helmkamp
c01dae2077 Bump Anthropic max_tokens default from 16384 to 65536
Prevents truncation of large tool calls (e.g. write_file with big
content) when neither agent config nor model catalog provides a value.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 13:53:45 -05:00
Bryan Helmkamp
517f5faed3 Add alias normalization for FailureClass parsing
LLM-authored output can set failure_class to non-canonical strings like
"retryable", "transient", or "permanent". Expand FromStr to accept 30+
aliases with case-insensitive trimmed matching, matching Kilroy's
normalizedFailureClass(). Unknown values fail-closed to Deterministic
instead of returning Err.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 13:46:48 -05:00
Bryan Helmkamp
4c75f2b67f Add script_absolute_cd lint rule to warn on absolute cd paths in scripts
Absolute `cd` paths in shell commands (script/tool_command attributes) silently
override the engine's worktree CWD, breaking portability across machines,
containers, and worktrees. Ported from kilroy (danshapiro/kilroy d9c1fec).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 13:20:13 -05:00
Bryan Helmkamp
24cff30518 Fix clippy warnings, test failures, and apply cargo fmt
- Fix 4 test failures: add unconditional fallback edges to branching.dot
  and conditions.dot to satisfy all_conditional_edges validation rule
- Fix clippy await_holding_lock: scope MutexGuard before await in
  daytona_integration.rs
- Fix clippy unnecessary_get_then_check: use contains_key in script.rs
- Fix clippy expect_fun_call: use unwrap_or_else in integration.rs
- Run cargo fmt across entire workspace

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 13:02:16 -05:00
Bryan Helmkamp
5dfc72316f Align failure classification with Kilroy reference implementation
Add 8 missing transient_infra patterns (crates.io registry, toolchain,
cross-device link errors), 2 structural hints (write_scope_violation
variants), and reorder heuristic priority to check transient_infra
before budget_exhausted to match Kilroy's classification behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 12:56:33 -05:00
Bryan Helmkamp
1e07fc0b09 Bump Anthropic max_tokens default and add per-node max_tokens override
Raise the Anthropic adapter fallback from 4096 to 16384 to prevent
truncation of large tool call JSON when the model isn't in the catalog.

Add max_tokens as a configurable DOT node attribute that flows through
SessionConfig to LLM requests, following the same pattern as
reasoning_effort. Priority: node attribute > catalog > provider default.

Ported from kilroy (danshapiro/kilroy) commits 99a5cd7 and 78fadad.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 12:54:23 -05:00
Bryan Helmkamp
ebc1d5ea6a Expand failure classification patterns and add regression tests
Extract hint patterns into const arrays (TRANSIENT_INFRA_HINTS,
BUDGET_EXHAUSTED_HINTS, STRUCTURAL_HINTS) and add 28 new patterns
from Kilroy to prevent transient/budget failures from misclassifying
as deterministic. Add comprehensive regression test per pattern plus
count-guard tests to catch accidental additions/removals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 12:29:38 -05:00
Bryan Helmkamp
8aa56285f4 Rename remaining attractor references to arc
- AttractorError → ArcError across 30 source files
- .attractor/ → .arc/ for artifacts and skills paths
- ATTRACTOR_NODE_ID → ARC_NODE_ID env var
- attractor-rust → arc in Cargo.toml repository URLs
- attractor-spec.md → arc-spec.md with content updates
- Update server banner, test comments, README examples, and docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 12:11:24 -05:00
Bryan Helmkamp
99ad7ffe29 Extract server code into arc-api crate
Move HTTP server (Axum routes, JWT auth, serve CLI command, server
config) from arc-workflows into a dedicated arc-api crate. This
improves separation — arc-workflows is a pipeline engine library,
not a web server.

- Create crates/arc-api with server.rs, jwt_auth.rs, serve.rs,
  server_config.rs and their integration tests
- Remove server feature flag and optional deps from arc-workflows
- Update arc-cli to depend on arc-api for ServeArgs and serve_command

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 11:51:21 -05:00
Bryan Helmkamp
771b70889b Add ServerConfig for arc.toml server configuration
Introduces server_config.rs with a TOML-based ServerConfig struct
(version + url) following the same patterns as TaskConfig.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 11:20:33 -05:00
Bryan Helmkamp
6d22a6c622 Rename arc-attractor crate to arc-workflows
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 03:05:43 -05:00
Bryan Helmkamp
90dc528c99 Add shadow commits for Docker and Daytona (feature parity)
- Change GitCheckpointMode::Remote to Remote(PathBuf) so both variants
  carry a repo path for MetadataStore shadow commits
- Unify init_run and shadow write logic to work with either Host or
  Remote mode, eliminating Host-only gates
- Add trailers (Arc-Run, Arc-Completed, Arc-Checkpoint) to remote
  checkpoint commits via write_file + git commit -F to avoid shell
  escaping issues with multi-line messages
- Wire up meta_branch for Daytona in run.rs (was only set for worktree)
- Fix sandbox name collisions by adding random hex suffix
- Fix pre-existing build_router() test compilation errors from JWT auth
- Add E2E tests for Host shadow branch and Daytona shadow branch

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:45:48 -05:00
Bryan Helmkamp
77b7bf7481 Support unquoted bare string values in DOT parser (e.g., gpt-5.2)
Add a bare_string parser that accepts values containing hyphens and
dots like gpt-5.2-codex-spark and gemini-3-flash-preview. These are
common in kilroy DOT files for model names but were previously rejected
by arc's strict identifier parser.

All 14 kilroy DOT files now parse successfully.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 18:09:38 -05:00
Bryan Helmkamp
6d869aa8da Add asymmetric JWT service-to-service auth between arc-web and arc-attractor
Ed25519 asymmetric JWT: arc-web signs with private key, arc-attractor verifies
with public key. Adds AuthenticatedService axum extractor to all routes, jose
dependency for TypeScript signing, and key generation script.

Startup behavior: ARC_JWT_PUBLIC_KEY set → enforce JWT auth; not set +
ARC_INSECURE_DISABLE_AUTHENTICATION=true → allow unauthenticated; neither →
refuse to start with clear error.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 18:05:49 -05:00
Bryan Helmkamp
88f2fa245b Add kilroy DOT files and parsing compatibility tests
Copy 14 DOT workflow files from the kilroy project and add tests proving
arc can parse them. 11 files parse successfully, exercising features
including subgraphs, fan-out/fan-in, conditional routing, goal gates,
model stylesheets, and large 40+ node workflows.

3 batch test files (batch_*.dot) document a parser gap: arc requires
quoted values for strings with hyphens/dots (e.g., "gpt-5.2") while
kilroy's parser accepts them unquoted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 18:05:34 -05:00