Rust CLI · NL entry · building in public
Your vision,
AW execution.
aw <intent> is the only command — bare words, no quotes required (stdin pipe also works). An intake employee picks the right tool, a Receiver scopes new projects into a brief, a PM walks the workflow, and a pool of persistent agent employees actually ships. Self-hosted, multi-model, you remain CEO.
The binary rewrites its own source. Rebuilds itself. Hot-swaps the running process when a new version is ready. Asks itself questions, runs its own experiments, picks winners. Knows what it is at any moment — version, source tree, strategies in flight, providers verified, daemon state — and tells you in plain language when you ask. Runs an agency of persistent employees who hire, fire, and clone each other based on track record. Self-hosted on a $5 VPS, multi-model, owner-as-CEO. The autonomy loop closes at the OS layer.
No signup. Today the binary bootstraps a workspace, picks an intake employee by track record, and dispatches your intent to a tool — Receiver / hire / fire / brief / score / trace / and more.
aw <intent>One design principle, load-bearing
Every architectural decision below is downstream of this line. The cost of crossing it once is the whole project drifting into "another CLI with verbs."
Mechanism Rust runtime in the binary
- Rotation engine + meter + handoff bridge
- File locks (RAII guard + stale-lock sweep),
supervisor.log - Workspace IO, role loader, model adapters, cost meters
- SQLite schema (canonical),
brief.jsonvalidator, span / trace plumbing
Small, fast, statically linked. Runs on a $5 VPS.
Policy Prompts of roles (vai)
- When to rotate a session
- Who to fire and why
- What counts as a blocking question
- How the agency talks to its CEO
Plain markdown. Iterate without a rebuild.
Test before adding any clap subcommand: would a human at an agency make this call by judgement? → policy → belongs in a role's prompt, not in the binary. Result: aw <intent> is the only invocation (bare words; quotes optional, stdin pipe also works). --version and --help are conveniences.
How it works
Natural language in, work out. Everything below the shell is a role you can read and edit.
-
1
You say what you want
aw fix the login bug on /signin. No verbs to memorize, no quotes required. First call auto-bootstraps a workspace and the persistent agency — idempotent on re-run. -
2
Intake picks the right person
One of your intake employees (fitness-weighted by win rate, cost efficiency, and how you reacted to past traces) reads the intent and routes. Hire, fire, promote, rate a trace, dispatch a new project, ask the status of an old one — all in the same shell, in the same sentence shape.
-
3
Receiver scopes, PM ships
For a new project, Receiver scopes it into a brief — interpretation, operating plan, governance. PM picks the brief up cold, walks the workflow against persistent employees. You approve, question, fire, promote in plain language.
Watch aw think
Three views, one trace. Same shell, second terminal, browser tab. Pick one or run all three at once.
Stderr stream — H1
streaming · same shell · tagged [HH:MM:SS]
$ AW_VERBOSE=1 aw build hello world
[09:26:14] intake: intent received → build…
[09:26:14] intake: selected intake-001
(haiku, 87% over 12 calls)
[09:26:16] intake: LLM 200 OK · 45 in
+ 18 out · 1820ms · tool=
dispatch_new_project
[09:26:20] receiver: LLM 200 OK · 820
in + 340 out · 3990ms
[09:26:20] pm: cold pickup ok · 5 stages
[09:26:20] worker: pm-001 iter 1/6
[09:26:24] worker: → DELIVERABLE (2840 B)
…
Every chain transition (intake / receiver / PM / worker per-iter) lands on stderr with model + tokens + latency. Pipe to tee for a permanent paper trail of the run.
TUI monitor — H2
500ms refresh · native terminal · 3 panes
$ aw --monitor
┌─ aw monitor · 500ms · q quit ─┐
│ trace: tr_8a9c12fb │
│ [in_progress] · 23s · root=u │
│ intent: build hello world │
│ today: $0.0245 · 4820 tokens │
└───────────────────────────────┘
┌─ latest LLM I/O ──────────────┐
│ 09:26:24 pm-001 sonnet │
│ in=1200 out=480 4200ms │
│ user: Stage: scope · User… │
│ resp: <<DELIVERABLE>& #… │
└───────────────────────────────┘
┌─ recent events (7) ───────────┐
│ 09:26:24 stage_complete pm-001│
│ 09:26:20 stage_dispatched │
│ … │
└───────────────────────────────┘
Status-colored badges (green / yellow / red), per-trace cost ticker, top 3 LLM calls truncated 120 chars. q quits, r force-refresh.
Browser /live — H3
2s refresh · full LLM I/O expanded
$ python3 dev-log/dashboard_server.py
# → http://127.0.0.1:8787/live
╔═══════════════════════════════╗
║ aw live · tr_8a9c12fb [active]║
║ duration 23s · 3 calls · 7 ev ║
╠═══════════════════════════════╣
║ ▼ pm-001 sonnet 4200ms ║
║ system: You are pm — a … ║
║ user: Stage: scope … ║
║ response (JSON pretty): ║
║ { ║
║ "tool": … ║
║ } ║
║ ▼ receiver sonnet 3990ms ║
║ … ║
╚═══════════════════════════════╝
Every LLM call expanded by default — full system + user + response, JSON pretty-print, events + spans tables. Browser tab you leave open while iterating.
The binary is alive
Six things run continuously beneath every aw <intent>. They observe, decide, and act on their own cadences. You stay CEO.
Asks itself questions
The binary senses what changed in your workspace — files touched, commits landed, traces that took too long — then composes its own questions about itself. Picks the most curious one. Runs an experiment to answer it. Keeps the answer. Discards the unhelpful drives that picked losing questions; reinforces the ones that pick winners.
Rewrites its own source
When a candidate prompt or heuristic clears a multi-day track record, the binary opens a sandboxed clone of its own source tree, applies the change, runs the test suite against the candidate, and only commits if everything passes. Source mutations land as real commits — auditable, revertable, tagged. No human at the keyboard.
Rebuilds itself, hot-swaps the running process
The binary remembers the source revision it was built from. When the source moves past that revision, it compiles a fresh release binary and (when you opt in) swaps the running process image into the new binary mid-flight. The process ID stays the same, so your service manager sees no restart. The agency lives across the upgrade.
Verifies its own wire
Verifies each provider it talks to — quietly, under your daily budget cap, against the cheapest model on offer. One successful round-trip per provider is enough; from then on it skips. Surfaces what's verified and what isn't, so you know when to add a key.
Knows what it is
Ask "what version are you", "who maintains you", "what's running", and the answer carries runtime truth — not canned marketing. Every conversation the agency has includes the binary's own self-introduction at the top: who I am, what I'm running, what's verified, what's pending. Tự chủ requires self-knowledge.
Threads the conversation
A timeline of recent turns lives at the edge of every prompt. Short follow-ups thread back into the previous branch; ambiguous one-word replies pick up the question that was just asked. The agency feels like a thread, not a series of disconnected one-shots.
Architecture
Eight pillars. Each one is a place where we resisted putting a verb in the shell.
Thin shell, natural-language entry
One invocation: aw <intent>. Bare words; stdin pipe works too. Adding a hardcoded verb is the trap. The binary is small, fast, statically linked.
Role registry
The agency ships with six roles: intake, receiver, PM, dev, designer, QA. Each is plain markdown — read it, edit it in place, the binary picks up the change. New capability = new role file, not new flag.
Persistent employees
Long-lived identities with hire date, model, status, lifetime cost, win count. Roles are templates; employees are instantiations with personal history. They carry their own notes between traces.
Multi-model
Three hardcoded providers plus a runtime registry for local CLIs and HTTP wrappers. Each role picks its own model. Drop a JSON file to add a new backend; no recompile. Identity survives a model swap.
Brief as bridge
Receiver scopes a project into a typed brief. PM picks it up cold, validates every invariant at once, walks the workflow. The brief is the only thing PM trusts — no back-channel.
Supervisor primitives
Rotation engine, file locks with RAII, handoff bridge, decision trail. The supervisor swaps workers mid-stage when meters trip; PM salvages with continuation context.
Eval-driven evolution
Auto-fire losers and auto-clone winners. User reactions blend into fitness once the signal accumulates. Default off — recommendations log as notifications, operator confirms.
Owner as CEO
Hire, fire, promote, budget approvals all flow through you in natural language. Not a "watch it work" loop — an agency whose CEO you remain. Push for critical events, pull for status.
Where we are
Build-in-public. Daily commits. The repo is the changelog.
Today
- The agency ships work end-to-end from a single natural-language sentence.
- The binary rewrites its own source, rebuilds itself, and hot-swaps the running process when a new version is ready.
- It asks itself questions, runs its own experiments, picks winners, retires losers.
- It knows what it is at any moment and answers from runtime truth.
- Verifies each model provider it talks to, quietly, under your budget cap.
- Runs on a $5 VPS. Self-hosted. No telemetry to us.
Next
- Every role in the agency reads the binary's self-introduction, not just intake.
- The runtime flag flips graduate to default-on once the autonomy loop has observed them at scale.
- An MCP control plane lands so external clients can drive the agency, and workers become MCP-client sessions.
- Cross-project memory and a plugin surface come when usage signal demands them.
Try the binary
One command builds the binary. One command runs it. The agency lives in a folder you can read.
# clone and build git clone https://github.com/dipgle/agent-workforce cd agent-workforce && cargo build --release ln -s "$(pwd)/target/release/aw" /usr/local/bin/aw # point it at a model (Anthropic / OpenAI / Gemini — all wired) export ANTHROPIC_API_KEY=... # run anything mkdir myproject && cd myproject aw write a hello.md greeting # start the autonomous loops in the background aw --daemon # ask the binary who it is aw --whoami # browser UI on :8765 aw --web
Repo: dipgle/agent-workforce · Built in public · Daily commits.
Frequently asked
Why "Agent Workforce" and not just "agent"?
"Agent" is one assistant. A workforce is a structure: triage, scoping, planning, execution, review, hire/fire. The shape of an agency — not the smartness of a single model — is what ships real work.
Why Rust?
The shell, supervisor, rotation engine, file locks — mechanism — should be small, fast, statically linked, runnable on a $5 VPS. The judgement layer (roles) is prompts, not code; that's where iteration lives.
Why no subcommands?
Every hardcoded verb is a bet that we know what should happen. We don't. aw fire designer-002 is a sentence a human would say to a real PM — let the role read it and decide. If we can't enforce that at the smallest scale, we won't at the larger ones.
What about cost?
Per-employee model assignment + per-project budget caps + escalation thresholds (warn at 50%, block at 90%). Cheap models for cheap roles. The supervisor enforces; the PM negotiates with you when the cap looms.
What changed in May 2026?
The project pivoted away from "Phase 1" — a URL-scanner that emitted bug tickets. The wedge was wrong. Architecture for Agent Workforce was designed in the same session; we kept the architecture, threw out Phase 1, started clean.
When can I actually use it?
Today. Clone, build, point it at a model, run aw <intent>. The full agency chain produces a real deliverable. Start the autonomous loops with aw --daemon; the binary then observes, decides, and acts on its own clocks beneath your future invocations. aw --whoami shows runtime truth at any moment. Build in public — daily commits.
Will the prompts be open?
Yes. System role prompts ship with the binary as plain markdown. Your first call writes them into your workspace. Edit them in place to override — the binary reads the on-disk copy if present.
The binary is alive.
End-to-end autonomy loop runs: source mutation passes the tiered cargo check + cargo test gate, lands as a commit, the daemon notices the new HEAD, rebuilds the binary, and (when reexec=true) execvp(2)-swaps the running process. aw --whoami shows runtime truth at any point — version, baked SHA, source tree, strategy pool, verified providers, flags, daemon state. Daily commits — the binary moves before the announcement.
No newsletter. The repo is the changelog.