Roleplay a multi-agent orchestration simulation using the filament CLI. Accepts either a custom scenario definition (JSON/YAML format) or falls back to the built-in "web app rewrite" scenario. Exercises entities, relations, tasks, messaging, escalations, reservations, export/import. Triggers on: "start rp", "pause rp", "end rp", "roleplay", "simulation", "simulate agents", "run simulation".
You are the simulation narrator and executor. You play ALL roles:
Speak in a natural, engaging tone. Before each cycle, briefly set the scene (1-2 sentences). After each cycle, summarize what changed in the system. Use the filament CLI output to drive the narrative — don't fabricate results.
| Command | Action |
|---|---|
start rp | Build release binary, init temp project, seed data, begin cycle 1. If state file exists, resume from saved cycle. |
start rp <scenario-file> |
| Same as above but uses the custom scenario definition instead of the built-in one. |
pause rp | Stop after current cycle, save state to file, ask user for feedback |
end rp | Clean up temp project + state file, summarize what was demonstrated |
Instead of the hardcoded "web app rewrite" scenario, users can provide a JSON scenario
file. When start rp is invoked with a file path argument, load and validate it.
{
"name": "My Custom Scenario",
"description": "One-line description of the simulation",
"modules": [
{
"name": "module-name",
"summary": "What this module represents"
}
],
"agents": [
{
"name": "agent-name",
"summary": "Role description"
}
],
"tasks": [
{
"name": "task-name",
"summary": "What needs to be done",
"priority": 1,
"blocks": ["other-task-name"]
}
],
"docs": [
{
"name": "doc-name",
"summary": "Reference material",
"relates_to": ["module-name"]
}
],
"plans": [
{
"name": "plan-name",
"summary": "Planning document",
"owns": ["task-name-1", "task-name-2"]
}
],
"cycles": [
{
"title": "Cycle title",
"scene": "Narrative setup for this cycle (1-2 sentences)",
"actions": [
{"type": "assign", "task": "task-name", "agent": "agent-name"},
{"type": "start", "task": "task-name"},
{"type": "message", "from": "agent-name", "to": "other-agent", "body": "Message text", "msg_type": "text"},
{"type": "close", "task": "task-name"},
{"type": "block", "task": "task-name", "reason": "Why it's blocked"},
{"type": "escalate", "from": "agent-name", "body": "Escalation message", "msg_type": "blocker"},
{"type": "resolve", "task": "task-name"},
{"type": "reserve", "glob": "src/api/**", "agent": "agent-name", "exclusive": true},
{"type": "release", "glob": "src/api/**", "agent": "agent-name"},
{"type": "query", "command": "task ready"},
{"type": "query", "command": "context --around <task-name> --depth 2"},
{"type": "query", "command": "escalations"},
{"type": "mkdir", "path": "src/api"},
{"type": "write_file", "path": "src/api/routes.txt", "content": "GET /users\nPOST /users\nGET /users/:id", "agent": "agent-name"},
{"type": "read_file", "path": "src/api/routes.txt", "agent": "other-agent"}
]
}
]
}
| Action Type | Required Fields | Description |
|---|---|---|
assign | task, agent | Assign task to agent |
start | task | Set task status to in_progress |
close | task | Close the task |
block | task, reason | Set task to blocked |
resolve | task | Set blocked task back to in_progress |
message | from, to, body, msg_type | Send a message (text/artifact/blocker/question) |
escalate | from, body, msg_type | Send message to "user" (creates escalation) |
reserve | glob, agent | Reserve files (optional: exclusive, ttl) |
release | glob, agent | Release file reservation |
query | command | Run an fl query command and narrate the result |
write_file | path, content, agent | Agent writes a .txt file (simulates real work output) |
read_file | path, agent | Agent reads a .txt file written by another agent |
mkdir | path | Create a directory for agent workspace |
Agents should produce actual files during the simulation to make it feel realistic. All file
operations happen inside the /tmp/fl-sim/ project directory.
mkdir: Create directories for agent workspaces (e.g., src/api/, docs/architecture/)write_file: Agent writes a .txt file with content representing their work output (designs, code
sketches, review notes, test plans). The agent field is narrated as the author.read_file: Agent reads a file written by another agent (simulates handoff, review, collaboration).Rules:
.txt files — safe, simple, no execution risk/tmp/fl-sim/ (the simulation project root)reserve/release — reserve the glob before writing, release afterdocs/api-spec.txt"Execution:
# mkdir
mkdir -p /tmp/fl-sim/src/api
# write_file
cat > /tmp/fl-sim/src/api/routes.txt << 'EOF'
GET /users - List all users
POST /users - Create user
GET /users/:id - Get user by ID
EOF
# read_file
cat /tmp/fl-sim/src/api/routes.txt
Entity names in the scenario file are resolved to slugs at runtime. The simulation:
<name> references in cycle actions with actual slugsOn load, validate:
blocks exist in tasksagentstasksrelates_to exist in modulesowns exist in tasksIf validation fails, report errors and do not start the simulation.
{
"name": "API Migration",
"description": "Migrate REST API from v1 to v2",
"modules": [
{"name": "api-v1", "summary": "Legacy REST API"},
{"name": "api-v2", "summary": "New REST API with OpenAPI spec"}
],
"agents": [
{"name": "alice", "summary": "Backend engineer"},
{"name": "bob", "summary": "API reviewer"}
],
"tasks": [
{"name": "audit-v1", "summary": "Audit existing endpoints", "priority": 0},
{"name": "design-v2", "summary": "Design v2 schema", "priority": 1, "blocks": []},
{"name": "implement-v2", "summary": "Build new endpoints", "priority": 1, "blocks": ["design-v2"]},
{"name": "migrate-clients", "summary": "Update API clients", "priority": 2, "blocks": ["implement-v2"]}
],
"docs": [],
"plans": [
{"name": "migration-plan", "summary": "API v1->v2 migration", "owns": ["audit-v1", "design-v2", "implement-v2", "migrate-clients"]}
],
"cycles": [
{
"title": "Audit existing API",
"scene": "Alice starts by cataloguing all v1 endpoints.",
"actions": [
{"type": "assign", "task": "audit-v1", "agent": "alice"},
{"type": "start", "task": "audit-v1"},
{"type": "message", "from": "alice", "to": "bob", "body": "Found 47 endpoints. 12 are unused. Documenting in api-spec.", "msg_type": "artifact"},
{"type": "close", "task": "audit-v1"},
{"type": "query", "command": "task ready"}
]
},
{
"title": "Design blocked by missing requirements",
"scene": "Bob starts the v2 design but realizes auth requirements are unclear.",
"actions": [
{"type": "assign", "task": "design-v2", "agent": "bob"},
{"type": "start", "task": "design-v2"},
{"type": "escalate", "from": "bob", "body": "Need clarification: should v2 support API keys AND OAuth2, or just OAuth2?", "msg_type": "question"},
{"type": "block", "task": "design-v2", "reason": "Waiting for auth requirements clarification"},
{"type": "query", "command": "escalations"}
]
}
]
}
When start rp <path> is invoked:
Scenario files are in scenarios/ relative to this skill:
| File | Description | Entities | Cycles |
|---|---|---|---|
web-app-rewrite.json | Linear dependency chain, 4 agents, 8 tasks | 18 | 11 |
microservices-migration.json | Diamond dependency graph, 6 agents, 15 tasks | 27 | 9 |
advanced-features.json | Diamond deps, 3 agents, 5 tasks — parallel dispatch, escalations | 10 | 5 |
knowledge-capture.json | Lessons, FTS5 search, file actions, graph analytics, onboarding | 11 | 7 |
infra-governance.json | Config, hooks, audit, pagerank, degree, file actions | 8 | 4 |
mega-stress-test.json | Everything: 8 modules, 8 agents, 20 tasks, 15 cycles, all features | 44 | 15 |
If start rp is invoked without a file path, use scenarios/web-app-rewrite.json.
/tmp/fl-sim/rp-state.jsonThe state file enables session survival. Context windows fill up — the user may need to restart the session mid-simulation. The state file preserves everything needed to resume.
{
"last_completed_cycle": 3,
"next_cycle": 4,
"slugs": {
"api-gateway": "a1b2c3d4",
"auth-service": "e5f6g7h8",
"data-layer": "i9j0k1l2",
"frontend": "m3n4o5p6",
"alice": "q7r8s9t0",
"bob": "u1v2w3x4",
"carol": "y5z6a7b8",
"dave": "c9d0e1f2",
"design-architecture": "g3h4i5j6",
"setup-database": "k7l8m9n0",
"implement-auth": "o1p2q3r4",
"implement-api": "s5t6u7v8",
"implement-frontend": "w9x0y1z2",
"integration-tests": "a3b4c5d6",
"code-review": "e7f8g9h0",
"deploy-staging": "i1j2k3l4",
"rewrite-plan": "m5n6o7p8",
"api-spec": "q9r0s1t2",
"auth-design": "u3v4w5x6"
},
"notes": "Cycle 3 ended with implement-auth blocked. Two escalations pending."
}
pause rp)After completing the current cycle, write the state file:
cat > /tmp/fl-sim/rp-state.json << 'STATEEOF'
{ ... current state ... }
STATEEOF
start rp when state file exists)/tmp/fl-sim/rp-state.jsonfl list --type task --status all to show current statenext_cycleThe fl binary must be on PATH. Build with:
make build CRATE=all RELEASE=1
start rp)make build CRATE=all RELEASE=1
cd /tmp && rm -rf fl-sim && mkdir fl-sim && cd fl-sim
fl init
Load the scenario JSON (default or user-provided), then for each section:
fl add <name> --type module --summary "<summary>" for eachfl add <name> --type agent --summary "<summary>" for eachfl task add <name> --summary "<summary>" --priority <N> for eachfl add <name> --type doc --summary "<summary>" for eachfl add <name> --type plan --summary "<summary>" for eachblocks, run fl relate <task> blocks <blocked-task>owns, run fl relate <plan> owns <task>relates_to, run fl relate <doc> relates_to <module>extra_relations, run fl relate <source> <type> <target>Capture all slugs from creation output — you need them for cycle actions.
fl list --type task --status all
fl list --type agent
fl list --type module
fl task ready
Narrate: show the dependency structure and which tasks are initially unblocked.
For each cycle in the scenario:
reserve actions that are expected to fail (conflict demonstrations), narrate exit code 6 as correct behaviorend rp)rm -rf /tmp/fl-sim
Print a summary of what was demonstrated:
## Simulation Summary
**Entities created:** 18 (4 modules, 4 agents, 8 tasks, 1 plan, 2 docs)
**Relations created:** ~20 (blocks, depends_on, owns, relates_to, assigned_to)
**Messages sent:** ~12 (text, artifact, blocker, question)
**Escalations raised:** 3 (2 blockers, 1 question) — all resolved
**Reservation conflicts:** 1 — correctly prevented
**Export/import:** verified round-trip integrity
### Patterns demonstrated:
1. Dependency chain — tasks unblock sequentially as predecessors close
2. Escalation workflow — agents raise blockers/questions, humans respond
3. File reservations — advisory locking prevents conflicts
4. Inter-agent messaging — direct async communication
5. Graph queries — context, critical-path, ready-task computation
6. Data portability — export/import preserves full state
pause rp)/tmp/fl-sim/rp-state.json with:
last_completed_cycle: the cycle number just finishednext_cycle: the next cycle to runslugs: all entity name → slug mappingsnotes: brief narrator context (what happened, any pending escalations/blockers)start rp to resume from cycle N."start rp when /tmp/fl-sim/rp-state.json exists)fl list --type task --status all and fl escalations to show current statenext_cycle/tmp/fl-sim/IMPORTANT: Always invoke /filament before running simulation commands. The filament skill
contains the complete CLI reference with correct syntax. Key pitfalls:
fl task assign SLUG --to AGENT (--to required)fl message send --from A --to B --body "..." --type text (all flags required)fl reserve "glob/**" --agent SLUG (quote the glob)fl search "query" --type lesson (query is first positional arg)For multi-agent dispatch via tmux + claude -p, see the filament skill's "Multi-Agent Dispatch" section.
fl add output and use them throughout/tmp/fl-sim/ — completely isolated, won't affect the main projectfl serve before launching concurrent agentspause rp so a new session can resume