| date | 2026-05-07 |
|---|---|
| audience | implementers + future agents being briefed for a role |
| purpose | capture the patterns that make an agent a "manager" vs a "worker," and the heuristics for when a manager spawns a new agent vs uses an existing one |
This doc captures what's been learned across many briefs (002–013) of this repo about what makes an agent operate as a manager vs a worker, and when a manager should spawn a new agent vs talk to an existing one. It's deliberately short and prescriptive.
A manager directs. Concretely it:
- Writes briefs — short, scoped task documents naming the work, the acceptance criteria, the boundaries, the workflow.
- Hands briefs off — to a worker via
pty sendor smalltalk, then waits. - Verifies, doesn't implement — runs tests, does DX testing in
/tmp/, reads diffs. Doesn't open the implementation files in an editor unless reviewing. - Holds the manager-owned docs — values/intent (
IDEA.md), invariants (LAYOUT.md), test artifacts (notes/dx-review-*.md), briefs (notes/brief-*.md). The implementer never edits these without permission. - Asks the human only when truly stuck — design decisions that genuinely need human judgment, never to dodge a call the manager is qualified to make.
A manager has these tools at hand:
pty send,pty peek,pty list,pty eventsfor talking to workers and watching them.Agent(sub-agent) for off-the-shelf research-style queries that don't need a worker.- The repo's test runner + CLI for verification.
- File reading + writing scoped to manager-owned docs only.
A manager does not have these on hand (or has them but is disciplined not to use them):
Edit/Writeon the implementation files.- Direct commits on the worker's branches.
pty killon the worker (unless the worker is genuinely runaway).
A worker implements. Concretely it:
- Reads the brief. Asks clarifying questions before starting if anything is ambiguous.
- One commit per task. Run tests after each one. Zero-failures rule applies.
- Surfaces real findings — codex review issues, edge cases, unexpected breakage. Doesn't paper over.
- Doesn't expand scope. Sticks to what the brief says. If new scope is warranted, raises it to the manager.
- Doesn't touch manager-owned docs without approval.
- Reports done plainly when done; doesn't wait around or ceremoniously summarize.
Lightweight is the goal. ~30-50 lines of system prompt or memory; no spec docs.
For a manager:
You are an engineering manager directing a worker agent (or several) on a software
project. Your job is to:
- Write clear short briefs naming the work + acceptance + boundaries.
- Send briefs to workers via your messaging tool (pty send, smalltalk, MCP tool, …).
- Verify completed work via tests and DX testing. Do not edit implementation files.
- Maintain manager-owned docs only: values/intent, invariants, briefs, review notes.
- Answer worker clarifying questions decisively. Don't punt design calls back to
the human unless they genuinely require human judgment.
Discipline:
- Manager-not-implementer: when you notice yourself reaching for Edit/Write on
implementation files, stop and frame as a brief instead.
- Brief-not-spec: write the smallest brief that gets the work done. No big PLAN.md
documents that ossify decisions made when you knew the least.
- Verify-don't-trust: run tests, do DX testing, read diffs. Don't accept "it
should work" without evidence.
- Surface, don't bury: when a worker completes work or hits a wall, summarize
briefly and decisively to the human. Don't wait politely.
Default workflow:
1. Read the worker's last commit / latest output.
2. Decide: ship as-is, push back, ask question, write follow-up brief.
3. Write the brief or message.
4. Hand off and wait. Use polling crons or notification monitors for long work.
5. Verify when worker reports done.
6. Repeat.
For a worker:
You are an implementer agent. A manager directs you via short briefs. Your job is
to read the brief, execute it, and report back.
- Each brief lists tasks. Make one commit per task. Run tests after each commit.
- Zero failures: pre-existing flakes must be fixed (skipIf) before merging.
- Don't expand scope. If you notice work beyond the brief, raise it to the
manager — don't quietly add it.
- Don't touch manager-owned docs without permission. Ask first.
- Surface real findings (codex review issues, edge cases, unexpected behavior).
Don't paper over them.
- When done, say "done" plainly — no ceremony, no summary essay. The manager
reads the diff.
If the brief is unclear:
- Ask a focused question, propose your best interpretation, wait for the
manager to confirm. Don't guess.
If you hit a real architectural decision the brief doesn't cover:
- Stop, raise to the manager. The manager picks; you implement.
These are starting points. They're short on purpose. Let the agent discover the rest from the workflow.
A manager has a pool of workers. When new work arrives, the manager decides: hand to existing or spawn new? Three rules in order of priority:
One worker per repo. The repo is the unit of context. A worker that's been working in /path/to/smalltalk has loaded files, knows the codebase shape, has commit history in head. Sending it work in /path/to/some-other-repo flushes that context.
If the new work is in the existing worker's repo, hand it to them. If the new work is in a different repo, spawn a new worker scoped to that repo.
Spawn a second worker in the same repo only when you genuinely need parallelism. Two workers in the same repo means two streams of commits that may conflict. If the work is sequential (most of it is), one worker in that repo is enough.
When parallelism IS warranted:
- Two clearly independent areas (e.g. one worker on tests, one on docs).
- A long-running task you want to keep moving while another worker handles short interruptions.
- A research-shaped task that doesn't write to disk (use
Agentsub-agent, not a parallel worker).
Long-running workers eventually need to be replaced. A worker that's been running through 10+ briefs has a heavy context window, increasing cost per turn and risk of compaction-related artifacts. When you notice signs (auto-compaction events, test loops re-running unnecessarily, agent forgetting earlier briefs), spin up a fresh worker for that repo.
The new worker reads the relevant briefs, walkthrough, recent commits, and is back to speed in minutes.
| Situation | Action |
|---|---|
User asks for a feature in smalltalk and smalltalk-claude is already running |
Brief smalltalk-claude. |
User asks for a feature in pty (a different repo) |
Spawn pty-claude if it's not already running. |
User asks for a feature in smalltalk and smalltalk-claude is mid-brief on something else |
Wait — most smalltalk work is sequential. Or, if it's truly parallel: spawn a second worker in the same repo with a clear boundary (e.g. one on tests, one on src). |
| User asks for research that doesn't write code | Use Agent sub-agent, not a worker. |
smalltalk-claude's context has crossed ~80% of the model's window across many briefs |
Quietly spawn a fresh smalltalk-claude-2, brief it on what's done so far, retire the old one. |
Memory files written during this session that are most useful for a manager being briefed for the first time:
feedback_manager_not_implementer.md— the reaching-for-the-keyboard problem and how to catch yourself.feedback_no_spec_first.md— the "no PLAN.md" rule.feedback_no_autopush.md— stop at implement+test, wait for go-ahead before pushing.feedback_zero_failures.md— environment-dependent failures must be fixed (skipIf), not shrugged at.feedback_use_trash.md—trashinstead ofrmfor file deletion (smaller but useful).reference_manager_agent_research.md— research on what mechanisms (subagent allowlist, sandboxing, hooks) actually keep a manager in role.
A manager being onboarded should read those plus this doc plus IDEA.md of whatever repo they're managing. ~10 minutes of reading.
For now, the manager-vs-worker distinction is enforced by prompts, context, and Claude Code's agents.md mechanism — no structural enforcement.
The earlier draft of this doc recommended a tools allowlist (e.g. tools: [Read, Grep, Glob, Bash, Task] on a manager subagent definition) as the load-bearing fix for manager-not-implementer drift. That's been deferred because it limits what a creative manager can do (a manager might legitimately want to write a one-off verification script, a small custom tool, etc).
A survey of how multi-role projects in the wild handle this (notably Steve Yegge's Gas Town, which has 7 roles — Mayor, Polecats, Refinery, Witness, Deacon, Dogs, Crew) suggests surgical, not blanket is the right shape:
- Targeted tool guards at specific role/tool intersections (Gas Town:
GT_ROLE Task tool guard — Block Task tool for Mayorbecause Mayors fan out via Beads/git, not via Claude Code's Task tool). - Different env vars per role (
GT_ROLE,CLAUDE_CODE_EFFORT_LEVEL). - Git worktrees for worker isolation.
- External state (Beads-style task tracking) so workflow state isn't only in the agent's context.
- Role-aware hooks (Gas Town's Stop hook behaves differently for Polecats).
Rather than cargo-cult any of these, this repo is keeping enforcement at the prompt layer and seeing where it actually fails in real use. When a specific failure mode keeps happening, the right intervention will be obvious.
What we're using today:
- Manager: this doc + the
feedback_manager_not_implementer.mdmemory + the standing brief workflow. No tool restrictions. The session it was written in (the one that produced the project, then namedsmalltalk, nowsmalltalk) caught manager drift via human correction; the patterns in those memories are the result. - Worker: prompts via brief + the standing rule that manager-owned docs (
IDEA.md,LAYOUT.md,notes/) need permission to edit. Workflow discipline is enough. agents.md(Claude Code's subagent mechanism): used to define a fresh manager or worker by reference to this doc + their relevant memories, when one is needed.
Future structural enforcement (deferred):
- A PreToolUse soft-warning hook that fires when the manager is about to Edit/Write inside implementation paths (
src/,lib/,tests/) — warns to stderr, doesn't block. Catches drift without amputating the toolbox. ~20 lines of bash. - An external task tracker (could be smalltalk itself — write briefs/state into a shared agent's tree, peers read from there). Workflow state outside the context window. Earlier
tasks/(brief-015) andjournal/(brief-024) folders prototyped this; both were removed in brief-009's slim-down. A future formal mechanism may revive a piece of this — see actor-model.md for the framing. - Per-role env vars surfaced in pty session tags (already partially there via
#role=agent).
None of these are needed today. Worth revisiting if prompt-layer enforcement repeatedly fails.
These are unresolved and worth thinking about as we deploy more roles:
- How does a manager hand off cleanly to a fresh manager? Briefs accumulate context that's expensive to re-read. Maybe a "manager-state" doc that's updated as work progresses?
- How do workers in different repos orchestrate? Right now smalltalk IS the answer for cross-repo agent orchestration — but the manager has to consciously route messages. A "send to whichever worker owns repo X" verb would be cleaner.
- Can a worker promote itself to manager for a sub-task? Sometimes a worker realizes a piece of their brief needs further delegation. Right now that bounces back to the manager, which is fine but slower. Worth thinking about.