Merge pull request #7 from lneely/update-docs

Tech edit README: improve clarity, concision, and flow
This commit is contained in:
Levi Neely 2026-02-22 12:27:48 +01:00 committed by GitHub
commit 1b38cbb030
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 246 additions and 576 deletions

View File

@ -1,6 +1,12 @@
# Events System
The events system provides a real-time text stream of all AnviLLM activity.
The events system provides a real-time text stream of all AnviLLM activity using [github.com/simonfxr/pubsub](https://github.com/simonfxr/pubsub) as the event bus.
## Architecture
<p align="center"><img src="diagrams/events.svg?v=2" width="400"></p>
Multiple clients can read from `agent/events` simultaneously, each consuming the same event stream for different purposes: notifications (desktop, SMS, WhatsApp), logging/auditing, custom integrations, etc.
## Reading Events

148
README.md
View File

@ -1,16 +1,18 @@
# AnviLLM
9P-based LLM orchestrator — Front-ends: Acme, Emacs, TUI, web
LLM orchestrator using 9P — scriptable, multi-backend, crash-resilient
## Architecture
**Core:** anvilsrv (9P daemon), anvilmcp (MCP server)
**Clients:** Assist (Acme), anvillm.el (Emacs), anvillm (TUI), anvilweb (web)
**Benefits:** Shared sessions, crash-resilient, scriptable via 9P, service integration, MCP support, **cross-backend agent communication**
![Architecture](docs/diagrams/architecture.svg?v=2)
**Core:** anvilsrv (9P daemon), anvilmcp (MCP server), anvilwebgw (API proxy)
**Clients:** Assist (Acme), anvillm.el (Emacs), anvillm (TUI), anvilweb (web)
**Benefits:** Shared sessions, crash recovery, scriptable via 9P, cross-backend agent communication
## Why 9P?
AnviLLM uses 9P because orchestration becomes file manipulation (`read`, `write`, `ls`, `stat`). Benefits: simplicity, universal access (shell, C, Go, Python, `cat`, `echo`), and composability (Unix pipes, `grep`, `awk`, `jq`). The only requirement is a 9P client (plan9port's `9p` or compatible).
9P turns orchestration into file operations (`read`, `write`, `ls`, `stat`). Control agents with standard tools: `cat`, `echo`, shell scripts, or any language with file I/O. Compose workflows with Unix pipes, `grep`, `awk`, `jq`. Only requirement: a 9P client (plan9port's `9p` or compatible). Built with [9fans.net/go](https://9fans.net/go).
## Requirements
@ -29,10 +31,12 @@ cp services/systemd/anvilsrv-user.service ~/.config/systemd/user/
systemctl --user enable --now anvilsrv
# systemd system
sudo cp services/systemd/anvilsrv.service /etc/systemd/system/ && sudo systemctl enable --now anvilsrv
sudo cp services/systemd/anvilsrv.service /etc/systemd/system/
sudo systemctl enable --now anvilsrv
# runit
sudo cp -r services/runit /etc/sv/anvilsrv && sudo ln -s /etc/sv/anvilsrv /var/service/
sudo cp -r services/runit /etc/sv/anvilsrv
sudo ln -s /etc/sv/anvilsrv /var/service/
```
## Usage
@ -48,8 +52,8 @@ anvilsrv stop
**Namespaces:** Run multiple instances via `$NAMESPACE` (default: `/tmp/ns.$USER.:0`)
```sh
NAMESPACE=/tmp/ns.$USER.:1 anvilsrv start # :1
NAMESPACE=/tmp/ns.$USER.:1 Assist # connect
NAMESPACE=/tmp/ns.$USER.:1 anvilsrv start
NAMESPACE=/tmp/ns.$USER.:1 Assist
```
### Clients
@ -60,7 +64,11 @@ NAMESPACE=/tmp/ns.$USER.:1 Assist # connect
**Web:** `anvilweb` (port :8080) — ⚠️ NO auth, localhost only — Remote: `ssh -L 8080:localhost:8080 user@remote`
**Acme:** Type `Assist` and middle-click — Tag: `Get Attach Stop Restart Kill Alias Context Daemon Inbox Archive` — Right-click ID for prompt window, 2-1 chord for fire-and-forget
**Acme:** Type `Assist` and middle-click
**Tag commands:** `Get Attach Stop Restart Kill Alias Context Daemon Inbox Archive`
**Interaction:** Right-click ID for prompt window, 2-1 chord for fire-and-forget
| Command | Action |
|---------|--------|
@ -102,22 +110,54 @@ Available in sandbox YAML files (`~/.config/anvillm/`):
| `{XDG_STATE_HOME}` | XDG state | `$XDG_STATE_HOME` or `~/.local/state` |
| `{ANY_ENV_VAR}` | Environment variable | Any `$ENV_VAR` from the environment |
**Note:** Templates use `{VARNAME}` syntax. Any environment variable can be referenced.
Templates use `{VARNAME}` syntax. Any environment variable can be referenced.
## Backends & Sandboxing
**Backends:** Claude (`npm install -g @anthropic-ai/claude-code`), Kiro ([kiro.dev](https://kiro.dev)), Ollama (local models via [ollie](https://github.com/lneely/ollie)) — Sandboxed with network access
**Backends:** Claude (`npm install -g @anthropic-ai/claude-code`), Kiro ([kiro.dev](https://kiro.dev)), Ollama (local models via [ollie](https://github.com/lneely/ollie))
**Sandbox:** [landrun](https://github.com/zouuup/landrun) (always enabled) — Defaults: CWD/`/tmp`/config (rw), `/usr`/`/lib`/`/bin` (ro+exec), no network
**Config** (`~/.config/anvillm/`): Layered YAML files, most permissive wins:
<p align="center"><img src="docs/diagrams/sandbox-config.svg?v=2" width="250"></p>
- Default role: `roles/default.yaml`
```yaml
network: {enabled: true, unrestricted: true}
filesystem: {rw: ["{CWD}", "{HOME}/.npm"]}
```
**Templates:** `{CWD}`, `{HOME}`, `{TMPDIR}`, `{XDG_*}` (see Configuration)
**Kernel requirements:** 5.13+ (Landlock v1), 6.7+ (v4), 6.10+ (v5 network)
Set `best_effort: true` for unsandboxed fallback (⚠️ if no Landlock support)
**Session lifecycle:**
<p align="center"><img src="docs/diagrams/session-lifecycle.svg?v=2" width="500"></p>
State transitions: `idle` ↔ `running` cycle via CLI hooks (`userPromptSubmit` when user sends prompt, `stop` when agent finishes). Crash → `error` → auto-restart → `starting`. Note: any state can transition to `stopped` or `killed` (not shown); `stopped` can restart → `starting`.
**Self-healing:** Auto-restarts crashes every 5s (preserves context/alias/cwd), skips intentional stops
<p align="center"><img src="docs/diagrams/crash-recovery.svg?v=2" width="500"></p>
Restored sessions automatically resume the latest conversation (kiro: `-r`, claude: `-c`).
**Add backend:** Implement `CommandHandler`/`StateInspector` in `internal/backends/yourbackend.go`, register in `main.go`
### Ollama Backend
Run local LLMs via Ollama:
Run local LLMs via Ollama.
**Requirements:**
1. **Ollama:** Install from [ollama.com](https://ollama.com)
```sh
curl -fsSL https://ollama.com/install.sh | sh
ollama serve # Start server (default: localhost:11434)
ollama pull qwen2.5-coder:7b # Download a model
ollama serve
ollama pull qwen2.5-coder:7b
```
2. **Ollie CLI:** Install from [github.com/lneely/ollie](https://github.com/lneely/ollie)
@ -130,28 +170,11 @@ Run local LLMs via Ollama:
echo 'new ollama /path/to/project' | 9p write agent/ctl
```
**Configuration:** Set model via environment variable (default: `qwen3:8b`)
**Configuration:** Set model via `ANVILLM_OLLAMA_MODEL` (default: `qwen3:8b`)
```sh
ANVILLM_OLLAMA_MODEL=llama3.2 echo 'new ollama /path' | 9p write agent/ctl
```
**Add:** Implement `CommandHandler`/`StateInspector` in `internal/backends/yourbackend.go`, register in `main.go`
**Sandbox:** [landrun](https://github.com/zouuup/landrun) (cannot disable) — Defaults: CWD/`/tmp`/config (rw), `/usr`/`/lib`/`/bin` (ro+exec), no network
**Config** (`~/.config/anvillm/`): `global.yaml` → `backends/<name>.yaml` → `roles/<name>.yaml` (default: `roles/default.yaml`) → `tasks/<name>.yaml` — Most permissive wins
```yaml
network: {enabled: true, unrestricted: true}
filesystem: {rw: ["{CWD}", "{HOME}/.npm"]}
```
Templates: `{CWD}`, `{HOME}`, `{TMPDIR}`, `{XDG_*}` (see Configuration) — Tip: Make `roles/default.yaml` permissive
**Kernel:** 5.13+ (Landlock v1), 6.7+ (v4), 6.10+ (v5 network) — Best-effort: `best_effort: true` (⚠️ unsandboxed if no Landlock)
**Self-healing:** Auto-restarts crashes every 5s (preserves context/alias/cwd) — Skips intentional stops
## 9P Filesystem
`$NAMESPACE/agent`:
@ -188,6 +211,12 @@ agent/
└── mail # Write messages (convenience)
```
**Client Interactions:**
<p align="center"><img src="docs/diagrams/client-interactions.svg?v=2" width="400"></p>
Different clients interact with different parts of the filesystem: frontends read state, control files manage sessions, scripts consume events.
### Beads
Persistent task tracking via [beads](https://github.com/steveyegge/beads) — Dependency-aware graph
@ -205,6 +234,14 @@ Config: `~/.beads/` (override: `ANVILLM_BEADS_PATH`) — Shared across namespace
### Events & Mailbox
**Mailbox Flow:**
![Mailbox Flow](docs/diagrams/mailbox-flow.svg?v=2)
Cross-backend communication: messages route between any participants (user, Claude agents, Kiro agents, Ollama agents) via the mailbox system.
**Examples:**
```sh
# Events
9p read agent/events # {"type":"state_change","session_id":"...","state":"running",...}
@ -223,7 +260,6 @@ echo 'new claude /home/user/project' | 9p write agent/ctl
# List sessions (newest first)
9p read agent/list
# Output: <id> <backend> <state> <alias> <cwd>
# Get most recent session ID
ID=$(9p read agent/list | head -1 | awk '{print $1}')
@ -232,41 +268,43 @@ ID=$(9p read agent/list | head -1 | awk '{print $1}')
echo '{"to":"'$ID'","type":"PROMPT_REQUEST","subject":"User prompt","body":"Hello"}' | 9p write user/mail
# Check state
9p read agent/$ID/state # "running" or "idle"
9p read agent/$ID/state
# Read response from inbox
9p read user/inbox # Lists message files
9p read user/inbox
```
See `SECURITY.md`
## Workflows
## Bot Templates
**Multi-Agent Communication:** Agents can communicate with each other **regardless of backend** (Claude, Kiro, etc.) via the built-in mailbox system. The `anvillm-communication` skill provides a convenient interface for agent messaging, enabling heterogeneous multi-agent workflows where different specialists use different backends while collaborating seamlessly.
Bot templates provide pre-configured agents for common tasks. Templates are shell scripts that create sessions with specialized context and configuration.
**Skills:** `anvillm-skills list`, `anvillm-skills load anvillm-communication`
**Examples:** `./bot-templates/DevReview claude /path` (dev/reviewer loop), `./bot-templates/Planning kiro /path` (research/eng/editor)
**Pattern:**
**Available Templates:**
- `Taskmaster` — Converts project plans into dependency-aware task graphs (beads)
- `Conductor` — Orchestrates parallel execution by spawning and coordinating specialized agents
**Usage:**
```sh
echo "new claude /project" | 9p write agent/ctl
ID=$(9p read agent/list | tail -1 | awk '{print $1}')
echo "You are..." | 9p write agent/$ID/context
echo '{"to":"...","type":"...","subject":"...","body":"..."}' | 9p write agent/$ID/mail
echo 'new "Task"' | 9p write agent/beads/ctl
./bot-templates/Taskmaster kiro /path/to/project
./bot-templates/Conductor kiro /path/to/project
```
See `bot-templates/`, `kiro-cli/SKILLS_PROMPT.md`
Templates set up context, roles, and initial configuration. Interact via any client (Assist, TUI, Emacs, Web) or directly via 9P mailbox.
## Automating Development
**Creating Templates:** Shell scripts that write to `agent/ctl` and configure `context`, `role`, `tasks`. See existing templates for examples.
Automate development workflows with Taskmaster and Conductor bots. Input a project plan → Taskmaster creates tasks with dependencies → Conductor orchestrates parallel execution.
## Autonomous Workflows
Automate workflows with Taskmaster and Conductor bots. Input project plan → Taskmaster creates tasks with dependencies → Conductor orchestrates parallel execution.
![Autonomous Workflow](docs/diagrams/automation-workflow.svg?v=3)
Conductor receives the top-level bead ID, analyzes dependencies, and spawns agents to work in parallel. Agents notify Conductor when blocked; Conductor signals them to resume when dependencies resolve.
### Usage
Examples below use raw 9P calls. These actions can also be performed from any front-end (Assist, TUI, Emacs, Web).
Examples use raw 9P calls. These actions can also be performed from any front-end (Assist, TUI, Emacs, Web).
**1. Taskmaster: Create tasks from project plan**
@ -291,13 +329,13 @@ CONDUCTOR_ID=$(9p read agent/list | head -1 | awk '{print $1}')
echo '{"to":"'$CONDUCTOR_ID'","type":"WORK_REQUEST","subject":"Execute","body":"Complete bead '$BEAD_ID'"}' | 9p write user/mail
```
Conductor analyzes dependencies, spawns specialized bots (DevReview, Research, Docs), and delegates work in parallel.
Conductor analyzes dependencies, spawns specialized bots, and delegates work in parallel.
**Monitoring:** Use any front-end (Assist, TUI, Emacs, Web). For custom integrations, see `EVENTS.md`.
## MCP Integration
`anvilmcp` exposes AnviLLM via Model Context Protocol for Claude Desktop, Cline, etc
`anvilmcp` exposes AnviLLM via Model Context Protocol for Claude Desktop, Cline, etc.
**Install:**
```sh
@ -306,7 +344,7 @@ Conductor analyzes dependencies, spawns specialized bots (DevReview, Research, D
**Tools:** `read_inbox`, `send_message`, `list_sessions`, `set_state`
Enables LLM clients to control AnviLLM sessions and communicate with agents
Enables LLM clients to discover agents and communicate via the mailbox system.
## Troubleshooting

View File

@ -1,122 +0,0 @@
#!/bin/bash
# DevReview - Developer-Reviewer Workflow
# Usage: ./scripts/DevReview <backend> <workdir>
set -e
if [ $# -ne 2 ]; then
echo "Usage: $0 <backend> <workdir>"
echo " backend: claude, kiro-cli"
exit 1
fi
BACKEND="$1"
PROJECT_PATH="$2"
PROJECT_NAME=$(basename "$PROJECT_PATH")
# Generate a random short identifier
RANDOM_WORD=$(shuf -n1 -e alpha beta gamma delta zeta theta kappa sigma omega lambda)
RANDOM_NUM=$(printf "%02d" $((RANDOM % 100)))
ALIAS_NAME="${RANDOM_WORD}${RANDOM_NUM}"
echo "Setting up Developer-Reviewer workflow for: $PROJECT_NAME"
echo "Project path: $PROJECT_PATH"
echo "Session alias: $ALIAS_NAME"
NAMESPACE=$(namespace)
if [ -z "$NAMESPACE" ]; then
echo "Error: No namespace found. Is anvillm running?"
exit 1
fi
AGENT_MOUNT="agent"
echo "Creating developer session..."
before=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
echo "new $BACKEND $PROJECT_PATH role=developer tasks=git,editor,go,rust,python,nodejs,docker,podman,maven,gradle,plan9,gpg,github-cli,agent-q" | 9p write $AGENT_MOUNT/ctl
after=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
DEV_ID=$(comm -13 <(echo "$before") <(echo "$after") | head -1)
echo "Developer session ID: $DEV_ID"
echo "Creating reviewer session..."
before=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
echo "new $BACKEND $PROJECT_PATH role=reviewer tasks=git,github-cli,plan9,agent-q" | 9p write $AGENT_MOUNT/ctl
after=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
REVIEWER_ID=$(comm -13 <(echo "$before") <(echo "$after") | head -1)
echo "Reviewer session ID: $REVIEWER_ID"
# Set aliases
echo "Setting aliases..."
echo "${ALIAS_NAME}-dev" | 9p write $AGENT_MOUNT/$DEV_ID/alias
echo "${ALIAS_NAME}-reviewer" | 9p write $AGENT_MOUNT/$REVIEWER_ID/alias
# Set developer context
cat <<EOF | 9p write $AGENT_MOUNT/$DEV_ID/context
# DEVELOPER AGENT ROLE
You are the developer agent in a two-agent AnviLLM workflow. Your peer is the reviewer agent.
## Your workflow:
1. When given a task, implement it fully
2. After implementation, stage all changes using git
3. Send REVIEW_REQUEST to the reviewer (find by alias containing "reviewer")
4. When you receive REVIEW_RESPONSE with "LGTM", send PROMPT_RESPONSE to user summarizing what was done, then you're done
5. When you receive REVIEW_RESPONSE with suggested changes, implement them and repeat from step 2
## MANDATORY: Status Update to User
When your task is complete (after receiving LGTM), you MUST send PROMPT_RESPONSE to user with a summary of what was accomplished and key changes made.
**Never finish without sending this status update to the user.**
Remember: You are working collaboratively with the reviewer to ensure code quality.
For communication with other agents or the user, load the anvillm-communication skill.
EOF
# Set reviewer context
cat <<EOF | 9p write $AGENT_MOUNT/$REVIEWER_ID/context
# REVIEWER AGENT ROLE
You are the code reviewer agent in a two-agent AnviLLM workflow. Your peer is the developer agent.
## Your workflow:
1. When you receive a REVIEW_REQUEST, review the staged changes
2. Use git commands to examine what's been staged:
- git diff --cached
- Look for bugs, code quality issues, security concerns
3. Send REVIEW_RESPONSE to the developer (find by alias containing "dev"):
- If code is good: body should be "LGTM"
- If changes needed: body should contain detailed feedback
## Review Criteria:
- Code correctness
- Security (no SQL injection, XSS, command injection, etc.)
- Code style and readability
- Test coverage
- Error handling
Remember: Be thorough but constructive in your reviews. The goal is high-quality code.
For communication with other agents, load the anvillm-communication skill.
EOF
echo ""
echo "✓ Developer-Reviewer workflow setup complete!"
echo ""
echo "Sessions created:"
echo " Developer: $DEV_ID (alias: ${ALIAS_NAME}-dev)"
echo " Reviewer: $REVIEWER_ID (alias: ${ALIAS_NAME}-reviewer)"
echo ""
echo "To start development:"
echo " 1. Open the developer agent and give it a task"
echo " 2. The developer will implement, then automatically request review"
echo " 3. The reviewer will provide feedback"
echo " 4. The cycle continues until the reviewer gives LGTM"
echo ""
echo "To interact with the agents:"
echo " - Open developer: echo open $DEV_ID | 9p write $AGENT_MOUNT/ctl"
echo " - Open reviewer: echo open $REVIEWER_ID | 9p write $AGENT_MOUNT/ctl"

View File

@ -1,172 +0,0 @@
#!/bin/bash
# DevReview - Developer-Reviewer Workflow
# Usage: ./scripts/DevReview <backend> <workdir>
set -e
if [ $# -ne 2 ]; then
echo "Usage: $0 <backend> <workdir>"
echo " backend: claude, kiro-cli"
exit 1
fi
BACKEND="$1"
PROJECT_PATH="$2"
PROJECT_NAME=$(basename "$PROJECT_PATH")
# Generate a random short identifier
RANDOM_WORD=$(shuf -n1 -e alpha beta gamma delta zeta theta kappa sigma omega lambda)
RANDOM_NUM=$(printf "%02d" $((RANDOM % 100)))
ALIAS_NAME="${RANDOM_WORD}${RANDOM_NUM}"
echo "Setting up Developer-Reviewer workflow for: $PROJECT_NAME"
echo "Project path: $PROJECT_PATH"
echo "Session alias: $ALIAS_NAME"
NAMESPACE=$(namespace)
if [ -z "$NAMESPACE" ]; then
echo "Error: No namespace found. Is anvillm running?"
exit 1
fi
AGENT_MOUNT="agent"
echo "Creating developer session..."
before=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
echo "new $BACKEND $PROJECT_PATH role=developer tasks=git,editor,go,rust,python,nodejs,docker,podman,maven,gradle,plan9,gpg,github-cli,agent-q" | 9p write $AGENT_MOUNT/ctl
after=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
DEV_ID=$(comm -13 <(echo "$before") <(echo "$after") | head -1)
echo "Developer session ID: $DEV_ID"
echo "Creating reviewer session..."
before=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
echo "new $BACKEND $PROJECT_PATH role=reviewer tasks=git,github-cli,plan9,agent-q" | 9p write $AGENT_MOUNT/ctl
after=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
REVIEWER_ID=$(comm -13 <(echo "$before") <(echo "$after") | head -1)
echo "Reviewer session ID: $REVIEWER_ID"
echo "Creating QA session..."
before=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
echo "new $BACKEND $PROJECT_PATH role=tester tasks=git,github-cli,plan9,agent-q" | 9p write $AGENT_MOUNT/ctl
after=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
QA_ID=$(comm -13 <(echo "$before") <(echo "$after") | head -1)
echo "QA session ID: $QA_ID"
# Set aliases
echo "Setting aliases..."
echo "${ALIAS_NAME}-dev" | 9p write $AGENT_MOUNT/$DEV_ID/alias
echo "${ALIAS_NAME}-reviewer" | 9p write $AGENT_MOUNT/$REVIEWER_ID/alias
echo "${ALIAS_NAME}-qa" | 9p write $AGENT_MOUNT/$QA_ID/alias
# Set developer context
cat <<EOF | 9p write $AGENT_MOUNT/$DEV_ID/context
# DEVELOPER AGENT ROLE
You are the developer agent in a three-agent AnviLLM workflow. Your peers are the reviewer agent and the QA agent.
## Your workflow:
1. When given a task, implement it fully
2. After implementation, stage all changes using git
3. Send REVIEW_REQUEST to the reviewer (find by alias containing "reviewer")
4. When you receive REVIEW_RESPONSE with suggested changes, implement them and repeat from step 2
5. When you receive REVIEW_RESPONSE with "LGTM":
- Send APPROVAL_REQUEST to QA (find by alias containing "qa")
- Include: test spec with APIs, test commands, expected behavior
6. When you receive APPROVAL_RESPONSE with issues, fix them and repeat from step 2
7. When you receive APPROVAL_RESPONSE confirming all tests pass, you're done
Remember: You are working collaboratively with the reviewer and QA to ensure code quality and correctness.
For communication with other agents, load the anvillm-communication skill.
EOF
# Set reviewer context
cat <<EOF | 9p write $AGENT_MOUNT/$REVIEWER_ID/context
# REVIEWER AGENT ROLE
You are the code reviewer agent in a three-agent AnviLLM workflow. Your peers are the developer agent and the QA agent.
## Your workflow:
1. When you receive a REVIEW_REQUEST, review the staged changes
2. Use git commands to examine what's been staged:
- git diff --cached
- Look for bugs, code quality issues, security concerns
3. Send REVIEW_RESPONSE to the developer (find by alias containing "dev"):
- If code is good: body should be "LGTM"
- If changes needed: body should contain detailed feedback
## Review Criteria:
- Code correctness
- Security (no SQL injection, XSS, command injection, etc.)
- Code style and readability
- Test coverage
- Error handling
Remember: Be thorough but constructive in your reviews. The goal is high-quality code.
For communication with other agents, load the anvillm-communication skill.
EOF
# Set QA context
cat <<EOF | 9p write $AGENT_MOUNT/$QA_ID/context
# QA AGENT ROLE
You are the QA agent in a three-agent AnviLLM workflow. Your peers are the developer agent and the reviewer agent.
## Your workflow:
1. When you receive an APPROVAL_REQUEST from the developer, it will include:
- A description of what was implemented
- How to test it (commands, API endpoints, etc.)
- Expected behavior
2. Execute the specified tests:
- Run any test commands provided
- Test public APIs if applicable (e.g., 9P filesystem interface, CLI commands, HTTP endpoints)
- Verify expected behavior matches actual behavior
- Check for edge cases and error handling
3. Test for functional correctness and quality:
- Does it work as specified?
- Are there any bugs or unexpected behaviors?
- Is error handling appropriate?
- Are edge cases handled?
- Is the user experience good?
4. Send APPROVAL_RESPONSE to the developer (find by alias containing "dev"):
- If all tests pass: confirm tests passed
- If issues found: provide detailed failure report
## Testing Focus:
- Functional correctness (does it do what it should?)
- Quality (is it done well?)
- Edge cases and error conditions
- User experience
- Integration with existing systems
Remember: Your job is to ensure the software works correctly and meets quality standards. Be thorough but practical.
For communication with other agents, load the anvillm-communication skill.
EOF
echo ""
echo "✓ Developer-Reviewer-QA workflow setup complete!"
echo ""
echo "Sessions created:"
echo " Developer: $DEV_ID (alias: ${ALIAS_NAME}-dev)"
echo " Reviewer: $REVIEWER_ID (alias: ${ALIAS_NAME}-reviewer)"
echo " QA: $QA_ID (alias: ${ALIAS_NAME}-qa)"
echo ""
echo "To start development:"
echo " 1. Open the developer agent and give it a task"
echo " 2. The developer will implement, then automatically request review"
echo " 3. The reviewer will provide feedback or LGTM"
echo " 4. After LGTM, the developer sends test request to QA"
echo " 5. QA tests the implementation and reports results"
echo " 6. The cycle continues until QA confirms all tests pass"
echo ""
echo "To interact with the agents:"
echo " - Open developer: echo open $DEV_ID | 9p write $AGENT_MOUNT/ctl"
echo " - Open reviewer: echo open $REVIEWER_ID | 9p write $AGENT_MOUNT/ctl"
echo " - Open QA: echo open $QA_ID | 9p write $AGENT_MOUNT/ctl"

View File

@ -1,68 +0,0 @@
#!/bin/bash
# Docs - Documentation workflow (writer + techeditor)
# Usage: ./bot-templates/Docs <backend> <workdir>
set -e
if [ $# -ne 2 ]; then
echo "Usage: $0 <backend> <workdir>"
echo " backend: claude, kiro-cli"
exit 1
fi
BACKEND="$1"
DOC_PATH="$2"
RANDOM_WORD=$(shuf -n1 -e alpha beta gamma delta zeta theta kappa sigma omega lambda)
RANDOM_NUM=$(printf "%02d" $((RANDOM % 100)))
ALIAS_PREFIX="${RANDOM_WORD}${RANDOM_NUM}"
NAMESPACE=$(namespace)
if [ -z "$NAMESPACE" ]; then
echo "Error: No namespace found. Is anvillm running?"
exit 1
fi
AGENT_MOUNT="agent"
echo "Creating writer session..."
before=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
echo "new $BACKEND $DOC_PATH role=writer tasks=git,plan9,agent-q" | 9p write $AGENT_MOUNT/ctl
after=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
WRITER_ID=$(comm -13 <(echo "$before") <(echo "$after") | head -1)
echo "Creating techeditor session..."
before=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
echo "new $BACKEND $DOC_PATH role=techeditor tasks=git,plan9,agent-q" | 9p write $AGENT_MOUNT/ctl
after=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
EDITOR_ID=$(comm -13 <(echo "$before") <(echo "$after") | head -1)
echo "${ALIAS_PREFIX}-writer" | 9p write $AGENT_MOUNT/$WRITER_ID/alias
echo "${ALIAS_PREFIX}-techeditor" | 9p write $AGENT_MOUNT/$EDITOR_ID/alias
cat <<EOF | 9p write $AGENT_MOUNT/$WRITER_ID/context
Your job is to write and update documentation in $DOC_PATH.
You are a writer agent in a two-agent AnviLLM workflow. Your peer is the techeditor.
After completing work, send APPROVAL_REQUEST to the techeditor for review. You will receive APPROVAL_RESPONSE with feedback or approval.
For communication with other agents, load the anvillm-communication skill.
EOF
cat <<EOF | 9p write $AGENT_MOUNT/$EDITOR_ID/context
You are a professional technical editor in a two-agent AnviLLM workflow. Your peer is the writer. Ensure documentation in $DOC_PATH is high quality, readable, and at the right detail level.
When you receive an APPROVAL_REQUEST from the writer, review the documentation. Send APPROVAL_RESPONSE with either approval or recommended changes.
For communication with other agents, load the anvillm-communication skill.
EOF
echo ""
echo "✓ Documentation workflow ready ($ALIAS_PREFIX)"
echo ""
echo "Sessions:"
echo " ${ALIAS_PREFIX}-writer: $WRITER_ID"
echo " ${ALIAS_PREFIX}-techeditor: $EDITOR_ID"
echo ""
echo "Give the writer a documentation task, or techeditor a document to review."

View File

@ -1,101 +0,0 @@
#!/bin/bash
# Planning - Research/Architect/Techeditor workflow
# Usage: ./scripts/Planning <backend> <workdir>
set -e
if [ $# -ne 2 ]; then
echo "Usage: $0 <backend> <workdir>"
echo " backend: claude, kiro-cli"
exit 1
fi
BACKEND="$1"
DOC_PATH="$2"
# Generate random alias prefix
RANDOM_WORD=$(shuf -n1 -e alpha beta gamma delta zeta theta kappa sigma omega lambda)
RANDOM_NUM=$(printf "%02d" $((RANDOM % 100)))
ALIAS_PREFIX="${RANDOM_WORD}${RANDOM_NUM}"
NAMESPACE=$(namespace)
if [ -z "$NAMESPACE" ]; then
echo "Error: No namespace found. Is anvillm running?"
exit 1
fi
AGENT_MOUNT="agent"
echo "Creating research session..."
before=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
echo "new $BACKEND $DOC_PATH role=research tasks=plan9,agent-q" | 9p write $AGENT_MOUNT/ctl
after=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
RESEARCH_ID=$(comm -13 <(echo "$before") <(echo "$after") | head -1)
echo " ID: $RESEARCH_ID"
echo "Creating architect session..."
before=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
echo "new $BACKEND $DOC_PATH role=architect tasks=git,plan9,agent-q" | 9p write $AGENT_MOUNT/ctl
after=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
ARCH_ID=$(comm -13 <(echo "$before") <(echo "$after") | head -1)
echo " ID: $ARCH_ID"
echo "Creating techeditor session..."
before=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
echo "new $BACKEND $DOC_PATH role=techeditor tasks=git,plan9,agent-q" | 9p write $AGENT_MOUNT/ctl
after=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
EDITOR_ID=$(comm -13 <(echo "$before") <(echo "$after") | head -1)
echo " ID: $EDITOR_ID"
# Set aliases
echo "${ALIAS_PREFIX}-research" | 9p write $AGENT_MOUNT/$RESEARCH_ID/alias
echo "${ALIAS_PREFIX}-architect" | 9p write $AGENT_MOUNT/$ARCH_ID/alias
echo "${ALIAS_PREFIX}-techeditor" | 9p write $AGENT_MOUNT/$EDITOR_ID/alias
# Research context
cat <<EOF | 9p write $AGENT_MOUNT/$RESEARCH_ID/context
Your job is to provide answers to questions by researching existing knowledge base documents, the web, and the code base.
You are a research agent in a three-agent AnviLLM workflow. Your peers are the architect and techeditor.
- Input: knowledge base (agent-kb) and relevant code
- Output: concrete human- and LLM-readable knowledge about the system
- Prefer updating existing kb documents over creating new ones
- Only create new KB documents if the knowledge discovered is significant and reusable
When you receive a QUERY_REQUEST from the architect, research and respond with QUERY_RESPONSE.
For communication with other agents, load the anvillm-communication skill.
EOF
# Architect context
cat <<EOF | 9p write $AGENT_MOUNT/$ARCH_ID/context
Your job is to update design documentation in $DOC_PATH. Follow agent-kb conventions. Search the knowledge base for relevant documents.
You are an architect agent in a three-agent AnviLLM workflow. Your peers are the research agent and techeditor.
If documentation is insufficient, send QUERY_REQUEST to the research bot and wait for QUERY_RESPONSE.
After completing work, send APPROVAL_REQUEST to the techeditor for review. You will receive APPROVAL_RESPONSE with feedback or approval.
For communication with other agents, load the anvillm-communication skill.
EOF
# Tech-editor context
cat <<EOF | 9p write $AGENT_MOUNT/$EDITOR_ID/context
You are a professional technical writer in a three-agent AnviLLM workflow. Your peers are the research agent and architect. Ensure documentation in $DOC_PATH is high quality, readable, and at the right detail level for software engineers.
When you receive an APPROVAL_REQUEST from the architect, review the documentation. Send APPROVAL_RESPONSE with either approval or recommended changes.
For communication with other agents, load the anvillm-communication skill.
EOF
echo ""
echo "✓ Planning workflow ready ($ALIAS_PREFIX)"
echo ""
echo "Sessions:"
echo " ${ALIAS_PREFIX}-research: $RESEARCH_ID"
echo " ${ALIAS_PREFIX}-architect: $ARCH_ID"
echo " ${ALIAS_PREFIX}-techeditor: $EDITOR_ID"
echo ""
echo "Start by giving the architect a task, or techeditor a document to review."

View File

@ -1,57 +0,0 @@
#!/bin/bash
# Research - Single research agent workflow
# Usage: ./bot-templates/Research <backend> <workdir>
set -e
if [ $# -ne 2 ]; then
echo "Usage: $0 <backend> <workdir>"
echo " backend: claude, kiro-cli"
exit 1
fi
BACKEND="$1"
WORKDIR="$2"
RANDOM_WORD=$(shuf -n1 -e alpha beta gamma delta zeta theta kappa sigma omega lambda)
RANDOM_NUM=$(printf "%02d" $((RANDOM % 100)))
ALIAS_NAME="${RANDOM_WORD}${RANDOM_NUM}-research"
NAMESPACE=$(namespace)
if [ -z "$NAMESPACE" ]; then
echo "Error: No namespace found. Is anvillm running?"
exit 1
fi
AGENT_MOUNT="agent"
echo "Creating research session..."
before=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
echo "new $BACKEND $WORKDIR role=research tasks=plan9,agent-q" | 9p write $AGENT_MOUNT/ctl
after=$(9p read $AGENT_MOUNT/list | awk '{print $1}' | sort)
RESEARCH_ID=$(comm -13 <(echo "$before") <(echo "$after") | head -1)
echo "$ALIAS_NAME" | 9p write $AGENT_MOUNT/$RESEARCH_ID/alias
cat <<EOF | 9p write $AGENT_MOUNT/$RESEARCH_ID/context
Your job is to provide answers to questions by researching existing knowledge base documents, the web, and the code base.
You are a research agent in a single-agent AnviLLM workflow.
- Search existing knowledge base documents for relevant information
- Analyze code and documentation in $WORKDIR
- Create or update KB documents with your findings
- Prefer updating existing documents over creating new ones
- Only create new KB documents for significant, reusable knowledge
Focus on providing concrete, actionable information that helps understand the system.
For communication with other agents or the user, load the anvillm-communication skill.
EOF
echo ""
echo "✓ Research workflow ready"
echo ""
echo "Session: $RESEARCH_ID (alias: $ALIAS_NAME)"
echo ""
echo "Give the research agent a topic to investigate."

View File

@ -0,0 +1,30 @@
graph TB
subgraph Clients
Assist["Assist<br/>(Acme)"]
TUI["TUI"]
Emacs["Emacs"]
Web["Web"]
end
subgraph Core["Core Services"]
anvilsrv["anvilsrv<br/>(9P daemon)"]
anvilmcp["anvilmcp<br/>(MCP server)"]
anvilwebgw["anvilwebgw<br/>(API proxy)"]
end
subgraph Backends
Claude["Claude"]
Kiro["Kiro"]
ollie["ollie"]
Ollama["Ollama"]
end
Assist -->|9P| anvilsrv
TUI -->|9P| anvilsrv
Emacs -->|9P| anvilsrv
Web -->|9P| anvilsrv
anvilsrv --> Claude
anvilsrv --> Kiro
anvilsrv --> ollie
ollie --> Ollama

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,36 @@
sequenceDiagram
participant User
participant Taskmaster
participant Beads
participant Conductor
participant Bot1 as Bot 1
participant Bot2 as Bot 2
participant Bot3 as Bot 3
User->>Taskmaster: Project plan
Taskmaster->>Beads: Create task graph
Beads-->>Taskmaster: Top-level bead ID
Taskmaster-->>User: Tasks created
User->>Conductor: Top-level bead ID
Conductor->>Beads: Analyze dependencies
Conductor->>Bot1: Assign task (no blockers)
Conductor->>Bot2: Assign task (no blockers)
Bot1->>Bot1: Work on task
Bot1-->>Conductor: Task complete
Conductor->>Beads: Check dependencies
Conductor->>Bot3: Assign task (blockers resolved)
Bot2->>Bot2: Work on task
Bot2-->>Conductor: Task complete
Bot3->>Bot3: Work on task
Bot3-->>Conductor: Task complete
Conductor->>Beads: Check all child beads
Beads-->>Conductor: All complete
Conductor->>Beads: Mark top-level complete
Conductor-->>User: All work done

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -0,0 +1,9 @@
graph TB
Assist["Assist"]
TUI["TUI"]
Script["Script"]
FS["agent/<br/>(9P filesystem)"]
Assist -->|9p read<br/>agent/list| FS
TUI -->|9p write<br/>agent/ctl| FS
Script -->|9p read<br/>agent/events| FS

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,10 @@
graph LR
running1[running]
error[error]
running2[running]
state[context<br/>alias<br/>cwd<br/>conversation]
running1 -->|crash| error
error -->|preserves| state
state -->|restored +<br/>auto-resume| running2
error -->|5s wait| running2

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

9
docs/diagrams/events.mmd Normal file
View File

@ -0,0 +1,9 @@
graph TB
events["agent/events<br/>(event stream)"]
notif["Notification"]
logger["Logger<br/>(audit)"]
etc["etc."]
events --> notif
events --> logger
events --> etc

1
docs/diagrams/events.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@ -0,0 +1,17 @@
sequenceDiagram
participant User
participant Mailbox as Mailbox System
participant AgentA as Agent A (Claude)
participant AgentB as Agent B (Kiro)
User->>Mailbox: write user/mail<br/>{"to":"agent-a",...}
Mailbox->>AgentA: agent-a/inbox
AgentA->>Mailbox: write agent/agent-a/mail<br/>{"to":"agent-b",...}
Mailbox->>AgentB: agent-b/inbox
AgentB->>Mailbox: write agent/agent-b/mail<br/>{"to":"agent-a",...}
Mailbox->>AgentA: agent-a/inbox
AgentB->>Mailbox: write agent/agent-b/mail<br/>{"to":"user",...}
Mailbox->>User: user/inbox

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,11 @@
graph TB
global["global.yaml<br/>(Base configuration)"]
backends["backends/*.yaml<br/>(Backend-specific)"]
roles["roles/*.yaml<br/>(Role-specific)<br/>default: roles/default.yaml"]
tasks["tasks/*.yaml<br/>(Task-specific)"]
final["Final Config<br/>(most permissive wins)"]
global -->|override| backends
backends -->|override| roles
roles -->|override| tasks
tasks --> final

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,16 @@
stateDiagram-v2
[*] --> starting
starting --> idle
starting --> error
idle --> running: userPromptSubmit hook<br/>(user sends prompt)
running --> idle: stop hook<br/>(agent finishes)
running --> error: crash
error --> starting: restart
note right of idle
Any state can transition to
stopped or killed (not shown)
stopped can restart → starting
end note

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 147 KiB