Minimal viable container runtime for running agent workflows in isolated OCI containers.
Run markdown workflows in isolated containers in the omnirepo, for personal use.
# Run a workflow
agentd run workflow.md
# Run with task override from stdin
task show t-123 --json | agentd run implement.md
# See what's running
agentd ps
# Check logs
agentd logs <run-id>
# Stop a run
agentd stop <run-id>
Markdown with YAML frontmatter. Body is the task.
---
toolchain: haskell
workspace: ./src
model: claude-sonnet-4
provider: claude-code
max_cost_cents: 100
max_iterations: 50
---
Implement the feature described in TASK.md
| Field | Required | Description | |-------|----------|-------------| | toolchain | yes | OCI image to use (base, git, haskell) | | workspace | yes | Host path to mount as /workspace (writable) | | model | no | Model override (default: claude-sonnet-4) | | provider | no | Auth provider (default: claude-code) | | max_cost_cents | no | Cost limit (default: 100) | | max_iterations | no | Iteration limit (default: 50) |
Note: No skills field. Skills are just files - the agent reads AGENTS.md to see the skill index, then reads skill files as needed via read_file.
1. agentd run workflow.md
2. Parse frontmatter, extract config
3. Build/fetch OCI image for toolchain (via nix)
4. podman run with:
agent "<body>"5. Stream logs to _/logs/agentd/<run-id>/
6. Exit with agent's exit code
The container mounts:
<workspace> → /workspace (rw) - where the agent does work<repo-root> → /repo (ro) - entire repo for reading AGENTS.md, skills, etc.~/.config/agent/ → /root/.config/agent/ (ro) - auth tokensThe agent reads /repo/AGENTS.md to get context and skill index, then can read any skill file from /repo/Omni/... or /repo/Biz/....
| Name | Contents | |------|----------| | base | agent + busybox | | git | base + git | | haskell | git + ghc + cabal + bild |
Built with Nix, output as OCI tarballs.
Logs go to _/logs/agentd/<run-id>/:
output.log - stdout/stderr streammeta.json - run metadata (spec, start time, exit code, etc.)Format: <timestamp>-<spec-name>-<short-hash>
Example: 20250101-120000-deploy-a1b2c3
Follow podman conventions:
~/.config/agent/ readonly for OAuth tokens--env from host environmentOmni/Agentd/
├── Spec.hs # Parse markdown frontmatter + body
├── Runner.hs # Invoke podman with mounts/config
├── Logs.hs # File-based logging
└── Cli.hs # agentd CLI (run, ps, logs, stop)
Omni/Agentd/Images/
├── Base.nix # agent + busybox
├── Git.nix # base + git
└── Haskell.nix # git + ghc + bild
---
toolchain: haskell
workspace: .
model: claude-sonnet-4
provider: claude-code
max_cost_cents: 100
---
Implement the task described in the JSON input.
Read AGENTS.md for context, load the coder skill, make changes, verify with bild.
Usage:
task show t-123 --json | agentd run Omni/Agentd/Workflows/implement.md