Files
JamBuddy/docs/agents/PROTOCOL.md
vadimwit 3c3e30de75 agents: six-agent ensemble system + /jam-loop conductor
Adds a standing team that builds JamBuddy as both jam companion and
open-source learning platform, collaborating through files (shared
ledger + repo), conducted by one scheduled loop.

- .claude/agents/{maestro,professor,luthier,muse,critic,herald}.md
  - dispatchable subagents, one per domain with file ownership + DoD
- .claude/skills/jam-loop/SKILL.md - the conductor (main loop appoints
  workers, Critic gates, Maestro reconciles); generalises /kb-expand
- docs/agents/ROSTER.md - team, ownership map, cadence weights
- docs/agents/PROTOCOL.md - task-locking conflict guardrail, ledger
  lifecycle, appointment algorithm, scheduling, PR-via-API
- docs/agents/LEDGER.md - live board seeded with sprint-jam-guide
- GOAL.md - links the ensemble; build still green

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-14 13:57:09 +01:00

7.4 KiB
Raw Permalink Blame History

Ensemble Protocol — How the Agents Collaborate

The operating system for the six-agent ensemble. Agents are isolated subagents — they share no memory, only files: the live ledger (LEDGER.md) and the repo. Everything below makes that file-mediated collaboration safe and productive.


1. The unit of work: a great task

An iteration is only as good as its tasks. Every ledger task MUST be:

  1. Bounded — one domain, one definition-of-done, completable in one session.
  2. Owned — exactly one agent appointed (domain → agent is 1:1).
  3. Locked — declares the files it will write; that set is its lock.
  4. Justified — content cites sources, code references the task id, design references tokens.
  5. Gated — Critic reviews before merge; nothing self-certifies.
  6. Logged — on completion: ledger updated, commit made, GOAL.md touched if scope shifted.

If a task can't be written this way, it's too big — Maestro splits it.


2. The ledger lifecycle

Status flow, managed in LEDGER.md:

backlog → ready → claimed → in-review → done
                     │           │
                     └───────────┴──→ returned (with findings) → ready
  • backlog — captured, not yet actionable.
  • ready — dependencies met; Maestro promoted it.
  • claimed — an agent is working it; its files are now locked.
  • in-review — work done, handed to Critic.
  • done — Critic passed it; merged.
  • returned — Critic failed it; carries specific findings; goes back to ready.

The locking rule (prevents file conflicts): an agent may only claim a ready task whose declared files do not overlap any claimed or in-review task. This serialises conflicting work without a central daemon — the check happens at claim time against the ledger.


3. File ownership map

Primary owner routes the task; co-reviewers must sign off on cross-domain files.

Path Primary Co-review
src/data/kb/** (content) Professor Critic (validator)
src/data/kb/SCHEMA.md, scripts/validate-kb.mjs Critic Professor, Luthier
src/components/**, src/services/**, src/App.jsx, electron/**, build cfg Luthier Critic; Muse if visual
tailwind.config.js, visual layer, SVG renderers Muse Luthier (integration), Critic
src/lib/theory.js shared Professor (music) + Luthier (code) Critic
docs/learn-curriculum.md, docs/progression-repertoire.md, docs/kb-*.md Professor Herald (clarity)
README.md, CONTRIBUTING.md, LICENSE, .github/** Herald Maestro
GOAL.md, docs/agents/LEDGER.md Maestro all read

Shared files (theory.js) get strict task-locking: only one task touching them runs at a time, reviewed by Critic and the non-owning domain.


4. The appointment algorithm (each iteration)

This is what /jam-loop (Maestro, run by the main loop) executes:

  1. PLAN — read LEDGER.md + GOAL.md. Promote backlog → ready where deps are met. Pick the next batch by priority × cadence-weight (weights in ROSTER), ensuring file-disjointness for any parallel batch.
  2. APPOINT — for each chosen task, dispatch the agent whose domain == task.domain.
  3. DISPATCH — choose the shape:
    • Serial (default, proven): one task → one agent via the Agent tool. A dependent chain → run in order.
    • Sprint (opt-in / "ultracode"): independent ready tasks → parallel; dependent tasks → pipeline; via the Workflow tool.
    • Parallel writes to disjoint files → give each agent isolation: "worktree".
  4. GATE — every completed worker task → Critic reviews (runs npm run build, node scripts/validate-kb.mjs, tests; applies judgment). Pass → done; fail → returned with findings.
  5. RECONCILE — Maestro commits passing work (one commit per task), updates LEDGER.md + GOAL.md, writes a one-line iteration log.
  6. CONTINUE — schedule the next iteration, or at sprint end open the PR (see §6).

Appointing correctly = the five rules of great iterations (§1) applied at dispatch: bounded scope to one agent, files locked, sources/refs required, Critic gate wired in, honest status on return.


5. Scheduling

The clean model: schedule the conductor, not the band. One recurring loop runs /jam-loop; each fire is one orchestrated iteration that appoints whichever agent the next ready task needs.

  • Session loop (runs while this terminal is open): /loop 1h /jam-loop — good for a focused build sprint you're watching.
  • Cloud schedule (durable, survives closing the session): /schedule → e.g. "run /jam-loop every weekday at 09:07" — good for steady background progress. Recommended for a standing ensemble.

Per-domain cadence is the weight, not a separate cron: content advances most iterations, OSS/docs every ~4th. To shift emphasis for a stretch (e.g. "design week"), Maestro raises Muse's weight in the ledger header — no schedule change.

Advanced — true parallel cadences (not default). You can run separate loops per agent (/loop 1h /jam-loop --only professor, /loop 3h /jam-loop --only luthier). Only do this with worktree isolation mandatory and strictly disjoint file ownership per loop, or they will collide on shared files (theory.js, App.jsx, the ledger). The single-conductor model avoids this entirely; prefer it unless you have a specific throughput need.


6. Branching, review, and PRs

  • One sprint branch off main (e.g. sprint-jam-guide); each task is a commit (parallel disjoint work uses worktrees off the branch).
  • Critic gates every commit; Maestro opens one PR per sprint to main summarising all tasks + validator/build status.
  • Known constraint (this machine): gh CLI is not installed. Open PRs via the GitHub API using stored git credentials:
    TOKEN=$(printf 'protocol=https\nhost=github.com\n\n' | git credential fill | sed -n 's/^password=//p')
    # POST to https://api.github.com/repos/whattheflat/JamBuddy/pulls with {title, head, base, body}
    
    (Repo was renamed whattheflatJamBuddy; origin URL still works for push.)

7. Conflict resolution

  • File clash at claim time → can't claim; pick another ready task or wait for the lock to clear.
  • Cross-domain disagreement (e.g. Muse wants a layout Luthier says is infeasible) → Maestro decides, records the call in the ledger, and if it's a product question surfaces it to the human instead of guessing.
  • Critic vs author → Critic's gate is binding on correctness/quality; on taste/scope, Maestro arbitrates. Returned work always carries specific, actionable findings — never a bare rejection.
  • Scope creep → if a task grows mid-flight, the agent stops, notes it in the ledger, and Maestro re-splits. Silent scope expansion is the cardinal sin.

8. State lives in files (because agents don't share memory)

Every iteration must leave perfect context for the next, since the next agent starts fresh:

  • the ledger carries task status, locks, and findings;
  • the commit carries the change and its rationale;
  • GOAL.md carries shifts in direction;
  • a recalled memory file (project_ensemble) carries the standing setup.

Write as if the next agent has never seen this conversation — because it hasn't.