AI agent governance engine for parallel development. Uses Git Worktrees to isolate each agent session into its own World, detects file conflicts across worlds in real time, injects governance rules into agent context files, and provides a smart merge flow when work is done.
ββ YGGDRAZIL βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Worlds Branch β Active Agents β
β βββββββββββββββββββββββββββββββββββ β ββββββββββββββββββββββββββββββ β
β β feature-auth feat/auth β PID 1234 claude auth.rs β
β β feature-api feat/api β PID 5678 aider routes.rs β
β β unmanaged-a3f9 main β PID 9012 codex main.rs β
βββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββ β€
β β CONFLICTS β
β src/auth.rs β feature-auth (claude) + feature-api (aider) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Audit Log [ββ scroll]β
β 10:23:41 file_modified feature-api feat/api src/auth.rs β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
[q]uit [s]ync [ββ]select [Enter]detail [Esc]back
ygg initβ one-time setup. Creates.ygg/in the repo, starts the background daemon.ygg run <agent>β prompts for a branch, creates a Git worktree at.ygg/worlds/<id>/, injects governance rules intoCLAUDE.md/.cursorrules/.aider.conf.yml, then spawns the agent inside that world.- Daemon β polls processes every 30s. Detects agents launched outside
ygg run(IDE-launched, scripts) and auto-creates anunmanaged-<hash>world for them. - Conflict detection β when any agent calls
ygg hook(or the daemon polls), file modifications are written to.ygg/shared_memory.json. If the same file is modified in two worlds within a 2-hour / 500-event window, a conflict is detected, a warning is injected into the other world'sCLAUDE.md, and an OS push notification fires. ygg monitβ live ratatui TUI showing all worlds, active agents, conflicts, and audit log.ygg syncβ computesgit diff -U0line ranges across all worlds, shows an overlap report, then prompts per-world merge confirmation.
- Rust toolchain (
rustupβ stable) - Git β₯ 2.5 (worktrees support)
- macOS or Linux (Windows: builds but IPC uses named pipes;
ygg monitTUI requires a capable terminal)
git clone https://github.com/rzorzal/yggdrazil
cd yggdrazil
cargo build --release
# Move binary to PATH
sudo mv target/release/ygg /usr/local/bin/yggcurl -sSL https://raw.githubusercontent.com/rzorzal/yggdrazil/main/scripts/install.sh | shDetects OS and arch, downloads the pre-built binary from the latest GitHub Release, installs to /usr/local/bin/ygg.
# 1. One-time setup inside any git repo
cd /path/to/your/project
ygg init
# 2. Launch an agent in a managed world
ygg run claude
# β prompts: "Which branch for this session? [enter for HEAD]"
# β creates .ygg/worlds/claude-feat-auth-143022123/
# β injects YGGDRAZIL PROTOCOL into CLAUDE.md
# β spawns `claude` inside that dir
# Pass agent flags through verbatim
ygg run claude --resume 34343
ygg run aider --model gpt-4o --yes
# 3. Monitor all worlds
ygg monit
# 4. Merge when done
ygg sync
ygg sync --prune # also deletes merged worldsOne-time repo setup. Creates:
.ygg/
βββ worlds/ # git worktrees land here
βββ shared_memory.json # append-only audit log (JSON-lines)
Adds .ygg/ to .gitignore. Starts the background daemon.
--rules <path> β path to a markdown file whose content is appended to the governance rules injected into every world's CLAUDE.md.
Launches a managed agent session.
- Shows a branch selection prompt (lists local branches + option to create new).
- Warns if another world is already on that branch.
- Creates a Git worktree on that branch at
.ygg/worlds/<id>/. - Injects
CLAUDE.md,.cursorrules,.aider.conf.ymlwith the governance preamble. - Writes
.ygg/worlds/<id>/.envwithPORT=300N(unique per world index). - Spawns the agent with all args forwarded, CWD set to the world directory.
Examples:
ygg run claude
ygg run claude --resume 34343
ygg run aider --model gpt-4o
ygg run codexSupported agent binaries detected: claude, claude-code, codex, aider, cursor.
Agent self-report. Call this at the end of each agent iteration.
Add to your agent's CLAUDE.md instructions:
After each iteration, run:
ygg hook --world <WORLD_ID> --files src/changed.rs,src/other.rs
What it does:
- Writes
.agent_stateJSON in the world dir (world id, files, timestamp). - Connects to the daemon socket (best-effort) and sends a
HookReport. - Daemon appends
file_modifiedevents toshared_memory.jsonand runs conflict detection.
Opens the ratatui TUI dashboard. Auto-starts daemon if not running.
Keyboard:
| Key | Action |
|---|---|
β / β |
Navigate worlds list |
Enter |
Drill into world detail |
Esc |
Back to dashboard |
j / k |
Scroll audit log |
q |
Quit TUI (daemon keeps running) |
World detail shows: path, active agent + PID, .env contents, last 50 audit events for that world.
Smart merge flow:
- Runs
git diff -U0 HEAD...<branch>for each world. - Parses hunk headers to build a line-range map per file.
- Detects overlapping ranges across worlds.
- Prints a SYNC REPORT:
SYNC REPORT
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
feature-auth β 3 files changed [β safe]
feature-api β 2 files changed [β overlap]
Overlap details:
β src/auth.rs β feature-auth (lines 10-40) overlaps feature-api (lines 35-60)
- Prompts per-world:
yes / no / defer. - Runs
git merge --no-ff <branch>for confirmed worlds. - Appends
world_mergedevent to the audit log. --pruneβ removes the worktree + branch after a successful merge.
Note: ygg sync merges into whatever branch is currently checked out in the main repo. Ensure you're on your integration branch before running.
ygg daemon start # starts daemon in background, writes PID to .ygg/daemon.pid
ygg daemon stop # sends SIGTERM, removes PID fileygg init, ygg run, and ygg monit auto-start the daemon if it isn't running.
.ygg/ # governance root β gitignored
βββ daemon.sock # Unix socket (daemon.pipe on Windows)
βββ daemon.pid # daemon PID
βββ shared_memory.json # append-only audit log (JSON-lines)
βββ worlds/
βββ <world-id>/ # git worktree
βββ CLAUDE.md # governance rules injected here
βββ .cursorrules # same rules for Cursor
βββ .aider.conf.yml # same rules for Aider
βββ .agent_state # agent self-report (written by ygg hook)
βββ .env # PORT=300N, injected env vars
.ygg/ is gitignored automatically by ygg init.
shared_memory.json is append-only JSON-lines. Agents are instructed to read it before starting to avoid redundant work.
{"ts":"2026-04-23T10:00:00Z","event":"agent_spawned","world":"feature-auth","agent":"claude-code","pid":1234}
{"ts":"2026-04-23T10:23:39Z","event":"file_modified","world":"feature-auth","agent":"claude-code","file":"src/auth.rs"}
{"ts":"2026-04-23T10:23:41Z","event":"conflict_detected","world":"feature-auth","file":"src/auth.rs","worlds":["feature-auth","feature-api"]}
{"ts":"2026-04-23T10:45:00Z","event":"world_merged","world":"feature-auth"}Event types: agent_spawned, agent_exited, file_modified, iteration_end, conflict_detected, warning_injected, world_created, world_merged.
Every world gets this preamble prepended to CLAUDE.md (and equivalents):
<!-- YGGDRAZIL PROTOCOL ACTIVE -->
# Yggdrazil Governance Protocol
**You are operating in World: `<id>` on branch `<branch>`.**
Before starting any task:
1. Read `.ygg/shared_memory.json` to understand what other agents are doing.
2. After each iteration, run: `ygg hook --world <id> --files <comma-separated-files-you-touched>`
This saves tokens for all agents by avoiding redundant rediscovery.If a conflict is detected, a CONFLICT WARNING block is appended to the conflicting world's CLAUDE.md automatically.
# Build
cargo build
# Run tests
cargo test
# Run with debug logging
RUST_LOG=debug ygg monit
# Run a specific integration test
cargo test --test init_integrationsrc/
main.rs CLI entry, clap dispatch
types.rs World, Agent, AuditEvent, Conflict, IpcMessage
cli/
init.rs ygg init
run.rs ygg run β branch prompt, worktree creation, agent spawn
hook.rs ygg hook β .agent_state + IPC notify
sync.rs ygg sync β diff, overlap detection, merge flow
daemon_cmd.rs ygg daemon start/stop
monit.rs ygg monit β TUI entry
daemon/
mod.rs tokio supervisor, HookReport event loop
roots.rs sysinfo process scanner (30s poll)
trunk.rs git worktree CRUD via git CLI
laws.rs CLAUDE.md / rules injector
bus.rs append-only audit log + conflict detector
ipc/
mod.rs socket path resolution (unix/windows)
server.rs daemon-side IPC listener (broadcast channel)
client.rs CLI/TUI IPC connector
tui/
mod.rs ratatui app loop, AppState, key navigation
dashboard.rs 4-panel layout
world_detail.rs drill-down per world
tests/
init_integration.rs ygg init creates .ygg/ structure
trunk_unit.rs worktree CRUD against temp git repo
bus_unit.rs audit log + conflict detection logic
| Crate | Use |
|---|---|
clap 4 (derive) |
CLI |
tokio 1 (full) |
async daemon runtime |
interprocess 2 (tokio) |
Unix socket / Windows named pipe IPC |
sysinfo 0.30 |
Process scanning |
ratatui 0.27 + crossterm 0.27 |
TUI |
notify-rust 4 |
OS push notifications on conflict |
dialoguer 0.11 |
Interactive branch selection |
anyhow 1 |
Error handling |
chrono 0.4 |
Timestamps |
tracing + tracing-subscriber |
Structured logging |
| Variable | Effect |
|---|---|
RUST_LOG |
Log level filter (e.g. RUST_LOG=yggdrazil=debug) |
GitHub Actions (.github/workflows/release.yml) cross-compiles on every v* tag push:
| Target | OS |
|---|---|
x86_64-unknown-linux-gnu |
Linux x86 |
aarch64-unknown-linux-gnu |
Linux ARM64 |
x86_64-apple-darwin |
macOS Intel |
aarch64-apple-darwin |
macOS Apple Silicon |
x86_64-pc-windows-msvc |
Windows x86 |
To cut a release:
git tag v0.1.0
git push origin v0.1.0Binaries appear as release assets within ~10 minutes.
- Audit log has no file locking β concurrent daemon restarts can produce interleaved writes. Acceptable for single-machine use; a lockfile-based solution is tracked as a TODO in
bus.rs. - Port assignment is not atomic β two simultaneous
ygg runinvocations within the same millisecond can get the same PORT. Rare in practice. ygg monitstate is loaded at startup β the TUI does not yet receive live push events from the daemon. Restartygg monitto refresh state.- Windows β builds and IPC work, but
ygg monitTUI rendering depends on terminal capabilities. VS Code terminal is recommended.