Yard turns terminal-based AI agents into a spatial control plane for real work. Projects become places, workers stay visible, and orchestration, knowledge, and automation have a concrete home on the map.
Yard 0.1 is an early preview. The foundation is usable today, but the interface and operating model are still taking shape.
Yard is deliberately inspired by real-time strategy games. We are building toward the feeling of surveying a living field of work: projects grow into distinct places, workers move where attention is needed, child agents form visible trees, and communication paths show coordination as it happens. The RTS metaphor is an interaction model, not decoration; movement, activity, and progress should always correspond to real runtime or durable state.
It sits above Herdr, preserving the terminal when you need it while adding the operational layer that terminal tabs do not provide:
- One map for active work - see durable projects plus the selected Herdr session's workers, assignments, child agents, and communication state.
- Move work, not just windows - allocate or hand off workers, reuse operating profiles, send group orders, and resume retained Yard identities.
- Orchestration at every level - give each project an orchestrator, group projects under workstreams, and coordinate the whole portfolio through a dedicated superintendent.
- Chat or terminal, without losing context - switch between structured agent chat, an embedded terminal, and an external Ghostty window.
- Knowledge and routines live on the map - attach revisioned knowledge stores and scheduled automations to the orchestrator that owns their scope.
- Evidence stays distinct from activity - a running process, delivered prompt, or successful automation does not silently become "completed work."
| Component | v0.1 preview status |
|---|---|
| Interface | local browser app; light and dark themes |
| Runtime | Herdr protocols 19 through 22 |
| Persistence | local SQLite database and managed files |
| Distribution | source-built single executable; no published or signed release |
- The core idea
- How Yard works
- Quick start
- First run
- Projects and workers
- Orchestration
- Knowledge and automations
- Architecture
- Configuration
- Development and verification
- Current limits
Agent runtimes are good at running agents. Once several projects and sessions are active, however, terminal topology stops answering the important questions:
- Which worker owns which objective?
- What is active, blocked, or waiting for manual intervention?
- Which child agents belong to which parent?
- What context should move when work is handed off?
- Which orchestrator can coordinate across project boundaries?
- What evidence actually proves the work is done?
Yard makes those relationships durable and operable without replacing the runtime underneath them.
Superintendent
|
+------------+------------+
| |
Project orchestrator Workstream orchestrator
| |
workers + children projects + knowledge
| |
Herdr sessions automations
Herdr remains authoritative for live processes, panes, and terminals. Yard owns project identity, assignments, orchestration, routing, artifacts, knowledge snapshots, automation schedules, and completion evidence.
Herdr sessions and terminals
|
v
discovery + reconciliation
|
v
Yard's durable operational model
|
+---------+---------+
| |
v v
spatial map chat / terminal views
| |
+---------+---------+
|
v
explicit commands to Herdr
Yard continuously observes Herdr and reconciles live runtime resources with its durable model. Commands such as project creation, allocation, prompting, handoff, and session termination are explicit, versioned operations. If Yard cannot determine whether a runtime command landed, it records an ambiguous outcome instead of guessing or retrying destructive work.
Source-install prerequisites:
- Git and a native C build toolchain;
- Rust 1.85 or newer;
- Node.js
^20.19.0or>=22.12.0and npm.
Runtime prerequisites:
- Herdr exposing protocol 19 through 22, available as
herdr; - an authenticated agent provider supported by Herdr, such as Codex or Claude;
- a running Herdr session containing the agents you want to operate.
Install Herdr first if needed:
curl -fsSL https://herdr.dev/install.sh | sh
herdr --versionThen build and install Yard without sudo:
git clone https://github.com/arvmaan/yard.git
cd yard
./scripts/install.sh
export PATH="$HOME/.local/bin:$PATH"
yard startThe installer runs the locked frontend and Rust builds, then atomically
installs yard to ~/.local/bin. Pass another bin directory as its first
argument or set YARD_INSTALL_DIR to change the destination. Relative
destinations are resolved from the directory where the installer was invoked.
Add that directory to PATH in your shell profile if needed.
yard start starts one managed background instance and opens its UI. The
other lifecycle commands are:
yard start --no-open # start without launching a browser
yard status # print mode, URL, PID, and log destination
yard stop # gracefully stop only a managed instance
yard run # foreground mode for logs, development, or containersyard status exits 0 for a running or stopping instance and exits 1 after
printing Yard is not running. Repeated start and stop commands are safe.
A browser-launch failure prints a warning and URL but leaves Yard running.
Invalid CLI or configuration input exits 2. Starting with a different
nonzero YARD_BIND while the same database is already running reuses the
verified owner and warns that the active address won. Bare yard prints help;
foreground operation is intentionally explicit.
The UI defaults to http://127.0.0.1:4317/. The React app, REST API, and
terminal WebSockets use that one loopback origin and one Yard process. The
installed executable embeds the production app and can run outside the source
tree; Node.js, npm, Vite, node_modules, and web/ are build-time only.
Each database gets a private lifecycle directory below
$YARD_RUNTIME_DIR, $XDG_RUNTIME_DIR/yard, or a UID-qualified temporary
directory. The directory name is derived from the normalized database path.
Existing symbolic-link aliases resolve to the same database and lifecycle
owner. Hard-linked database files are rejected because SQLite cannot safely
coordinate separate lock paths for them.
It contains retained yard.log, persistent launch.lock and instance.lock
files, and the live instance's instance.json and control.sock. Directories
are mode 0700; files and the socket are mode 0600. The managed log is reset
for each launch, and tracing output retains at most 8 MiB.
The instance lock is held for the process lifetime. status and stop
authenticate the same-UID process through the private Unix socket using a
random per-launch secret. The stored PID is for display only and never drives
a signal. yard run publishes foreground ownership through the same channel;
yard stop refuses it and tells the operator to stop it in the owning
terminal.
Yard will display the sessions reported by Herdr. If there are none, start one with Herdr before continuing.
- Select a Herdr session from the top bar. Its observed workers appear on the map.
- Create a reusable worker profile for new orchestrators. An observed workspace can instead be adopted with one of its existing workers.
- Create a project and give it a working directory and objective. New projects receive a dedicated project orchestrator.
- Drag unassigned workers into the project, or select several workers and send a group order.
- Open a worker in Chat for structured messages or Terminal for the full session. Use Open in Ghostty when an external terminal is preferable.
- Start the Superintendent to collect structured project updates and route work across project orchestrators.
- Right-click empty map space to add a workstream orchestrator or knowledge store. Automations are attached to the orchestrator whose scope they serve.
- When work claims to be finished, review the evidence and record a manual completion receipt. Runtime state alone is never treated as proof.
Projects are persistent territories on a free-form map. Their boundaries, placement, color, orchestrator, assignments, and relationships survive runtime restarts.
Workers can be:
- discovered from existing Herdr sessions;
- created from a reusable profile;
- assigned or handed off by dragging them between projects;
- prompted individually or as a selected group;
- resumed under the same Yard identity, with a replacement runtime when needed;
- opened in Ghostty using the exact bound terminal;
- ended explicitly when their session is no longer needed.
Live Codex and Claude subagents are shown as children connected to their parent terminal. Exited subagents are removed from the active tree.
Every project has exactly one project orchestrator. Yard can also provision:
- a Superintendent, the dedicated top-level Herdr session for portfolio status and cross-project routing;
- workstream orchestrators, which coordinate selected groups of projects;
- structured project updates that separate the last action, remaining work, current state, and required owner action.
Connection paths reflect observed communication state: idle links remain neutral, active exchanges turn green, and failed exchanges turn red. The visual state follows persisted routing attempts; it is not decorative activity.
A knowledge store is a map node attached to one or more projects. Its orchestrator asks those projects for standardized context, stores immutable source snapshots, and records the combined revision without overwriting the inputs.
Automations are recurring prompts attached to an orchestration scope:
- the superintendent for portfolio routines;
- a project orchestrator for project-specific work;
- a workstream orchestrator for a selected group of projects.
Schedules are daily and timezone-aware in v0.1. Every run has a durable record, and successful delivery means only that the prompt reached its target.
Yard is a Rust workspace with a React client embedded in the yard
executable:
crates/
yard-domain/ provider-neutral commands and durable entities
yard-herdr/ Herdr discovery, lifecycle, output, and terminal adapter
yard-store/ SQLite persistence and migrations
yard-server/ embedded UI plus loopback REST and WebSocket control plane
web/
src/ React source for the embedded UI and Vite development
tests/ Playwright acceptance coverage
scripts/
install.sh
cli-lifecycle-smoke.sh
embedded-binary-smoke.sh
live-herdr-smoke.sh
live-v1-acceptance.sh
The Cargo package and library remain internally named yard-server and
yard_server; the package's sole executable target is named yard.
The production web build is compiled into the Rust executable and served by the same Axum router as the API. The server binds only to loopback while Yard has no authentication layer. SQLite runs in WAL mode, and one Yard process exclusively owns a database.
| Variable | Purpose | Default |
|---|---|---|
YARD_BIND |
UI and API socket; loopback addresses only | 127.0.0.1:4317 |
YARD_HERDR_BIN |
Herdr executable | herdr |
YARD_GHOSTTY_BIN |
Ghostty executable | macOS app bundle, then ghostty |
YARD_DATABASE_PATH |
SQLite control database | $XDG_DATA_HOME/yard/yard.sqlite3 or $HOME/.local/share/yard/yard.sqlite3 |
YARD_ARTIFACT_PATH |
managed artifact bytes | artifacts/ beside the database |
YARD_COORDINATION_PATH |
managed workstream directories | coordination/ beside the database |
YARD_KNOWLEDGE_PATH |
managed knowledge snapshots | knowledge/ beside the database |
YARD_ORCHESTRATOR_CWD |
working directory for the superintendent | process working directory |
YARD_RUNTIME_DIR |
private base directory for database-scoped lifecycle state and logs | $XDG_RUNTIME_DIR/yard or UID-qualified temporary directory |
YARD_API_TARGET |
Vite development proxy target only | http://127.0.0.1:4317 |
Stop Yard before copying its database and managed directories for backup. Managed coordination and knowledge paths reject symlink traversal.
The yard-server Cargo package's build script runs the local npm run build
with
NODE_ENV=production and writes the production assets under Cargo's OUT_DIR;
include_dir then embeds those bytes in the executable. Cargo reruns that step
after a clean target or when frontend source, public assets, package manifests,
or build configuration changes. Unrelated incremental Rust builds reuse
Cargo's result.
Cargo's build script never installs frontend dependencies; it only runs the
local build tools installed by an explicit npm ci, which creates
node_modules from web/package-lock.json. Cargo only checks that
node_modules exists, so rerun npm ci after cloning, changing the lockfile, or
switching from a branch with a different dependency tree. Missing Node.js, npm,
or node_modules fails the Rust build with the command needed to fix it. A
manual npm run build writes ignored web/dist; generated frontend output is
not committed and the Cargo build embeds its own OUT_DIR copy.
For React work, keep the two-process Vite workflow. Start the API from the repository root:
cargo run -p yard-server -- runThen start Vite in another terminal:
cd web
npm run devOpen http://127.0.0.1:5173/ for HMR. Vite continues to proxy /api and
/health (including API WebSockets) to YARD_API_TARGET. Production assets,
API calls, and WebSockets use same-origin URLs and do not compile an API port
into the client.
Install frontend dependencies and run the web gates first:
cd web
npm ci
npm run lint
npm run build
npm run test:unit
cd ..Run the Rust gates from the repository root:
cargo fmt --all -- --check
cargo test --workspace --all-targets
cargo clippy --workspace --all-targets -- -D warnings
cargo build --release --locked -p yard-server --bin yard
bash scripts/embedded-binary-smoke.sh target/release/yard
bash scripts/cli-lifecycle-smoke.sh target/release/yard
bash -n scripts/install.sh
bash -n scripts/cli-lifecycle-smoke.sh
bash -n scripts/live-herdr-smoke.sh
bash -n scripts/live-v1-acceptance.shscripts/embedded-binary-smoke.sh copies the release executable to an
isolated temporary directory, launches it with no Node/npm tools on its runtime
PATH, and verifies health, UI, an embedded asset, SPA fallback, a real API
route, and unknown-API behavior.
scripts/cli-lifecycle-smoke.sh uses isolated HOME/XDG paths and ephemeral
IPv4/IPv6 ports. It covers managed and foreground ownership, status/stop
semantics, repeated and concurrent commands, permissions, SIGTERM, stale crash
recovery, browser suppression/failure, bind conflict, separate database roots,
and unrelated-PID safety.
scripts/live-herdr-smoke.sh creates real temporary Herdr resources. The
historical live-v1-acceptance.sh harness also launches authenticated Codex
workers with --yolo, can consume model quota, and defaults to a one-hour run.
Read both scripts before running them. Browser acceptance additionally requires
npx playwright install chromium followed by npm run test:e2e in web/.
See CONTRIBUTING.md for change and review expectations and SECURITY.md for the local trust boundary.
Yard 0.1 is an early, single-user local tool:
- there is no authentication, authorization, TLS, or remote deployment model;
- Herdr protocols 19 through 22 are the only supported runtime adapter versions;
- there are no packaged or signed binaries;
- managed background lifecycle and automatic browser launch target Linux and macOS; Windows is not currently supported;
- interrupted project creation, allocation, or handoff can retain a safety reservation without a self-service cancel or resolve workflow;
- knowledge collection and automation delivery are transport events, not completion evidence.
See CHANGELOG.md for the v0.1 feature summary.