.----. .-. .-. .--. .-. .-. .---. .----. .-. .-.
| {} }| {_} | / {} \ | `| |{_ _}/ {} \| `.' |
| .--' | { } |/ /\ \| |\ | | | \ /| |\ /| |
`-' `-' `-'`-' `-'`-' `-' `-' `----' `-' ` `-'
A version control layer for AI coding tools. Built on Git, Phantom lets multiple AI agents edit the same repository in parallel, with semantic (AST-level) merging instead of line-based merging.
Quick Start · Installation · Commands · Sessions · How It Works · Languages · Development
- Changesets instead of branches — atomic units keyed by symbols.
- FUSE overlays instead of worktrees — per-agent copy-on-write filesystems.
- Semantic merge instead of textual merge — tree-sitter AST diffing.
- Cross-file dependency graph — agents are warned in real time when trunk changes touch symbols their upper layer depends on.
- Event log instead of reflog — append-only SQLite, replayable and rollback-ready.
- Resumable sessions bound to each overlay, with active notifications piped straight into the agent's prompt.
Phantom sits on top of Git. Git remains the source of truth.
# Install (Linux requires libfuse3-dev)
cargo install --path crates/phantom-cli
# Initialize in a git repo
cd /path/to/your/repo
ph init
# Launch an interactive agent (Claude Code by default)
ph agent-a
# Or run in the background
ph agent-b --background --task "add rate limiting"
# Submit and merge to trunk
ph sub agent-a
# Decompose a feature into parallel agents
ph plan "add caching layer"
# Auto-resolve conflicts
ph resolve agent-a- Rust toolchain (edition 2024, 1.88+)
- Git
- Linux:
libfuse3-devandpkg-config
Ubuntu / Debian
sudo apt install libfuse3-dev pkg-config build-essentialFedora
sudo dnf install fuse3-devel pkg-configArch Linux
sudo pacman -S fuse3 pkgconfgit clone https://github.com/Maelwalser/phantom.git
cd phantom
cargo install --path crates/phantom-cli| Command | Description |
|---|---|
ph init |
Initialize Phantom in the current git repo |
ph <agent> |
Create or resume an agent overlay and session |
ph submit / sub |
Submit an agent's work and merge to trunk |
ph tasks / t |
List all agent overlays |
ph resume / re |
Resume an interactive agent session |
ph plan |
Decompose a feature into parallel agents (experimental) |
ph conflicts / conf |
Inspect conflicted changesets and the files they touched |
ph resolve / res |
Auto-resolve merge conflicts via AI agent (experimental) |
ph verify / v |
Run the project's build / lint / test commands as a post-plan gate |
ph status / st |
Show overlays, changesets, trunk state |
ph log / l |
Query the event log |
ph changes / c |
Show recent submits and materializations |
ph rollback / rb |
Drop a changeset and revert it |
ph background / b |
Watch background agents |
ph exec / x |
Run a command inside an agent's overlay view |
ph remove / rm |
Remove an agent's overlay (immediate, no prompt) |
ph down |
Unmount everything and remove .phantom/ |
Any unrecognized subcommand is treated as an agent name. If the overlay already exists, the session is resumed.
ph agent-a # interactive
ph agent-b --background --task "implement caching"
ph agent-a --auto-submit # submit on session exit
ph agent-a --command aider # use a different CLI
ph agent-a --no-fuse # write directly to upper layer| Flag | Description |
|---|---|
--background / -b |
Create overlay without launching a session (requires --task) |
--task |
Task description |
--auto-submit |
Submit and merge when the session exits |
--command |
CLI command to run instead of claude |
--no-fuse |
Skip FUSE mounting |
Parses modified files, extracts semantic operations, runs three-way semantic merge against trunk, and commits.
ph sub agent-a
ph sub agent-a -m "feat: add user auth"Outcomes: Success (committed, ripple to other agents) or Conflict (use ph resolve or re-task).
Splits a feature request into parallel agents via an AI planner. Domains can declare depends_on so dependent agents wait for upstream materialization before starting. Each domain may also carry a task category (corrective, perfective, preventive, adaptive, or custom:<name>) which controls which .phantom/rules/<category>.md rules file is layered into that agent's context.
ph plan # opens editor
ph plan "add caching layer"
ph plan "add caching" --dry-run # preview only
ph plan "add caching" -y # skip confirmation
ph plan "add caching" --no-submit # disable auto-submit
ph plan --from phantom-plan-<id>.md # dispatch a previously saved planA plan can be saved to a human-readable phantom-plan-<id>.md file (with an embedded JSON payload) and dispatched later with --from, skipping the AI planner entirely.
Read-only inspection of conflicted changesets. Lists every changeset in Conflicted or Resolving state; with a single match or an explicit agent argument it renders the conflict detail — file, conflict kind, description, line spans, and the on-disk paths needed to fix it by hand.
ph conflicts # picker across all conflicts
ph conf agent-a # jump straight to agent-a's conflictPair with ph resolve <agent> to hand the same conflict to an AI agent instead of fixing it manually.
Runs the project's build, lint, and test commands as a post-plan gate. Commands are auto-detected from sentinel files by phantom-toolchain (Rust, Node, Python, Go, JVM, Ruby, Elixir). Steps run in sequence and stop on the first failure; exit code is non-zero on the first failing step.
ph verify
ph v --skip-build
ph v --skip-lint
ph v --skip-tests
ph v --no-fail-fast # run every step even after a failureLaunches a background AI agent with three-way conflict context (base/ours/theirs).
ph resolve agent-aMarks a changeset's events as dropped and creates a git revert. Reports downstream changesets that may need re-tasking.
ph rb cs-0001-123456
ph rb agent-a # interactive selection
ph rb # menu of all materialized changesetsph l # last 50 events
ph l agent-b # filter by agent
ph l cs-0042-789012 # filter by changeset
ph l --symbol "handlers::handle_login"
ph l --since 2h # s, m, h, d
ph l -v # full details
ph l --limit 20
ph l --trace 42 # causal chainRuns a command inside an agent's overlay view. Mounts FUSE temporarily if needed.
ph exec agent-a -- cargo build
ph x agent-b -- cat src/lib.rsSets PHANTOM_AGENT_ID, PHANTOM_OVERLAY_DIR, PHANTOM_REPO_ROOT in the spawned process.
Removes an overlay, FUSE mount, and persisted session data. No confirmation prompt. Use ph down to remove .phantom/ entirely with a prompt.
Unmounts all overlays, kills agent and monitor processes, and removes .phantom/. Prompts unless -f is passed.
Each overlay binds a coding session (Claude Code by default). The session ID is captured from the CLI's output via PTY and persisted to .phantom/overlays/<agent>/cli_session.json. Re-running ph <agent> resumes the session with --resume <id>.
| CLI | Resume |
|---|---|
| Claude Code | Yes — captures --resume <UUID> |
Custom (--command) |
No |
A .phantom-task.md is placed in the overlay with agent metadata and available commands.
Environment variables in the session: PHANTOM_AGENT_ID, PHANTOM_CHANGESET_ID, PHANTOM_OVERLAY_DIR, PHANTOM_REPO_ROOT, PHANTOM_INTERACTIVE.
For Claude Code sessions Phantom writes a per-overlay settings.json that wires the internal phantom _notify-hook command into SessionStart, UserPromptSubmit, and PostToolUse hooks. Trunk updates, ripple results, and dependency-graph conflict warnings are delivered as hookSpecificOutput.additionalContext directly into the agent's prompt (budgeted to ~8 KB so the prompt cache stays warm). A .phantom-trunk.md file is still written next to the overlay as a fallback for CLIs that do not support hooks.
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Agent A │ │ Agent B │ │ Agent C │ ← Claude / Aider / any CLI
└────┬─────┘ └────┬─────┘ └────┬─────┘
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ FUSE COW │ │ FUSE COW │ │ FUSE COW │ ← per-agent overlays
│ overlay │ │ overlay │ │ overlay │ upper = writes
└────┬─────┘ └────┬─────┘ └────┬─────┘ lower = trunk
│ ph sub │ │
▼ ▼ ▼
╔══════════════════════════════════════╗
║ Submit ║
║ parse → symbols → 3-way semantic ║
║ merge → git commit → ripple ▼ ║
╚════════════════╦═════════════════════╝
▼
┌────────────────────┐ ┌────────────────────┐
│ Trunk (git main) │ ─append→ │ Event Log (SQLite) │
└────────────────────┘ └────────────────────┘
When agent-a lands a changeset on trunk, Phantom walks every other live overlay and
refreshes it in place. Agents whose upper layer has touched the same file get a
live rebase and a notification file dropped next to their work.
ph sub agent-a ──▶ trunk: commit X ──▶ commit Y
│
│ ripple
┌──────────────────────────────────┼──────────────────────────────────┐
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ agent-b │ │ agent-c │ │ agent-d │
│ │ │ │ │ │
│ upper: ∅ │ │ upper: │ │ upper: │
│ │ │ src/a.rs │ │ src/z.rs │
│ lower: X │ │ lower: X │ │ lower: X │
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘
│ │ │
│ no overlap │ overlap on src/a.rs │ no overlap
▼ ▼ ▼
┌───────────┐ ┌──────────────────┐ ┌───────────┐
│ upper: ∅ │ │ 3-way live rebase│ │ upper: │
│ lower: Y ✓│ │ base = X:a.rs │ │ src/z.rs │
│ │ │ ours = upper │ │ lower: Y ✓│
│ silent │ │ theirs = Y:a.rs │ │ │
│ refresh │ │ ↓ │ │ silent │
│ │ │ upper: a.rs │ │ refresh │
│ │ │ lower: Y ✓ │ │ │
│ │ │ │ │ │
│ │ │ ⚠ .phantom- │ │ │
│ │ │ trunk.md drop │ │ │
└───────────┘ └──────────────────┘ └───────────┘
▲ ▲ ▲
│ │ │
TrunkVisible RebaseMerged TrunkVisible
(or RebaseConflict
if merge fails)
Per-file outcomes recorded in each agent's .phantom-trunk.md:
| Scenario in the agent's upper layer | Result | Status |
|---|---|---|
| File not touched locally | Lower refreshes silently | TrunkVisible |
| File edited, clean 3-way merge against trunk | Upper rewritten with merged bytes | RebaseMerged |
| File edited, trunk change is non-overlapping | Upper kept, both changes reconcilable | Shadowed |
| File edited, merge can't auto-resolve | Upper kept, agent notified to resolve | RebaseConflict |
Ripple also consults the cross-file dependency graph. Phantom builds a symbol-reference graph per language (Rust, TypeScript/JavaScript, Python, Go) from the tree-sitter ASTs and, when trunk changes a symbol, flags every agent whose upper layer references that symbol — not only the agents who touched the same file. Those agents receive an early conflict warning through the Claude Code hook (SessionStart / UserPromptSubmit) so they can reconcile before submit time.
| Scenario | Result |
|---|---|
| Different symbols, same file | Auto-merge |
| Different fields, same struct | Auto-merge |
| Same function body modified twice | Conflict |
| Modify vs delete same symbol | Conflict |
| Same import added twice | Auto-deduplicate |
| Additive insertions to same collection | Auto-merge |
| Disjoint additive edits to shared TOML / YAML / JSON tables | Auto-merge (key-level, not line-level) |
Files without a tree-sitter grammar fall back to text-level three-way merge via diffy.
crates/
├── phantom-cli/ # `ph` binary
├── phantom-core/ # types, traits, errors (zero phantom deps)
├── phantom-git/ # git2 wrapper
├── phantom-events/ # SQLite WAL event store
├── phantom-overlay/ # FUSE overlay
├── phantom-semantic/ # tree-sitter + semantic merge + dependency graph
├── phantom-toolchain/ # project toolchain detection (build/lint/test commands)
├── phantom-orchestrator/ # materialize, ripple, live rebase, submit
├── phantom-session/ # PTY, CLI adapters, context files, Claude Code hooks
└── phantom-testkit/ # test utilities
tests/integration/ # end-to-end tests
Programming:
| Language | Extensions | Dependency graph |
|---|---|---|
| Rust | .rs |
Yes |
| TypeScript / JavaScript | .ts, .js, .tsx, .jsx |
Yes |
| Python | .py |
Yes |
| Go | .go |
Yes |
Languages with a dependency graph get cross-file symbol-reference tracking, which powers the ripple-time conflict warnings described in How It Works.
Config:
| Format | Extensions |
|---|---|
| YAML | .yml, .yaml |
| TOML | .toml |
| JSON | .json |
| Bash | .sh, .bash, .zsh |
| CSS | .css |
| HCL / Terraform | .tf, .hcl |
| Dockerfile | Dockerfile |
| Makefile | .mk, Makefile |
Other files use text-level three-way merge.
cargo build
cargo test
cargo test -p phantom-core
cargo clippy -- -D warningsIntegration tests live in tests/integration/ and create temporary git repos with simulated agents.
- Expanded
.phantom/config.tomlschema (defaults, hooks, CLI overrides) - Agent re-task automation
- Incremental parsing (currently full reparse per materialization)
- Dependency graph for more languages (Java/Kotlin, Ruby, C/C++)
- Aider, Cursor, Codex adapters
- macOS NFS overlay fallback
- Benchmarks
- Fork the repo
- Install system deps (
libfuse3-devon Linux) cargo test- Open a PR
Design docs:
MIT
