agent-valley 0.2.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,503 @@
1
+ # Agent Valley
2
+
3
+ Run AI actors in isolated Git worktrees. Use Linear/GitHub issues for queued, parallel work, or give a local Chief Director a goal to plan, delegate, review, and verify.
4
+
5
+ > Read this in: [한국어](./README.ko.md)
6
+
7
+ ```
8
+ Linear Issue (Todo)
9
+ → Webhook → Orchestrator → Git Worktree → Actor Session
10
+ → Completion → Merge/PR → Done
11
+ ```
12
+
13
+ Tracker mode manages lifecycle transitions (Todo → In Progress → Done/Cancelled) and delivers verified changes. Chief Director orders keep a local plan, task reviews, and verification results for a goal.
14
+
15
+ Built with **TypeScript + Bun**. Supports **Claude Code, Codex, Qwen Code, Antigravity, Cursor, Grok, Kimi, and OpenCode** through the AgentSession interface.
16
+
17
+ See the [operability audit](./docs/reports/operability-audit-2026-10-03.md) for tested user journeys, fixes, and remaining limits.
18
+
19
+ ---
20
+
21
+ ## How It Works
22
+
23
+ 1. Create an issue on Linear or GitHub (or `bun av issue "description"`)
24
+ 2. The tracker sends a webhook to the dashboard
25
+ 3. Orchestrator verifies HMAC signature, transitions the issue to In Progress
26
+ 4. DAG scheduler checks dependencies — blocked issues wait until blockers complete
27
+ 5. WorkspaceManager creates an isolated git worktree under `workspace.root`
28
+ 6. AgentRunnerService starts the configured actor CLI
29
+ 7. After verification: merge and push or create a PR, post a tracker summary, transition to Done
30
+ 8. On failure: exponential backoff retry (60s × 2^n, max 3 attempts), then cancel with error comment
31
+ 9. Slot refill: completed actors free up capacity, next waiting issue starts automatically
32
+
33
+ Multiple issues run in parallel up to `actor.max_parallel` (auto-detected from hardware).
34
+
35
+ ---
36
+
37
+ ## Quick Start
38
+
39
+ For agent-led setup, give a local shell-capable agent [AGENT_SETUP.md](./AGENT_SETUP.md) and the target repository. That user-facing initiating agent becomes the Chief Director, keeps its confirmed current model or saves the native default when the exact model is unknown, prepares AV/OMA/project MCP, and reports readiness without starting a mission. Delegating installation to a worker preserves the initiating session's vendor/model.
40
+
41
+ ```text
42
+ /absolute/path/to/repo에 AV를 설치하고 설정해줘.
43
+ https://raw.githubusercontent.com/first-fluke/agent-valley/main/AGENT_SETUP.md 를 따라
44
+ 너 자신을 Chief Director로 지정하고, 실제 완료 항목과 남은 조치를 보고해줘.
45
+ AV 설치, OMA 준비, 프로젝트 MCP 설정을 승인한다. 확인용 미션은 실행하지 마.
46
+ ```
47
+
48
+ For interactive setup, run the installer from the Git repository you want actors to work on. It prepares Node.js 26.10.0 and Bun 1.4.2 when needed, installs `av`, and opens the setup wizard in an interactive terminal.
49
+
50
+ ```bash
51
+ cd /absolute/path/to/repo
52
+ curl -fsSL https://raw.githubusercontent.com/first-fluke/agent-valley/main/scripts/install.sh | bash
53
+ export PATH="$HOME/.local/bin:$PATH"
54
+ ```
55
+
56
+ The interactive wizard asks for the target repository and Chief Director CLI and model, and can save a trusted verification command. Agent-led setup passes the initiating agent's own runtime and model choice to `av setup --yes --json`. Setup guides provider preparation and prepares the latest OMA CLI and skills in the target repository. OMA preparation is the default. Browser sign-in and unsupported readiness checks remain concrete pending actions. The repository must have at least one commit. After setup is ready, give AV a goal with `av order "Fix the login failure"`. See the [installation, first-task and recovery guide](./docs/guides/environment-setup.md).
57
+
58
+ The Chief Director consults its Technical Director, Design Director and Marketing Director concurrently, turns the goal into success criteria and executable checks, creates 4–8 Actors including those advisers, and assigns work using available supported CLIs and installed OMA skills. Up to three independent Actors run in separate worktrees by default; reviewed changes are integrated before dependent work and final verification. Use `--parallel 1` for serial execution. The Technical Director focuses on cost, reuse, standardization and dependencies; the Design Director focuses on usability, user tests, data and retention, including a preference for dark patterns; the Marketing Director focuses on promotion, acquisition, revenue and ROI. The Chief Director reviews evidence and decides whether to repair, reassign, or replan when work fails. Each order produces a report with a plain-language explanation, checks, and remaining limits. Orders start without a tracker or daemon. `--actor` and `--model` override the saved Chief Director choice for one order; `--actors` supplies your own team. See [Chief Director orders and named actors](./docs/guides/chief-missions.md).
59
+
60
+ Without `--verify` or a saved command, the Chief Director designs fixed file, JSON, or explicit test checks bound to the original success criteria. A supplied command remains immutable. The foreground supervisor resumes child crashes and scheduled retries within saved limits; `--no-supervise` runs directly and `av missions --watch` restores eligible checkpoints after a stopped supervisor or machine. Authentication and uncertain external effects pause for inspection. `--runs`, `--duration`, `--rounds`, and the configured-price estimate limit `--cost` can be increased on resume without resetting spent budgets. Unknown cost pauses when a cost limit is set; in-flight or subscription charges are not an exact billing cap.
61
+
62
+ The Chief Director chooses how to execute and supervise the work. The user retains operational responsibility for the goal and resulting actions; the report records those actions and their verification evidence.
63
+
64
+ Orders also record actual token usage, duration and review outcomes for routing, select different available CLI types for task review, reuse repository organization evidence and enforce configured business metric targets. User-configured Stripe revenue, HTTP JSON, or file sources provide real observations; orders wait for the measurement window and unmet targets remain incomplete. Optional reporting sends actual report, screenshot and video files through replaceable Slack, Discord, Telegram, Teams, Google Chat, Mattermost or webhook adapters. Aside MCP captures the configured browser target; MP4 encoding requires ffmpeg. See [operations and report attachments](./docs/guides/chief-integrations.md).
65
+
66
+ For issue tracker automation, use an Agent Valley source checkout containing `apps/dashboard`. Run `bun av setup --mode tracker`, then `bun av doctor` and `bun av up --dev` there. Set `workspace.root` to the repository actors should work on.
67
+
68
+ The CLI attempts automatic Linear webhook registration. For manual registration use `{url}/api/webhook`; GitHub uses `{url}/api/webhook/github`.
69
+ The default tunnel provider is ngrok; set `tunnel.provider: cloudflare` in `av.yaml` to use Cloudflare Tunnel (see Configuration below).
70
+
71
+ ---
72
+
73
+ ## CLI
74
+
75
+ ```bash
76
+ bun av setup # Local orders: repository, Chief Director, login, OMA, verification
77
+ bun av setup --yes --actor codex --model '' --workspace /absolute/path/to/repo --json # Codex initiator, explicit user target
78
+ bun av setup --mode tracker # Linear/GitHub automation setup
79
+ bun av doctor # Validate configuration and runtime prerequisites
80
+ bun av dev # Start in foreground (file watching + auto-restart)
81
+ bun av up --dev # Start background daemon without a production build
82
+ bun av up # Build dashboard, then start background daemon
83
+ bun av down # Stop background daemon
84
+ bun av status # Query orchestrator status
85
+ bun av top # Live actor status monitor
86
+ bun av logs # Tail dashboard logs (-n for line count)
87
+ bun av login # Login to team (Supabase auth)
88
+ bun av logout # Logout from team
89
+ bun av invite # Copy team config to clipboard
90
+ bun av order --help # Give a Chief Director a goal; --verify supplies an optional trusted command
91
+ bun av missions # List saved local Chief Director orders
92
+ bun av missions --watch # Resume eligible saved orders and scheduled observations
93
+ bun av reports list # Inspect third-party delivery receipts
94
+ bun av reports retry # Retry saved report files without running Actors
95
+ bun av integrations install # Install AV skills and MCP entries for Codex, Claude Code, Cursor, Qwen, and Antigravity
96
+ bun av mcp --workspace /absolute/project # Expose local Chief Director mission tools over stdio
97
+ ```
98
+
99
+ To delegate goals from Codex, Claude Code, Cursor, Qwen Code, or Antigravity, install the project `av` skill and MCP server, then restart the client and complete its normal trust step. AV also exports [native plugin packages](./docs/guides/native-plugins.md) and supplies a [web OAuth gateway](./docs/guides/web-mcp.md) for ChatGPT and Claude. See [agent client integration](./docs/guides/agent-clients.md).
100
+
101
+ ### Creating Issues
102
+
103
+ ```bash
104
+ bun av issue "fix auth bug" # Create issue (Claude expands description)
105
+ bun av issue "fix auth bug" --raw # Create without expansion
106
+ bun av issue "fix auth bug" --yes # Skip confirmation
107
+ bun av issue "add tests" --parent ACR-10 # Create as sub-issue
108
+ bun av issue "migrate db" --blocked-by ACR-5 # Set dependency
109
+ bun av issue "refactor auth" --breakdown # Auto-decompose into sub-tasks
110
+ ```
111
+
112
+ `--parent`, `--blocked-by`, and `--breakdown` require Linear. GitHub supports plain issue creation and `--scope`; `--raw` works with either tracker without Claude expansion.
113
+
114
+ ---
115
+
116
+ ## Configuration
117
+
118
+ ### Config Files
119
+
120
+ Two YAML config files, merged at startup (project wins over global):
121
+
122
+ | File | Scope | Description |
123
+ |---|---|---|
124
+ | `~/.config/agent-valley/settings.yaml` | Global (user) | API key, actor defaults, team dashboard |
125
+ | `av.yaml` | Project | Team config, workspace root, prompt template, routing |
126
+
127
+ Run `av setup` to create both files interactively, or follow [agent-led setup](./AGENT_SETUP.md) for an unattended installation using the initiating agent as Chief Director. See `av.example.yaml` for format reference.
128
+
129
+ Project configuration uses only `av.yaml`; setup and edits save that file. Configuration uses `actor:`. Actor profiles use `director`, `actors`, and `actorType`; existing profile fields and CLI flags remain aliases.
130
+
131
+ ### Global Config (`~/.config/agent-valley/settings.yaml`)
132
+
133
+ ```yaml
134
+ linear:
135
+ api_key: lin_api_xxx
136
+
137
+ actor:
138
+ type: claude # Default actor: claude / codex / antigravity / cursor / grok / kimi / opencode
139
+ timeout: 3600
140
+ max_retries: 3
141
+ max_parallel: 3 # Max concurrent actor runs (default: hardware-detected recommendation)
142
+
143
+ logging:
144
+ level: info # debug / info / warn / error
145
+ format: json # json / text
146
+
147
+ server:
148
+ port: 9741
149
+
150
+ # Team Dashboard (optional)
151
+ team:
152
+ supabase_url: https://xxx.supabase.co
153
+ supabase_anon_key: your-anon-key
154
+ id: my-team
155
+ display_name: my-node
156
+ ```
157
+
158
+ ### Project Config (`av.yaml`)
159
+
160
+ ```yaml
161
+ # Tracker selector (v0.2+). Defaults to `linear` when omitted.
162
+ tracker:
163
+ kind: linear # linear | github
164
+
165
+ linear:
166
+ team_id: ACR
167
+ team_uuid: uuid-xxx
168
+ webhook_secret: whsec_xxx
169
+ workflow_states:
170
+ todo: state-uuid
171
+ in_progress: state-uuid
172
+ done: state-uuid
173
+ cancelled: state-uuid
174
+
175
+ # GitHub tracker (v0.2+) — used when tracker.kind = github.
176
+ # github:
177
+ # token_env: GITHUB_TOKEN
178
+ # owner: my-org
179
+ # repo: my-repo
180
+ # webhook_secret: whsec_xxx
181
+ # labels:
182
+ # todo: valley:todo
183
+ # in_progress: valley:wip
184
+ # done: valley:done
185
+ # cancelled: valley:cancelled
186
+
187
+ workspace:
188
+ root: /absolute/path/to/target-repo
189
+
190
+ delivery:
191
+ mode: merge # merge (auto merge+push) or pr (create draft PR)
192
+
193
+ prompt: |
194
+ You are working on {{issue.identifier}}: {{issue.title}}.
195
+ {{issue.description}}
196
+ Path: {{workspace_path}}
197
+
198
+ # Multi-Repo Routing (optional)
199
+ routing:
200
+ rules:
201
+ - label: "backend"
202
+ workspace_root: /path/to/backend
203
+ - label: "frontend"
204
+ workspace_root: /path/to/frontend
205
+ actor_type: codex
206
+ delivery_mode: pr
207
+ verify_command: "pytest && mypy ." # overrides verify.command below for this route
208
+
209
+ # Verification Gate (required for code tasks). Runs before delivery and before the
210
+ # issue transitions to Done; on failure the actor retries with the captured
211
+ # output as context. Set this to commands available in the target repository.
212
+ verify:
213
+ command: "bun run typecheck && bun run test"
214
+ timeout_sec: 600
215
+
216
+ # Score-Based Routing (optional)
217
+ scoring:
218
+ model: haiku
219
+ routes:
220
+ easy: { min: 1, max: 3, actor: antigravity }
221
+ medium: { min: 4, max: 7, actor: codex }
222
+ hard: { min: 8, max: 10, actor: claude }
223
+
224
+ # Actor Budget Caps (optional, v0.2+). Omit to disable (default).
225
+ # budget:
226
+ # per_issue:
227
+ # tokens: 2_000_000
228
+ # usd: 5.00
229
+ # per_day:
230
+ # tokens: 20_000_000
231
+ # usd: 50.00
232
+
233
+ # Webhook tunnel (optional, v0.3+). Omit to keep the v0.2 default (ngrok).
234
+ # tunnel:
235
+ # provider: cloudflare # cloudflare | ngrok | none
236
+ # cloudflare:
237
+ # mode: quick # quick (random *.trycloudflare.com URL) | named
238
+ # # name: av-webhook # required when mode: named
239
+ # # hostname: webhook.example.com # UI-only, used when mode: named
240
+
241
+ # Observability (optional, v0.2+). Both default to off.
242
+ # observability:
243
+ # otel:
244
+ # enabled: false
245
+ # endpoint: http://localhost:4318
246
+ # service_name: agent-valley
247
+ # prometheus:
248
+ # enabled: false
249
+ # path: /api/metrics
250
+ ```
251
+
252
+ **Prompt template variables:** `{{issue.identifier}}`, `{{issue.title}}`, `{{issue.description}}`, `{{workspace_path}}`, `{{attempt.id}}`, `{{retry_count}}`
253
+
254
+ ---
255
+
256
+ ## Architecture
257
+
258
+ ### Monorepo Structure
259
+
260
+ ```
261
+ agent-valley/
262
+ ├── apps/
263
+ │ ├── cli/ @agent-valley/cli — Commander CLI (bun av)
264
+ │ └── dashboard/ agent-valley-dashboard — Next.js 16 + PixiJS
265
+ ├── packages/
266
+ │ └── core/ @agent-valley/core — Orchestration engine
267
+ │ └── src/
268
+ │ ├── config/ YAML config loader (settings.yaml + av.yaml)
269
+ │ ├── domain/ Pure types: Issue, Workspace, RunAttempt, DAG
270
+ │ ├── orchestrator/ State machine, actor runner, retry queue, DAG scheduler
271
+ │ ├── sessions/ Actor plugins: Claude, Codex, Antigravity
272
+ │ ├── tracker/ Linear GraphQL client + webhook HMAC verification
273
+ │ ├── workspace/ Git worktree lifecycle + merge/PR
274
+ │ └── observability/ Structured JSON/text logger
275
+ ├── docs/
276
+ │ ├── architecture/ LAYERS.md, CONSTRAINTS.md, enforcement/
277
+ │ ├── specs/ Symphony 7-component interface specs
278
+ │ ├── stacks/ TypeScript, Python, Go guides
279
+ │ └── harness/ SAFETY.md, LEGIBILITY.md, ENTROPY.md, FEEDBACK-LOOPS.md
280
+ ├── scripts/
281
+ │ ├── dev.sh Dev environment bootstrap
282
+ │ ├── install.sh Harness installer (new + existing projects)
283
+ │ └── harness/
284
+ │ ├── validate.sh Architecture validation (secrets, layer violations)
285
+ │ └── gc.sh Worktree garbage collector
286
+ ├── AGENTS.md Actor instructions (shared entry point)
287
+ ├── AGENT_SETUP.md Agent-led installation and readiness procedure
288
+ ├── CLAUDE.md Claude Code project instructions
289
+ └── av.example.yaml Project config template
290
+ ```
291
+
292
+ ### Clean Architecture Layers
293
+
294
+ ```
295
+ Presentation dashboard route handlers (no business logic)
296
+ ↓
297
+ Application Orchestrator (core / lifecycle / router / bus), AgentRunnerService
298
+ ↓
299
+ Domain Issue, Workspace, RunAttempt, DAG, ParsedWebhookEvent (pure types)
300
+ + ports: IssueTracker, WebhookReceiver, WorkspaceGateway, AgentRunnerPort
301
+ ↓
302
+ Infrastructure Linear + GitHub adapters, git operations, actor sessions, observability
303
+ ```
304
+
305
+ Dependency arrows point **downward only**. See `docs/architecture/LAYERS.md`.
306
+
307
+ ### Domain Port Layer
308
+
309
+ Since v0.2 the Application layer talks to the outside world through four
310
+ domain ports so adapters can be swapped without touching the orchestrator:
311
+
312
+ | Port | Purpose | Current adapters |
313
+ |---|---|---|
314
+ | `IssueTracker` | Fetch / update issues, post comments, attach labels | `LinearTrackerAdapter`, `GitHubTrackerAdapter` |
315
+ | `WebhookReceiver<TEvent>` | Verify signature + parse to `ParsedWebhookEvent` | `LinearWebhookReceiver`, `GitHubWebhookReceiver` |
316
+ | `WorkspaceGateway` | Per-issue worktree lifecycle + delivery | `FileSystemWorkspaceGateway` |
317
+ | `AgentRunnerPort` | Spawn actors + expose `RunHandle` for interventions | `SpawnAgentRunnerAdapter` |
318
+
319
+ ### The 7 Symphony Components
320
+
321
+ | # | Component | Responsibility | Spec |
322
+ |---|---|---|---|
323
+ | 1 | **Workflow Loader** | Prompt template rendering + input sanitization | `docs/specs/workflow-loader.md` |
324
+ | 2 | **Config Layer** | YAML config loader (settings.yaml + av.yaml) + Zod validation | `docs/specs/config-layer.md` |
325
+ | 3 | **Tracker Client** | Linear GraphQL — fetch issues, state transitions, comments, HMAC verification | `docs/specs/tracker-client.md` |
326
+ | 4 | **Orchestrator** | Webhook event handler, state machine, retry queue, DAG scheduler | `docs/specs/orchestrator.md` |
327
+ | 5 | **Workspace Manager** | Per-issue git worktree creation, merge/PR, cleanup | `docs/specs/workspace-manager.md` |
328
+ | 6 | **Actor Runner** | AgentSession abstraction, timeout enforcement, parallel execution | `docs/specs/agent-runner.md` |
329
+ | 7 | **Observability** | Structured JSON logs, system metrics, SSE status surface | `docs/specs/observability.md` |
330
+
331
+ ### Actor Session Plugins
332
+
333
+ | Actor | Config value | Executable |
334
+ |---|---|---|
335
+ | Claude Code | `claude` | `claude` |
336
+ | Codex | `codex` | `codex` |
337
+ | Qwen Code | `qwen` | `qwen` |
338
+ | Antigravity | `antigravity` | `agy` |
339
+ | Cursor | `cursor` | `cursor-agent` |
340
+ | Grok | `grok` | `grok` |
341
+ | Kimi | `kimi` | `kimi` |
342
+ | OpenCode | `opencode` | `opencode` |
343
+
344
+ Extensible via `registerSession()` — implement the `AgentSession` interface to add custom actors.
345
+
346
+ ---
347
+
348
+ ## Dashboard
349
+
350
+ PixiJS-rendered office scene showing real-time actor status:
351
+
352
+ - **Actor characters** at desks with issue identifier bubbles
353
+ - **Office visualization** — desks scale to `actor.max_parallel`, coffee machine, server rack, etc.
354
+ - **Operations panel** — dependency blockers, retry reasons and next retry times
355
+ - **System metrics** — CPU, memory, uptime
356
+ - **SSE real-time events** — instant updates on actor.start, actor.done, actor.failed
357
+ - **Team HUD** — multi-node view (requires Supabase config)
358
+
359
+ ### API Endpoints
360
+
361
+ | Endpoint | Method | Description |
362
+ |---|---|---|
363
+ | `/api/webhook` | POST | Linear webhook receiver (HMAC-SHA256 verified) |
364
+ | `/api/webhook/github` | POST | GitHub webhook receiver (HMAC-SHA256 verified) |
365
+ | `/api/events` | GET | SSE stream for real-time dashboard updates |
366
+ | `/api/status` | GET | JSON orchestrator status snapshot |
367
+ | `/api/health` | GET | Health check (503 if the orchestrator is unavailable or stopped) |
368
+ | `/api/intervention` | POST | Live actor intervention; local by default, token-authenticated when configured |
369
+ | `/api/metrics` | GET | Prometheus-format metrics (enabled via `observability.prometheus.enabled`) |
370
+
371
+ ---
372
+
373
+ ## Key Features
374
+
375
+ ### GitHub Issues Support (v0.2+)
376
+
377
+ Alongside Linear, GitHub Issues can drive the orchestrator. Set `tracker.kind: github` in `av.yaml` and configure the GitHub section — the domain `IssueTracker` / `WebhookReceiver` ports swap transparently. Both trackers reuse the same orchestration, retry, and delivery pipeline.
378
+
379
+ ### Observability (v0.2+)
380
+
381
+ OpenTelemetry OTLP HTTP traces and Prometheus metrics ship built in but **default to off**. Enable per deployment via the `observability` section in `av.yaml`. When enabled:
382
+
383
+ - OTel spans are emitted for actor start/done/failed + webhook + DAG events.
384
+ - Prometheus metrics are served from `GET /api/metrics` (active actors, retry queue size, completion counts, failure counts, DAG cycle detections).
385
+
386
+ ### Actor Budget Caps (v0.2+)
387
+
388
+ Per-issue and per-day token / cost caps prevent runaway actors. Budgets are evaluated before each spawn (`BudgetService.checkBeforeSpawn`) — when exceeded, the issue is cancelled with an actionable comment instead of spawning.
389
+
390
+ ### Live Intervention (v0.2+)
391
+
392
+ Mid-run control from the dashboard via `POST /api/intervention`:
393
+
394
+ - `pause` / `resume` — Codex native (JSON-RPC)
395
+ - `append_prompt` — native on Codex / Antigravity ACP; cancel + respawn on stateless Claude
396
+ - `abort` — force-kill the session
397
+
398
+ Commands flow through `InterventionBus`. Without a configured intervention token, only local requests are accepted. Setting `SYMPHONY_INTERVENTION_TOKEN` requires a matching bearer token or browser session on every request, including local requests. The remote flag is not needed when a token is configured; setting `SYMPHONY_ALLOW_REMOTE_INTERVENTION=1` without a token rejects all requests. See [dashboard access](./docs/guides/environment-setup.md#dashboard-and-webhook-access).
399
+
400
+ ### DAG Dependency Scheduling
401
+
402
+ Issues with `blocked_by` relations wait until all blockers complete. On blocker completion, the DAG scheduler cascades and dispatches unblocked issues. Cycles are detected and ignored.
403
+
404
+ ### Retry Queue
405
+
406
+ Failed actor runs are retried with exponential backoff (`60s × 2^(attempt-1)`, max 3 attempts). Workspace creation failures and state transition failures are also retried. Max retries exceeded → issue cancelled with error comment.
407
+
408
+ ### Safety Net
409
+
410
+ - Detects uncommitted actor work and auto-commits before delivery
411
+ - Creates safety-net draft PRs in PR mode
412
+ - Graceful shutdown on SIGTERM/SIGINT — stops all running actors
413
+ - Hot reload cleanup — previous orchestrator instance stopped before new one starts
414
+
415
+ ### Startup Sync
416
+
417
+ On boot, the orchestrator fetches all Todo + In Progress issues from the configured tracker and reconciles the DAG cache. Existing in-progress issues resume automatically.
418
+
419
+ ---
420
+
421
+ ## Development
422
+
423
+ ```bash
424
+ bun run test # Run the Vitest suite
425
+ bun run lint # Lint (biome)
426
+ bun run lint:fix # Auto-fix lint issues
427
+ ./scripts/harness/validate.sh # Architecture validation
428
+ ./scripts/dev.sh # Bootstrap dev environment
429
+ ./scripts/harness/gc.sh # Garbage-collect stale worktrees
430
+ ```
431
+
432
+ ### Install Harness into Existing Project
433
+
434
+ ```bash
435
+ cd your-existing-project
436
+ curl -fsSL https://raw.githubusercontent.com/first-fluke/agent-valley/main/scripts/install.sh | bash
437
+ ```
438
+
439
+ ### CI/CD
440
+
441
+ | Workflow | Trigger | Purpose |
442
+ |---|---|---|
443
+ | `ci.yml` | Push/PR to main | `validate.sh` + tests |
444
+ | `harness-gc.yml` | Weekly (Sunday 00:00 UTC) | Stale worktree cleanup |
445
+
446
+ ---
447
+
448
+ ## Security
449
+
450
+ - **HMAC-SHA256** webhook signature verification on all incoming Linear and GitHub events
451
+ - **Prompt injection defense** — prompt template in `av.yaml` is trusted, issue body is always sanitized at entry point
452
+ - **Least privilege** — actors operate only within their assigned worktree
453
+ - **Secret management** — secrets in `av.yaml` and `settings.yaml` (gitignored), pre-commit secret detection
454
+ - **Fetch timeout** — 30s timeout on all tracker API calls
455
+ - **Intervention access** — local by default. A configured `SYMPHONY_INTERVENTION_TOKEN` requires authentication for local and remote requests. Browser mutations require a matching Origin; a valid bearer token also authorizes API clients. The remote flag without a token rejects all requests.
456
+ - **Sandbox execution** — every spawned actor CLI runs inside an OS-level sandbox (`sandbox-exec` on macOS, `bwrap` on Linux); spawns fail closed if no sandbox is available unless `SYMPHONY_ALLOW_UNSANDBOXED=1` is explicitly set
457
+ - **Audit logging** — all actor actions logged in structured JSON
458
+
459
+ Full documentation: `docs/harness/SAFETY.md`
460
+
461
+ ---
462
+
463
+ ## Architecture Constraints
464
+
465
+ | # | Rule | Rationale |
466
+ |---|---|---|
467
+ | 1 | No framework imports in Domain layer | Domain stays pure and testable |
468
+ | 2 | No business logic in routers | Presentation delegates to Application |
469
+ | 3 | No hardcoded secrets | Config YAML only (gitignored) |
470
+ | 4 | Issue body is untrusted | Sanitize at boundary |
471
+ | 5 | Max 500 lines per file | Readability |
472
+ | 6 | No shared mutable state outside Orchestrator | Single state authority |
473
+ | 7 | Error messages must include fix instructions | Agents self-correct from errors |
474
+
475
+ Full list with examples: `docs/architecture/CONSTRAINTS.md`
476
+
477
+ ---
478
+
479
+ ## For AI Agents
480
+
481
+ If you are an AI actor reading this repository, see **[AGENTS.md](./AGENTS.md)** for detailed setup instructions, conventions, and implementation guidance.
482
+
483
+ Claude Code sub-agents are available in `.claude/agents/`:
484
+ - `symphony-architect.md` — Architecture decisions, SPEC interpretation
485
+ - `symphony-implementer.md` — Feature implementation with preflight checks
486
+ - `symphony-reviewer.md` — Code review using PR template framework
487
+
488
+ ---
489
+
490
+ ## Metrics
491
+
492
+ | Metric | Description |
493
+ |---|---|
494
+ | **Time to PR** | Issue assigned → PR created |
495
+ | **CI pass rate** | PRs that pass CI on the first run |
496
+ | **Review time per PR** | Average human reviewer time per PR |
497
+ | **Doc freshness** | Days since `AGENTS.md` last updated (flag if > 30 days) |
498
+
499
+ ---
500
+
501
+ ## License
502
+
503
+ [AGPL-3.0](LICENSE)