macro-agent 0.0.10 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.macro-agent/teams/self-driving/prompts/grinder.md +27 -0
- package/.macro-agent/teams/self-driving/prompts/judge.md +27 -0
- package/.macro-agent/teams/self-driving/prompts/planner.md +33 -0
- package/.macro-agent/teams/self-driving/roles/grinder.yaml +17 -0
- package/.macro-agent/teams/self-driving/roles/judge.yaml +24 -0
- package/.macro-agent/teams/self-driving/roles/planner.yaml +18 -0
- package/.macro-agent/teams/self-driving/team.yaml +103 -0
- package/.macro-agent/teams/structured/prompts/developer.md +26 -0
- package/.macro-agent/teams/structured/prompts/lead.md +25 -0
- package/.macro-agent/teams/structured/prompts/reviewer.md +24 -0
- package/.macro-agent/teams/structured/roles/developer.yaml +12 -0
- package/.macro-agent/teams/structured/roles/lead.yaml +11 -0
- package/.macro-agent/teams/structured/roles/reviewer.yaml +19 -0
- package/.macro-agent/teams/structured/team.yaml +89 -0
- package/.sudocode/issues.jsonl +56 -51
- package/.sudocode/specs.jsonl +8 -1
- package/CLAUDE.md +121 -30
- package/README.md +60 -3
- package/dist/acp/macro-agent.d.ts +4 -0
- package/dist/acp/macro-agent.d.ts.map +1 -1
- package/dist/acp/macro-agent.js +50 -4
- package/dist/acp/macro-agent.js.map +1 -1
- package/dist/acp/session-mapper.d.ts +20 -1
- package/dist/acp/session-mapper.d.ts.map +1 -1
- package/dist/acp/session-mapper.js +90 -1
- package/dist/acp/session-mapper.js.map +1 -1
- package/dist/acp/types.d.ts +24 -1
- package/dist/acp/types.d.ts.map +1 -1
- package/dist/acp/types.js.map +1 -1
- package/dist/agent/agent-manager.d.ts +40 -1
- package/dist/agent/agent-manager.d.ts.map +1 -1
- package/dist/agent/agent-manager.js +172 -8
- package/dist/agent/agent-manager.js.map +1 -1
- package/dist/agent/types.d.ts +22 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/agent/wake.d.ts +15 -0
- package/dist/agent/wake.d.ts.map +1 -1
- package/dist/agent/wake.js +15 -0
- package/dist/agent/wake.js.map +1 -1
- package/dist/agent-detection/command-builder.d.ts +30 -0
- package/dist/agent-detection/command-builder.d.ts.map +1 -0
- package/dist/agent-detection/command-builder.js +71 -0
- package/dist/agent-detection/command-builder.js.map +1 -0
- package/dist/agent-detection/detector.d.ts +84 -0
- package/dist/agent-detection/detector.d.ts.map +1 -0
- package/dist/agent-detection/detector.js +240 -0
- package/dist/agent-detection/detector.js.map +1 -0
- package/dist/agent-detection/index.d.ts +12 -0
- package/dist/agent-detection/index.d.ts.map +1 -0
- package/dist/agent-detection/index.js +14 -0
- package/dist/agent-detection/index.js.map +1 -0
- package/dist/agent-detection/registry.d.ts +53 -0
- package/dist/agent-detection/registry.d.ts.map +1 -0
- package/dist/agent-detection/registry.js +177 -0
- package/dist/agent-detection/registry.js.map +1 -0
- package/dist/agent-detection/types.d.ts +121 -0
- package/dist/agent-detection/types.d.ts.map +1 -0
- package/dist/agent-detection/types.js +20 -0
- package/dist/agent-detection/types.js.map +1 -0
- package/dist/api/server.d.ts +5 -1
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +362 -0
- package/dist/api/server.js.map +1 -1
- package/dist/api/types.d.ts +50 -1
- package/dist/api/types.d.ts.map +1 -1
- package/dist/cli/acp.d.ts +2 -0
- package/dist/cli/acp.d.ts.map +1 -1
- package/dist/cli/acp.js +8 -1
- package/dist/cli/acp.js.map +1 -1
- package/dist/cli/index.js +29 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp.js +38 -0
- package/dist/cli/mcp.js.map +1 -1
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/project-config.d.ts +46 -0
- package/dist/config/project-config.d.ts.map +1 -0
- package/dist/config/project-config.js +68 -0
- package/dist/config/project-config.js.map +1 -0
- package/dist/lifecycle/cascade.d.ts +1 -1
- package/dist/lifecycle/cascade.d.ts.map +1 -1
- package/dist/lifecycle/handlers/index.d.ts +4 -0
- package/dist/lifecycle/handlers/index.d.ts.map +1 -1
- package/dist/lifecycle/handlers/index.js +2 -0
- package/dist/lifecycle/handlers/index.js.map +1 -1
- package/dist/lifecycle/handlers/worker.d.ts +4 -0
- package/dist/lifecycle/handlers/worker.d.ts.map +1 -1
- package/dist/lifecycle/handlers/worker.js +35 -3
- package/dist/lifecycle/handlers/worker.js.map +1 -1
- package/dist/mail/conversation-map.d.ts +33 -0
- package/dist/mail/conversation-map.d.ts.map +1 -0
- package/dist/mail/conversation-map.js +61 -0
- package/dist/mail/conversation-map.js.map +1 -0
- package/dist/mail/index.d.ts +11 -0
- package/dist/mail/index.d.ts.map +1 -0
- package/dist/mail/index.js +11 -0
- package/dist/mail/index.js.map +1 -0
- package/dist/mail/mail-service.d.ts +85 -0
- package/dist/mail/mail-service.d.ts.map +1 -0
- package/dist/mail/mail-service.js +121 -0
- package/dist/mail/mail-service.js.map +1 -0
- package/dist/mail/stores/eventstore-conversation-store.d.ts +40 -0
- package/dist/mail/stores/eventstore-conversation-store.d.ts.map +1 -0
- package/dist/mail/stores/eventstore-conversation-store.js +131 -0
- package/dist/mail/stores/eventstore-conversation-store.js.map +1 -0
- package/dist/mail/stores/eventstore-participant-store.d.ts +43 -0
- package/dist/mail/stores/eventstore-participant-store.d.ts.map +1 -0
- package/dist/mail/stores/eventstore-participant-store.js +145 -0
- package/dist/mail/stores/eventstore-participant-store.js.map +1 -0
- package/dist/mail/stores/eventstore-thread-store.d.ts +46 -0
- package/dist/mail/stores/eventstore-thread-store.d.ts.map +1 -0
- package/dist/mail/stores/eventstore-thread-store.js +118 -0
- package/dist/mail/stores/eventstore-thread-store.js.map +1 -0
- package/dist/mail/stores/eventstore-turn-store.d.ts +47 -0
- package/dist/mail/stores/eventstore-turn-store.d.ts.map +1 -0
- package/dist/mail/stores/eventstore-turn-store.js +153 -0
- package/dist/mail/stores/eventstore-turn-store.js.map +1 -0
- package/dist/mail/stores/index.d.ts +12 -0
- package/dist/mail/stores/index.d.ts.map +1 -0
- package/dist/mail/stores/index.js +12 -0
- package/dist/mail/stores/index.js.map +1 -0
- package/dist/mail/stores/types.d.ts +146 -0
- package/dist/mail/stores/types.d.ts.map +1 -0
- package/dist/mail/stores/types.js +13 -0
- package/dist/mail/stores/types.js.map +1 -0
- package/dist/mail/turn-recorder.d.ts +30 -0
- package/dist/mail/turn-recorder.d.ts.map +1 -0
- package/dist/mail/turn-recorder.js +98 -0
- package/dist/mail/turn-recorder.js.map +1 -0
- package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
- package/dist/map/adapter/acp-over-map.js +32 -2
- package/dist/map/adapter/acp-over-map.js.map +1 -1
- package/dist/map/adapter/event-translator.d.ts.map +1 -1
- package/dist/map/adapter/event-translator.js +4 -0
- package/dist/map/adapter/event-translator.js.map +1 -1
- package/dist/map/adapter/extensions/agent-detection.d.ts +49 -0
- package/dist/map/adapter/extensions/agent-detection.d.ts.map +1 -0
- package/dist/map/adapter/extensions/agent-detection.js +91 -0
- package/dist/map/adapter/extensions/agent-detection.js.map +1 -0
- package/dist/map/adapter/extensions/index.d.ts +10 -1
- package/dist/map/adapter/extensions/index.d.ts.map +1 -1
- package/dist/map/adapter/extensions/index.js +39 -0
- package/dist/map/adapter/extensions/index.js.map +1 -1
- package/dist/map/adapter/extensions/resume.d.ts +47 -0
- package/dist/map/adapter/extensions/resume.d.ts.map +1 -0
- package/dist/map/adapter/extensions/resume.js +59 -0
- package/dist/map/adapter/extensions/resume.js.map +1 -0
- package/dist/map/adapter/extensions/workspace-files.d.ts +42 -0
- package/dist/map/adapter/extensions/workspace-files.d.ts.map +1 -0
- package/dist/map/adapter/extensions/workspace-files.js +338 -0
- package/dist/map/adapter/extensions/workspace-files.js.map +1 -0
- package/dist/map/adapter/mail-handler-adapter.d.ts +27 -0
- package/dist/map/adapter/mail-handler-adapter.d.ts.map +1 -0
- package/dist/map/adapter/mail-handler-adapter.js +292 -0
- package/dist/map/adapter/mail-handler-adapter.js.map +1 -0
- package/dist/map/adapter/map-adapter.d.ts +34 -10
- package/dist/map/adapter/map-adapter.d.ts.map +1 -1
- package/dist/map/adapter/map-adapter.js +110 -14
- package/dist/map/adapter/map-adapter.js.map +1 -1
- package/dist/map/adapter/rpc-handler.d.ts +4 -1
- package/dist/map/adapter/rpc-handler.d.ts.map +1 -1
- package/dist/map/adapter/rpc-handler.js +6 -0
- package/dist/map/adapter/rpc-handler.js.map +1 -1
- package/dist/map/index.d.ts +1 -0
- package/dist/map/index.d.ts.map +1 -1
- package/dist/map/index.js +2 -0
- package/dist/map/index.js.map +1 -1
- package/dist/map/types.d.ts +3 -1
- package/dist/map/types.d.ts.map +1 -1
- package/dist/map/types.js.map +1 -1
- package/dist/mcp/mcp-server.d.ts +6 -0
- package/dist/mcp/mcp-server.d.ts.map +1 -1
- package/dist/mcp/mcp-server.js +45 -0
- package/dist/mcp/mcp-server.js.map +1 -1
- package/dist/mcp/tools/claim_task.d.ts +35 -0
- package/dist/mcp/tools/claim_task.d.ts.map +1 -0
- package/dist/mcp/tools/claim_task.js +58 -0
- package/dist/mcp/tools/claim_task.js.map +1 -0
- package/dist/mcp/tools/done.d.ts +15 -2
- package/dist/mcp/tools/done.d.ts.map +1 -1
- package/dist/mcp/tools/done.js +45 -10
- package/dist/mcp/tools/done.js.map +1 -1
- package/dist/mcp/tools/list_claimable_tasks.d.ts +38 -0
- package/dist/mcp/tools/list_claimable_tasks.d.ts.map +1 -0
- package/dist/mcp/tools/list_claimable_tasks.js +63 -0
- package/dist/mcp/tools/list_claimable_tasks.js.map +1 -0
- package/dist/mcp/tools/unclaim_task.d.ts +31 -0
- package/dist/mcp/tools/unclaim_task.d.ts.map +1 -0
- package/dist/mcp/tools/unclaim_task.js +47 -0
- package/dist/mcp/tools/unclaim_task.js.map +1 -0
- package/dist/metrics/index.d.ts +2 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +2 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/metrics.d.ts +79 -0
- package/dist/metrics/metrics.d.ts.map +1 -0
- package/dist/metrics/metrics.js +166 -0
- package/dist/metrics/metrics.js.map +1 -0
- package/dist/roles/capabilities.d.ts +1 -0
- package/dist/roles/capabilities.d.ts.map +1 -1
- package/dist/roles/capabilities.js +3 -0
- package/dist/roles/capabilities.js.map +1 -1
- package/dist/roles/types.d.ts +1 -1
- package/dist/roles/types.d.ts.map +1 -1
- package/dist/router/channels.d.ts +2 -4
- package/dist/router/channels.d.ts.map +1 -1
- package/dist/router/channels.js.map +1 -1
- package/dist/router/message-router.d.ts +85 -9
- package/dist/router/message-router.d.ts.map +1 -1
- package/dist/router/message-router.js +203 -14
- package/dist/router/message-router.js.map +1 -1
- package/dist/router/role-resolver.d.ts +10 -1
- package/dist/router/role-resolver.d.ts.map +1 -1
- package/dist/router/role-resolver.js +15 -1
- package/dist/router/role-resolver.js.map +1 -1
- package/dist/router/types.d.ts +30 -1
- package/dist/router/types.d.ts.map +1 -1
- package/dist/router/types.js.map +1 -1
- package/dist/server/combined-server.d.ts +6 -0
- package/dist/server/combined-server.d.ts.map +1 -1
- package/dist/server/combined-server.js +24 -2
- package/dist/server/combined-server.js.map +1 -1
- package/dist/store/event-store.d.ts +14 -1
- package/dist/store/event-store.d.ts.map +1 -1
- package/dist/store/event-store.js +456 -4
- package/dist/store/event-store.js.map +1 -1
- package/dist/store/types/agents.d.ts +1 -1
- package/dist/store/types/agents.d.ts.map +1 -1
- package/dist/store/types/conversations.d.ts +91 -0
- package/dist/store/types/conversations.d.ts.map +1 -0
- package/dist/store/types/conversations.js +8 -0
- package/dist/store/types/conversations.js.map +1 -0
- package/dist/store/types/events.d.ts +1 -1
- package/dist/store/types/events.d.ts.map +1 -1
- package/dist/store/types/events.js.map +1 -1
- package/dist/store/types/index.d.ts +2 -0
- package/dist/store/types/index.d.ts.map +1 -1
- package/dist/store/types/index.js +2 -0
- package/dist/store/types/index.js.map +1 -1
- package/dist/store/types/sessions.d.ts +44 -0
- package/dist/store/types/sessions.d.ts.map +1 -0
- package/dist/store/types/sessions.js +9 -0
- package/dist/store/types/sessions.js.map +1 -0
- package/dist/store/types/tasks.d.ts +2 -0
- package/dist/store/types/tasks.d.ts.map +1 -1
- package/dist/task/backend/memory.d.ts +4 -1
- package/dist/task/backend/memory.d.ts.map +1 -1
- package/dist/task/backend/memory.js +81 -0
- package/dist/task/backend/memory.js.map +1 -1
- package/dist/task/backend/types.d.ts +30 -0
- package/dist/task/backend/types.d.ts.map +1 -1
- package/dist/task/backend/types.js.map +1 -1
- package/dist/teams/index.d.ts +4 -0
- package/dist/teams/index.d.ts.map +1 -0
- package/dist/teams/index.js +4 -0
- package/dist/teams/index.js.map +1 -0
- package/dist/teams/team-loader.d.ts +20 -0
- package/dist/teams/team-loader.d.ts.map +1 -0
- package/dist/teams/team-loader.js +293 -0
- package/dist/teams/team-loader.js.map +1 -0
- package/dist/teams/team-runtime.d.ts +139 -0
- package/dist/teams/team-runtime.d.ts.map +1 -0
- package/dist/teams/team-runtime.js +613 -0
- package/dist/teams/team-runtime.js.map +1 -0
- package/dist/teams/types.d.ts +266 -0
- package/dist/teams/types.d.ts.map +1 -0
- package/dist/teams/types.js +20 -0
- package/dist/teams/types.js.map +1 -0
- package/dist/trigger/router/trigger-router.d.ts +30 -3
- package/dist/trigger/router/trigger-router.d.ts.map +1 -1
- package/dist/trigger/router/trigger-router.js +30 -3
- package/dist/trigger/router/trigger-router.js.map +1 -1
- package/dist/trigger/wake/types.d.ts +31 -5
- package/dist/trigger/wake/types.d.ts.map +1 -1
- package/dist/trigger/wake/types.js +19 -0
- package/dist/trigger/wake/types.js.map +1 -1
- package/dist/workspace/dataplane-adapter.d.ts +1 -1
- package/dist/workspace/dataplane-adapter.d.ts.map +1 -1
- package/dist/workspace/dataplane-adapter.js +1 -1
- package/dist/workspace/dataplane-adapter.js.map +1 -1
- package/dist/workspace/index.d.ts +1 -1
- package/dist/workspace/index.d.ts.map +1 -1
- package/dist/workspace/strategies/index.d.ts +6 -0
- package/dist/workspace/strategies/index.d.ts.map +1 -0
- package/dist/workspace/strategies/index.js +5 -0
- package/dist/workspace/strategies/index.js.map +1 -0
- package/dist/workspace/strategies/optimistic.d.ts +26 -0
- package/dist/workspace/strategies/optimistic.d.ts.map +1 -0
- package/dist/workspace/strategies/optimistic.js +121 -0
- package/dist/workspace/strategies/optimistic.js.map +1 -0
- package/dist/workspace/strategies/queue.d.ts +26 -0
- package/dist/workspace/strategies/queue.d.ts.map +1 -0
- package/dist/workspace/strategies/queue.js +67 -0
- package/dist/workspace/strategies/queue.js.map +1 -0
- package/dist/workspace/strategies/registry.d.ts +37 -0
- package/dist/workspace/strategies/registry.d.ts.map +1 -0
- package/dist/workspace/strategies/registry.js +63 -0
- package/dist/workspace/strategies/registry.js.map +1 -0
- package/dist/workspace/strategies/trunk.d.ts +20 -0
- package/dist/workspace/strategies/trunk.d.ts.map +1 -0
- package/dist/workspace/strategies/trunk.js +108 -0
- package/dist/workspace/strategies/trunk.js.map +1 -0
- package/dist/workspace/strategies/types.d.ts +104 -0
- package/dist/workspace/strategies/types.d.ts.map +1 -0
- package/dist/workspace/strategies/types.js +11 -0
- package/dist/workspace/strategies/types.js.map +1 -0
- package/dist/workspace/types.d.ts +1 -1
- package/dist/workspace/types.d.ts.map +1 -1
- package/dist/workspace/workspace-manager.d.ts +1 -1
- package/dist/workspace/workspace-manager.d.ts.map +1 -1
- package/docs/implementation-details.md +1127 -0
- package/docs/implementation-summary.md +448 -0
- package/docs/mail-integration.md +608 -0
- package/docs/plan-self-driving-support.md +433 -0
- package/docs/spec-self-driving-support.md +462 -0
- package/docs/team-templates.md +860 -0
- package/docs/teams.md +233 -0
- package/package.json +5 -3
- package/src/acp/__tests__/integration.test.ts +161 -1
- package/src/acp/__tests__/macro-agent.test.ts +95 -0
- package/src/acp/__tests__/session-persistence.test.ts +276 -0
- package/src/acp/macro-agent.ts +79 -7
- package/src/acp/session-mapper.ts +108 -1
- package/src/acp/types.ts +33 -1
- package/src/agent/agent-manager.ts +278 -6
- package/src/agent/types.ts +27 -0
- package/src/agent/wake.ts +15 -0
- package/src/agent-detection/__tests__/command-builder.test.ts +336 -0
- package/src/agent-detection/__tests__/detector.test.ts +768 -0
- package/src/agent-detection/__tests__/registry.test.ts +254 -0
- package/src/agent-detection/command-builder.ts +90 -0
- package/src/agent-detection/detector.ts +307 -0
- package/src/agent-detection/index.ts +36 -0
- package/src/agent-detection/registry.ts +200 -0
- package/src/agent-detection/types.ts +184 -0
- package/src/api/__tests__/conversation-api.test.ts +468 -0
- package/src/api/server.ts +425 -1
- package/src/api/types.ts +64 -1
- package/src/cli/acp.ts +9 -1
- package/src/cli/index.ts +44 -0
- package/src/cli/mcp.ts +47 -0
- package/src/config/index.ts +9 -0
- package/src/config/project-config.ts +107 -0
- package/src/lifecycle/cascade.ts +1 -1
- package/src/lifecycle/handlers/index.ts +8 -0
- package/src/lifecycle/handlers/worker.ts +48 -3
- package/src/mail/__tests__/conversation-lifecycle.test.ts +409 -0
- package/src/mail/__tests__/eventstore-stores.test.ts +1073 -0
- package/src/mail/__tests__/mail-full-agent.e2e.test.ts +575 -0
- package/src/mail/__tests__/mail-integration.test.ts +759 -0
- package/src/mail/__tests__/mail-map-protocol.e2e.test.ts +1068 -0
- package/src/mail/__tests__/mail-service.test.ts +506 -0
- package/src/mail/__tests__/turn-recorder.test.ts +328 -0
- package/src/mail/conversation-map.ts +107 -0
- package/src/mail/index.ts +25 -0
- package/src/mail/mail-service.ts +257 -0
- package/src/mail/stores/eventstore-conversation-store.ts +146 -0
- package/src/mail/stores/eventstore-participant-store.ts +172 -0
- package/src/mail/stores/eventstore-thread-store.ts +129 -0
- package/src/mail/stores/eventstore-turn-store.ts +173 -0
- package/src/mail/stores/index.ts +12 -0
- package/src/mail/stores/types.ts +160 -0
- package/src/mail/turn-recorder.ts +124 -0
- package/src/map/README.md +79 -0
- package/src/map/adapter/__tests__/extensions.test.ts +359 -0
- package/src/map/adapter/__tests__/map-adapter.test.ts +90 -0
- package/src/map/adapter/__tests__/workspace-files.test.ts +673 -0
- package/src/map/adapter/acp-over-map.ts +45 -2
- package/src/map/adapter/event-translator.ts +4 -0
- package/src/map/adapter/extensions/agent-detection.ts +201 -0
- package/src/map/adapter/extensions/index.ts +63 -0
- package/src/map/adapter/extensions/resume.ts +114 -0
- package/src/map/adapter/extensions/workspace-files.ts +449 -0
- package/src/map/adapter/mail-handler-adapter.ts +429 -0
- package/src/map/adapter/map-adapter.ts +173 -27
- package/src/map/adapter/rpc-handler.ts +8 -1
- package/src/map/index.ts +3 -0
- package/src/map/types.ts +3 -1
- package/src/mcp/mcp-server.ts +67 -0
- package/src/mcp/tools/claim_task.ts +86 -0
- package/src/mcp/tools/done.ts +59 -10
- package/src/mcp/tools/list_claimable_tasks.ts +93 -0
- package/src/mcp/tools/unclaim_task.ts +71 -0
- package/src/metrics/index.ts +9 -0
- package/src/metrics/metrics.ts +280 -0
- package/src/roles/capabilities.ts +3 -0
- package/src/roles/types.ts +2 -1
- package/src/router/README.md +120 -0
- package/src/router/__tests__/message-router.test.ts +561 -0
- package/src/router/channels.ts +3 -4
- package/src/router/message-router.ts +308 -22
- package/src/router/role-resolver.ts +22 -1
- package/src/router/types.ts +36 -1
- package/src/server/combined-server.ts +36 -2
- package/src/store/README.md +134 -0
- package/src/store/event-store.ts +546 -3
- package/src/store/types/agents.ts +1 -1
- package/src/store/types/conversations.ts +129 -0
- package/src/store/types/events.ts +5 -1
- package/src/store/types/index.ts +2 -0
- package/src/store/types/sessions.ts +53 -0
- package/src/store/types/tasks.ts +3 -0
- package/src/task/backend/memory.ts +116 -0
- package/src/task/backend/types.ts +43 -0
- package/src/teams/__tests__/cross-subsystem.integration.test.ts +983 -0
- package/src/teams/__tests__/e2e/team-runtime.e2e.test.ts +553 -0
- package/src/teams/__tests__/team-system.test.ts +1280 -0
- package/src/teams/index.ts +13 -0
- package/src/teams/team-loader.ts +434 -0
- package/src/teams/team-runtime.ts +727 -0
- package/src/teams/types.ts +377 -0
- package/src/trigger/router/trigger-router.ts +30 -3
- package/src/trigger/wake/types.ts +32 -5
- package/src/trigger/wake/wake-manager.ts +2 -2
- package/src/workspace/dataplane-adapter.ts +1 -1
- package/src/workspace/index.ts +1 -1
- package/src/workspace/strategies/index.ts +18 -0
- package/src/workspace/strategies/optimistic.ts +136 -0
- package/src/workspace/strategies/queue.ts +81 -0
- package/src/workspace/strategies/registry.ts +89 -0
- package/src/workspace/strategies/trunk.ts +123 -0
- package/src/workspace/strategies/types.ts +145 -0
- package/src/workspace/types.ts +1 -1
- package/src/workspace/workspace-manager.ts +1 -1
- package/.claude/settings.local.json +0 -59
- package/dist/map/utils/address-translation.d.ts +0 -99
- package/dist/map/utils/address-translation.d.ts.map +0 -1
- package/dist/map/utils/address-translation.js +0 -285
- package/dist/map/utils/address-translation.js.map +0 -1
- package/dist/map/utils/index.d.ts +0 -7
- package/dist/map/utils/index.d.ts.map +0 -1
- package/dist/map/utils/index.js +0 -7
- package/dist/map/utils/index.js.map +0 -1
- package/openspec/AGENTS.md +0 -456
- package/openspec/changes/archive/2025-12-21-add-mvp-foundation/design.md +0 -128
- package/openspec/changes/archive/2025-12-21-add-mvp-foundation/proposal.md +0 -49
- package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/agent-manager/spec.md +0 -150
- package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/cli-api/spec.md +0 -258
- package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/event-store/spec.md +0 -160
- package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/mcp-tools/spec.md +0 -224
- package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/message-router/spec.md +0 -153
- package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/task-manager/spec.md +0 -136
- package/openspec/changes/archive/2025-12-21-add-mvp-foundation/tasks.md +0 -147
- package/openspec/project.md +0 -31
- package/openspec/specs/agent-manager/spec.md +0 -154
- package/openspec/specs/cli-api/spec.md +0 -262
- package/openspec/specs/event-store/spec.md +0 -164
- package/openspec/specs/mcp-tools/spec.md +0 -228
- package/openspec/specs/message-router/spec.md +0 -157
- package/openspec/specs/task-manager/spec.md +0 -140
- package/references/acp-factory-ref/CHANGELOG.md +0 -33
- package/references/acp-factory-ref/LICENSE +0 -21
- package/references/acp-factory-ref/README.md +0 -341
- package/references/acp-factory-ref/package-lock.json +0 -3102
- package/references/acp-factory-ref/package.json +0 -96
- package/references/acp-factory-ref/python/CHANGELOG.md +0 -33
- package/references/acp-factory-ref/python/LICENSE +0 -21
- package/references/acp-factory-ref/python/Makefile +0 -57
- package/references/acp-factory-ref/python/README.md +0 -253
- package/references/acp-factory-ref/python/pyproject.toml +0 -73
- package/references/acp-factory-ref/python/tests/__init__.py +0 -0
- package/references/acp-factory-ref/python/tests/e2e/__init__.py +0 -1
- package/references/acp-factory-ref/python/tests/e2e/test_codex_e2e.py +0 -349
- package/references/acp-factory-ref/python/tests/e2e/test_gemini_e2e.py +0 -165
- package/references/acp-factory-ref/python/tests/e2e/test_opencode_e2e.py +0 -296
- package/references/acp-factory-ref/python/tests/test_client_handler.py +0 -543
- package/references/acp-factory-ref/python/tests/test_pushable.py +0 -199
- package/references/claude-code-acp/.github/workflows/ci.yml +0 -45
- package/references/claude-code-acp/.github/workflows/publish.yml +0 -34
- package/references/claude-code-acp/.prettierrc.json +0 -4
- package/references/claude-code-acp/CHANGELOG.md +0 -249
- package/references/claude-code-acp/LICENSE +0 -222
- package/references/claude-code-acp/README.md +0 -53
- package/references/claude-code-acp/docs/RELEASES.md +0 -24
- package/references/claude-code-acp/eslint.config.js +0 -48
- package/references/claude-code-acp/package-lock.json +0 -4570
- package/references/claude-code-acp/package.json +0 -88
- package/references/claude-code-acp/scripts/release.sh +0 -119
- package/references/claude-code-acp/src/acp-agent.ts +0 -2065
- package/references/claude-code-acp/src/index.ts +0 -26
- package/references/claude-code-acp/src/lib.ts +0 -38
- package/references/claude-code-acp/src/mcp-server.ts +0 -911
- package/references/claude-code-acp/src/settings.ts +0 -522
- package/references/claude-code-acp/src/tests/.claude/commands/quick-math.md +0 -5
- package/references/claude-code-acp/src/tests/.claude/commands/say-hello.md +0 -6
- package/references/claude-code-acp/src/tests/acp-agent-fork.test.ts +0 -479
- package/references/claude-code-acp/src/tests/acp-agent.test.ts +0 -1502
- package/references/claude-code-acp/src/tests/extract-lines.test.ts +0 -103
- package/references/claude-code-acp/src/tests/fork-session.test.ts +0 -335
- package/references/claude-code-acp/src/tests/replace-and-calculate-location.test.ts +0 -334
- package/references/claude-code-acp/src/tests/settings.test.ts +0 -617
- package/references/claude-code-acp/src/tests/skills-options.test.ts +0 -187
- package/references/claude-code-acp/src/tests/tools.test.ts +0 -318
- package/references/claude-code-acp/src/tests/typescript-declarations.test.ts +0 -558
- package/references/claude-code-acp/src/tools.ts +0 -819
- package/references/claude-code-acp/src/utils.ts +0 -171
- package/references/claude-code-acp/tsconfig.json +0 -18
- package/references/claude-code-acp/vitest.config.ts +0 -19
- package/references/multi-agent-protocol/.sudocode/issues.jsonl +0 -82
- package/references/multi-agent-protocol/.sudocode/specs.jsonl +0 -9
- package/references/multi-agent-protocol/LICENSE +0 -21
- package/references/multi-agent-protocol/README.md +0 -113
- package/references/multi-agent-protocol/docs/00-design-specification.md +0 -460
- package/references/multi-agent-protocol/docs/01-open-questions.md +0 -1050
- package/references/multi-agent-protocol/docs/02-wire-protocol.md +0 -296
- package/references/multi-agent-protocol/docs/03-streaming-semantics.md +0 -252
- package/references/multi-agent-protocol/docs/04-error-handling.md +0 -231
- package/references/multi-agent-protocol/docs/05-connection-model.md +0 -244
- package/references/multi-agent-protocol/docs/06-visibility-permissions.md +0 -243
- package/references/multi-agent-protocol/docs/07-federation.md +0 -259
- package/references/multi-agent-protocol/docs/08-macro-agent-migration.md +0 -253
- package/references/multi-agent-protocol/package-lock.json +0 -3239
- package/references/multi-agent-protocol/package.json +0 -56
- package/references/multi-agent-protocol/schema/meta.json +0 -337
- package/references/multi-agent-protocol/schema/schema.json +0 -1828
|
@@ -0,0 +1,860 @@
|
|
|
1
|
+
# Team Templates
|
|
2
|
+
|
|
3
|
+
Detailed design for the team template system — the modular layer that enables loading different agent team structures on top of macro-agent's role-agnostic core.
|
|
4
|
+
|
|
5
|
+
## Problem
|
|
6
|
+
|
|
7
|
+
macro-agent provides powerful primitives: roles with capabilities, workspace isolation, message routing, lifecycle management. But composing these into a working multi-agent team requires knowing which roles to define, how they interact, what prompts they need, and which integration/task patterns to use.
|
|
8
|
+
|
|
9
|
+
Today, this composition is implicit — you spawn a coordinator, it spawns workers, the integrator processes the merge queue. There's one interaction pattern hardcoded across the system.
|
|
10
|
+
|
|
11
|
+
Different workflows need different team shapes:
|
|
12
|
+
- **Structured development**: Coordinator decomposes tasks, pushes to workers, integrator gates merges (current model)
|
|
13
|
+
- **Self-driving**: Planners continuously discover work, workers pull tasks, trunk-based integration, judge evaluates quality
|
|
14
|
+
- **Code review**: Author agents write code, reviewer agents evaluate, gatekeeper merges approved changes
|
|
15
|
+
- **Migration**: Scanner identifies work, transformer agents apply changes in parallel, validator confirms correctness
|
|
16
|
+
|
|
17
|
+
Team templates make these compositions **declarative and loadable** without modifying macro-agent core.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## File Structure
|
|
22
|
+
|
|
23
|
+
A team template is a directory. The structure is designed to be interoperable with other multi-agent systems — the core topology and role structure uses a generic schema, while macro-agent specific configuration lives in clearly namespaced extension fields.
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
.macro-agent/teams/<team-name>/
|
|
27
|
+
├── team.yaml # Manifest: topology, communication, modes
|
|
28
|
+
├── roles/ # Role definitions
|
|
29
|
+
│ ├── <role-name>.yaml
|
|
30
|
+
│ └── ...
|
|
31
|
+
├── prompts/ # Static role prompt files
|
|
32
|
+
│ ├── <role-name>.md
|
|
33
|
+
│ └── ...
|
|
34
|
+
└── tools/ # Additional MCP servers / tool configs
|
|
35
|
+
├── mcp-servers.json # Additional MCP servers to mount per role
|
|
36
|
+
└── ...
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Interoperability
|
|
40
|
+
|
|
41
|
+
The manifest schema separates **generic multi-agent concepts** from **macro-agent specifics**:
|
|
42
|
+
|
|
43
|
+
```yaml
|
|
44
|
+
# Generic multi-agent fields (portable across systems)
|
|
45
|
+
name: self-driving
|
|
46
|
+
description: "Autonomous codebase development"
|
|
47
|
+
version: 1
|
|
48
|
+
roles: [...]
|
|
49
|
+
topology: { ... }
|
|
50
|
+
communication: { ... }
|
|
51
|
+
|
|
52
|
+
# macro-agent specific extensions (namespaced)
|
|
53
|
+
macro_agent:
|
|
54
|
+
integration:
|
|
55
|
+
strategy: trunk
|
|
56
|
+
config: { ... }
|
|
57
|
+
task_assignment:
|
|
58
|
+
mode: pull
|
|
59
|
+
pull: { ... }
|
|
60
|
+
lifecycle: { ... }
|
|
61
|
+
observability: { ... }
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The `topology`, `roles`, and `communication` sections are generic enough to describe any multi-agent team. The `macro_agent` section contains implementation-specific configuration that another system would ignore (or define its own equivalent).
|
|
65
|
+
|
|
66
|
+
Similarly, role definitions separate generic fields from extensions:
|
|
67
|
+
|
|
68
|
+
```yaml
|
|
69
|
+
# Generic
|
|
70
|
+
name: planner
|
|
71
|
+
extends: coordinator
|
|
72
|
+
description: "..."
|
|
73
|
+
capabilities: [...]
|
|
74
|
+
|
|
75
|
+
# macro-agent specific
|
|
76
|
+
macro_agent:
|
|
77
|
+
workspace: { ... }
|
|
78
|
+
lifecycle: { ... }
|
|
79
|
+
protocol: { ... }
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
This means the same team template directory could be consumed by different orchestrators — each reading the generic topology and applying their own runtime semantics.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Manifest: team.yaml
|
|
87
|
+
|
|
88
|
+
```yaml
|
|
89
|
+
name: self-driving
|
|
90
|
+
description: "Autonomous codebase development with continuous planning"
|
|
91
|
+
version: 1
|
|
92
|
+
|
|
93
|
+
# ─────────────────────────────────────────────────────────────
|
|
94
|
+
# Roles
|
|
95
|
+
# ─────────────────────────────────────────────────────────────
|
|
96
|
+
# References role files in roles/ directory or built-in roles.
|
|
97
|
+
roles:
|
|
98
|
+
- planner
|
|
99
|
+
- grinder
|
|
100
|
+
- judge
|
|
101
|
+
|
|
102
|
+
# ─────────────────────────────────────────────────────────────
|
|
103
|
+
# Topology
|
|
104
|
+
# ─────────────────────────────────────────────────────────────
|
|
105
|
+
# Defines the agent spawn graph.
|
|
106
|
+
topology:
|
|
107
|
+
# The initial agent spawned when the team starts
|
|
108
|
+
root:
|
|
109
|
+
role: planner
|
|
110
|
+
prompt: prompts/planner.md # Static prompt file
|
|
111
|
+
config:
|
|
112
|
+
model: sonnet
|
|
113
|
+
|
|
114
|
+
# Agents spawned alongside root (peers, not children)
|
|
115
|
+
companions:
|
|
116
|
+
- role: judge
|
|
117
|
+
prompt: prompts/judge.md
|
|
118
|
+
config:
|
|
119
|
+
model: haiku
|
|
120
|
+
|
|
121
|
+
# Which roles can spawn which other roles.
|
|
122
|
+
# Overrides the default capability-based spawn checks.
|
|
123
|
+
spawn_rules:
|
|
124
|
+
planner: [grinder, planner]
|
|
125
|
+
judge: []
|
|
126
|
+
grinder: []
|
|
127
|
+
|
|
128
|
+
# ─────────────────────────────────────────────────────────────
|
|
129
|
+
# Communication
|
|
130
|
+
# ─────────────────────────────────────────────────────────────
|
|
131
|
+
# Detailed below in the Communication Topology section.
|
|
132
|
+
communication:
|
|
133
|
+
channels:
|
|
134
|
+
task_updates:
|
|
135
|
+
description: "Task lifecycle events"
|
|
136
|
+
signals: [TASK_CREATED, TASK_COMPLETED, TASK_FAILED]
|
|
137
|
+
work_coordination:
|
|
138
|
+
description: "Work assignment and completion"
|
|
139
|
+
signals: [WORK_ASSIGNED, WORKER_DONE, MERGE_REQUEST]
|
|
140
|
+
health:
|
|
141
|
+
description: "System health monitoring"
|
|
142
|
+
signals: [HEALTH_CHECK, METRIC_SNAPSHOT, GREEN_SNAPSHOT]
|
|
143
|
+
|
|
144
|
+
subscriptions:
|
|
145
|
+
planner:
|
|
146
|
+
- channel: task_updates
|
|
147
|
+
- channel: work_coordination
|
|
148
|
+
signals: [WORKER_DONE]
|
|
149
|
+
- channel: health
|
|
150
|
+
signals: [METRIC_SNAPSHOT]
|
|
151
|
+
judge:
|
|
152
|
+
- channel: task_updates
|
|
153
|
+
signals: [TASK_FAILED]
|
|
154
|
+
- channel: work_coordination
|
|
155
|
+
signals: [WORKER_DONE]
|
|
156
|
+
- channel: health
|
|
157
|
+
grinder:
|
|
158
|
+
- channel: work_coordination
|
|
159
|
+
signals: [WORK_ASSIGNED]
|
|
160
|
+
|
|
161
|
+
emissions:
|
|
162
|
+
planner: [TASK_CREATED, WORK_ASSIGNED, PLANNING_COMPLETE]
|
|
163
|
+
judge: [HEALTH_CHECK, GREEN_SNAPSHOT, FIXUP_CREATED]
|
|
164
|
+
grinder: [WORKER_DONE]
|
|
165
|
+
|
|
166
|
+
# How roles communicate with each other (see Communication Topology section)
|
|
167
|
+
routing:
|
|
168
|
+
# Status flows upward by default (subtree subscriptions)
|
|
169
|
+
status: upstream
|
|
170
|
+
|
|
171
|
+
# Explicit peer connections (non-hierarchical)
|
|
172
|
+
peers:
|
|
173
|
+
- from: judge
|
|
174
|
+
to: planner
|
|
175
|
+
via: direct # Direct agent-to-agent messaging
|
|
176
|
+
signals: [FIXUP_CREATED, GREEN_SNAPSHOT]
|
|
177
|
+
- from: planner
|
|
178
|
+
to: judge
|
|
179
|
+
via: direct
|
|
180
|
+
signals: [CONVERGENCE_CHECK]
|
|
181
|
+
|
|
182
|
+
# ─────────────────────────────────────────────────────────────
|
|
183
|
+
# macro-agent specific extensions
|
|
184
|
+
# ─────────────────────────────────────────────────────────────
|
|
185
|
+
macro_agent:
|
|
186
|
+
task_assignment:
|
|
187
|
+
mode: pull
|
|
188
|
+
pull:
|
|
189
|
+
idle_timeout_s: 300
|
|
190
|
+
claim_retry_delay_ms: 2000
|
|
191
|
+
max_concurrent_per_agent: 1
|
|
192
|
+
|
|
193
|
+
integration:
|
|
194
|
+
strategy: trunk
|
|
195
|
+
config:
|
|
196
|
+
max_retries: 3
|
|
197
|
+
conflict_action: abandon
|
|
198
|
+
|
|
199
|
+
lifecycle:
|
|
200
|
+
continuations:
|
|
201
|
+
enabled: true
|
|
202
|
+
max_history_messages: 50
|
|
203
|
+
checkpoint_interval: round_trip
|
|
204
|
+
scaling:
|
|
205
|
+
min_workers: 3
|
|
206
|
+
max_workers: 20
|
|
207
|
+
scale_on: task_queue_depth
|
|
208
|
+
idle_drain: true
|
|
209
|
+
|
|
210
|
+
observability:
|
|
211
|
+
metrics_window_s: 3600
|
|
212
|
+
snapshot_interval_s: 300
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Communication Topology
|
|
218
|
+
|
|
219
|
+
This is the most architecturally significant part of the team template. The communication section declares *how agents talk to each other* — which is what distinguishes one team shape from another.
|
|
220
|
+
|
|
221
|
+
### The Problem Communication Topology Solves
|
|
222
|
+
|
|
223
|
+
macro-agent's MessageRouter is powerful but low-level. It supports seven channel types (`agent`, `task`, `lineage`, `subtree`, `topic`, `broadcast`, `role`) and MAP addresses (direct, scope, role, hierarchical, federated). An agent can technically send a message to anyone via any mechanism.
|
|
224
|
+
|
|
225
|
+
But a well-functioning team needs **structured communication** — not a free-for-all. The planner shouldn't be interrupted by every grinder's debug output. The judge shouldn't broadcast to workers directly. Workers shouldn't message each other about unrelated tasks.
|
|
226
|
+
|
|
227
|
+
The communication topology declares the **intended** communication patterns. The TeamRuntime translates these into the right subscriptions, address restrictions, and routing rules.
|
|
228
|
+
|
|
229
|
+
### Three Layers of Communication
|
|
230
|
+
|
|
231
|
+
macro-agent communication already operates at three layers. The team template configures each:
|
|
232
|
+
|
|
233
|
+
#### Layer 1: Status Flow (Automatic, Hierarchical)
|
|
234
|
+
|
|
235
|
+
Status events (`started`, `checkpoint`, `completed`, `failed`, `blocked`) flow automatically from children to parents via subtree subscriptions. This is already implemented — `setupDefaultSubscriptions` subscribes parents to children's subtree.
|
|
236
|
+
|
|
237
|
+
```yaml
|
|
238
|
+
communication:
|
|
239
|
+
routing:
|
|
240
|
+
status: upstream # Default: status flows up the spawn tree
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
In most teams, this is sufficient — a planner spawns grinders, and automatically receives their status updates. No additional configuration needed.
|
|
244
|
+
|
|
245
|
+
**But** the self-driving team has a non-hierarchical topology: the judge is a companion (peer of the planner), not a child. It still needs to see worker status. This is where explicit subscriptions come in.
|
|
246
|
+
|
|
247
|
+
#### Layer 2: Signal Channels (Topic-Based Pub/Sub)
|
|
248
|
+
|
|
249
|
+
Signals are named events that agents publish and subscribe to. They map directly to macro-agent's `topic` channel type and the existing `protocol.subscriptions` / `protocol.canEmit` in role definitions.
|
|
250
|
+
|
|
251
|
+
The team manifest groups signals into **named channels** for clarity:
|
|
252
|
+
|
|
253
|
+
```yaml
|
|
254
|
+
communication:
|
|
255
|
+
channels:
|
|
256
|
+
task_updates:
|
|
257
|
+
signals: [TASK_CREATED, TASK_COMPLETED, TASK_FAILED]
|
|
258
|
+
work_coordination:
|
|
259
|
+
signals: [WORK_ASSIGNED, WORKER_DONE, MERGE_REQUEST]
|
|
260
|
+
health:
|
|
261
|
+
signals: [HEALTH_CHECK, METRIC_SNAPSHOT, GREEN_SNAPSHOT]
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Each role subscribes to channels (or specific signals within a channel):
|
|
265
|
+
|
|
266
|
+
```yaml
|
|
267
|
+
subscriptions:
|
|
268
|
+
planner:
|
|
269
|
+
- channel: task_updates # All signals in channel
|
|
270
|
+
- channel: work_coordination
|
|
271
|
+
signals: [WORKER_DONE] # Specific signal only
|
|
272
|
+
- channel: health
|
|
273
|
+
signals: [METRIC_SNAPSHOT]
|
|
274
|
+
judge:
|
|
275
|
+
- channel: task_updates
|
|
276
|
+
signals: [TASK_FAILED] # Only failures
|
|
277
|
+
- channel: health # All health signals
|
|
278
|
+
grinder:
|
|
279
|
+
- channel: work_coordination
|
|
280
|
+
signals: [WORK_ASSIGNED]
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
And declares what it can emit:
|
|
284
|
+
|
|
285
|
+
```yaml
|
|
286
|
+
emissions:
|
|
287
|
+
planner: [TASK_CREATED, WORK_ASSIGNED]
|
|
288
|
+
judge: [HEALTH_CHECK, GREEN_SNAPSHOT, FIXUP_CREATED]
|
|
289
|
+
grinder: [WORKER_DONE]
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**How this maps to macro-agent primitives**:
|
|
293
|
+
|
|
294
|
+
When the TeamRuntime initializes, for each agent spawned with role `planner`:
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
// For each channel subscription:
|
|
298
|
+
// channel: task_updates → subscribe to topic "task_updates"
|
|
299
|
+
messageRouter.subscribe(agentId, { type: "topic", target: "task_updates" });
|
|
300
|
+
|
|
301
|
+
// For signal-filtered subscriptions, the filtering happens at read time:
|
|
302
|
+
// The agent receives all messages on the channel topic,
|
|
303
|
+
// but the signal filter is applied when getMessages() is called
|
|
304
|
+
// (or encoded in the subscription metadata for routing-level filtering)
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
When an agent emits a signal (e.g., `WORKER_DONE`), the emission is routed:
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
// emitStatus with signal details → routes to topic subscribers
|
|
311
|
+
messageRouter.emitStatus({
|
|
312
|
+
from: { agent_id: grinderId },
|
|
313
|
+
status_type: "completed",
|
|
314
|
+
summary: "Task done",
|
|
315
|
+
details: { signal: "WORKER_DONE", taskId, ... }
|
|
316
|
+
});
|
|
317
|
+
// This reaches all agents subscribed to the topic containing WORKER_DONE
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**The channel abstraction is purely organizational** — it groups related signals under a name for readability. Under the hood, each channel maps to a topic subscription. The signals within a channel can be used for filtering.
|
|
321
|
+
|
|
322
|
+
#### Layer 3: Direct Messaging (Peer-to-Peer)
|
|
323
|
+
|
|
324
|
+
Some communication doesn't fit the pub/sub model. The judge needs to tell the planner about a specific fixup. The planner needs to ask the judge to run an evaluation. These are directed, point-to-point messages.
|
|
325
|
+
|
|
326
|
+
```yaml
|
|
327
|
+
communication:
|
|
328
|
+
routing:
|
|
329
|
+
peers:
|
|
330
|
+
- from: judge
|
|
331
|
+
to: planner
|
|
332
|
+
via: direct
|
|
333
|
+
signals: [FIXUP_CREATED, GREEN_SNAPSHOT]
|
|
334
|
+
- from: planner
|
|
335
|
+
to: judge
|
|
336
|
+
via: direct
|
|
337
|
+
signals: [CONVERGENCE_CHECK]
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
**How this maps to macro-agent primitives**:
|
|
341
|
+
|
|
342
|
+
Peer connections use MAP's `role` addressing. When the judge sends `FIXUP_CREATED`:
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
// The judge sends to the planner role (resolved to specific agent IDs)
|
|
346
|
+
messageRouter.sendToAddress({
|
|
347
|
+
from: judgeAgentId,
|
|
348
|
+
to: { role: "planner" }, // RoleAddress — resolved to planner agent(s)
|
|
349
|
+
content: JSON.stringify({ signal: "FIXUP_CREATED", taskId, ... }),
|
|
350
|
+
options: { priority: "high" }
|
|
351
|
+
});
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
The `via: direct` means use MAP agent/role addressing (not topic pub/sub). The `via` field can be:
|
|
355
|
+
- `direct` — MAP `{ role: "target_role" }` or `{ agent: id }` addressing
|
|
356
|
+
- `topic` — publish to a shared topic (same as channel subscriptions)
|
|
357
|
+
- `scope` — MAP `{ scope: "scope_name" }` addressing (explicit scope membership)
|
|
358
|
+
|
|
359
|
+
**Why this matters for the self-driving team**: The judge and planner are peers (not parent-child). Without explicit peer routing, the judge has no way to reach the planner. The peer connection declares this path and the TeamRuntime sets up the necessary subscriptions/address resolution.
|
|
360
|
+
|
|
361
|
+
### Communication Topology Enforcement
|
|
362
|
+
|
|
363
|
+
The team template doesn't just *suggest* communication patterns — it can *enforce* them. The `emissions` field restricts what signals a role can emit (maps to `protocol.canEmit` in the role definition). If a grinder tries to emit `HEALTH_CHECK`, it's blocked.
|
|
364
|
+
|
|
365
|
+
```yaml
|
|
366
|
+
emissions:
|
|
367
|
+
grinder: [WORKER_DONE] # Grinders can ONLY emit WORKER_DONE
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
Similarly, the `subscriptions` field restricts what a role receives. The combination of emission restrictions + subscription filters means agents can only communicate through declared paths.
|
|
371
|
+
|
|
372
|
+
**Enforcement levels** (configured per team):
|
|
373
|
+
|
|
374
|
+
```yaml
|
|
375
|
+
communication:
|
|
376
|
+
enforcement: strict # strict | permissive | audit
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
- `strict` — Agents can only emit declared signals, only receive subscribed channels. Violations are blocked.
|
|
380
|
+
- `permissive` — All communication allowed, but undeclared patterns are logged as warnings.
|
|
381
|
+
- `audit` — All communication allowed, undeclared patterns recorded for analysis.
|
|
382
|
+
|
|
383
|
+
Default is `permissive` — teams work without declaring every signal, but you get visibility into undeclared communication for iterative refinement.
|
|
384
|
+
|
|
385
|
+
### Addressing Summary
|
|
386
|
+
|
|
387
|
+
How team template communication concepts map to macro-agent's existing addressing:
|
|
388
|
+
|
|
389
|
+
| Team Concept | MAP Address Type | Channel Type | Notes |
|
|
390
|
+
|---|---|---|---|
|
|
391
|
+
| Status flow (upstream) | Automatic via subtree | `subtree` | Already implemented by `setupDefaultSubscriptions` |
|
|
392
|
+
| Channel subscription | `{ scope: "channel_name" }` | `topic` | Agent subscribes to topic matching channel name |
|
|
393
|
+
| Signal emission | `emitStatus()` with signal details | `topic` routing | Details carry signal name for filtering |
|
|
394
|
+
| Peer direct message | `{ role: "target_role" }` | `role` | Resolved to agent IDs at send time |
|
|
395
|
+
| Broadcast to role | `{ role: "grinder" }` | `role` | Fan-out to all agents with that role |
|
|
396
|
+
| Hierarchical (parent) | `{ parent: true }` | `lineage` | Resolved relative to sender |
|
|
397
|
+
| Hierarchical (children) | `{ children: true }` | `subtree` | Resolved relative to sender |
|
|
398
|
+
| Broadcast to all | `{ broadcast: true }` | `broadcast` | All active agents |
|
|
399
|
+
|
|
400
|
+
### Example: Communication Flow in Self-Driving Team
|
|
401
|
+
|
|
402
|
+
```
|
|
403
|
+
Planner Judge Grinder (x N)
|
|
404
|
+
│ │ │
|
|
405
|
+
│ ── TASK_CREATED ──────▷ │ (via task_updates topic) │
|
|
406
|
+
│ │ │
|
|
407
|
+
│ ── WORK_ASSIGNED ─────────────────────────────────▷ │ (via work_coordination topic)
|
|
408
|
+
│ │ │
|
|
409
|
+
│ │ ◁── WORKER_DONE ── │
|
|
410
|
+
│ ◁── WORKER_DONE ──────────────────│ (both subscribed)
|
|
411
|
+
│ │ │
|
|
412
|
+
│ │── FIXUP_CREATED ──▷│ │ (peer direct)
|
|
413
|
+
│ ◁── FIXUP_CREATED ─────│ │
|
|
414
|
+
│ │ │
|
|
415
|
+
│ ── CONVERGENCE_CHECK ──▷│ │ (peer direct)
|
|
416
|
+
│ │ │
|
|
417
|
+
│ │── GREEN_SNAPSHOT ──▷ (health topic)
|
|
418
|
+
│ ◁── GREEN_SNAPSHOT ─────│ (planner subscribes to health.METRIC_SNAPSHOT)
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
Key observations:
|
|
422
|
+
- Grinders emit WORKER_DONE to the `work_coordination` topic — both planner and judge receive it
|
|
423
|
+
- Judge sends FIXUP_CREATED directly to planner via role addressing (peer connection)
|
|
424
|
+
- Planner sends CONVERGENCE_CHECK directly to judge (peer connection)
|
|
425
|
+
- Status flows upstream automatically (grinder → planner via subtree subscription)
|
|
426
|
+
- Judge receives TASK_FAILED from `task_updates` topic but ignores TASK_CREATED
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## Role Definitions
|
|
431
|
+
|
|
432
|
+
Roles in a team template extend macro-agent's `RoleDefinition`. The generic fields are portable; macro-agent specifics live under `macro_agent:`.
|
|
433
|
+
|
|
434
|
+
```yaml
|
|
435
|
+
# roles/planner.yaml
|
|
436
|
+
name: planner
|
|
437
|
+
extends: coordinator
|
|
438
|
+
display_name: "Planner"
|
|
439
|
+
description: "Continuously explores codebase and creates tasks"
|
|
440
|
+
|
|
441
|
+
# Capability composition (generic)
|
|
442
|
+
capabilities:
|
|
443
|
+
add:
|
|
444
|
+
- task.create
|
|
445
|
+
- task.update
|
|
446
|
+
- task.close
|
|
447
|
+
- task.claim
|
|
448
|
+
remove:
|
|
449
|
+
- agent.spawn.integrator
|
|
450
|
+
- agent.spawn.monitor
|
|
451
|
+
|
|
452
|
+
# Prompt (static file, no template rendering)
|
|
453
|
+
prompt: prompts/planner.md
|
|
454
|
+
|
|
455
|
+
# macro-agent specific enforcement
|
|
456
|
+
macro_agent:
|
|
457
|
+
workspace:
|
|
458
|
+
type: own
|
|
459
|
+
branch_pattern: "planner/{agent-id}"
|
|
460
|
+
cleanup_on_terminate: true
|
|
461
|
+
lifecycle:
|
|
462
|
+
type: daemon
|
|
463
|
+
cascade_terminate: true
|
|
464
|
+
self_cleanup: true
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Capability Composition
|
|
468
|
+
|
|
469
|
+
Roles can compose capabilities in two ways:
|
|
470
|
+
|
|
471
|
+
**1. Full replacement**:
|
|
472
|
+
```yaml
|
|
473
|
+
capabilities:
|
|
474
|
+
- file.read
|
|
475
|
+
- file.write
|
|
476
|
+
- task.create
|
|
477
|
+
- lifecycle.done
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
**2. Additive/subtractive** (relative to parent via `extends`):
|
|
481
|
+
```yaml
|
|
482
|
+
extends: worker
|
|
483
|
+
capabilities:
|
|
484
|
+
add:
|
|
485
|
+
- task.claim
|
|
486
|
+
- git.push
|
|
487
|
+
remove:
|
|
488
|
+
- agent.spawn.worker
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
The final capability set is: `(parent_capabilities + added) - removed`
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
## Prompts
|
|
496
|
+
|
|
497
|
+
Prompts are **static markdown files** in `prompts/`. No template rendering — they are included as-is in the system prompt.
|
|
498
|
+
|
|
499
|
+
The system prompt assembler combines prompts from multiple sources:
|
|
500
|
+
|
|
501
|
+
```
|
|
502
|
+
1. Base sections (identity, agent ID, task, lineage) ← system-prompt.ts (always)
|
|
503
|
+
2. Role prompt (prompts/<role>.md) ← team template (if provided)
|
|
504
|
+
OR role.systemPrompt field ← role definition fallback
|
|
505
|
+
OR generated role guidance ← system-prompt.ts default
|
|
506
|
+
3. Interaction pattern guidance ← derived from macro_agent config
|
|
507
|
+
4. Tool listing ← filtered by capabilities
|
|
508
|
+
5. Communication guidelines ← system-prompt.ts (always)
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
The role prompt file is the only part the team template author writes. It's static and self-contained — it describes what the role does, how it should think, what conventions to follow. The system injects the dynamic context (agent ID, task, available tools, interaction mode) around it.
|
|
512
|
+
|
|
513
|
+
### Interaction Pattern Injection
|
|
514
|
+
|
|
515
|
+
When `macro_agent.task_assignment.mode: pull` is set, the assembler injects a small operational section after the role prompt:
|
|
516
|
+
|
|
517
|
+
```
|
|
518
|
+
## Task Claiming
|
|
519
|
+
|
|
520
|
+
You operate in PULL mode. After completing a task:
|
|
521
|
+
1. Call done() with your results
|
|
522
|
+
2. Call claim_task() to get your next task
|
|
523
|
+
3. If no tasks available, wait briefly and retry
|
|
524
|
+
4. After extended idle, call done() to exit gracefully
|
|
525
|
+
|
|
526
|
+
Claim and execute independently — do not wait for instructions.
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
Similarly for trunk integration, session continuations, etc. These injected sections are small and operational. They don't overlap with the role prompt (which is about domain expertise and strategy).
|
|
530
|
+
|
|
531
|
+
---
|
|
532
|
+
|
|
533
|
+
## Tools and MCP Servers
|
|
534
|
+
|
|
535
|
+
For tools beyond macro-agent's built-in MCP tools, the team template can declare additional MCP servers to mount per role. This uses Claude Code's native MCP server configuration format.
|
|
536
|
+
|
|
537
|
+
```json
|
|
538
|
+
// tools/mcp-servers.json
|
|
539
|
+
{
|
|
540
|
+
"planner": {
|
|
541
|
+
"servers": [
|
|
542
|
+
{
|
|
543
|
+
"name": "project-knowledge",
|
|
544
|
+
"command": "npx",
|
|
545
|
+
"args": ["@org/project-knowledge-mcp"],
|
|
546
|
+
"env": {
|
|
547
|
+
"PROJECT_ROOT": "${MACRO_AGENT_CWD}"
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
]
|
|
551
|
+
},
|
|
552
|
+
"judge": {
|
|
553
|
+
"servers": [
|
|
554
|
+
{
|
|
555
|
+
"name": "ci-status",
|
|
556
|
+
"command": "npx",
|
|
557
|
+
"args": ["@org/ci-status-mcp"],
|
|
558
|
+
"env": {
|
|
559
|
+
"CI_TOKEN": "${CI_TOKEN}"
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
]
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
This is already supported by `AgentSpawnConfig.config.mcpServers` — the TeamRuntime just passes these through when spawning agents of that role.
|
|
568
|
+
|
|
569
|
+
Future iterations may support Claude Code's native skill/slash-command system for defining reusable tool+prompt bundles per role. For now, additional capabilities are expressed as MCP servers.
|
|
570
|
+
|
|
571
|
+
---
|
|
572
|
+
|
|
573
|
+
## Team Loading and Runtime
|
|
574
|
+
|
|
575
|
+
### TeamLoader
|
|
576
|
+
|
|
577
|
+
Reads and validates the template directory:
|
|
578
|
+
|
|
579
|
+
```
|
|
580
|
+
TeamLoader.load(teamName, basePath?)
|
|
581
|
+
1. Resolve: .macro-agent/teams/<teamName>/
|
|
582
|
+
2. Parse team.yaml, validate schema
|
|
583
|
+
3. For each role in manifest:
|
|
584
|
+
a. Load roles/<role>.yaml if present
|
|
585
|
+
b. Resolve extends chain against RoleRegistry
|
|
586
|
+
c. Compute final capabilities (parent + add - remove)
|
|
587
|
+
d. Validate enforcement sections
|
|
588
|
+
4. Load prompt files from prompts/
|
|
589
|
+
5. Load tools/mcp-servers.json if present
|
|
590
|
+
6. Return TeamManifest (fully resolved)
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
### TeamRuntime
|
|
594
|
+
|
|
595
|
+
Wires the loaded template into the running system:
|
|
596
|
+
|
|
597
|
+
```
|
|
598
|
+
TeamRuntime.initialize(manifest, services)
|
|
599
|
+
1. Register roles into RoleRegistry (team layer)
|
|
600
|
+
2. Set up communication topology:
|
|
601
|
+
a. Register named channels as topics
|
|
602
|
+
b. Configure per-role subscription templates
|
|
603
|
+
(applied when agents of that role are spawned)
|
|
604
|
+
c. Set up peer routing rules
|
|
605
|
+
d. Configure enforcement level
|
|
606
|
+
3. Compose system prompts:
|
|
607
|
+
a. Load static prompt files
|
|
608
|
+
b. Prepare interaction pattern injection sections
|
|
609
|
+
4. Select IntegrationStrategy from registry
|
|
610
|
+
5. Configure TaskBackend mode (push/pull)
|
|
611
|
+
6. Store active team state for context propagation
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
### Agent Spawn with Team Context
|
|
615
|
+
|
|
616
|
+
When an agent is spawned within a team, the TeamRuntime intercepts the spawn and applies team configuration:
|
|
617
|
+
|
|
618
|
+
```
|
|
619
|
+
TeamRuntime.onAgentSpawn(role, spawnOptions)
|
|
620
|
+
1. Look up role in team manifest
|
|
621
|
+
2. Apply communication topology:
|
|
622
|
+
a. Add topic subscriptions from manifest channels
|
|
623
|
+
b. Register peer routes (if this role has peer connections)
|
|
624
|
+
c. Subscribe to role channel (for role-addressed messages)
|
|
625
|
+
3. Assemble system prompt:
|
|
626
|
+
a. Base sections (identity, task)
|
|
627
|
+
b. Role prompt file (static)
|
|
628
|
+
c. Interaction pattern sections (auto-injected)
|
|
629
|
+
d. Tool listing (capability-filtered)
|
|
630
|
+
e. Communication guidelines
|
|
631
|
+
4. Add MCP servers from tools/mcp-servers.json (if any for this role)
|
|
632
|
+
5. Set team environment variables:
|
|
633
|
+
MACRO_TEAM_NAME, MACRO_INTEGRATION_STRATEGY, MACRO_TASK_MODE
|
|
634
|
+
6. Return enriched spawn options
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
### Team Bootstrap
|
|
638
|
+
|
|
639
|
+
After initialization, spawns the starting agents:
|
|
640
|
+
|
|
641
|
+
```
|
|
642
|
+
TeamRuntime.bootstrap()
|
|
643
|
+
1. Spawn root agent per topology.root
|
|
644
|
+
2. Spawn each companion per topology.companions
|
|
645
|
+
3. Emit TEAM_STARTED event
|
|
646
|
+
4. If scaling.min_workers > 0:
|
|
647
|
+
Spawn initial worker pool
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
---
|
|
651
|
+
|
|
652
|
+
## Example: Self-Driving Team
|
|
653
|
+
|
|
654
|
+
### roles/planner.yaml
|
|
655
|
+
|
|
656
|
+
```yaml
|
|
657
|
+
name: planner
|
|
658
|
+
extends: coordinator
|
|
659
|
+
display_name: "Planner"
|
|
660
|
+
description: "Continuously explores the codebase, creates and prioritizes tasks"
|
|
661
|
+
|
|
662
|
+
capabilities:
|
|
663
|
+
add: [task.claim]
|
|
664
|
+
remove: [agent.spawn.integrator, agent.spawn.monitor]
|
|
665
|
+
|
|
666
|
+
prompt: prompts/planner.md
|
|
667
|
+
|
|
668
|
+
macro_agent:
|
|
669
|
+
lifecycle:
|
|
670
|
+
type: daemon
|
|
671
|
+
cascade_terminate: true
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
### roles/grinder.yaml
|
|
675
|
+
|
|
676
|
+
```yaml
|
|
677
|
+
name: grinder
|
|
678
|
+
extends: worker
|
|
679
|
+
display_name: "Grinder"
|
|
680
|
+
description: "Claims and executes tasks autonomously"
|
|
681
|
+
|
|
682
|
+
capabilities:
|
|
683
|
+
add: [task.claim, git.push]
|
|
684
|
+
|
|
685
|
+
prompt: prompts/grinder.md
|
|
686
|
+
|
|
687
|
+
macro_agent:
|
|
688
|
+
lifecycle:
|
|
689
|
+
type: ephemeral
|
|
690
|
+
task_bound: false
|
|
691
|
+
max_duration_ms: 3600000
|
|
692
|
+
self_cleanup: true
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
### roles/judge.yaml
|
|
696
|
+
|
|
697
|
+
```yaml
|
|
698
|
+
name: judge
|
|
699
|
+
extends: monitor
|
|
700
|
+
display_name: "Judge"
|
|
701
|
+
description: "Periodically evaluates codebase health and creates fixup tasks"
|
|
702
|
+
|
|
703
|
+
capabilities:
|
|
704
|
+
add: [exec.build, exec.test, exec.lint, task.create, task.update, git.branch.create, git.push]
|
|
705
|
+
|
|
706
|
+
prompt: prompts/judge.md
|
|
707
|
+
|
|
708
|
+
macro_agent:
|
|
709
|
+
workspace:
|
|
710
|
+
type: own
|
|
711
|
+
branch_pattern: "judge/{agent-id}"
|
|
712
|
+
cleanup_on_terminate: true
|
|
713
|
+
lifecycle:
|
|
714
|
+
type: event-driven
|
|
715
|
+
parent_bound: false
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
### prompts/planner.md
|
|
719
|
+
|
|
720
|
+
```markdown
|
|
721
|
+
# Planner
|
|
722
|
+
|
|
723
|
+
You are the Planner. Your job is to continuously explore the codebase,
|
|
724
|
+
understand the current state, and create well-defined tasks for workers.
|
|
725
|
+
|
|
726
|
+
## How You Work
|
|
727
|
+
|
|
728
|
+
1. **Explore**: Read the codebase to understand architecture, patterns, and gaps
|
|
729
|
+
2. **Plan**: Break the objective into independent, parallelizable tasks
|
|
730
|
+
3. **Create**: Use create_task to add tasks to the pool with clear descriptions and tags
|
|
731
|
+
4. **Monitor**: Watch for completed/failed tasks and adjust the plan
|
|
732
|
+
5. **Repeat**: Planning is continuous — as work completes, create the next batch
|
|
733
|
+
|
|
734
|
+
## Planning Guidelines
|
|
735
|
+
|
|
736
|
+
- Each task should be completable in 5-30 minutes by a single worker
|
|
737
|
+
- Tag tasks with subsystem and type for filtered claiming
|
|
738
|
+
- Set dependencies (blockers) when ordering matters
|
|
739
|
+
- Prefer many small tasks over few large ones — parallelism is the goal
|
|
740
|
+
- Include enough context for a worker to start without re-exploring
|
|
741
|
+
|
|
742
|
+
## Constraints
|
|
743
|
+
|
|
744
|
+
- Do NOT instruct on things the model already knows (coding, testing, etc.)
|
|
745
|
+
- DO specify things specific to this codebase (conventions, build system, deploy pipeline)
|
|
746
|
+
- Constraints are more effective than instructions: "No TODOs, no partial implementations"
|
|
747
|
+
|
|
748
|
+
## Sub-Planners
|
|
749
|
+
|
|
750
|
+
For large subsystems (>10 tasks), spawn a sub-planner:
|
|
751
|
+
- spawn_agent({ role: "planner", task: "Plan the [subsystem] changes" })
|
|
752
|
+
- Sub-planners create tasks in the shared pool
|
|
753
|
+
- You maintain the high-level view
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
### prompts/judge.md
|
|
757
|
+
|
|
758
|
+
```markdown
|
|
759
|
+
# Judge
|
|
760
|
+
|
|
761
|
+
You periodically evaluate the health of the codebase and take corrective action.
|
|
762
|
+
|
|
763
|
+
## Evaluation Cycle
|
|
764
|
+
|
|
765
|
+
Every time you activate:
|
|
766
|
+
1. Run the build — check compilation
|
|
767
|
+
2. Run the test suite — check correctness
|
|
768
|
+
3. Run the linter — check code quality
|
|
769
|
+
4. If all pass: snapshot to green branch, emit GREEN_SNAPSHOT
|
|
770
|
+
5. If any fail: create fixup tasks with tag "fixup" and priority "critical"
|
|
771
|
+
|
|
772
|
+
## Green Branch
|
|
773
|
+
|
|
774
|
+
Maintain a clean snapshot at `green/latest`:
|
|
775
|
+
- Only update when build + tests + lint all pass
|
|
776
|
+
- This is the team's release candidate at any point in time
|
|
777
|
+
- Workers may be on a broken trunk — that's expected
|
|
778
|
+
|
|
779
|
+
## Creating Fixup Tasks
|
|
780
|
+
|
|
781
|
+
When you find failures:
|
|
782
|
+
- Create one task per distinct issue (don't bundle)
|
|
783
|
+
- Include the exact error output in the task description
|
|
784
|
+
- Tag with: ["fixup", "<subsystem>"]
|
|
785
|
+
- Set priority: critical
|
|
786
|
+
- Reference the failing file and test
|
|
787
|
+
```
|
|
788
|
+
|
|
789
|
+
---
|
|
790
|
+
|
|
791
|
+
## Example: Structured Team (Backward Compatibility)
|
|
792
|
+
|
|
793
|
+
The existing coordinator/integrator/worker pattern expressed as a team template:
|
|
794
|
+
|
|
795
|
+
```yaml
|
|
796
|
+
name: structured
|
|
797
|
+
description: "Traditional structured development"
|
|
798
|
+
version: 1
|
|
799
|
+
|
|
800
|
+
roles:
|
|
801
|
+
- coordinator
|
|
802
|
+
- integrator
|
|
803
|
+
- worker
|
|
804
|
+
- monitor
|
|
805
|
+
|
|
806
|
+
topology:
|
|
807
|
+
root:
|
|
808
|
+
role: coordinator
|
|
809
|
+
spawn_rules:
|
|
810
|
+
coordinator: [worker, integrator, monitor]
|
|
811
|
+
integrator: [worker]
|
|
812
|
+
worker: []
|
|
813
|
+
monitor: []
|
|
814
|
+
|
|
815
|
+
communication:
|
|
816
|
+
channels:
|
|
817
|
+
work:
|
|
818
|
+
signals: [WORK_ASSIGNED, WORKER_DONE, MERGE_REQUEST, MERGE_COMPLETE]
|
|
819
|
+
health:
|
|
820
|
+
signals: [HEALTH_CHECK, STALE_AGENT]
|
|
821
|
+
subscriptions:
|
|
822
|
+
coordinator:
|
|
823
|
+
- channel: work
|
|
824
|
+
- channel: health
|
|
825
|
+
integrator:
|
|
826
|
+
- channel: work
|
|
827
|
+
signals: [MERGE_REQUEST, WORKER_DONE]
|
|
828
|
+
worker:
|
|
829
|
+
- channel: work
|
|
830
|
+
signals: [WORK_ASSIGNED]
|
|
831
|
+
monitor:
|
|
832
|
+
- channel: health
|
|
833
|
+
|
|
834
|
+
macro_agent:
|
|
835
|
+
task_assignment:
|
|
836
|
+
mode: push
|
|
837
|
+
integration:
|
|
838
|
+
strategy: queue
|
|
839
|
+
lifecycle:
|
|
840
|
+
continuations:
|
|
841
|
+
enabled: false
|
|
842
|
+
scaling:
|
|
843
|
+
scale_on: manual
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
No custom roles, no custom prompts — just built-in roles wired together. This demonstrates that team templates are a superset of the existing behavior.
|
|
847
|
+
|
|
848
|
+
---
|
|
849
|
+
|
|
850
|
+
## Open Questions
|
|
851
|
+
|
|
852
|
+
1. **Channel-level vs signal-level subscription granularity** — Is subscribing to a channel with signal filters the right granularity? Or should every signal be an independent topic? Channel grouping is cleaner for authoring but requires filtering at receive time. Signal-per-topic is cleaner at the routing layer but verbose in the manifest.
|
|
853
|
+
|
|
854
|
+
2. **Enforcement of emissions** — Should emission enforcement be at the routing layer (block the emit) or the audit layer (log but allow)? Strict enforcement could break agents that need to emit undeclared signals during error handling. Starting with `permissive` default and letting teams opt into `strict` seems right.
|
|
855
|
+
|
|
856
|
+
3. **Peer discovery for companions** — Companions are spawned as peers (no parent-child relationship). How do they discover each other? Options: (a) both subscribe to a shared team scope, (b) the bootstrap process shares agent IDs via environment variables, (c) role-based addressing (`{ role: "judge" }`) resolves to companion agents. Option (c) is cleanest — it's already supported by the router.
|
|
857
|
+
|
|
858
|
+
4. **Cross-team communication** — If multiple teams run simultaneously (e.g., a "frontend" team and a "backend" team), can they communicate? This maps to MAP's federated addressing but needs team-scoped routing rules. Deferred — single-team focus for now.
|
|
859
|
+
|
|
860
|
+
5. **Skill system evolution** — The current design uses static prompts + MCP servers for tool configuration. A future iteration could adopt Claude Code's native skill system (slash commands, tool bundles) for more structured reusable behaviors. The prompt file slot in role definitions is designed to be replaceable by a richer skill reference.
|