Standalone multi-agent Discord workflow runtime for backlog-first project execution.
teams_runtime is a self-contained Python package that runs a fixed team of Discord-connected roles against a project workspace. It handles request intake, planner-owned backlog management, autonomous sprint execution, role session management, relay transport, and git-backed closeout without depending on repo-local libs.* modules.
- 6 fixed public roles:
orchestrator,planner,designer,architect,developer,qa - 3 internal runtime agents:
parser,sourcer,version_controller - orchestrator-first request intake over Discord DMs and mentions
- backlog-first routing instead of immediate freeform execution
- autonomous or manual sprint lifecycle
- a fixed execution chain for sprint work:
planner -> architect guidance -> developer -> architect review -> qa -> version_controller - workspace scaffolding for role folders, shared docs, and runtime state
- runtime-selectable relay transport:
internalby default,discordfor relay-channel debugging - persisted machine-readable state under
.teams_runtime/ - human-readable planning and sprint artifacts under
shared_workspace/
Normal user requests do not go straight to implementation.
- The
orchestratorreceives the Discord message first. - Planning and backlog decisions go to
planner. - Planner persists backlog changes directly.
- The scheduler or operator starts a sprint from actionable backlog.
- Sprint todos run through the orchestrator-governed workflow contract.
version_controllerhandles task closeout and commit reporting.
Planning and implementation are intentionally separated. Planner-owned surfaces such as shared_workspace/backlog.md, completed_backlog.md, and current_sprint.md stay under planning ownership; execution roles do not redefine those files as implementation output.
- Python 3.10+
gitonPATHcodexCLI onPATH- Discord bot tokens for the configured roles
The Discord client also loads the nearest .env file automatically, so tokens may be exported in the shell or stored in a local .env.
Install the package dependencies:
pip install -r requirements.txtCommands below assume teams_runtime is importable, either because you are running from the parent directory that contains this package or because that parent directory is on PYTHONPATH.
python -m teams_runtime initWorkspace resolution is computed as:
- current directory if it already contains both
team_runtime.yamlanddiscord_agents_config.yaml ./teams_generated./workspace/teams_generated
init uses <workspace-root> as the resolved target and writes generated runtime content there. If the target already exists, it preserves:
discord_agents_config.yaml- archived sprint history under
shared_workspace/sprint_history/
Edit <workspace-root>/discord_agents_config.yaml and replace every scaffold placeholder snowflake before starting listeners.
Minimal example:
relay_channel_id: "123456789012345678"
startup_channel_id: "123456789012345679"
report_channel_id: "123456789012345680"
agents:
orchestrator:
name: "Orchestrator"
role: "orchestrator"
description: "Owns request routing"
token_env: "AGENT_DISCORD_TOKEN_ORCHESTRATOR"
bot_id: "123456789012345681"
planner:
name: "Planner"
role: "planner"
description: "Planning role"
token_env: "AGENT_DISCORD_TOKEN_PLANNER"
bot_id: "123456789012345682"
designer:
name: "Designer"
role: "designer"
description: "UX and message advisory role"
token_env: "AGENT_DISCORD_TOKEN_DESIGNER"
bot_id: "123456789012345683"
architect:
name: "Architect"
role: "architect"
description: "Architecture and code review role"
token_env: "AGENT_DISCORD_TOKEN_ARCHITECT"
bot_id: "123456789012345684"
developer:
name: "Developer"
role: "developer"
description: "Implementation role"
token_env: "AGENT_DISCORD_TOKEN_DEVELOPER"
bot_id: "123456789012345685"
qa:
name: "QA"
role: "qa"
description: "Validation role"
token_env: "AGENT_DISCORD_TOKEN_QA"
bot_id: "123456789012345686"
internal_agents:
sourcer:
name: "CS_ADMIN"
role: "sourcer"
description: "Internal backlog sourcing reporter"
token_env: "AGENT_DISCORD_TOKEN_CS_ADMIN"
bot_id: "123456789012345687"Notes:
relay_channel_idis requiredstartup_channel_iddefaults torelay_channel_idif omittedreport_channel_iddefaults tostartup_channel_idif omitted- every public role requires
name,role,description,token_env, andbot_id internal_agentsis optional; the scaffold includessourcerby default
Edit <workspace-root>/team_runtime.yaml.
The only required field is:
sprint:
id: "2026-Sprint-03"A practical starter config looks like:
sprint:
id: "2026-Sprint-03"
interval_minutes: 180
timezone: "Asia/Seoul"
mode: "hybrid"
start_mode: "auto"
cutoff_time: "22:00"
overlap_policy: "no_overlap"
ingress_mode: "backlog_first"
discovery_scope: "broad_scan"
discovery_actions: []
ingress:
dm: true
mentions: true
allowed_guild_ids: []
role_defaults:
planner:
model: "gpt-5.4"
reasoning: "xhigh"
developer:
model: "gpt-5.3-codex-spark"
reasoning: "xhigh"
actions: {}actions: {} is valid. In that mode, orchestration still works, but user execute requests remain disabled.
You can also update role defaults through the CLI:
python -m teams_runtime config role set --agent developer --model gpt-5.4 --reasoning highexport AGENT_DISCORD_TOKEN_ORCHESTRATOR=...
export AGENT_DISCORD_TOKEN_PLANNER=...
export AGENT_DISCORD_TOKEN_DESIGNER=...
export AGENT_DISCORD_TOKEN_ARCHITECT=...
export AGENT_DISCORD_TOKEN_DEVELOPER=...
export AGENT_DISCORD_TOKEN_QA=...
export AGENT_DISCORD_TOKEN_CS_ADMIN=...# default relay transport: internal (relay summary + persisted envelope)
python -m teams_runtime start
# internal relay persists full envelope at:
# <workspace-root>/.teams_runtime/internal_relay/inbox/<role>/<relay_id>.json
# then moves processed relays to:
# <workspace-root>/.teams_runtime/internal_relay/archive/<role>/<relay_id>.json
# and posts a compact summary to relay channel
# internal mode includes summary posts to relay channel while persisting full payload in files
# debug relay transport: Discord relay-channel envelopes
python -m teams_runtime start --relay-transport discordForeground mode is also available:
# internal relay default
python -m teams_runtime run
# explicit envelopes for debugging
python -m teams_runtime run --relay-transport discordpython -m teams_runtime status
python -m teams_runtime status --backlog
python -m teams_runtime sprint status
python -m teams_runtime listpython -m teams_runtime sprint start --milestone "Login workflow cleanup"
python -m teams_runtime sprint start --milestone "Login workflow cleanup" --brief "Preserve current relay flow" --requirement "Keep kickoff docs as source of truth"
python -m teams_runtime sprint stop
python -m teams_runtime sprint restartDM or mention the orchestrator bot with a request such as:
intent: plan
scope: Draft the login workflow and define backlog items
User-originated requests are orchestrator-first. Messaging another role directly still routes through the orchestrator as the runtime governor.
python -m teams_runtime init
python -m teams_runtime start
python -m teams_runtime stop
python -m teams_runtime restart
python -m teams_runtime status
python -m teams_runtime status --request-id 20260323-abcd1234
python -m teams_runtime start --agent orchestrator
python -m teams_runtime status --agent developer
python -m teams_runtime config role set --agent planner --model gpt-5.4 --reasoning medium
python -m teams_runtime sprint statusGenerated workspace (resolved <workspace-root>):
<workspace-root>/
├── discord_agents_config.yaml
├── team_runtime.yaml
├── communication_protocol.md
├── file_contracts.md
├── COMMIT_POLICY.md
├── orchestrator/
├── planner/
├── designer/
├── architect/
├── developer/
├── qa/
├── internal/
└── shared_workspace/
internal/ below is a container for generated internal workspaces:
internal/parser, internal/sourcer, internal/version_controller.
(discord_agents_config.yaml의 internal_agents.sourcer는 Discord presence/reporting 설정 샘플이며,
internal/ 하위 동시 생성되는 작업공간 구성을 의미하지 않습니다.)
Role-session workspace (seeded per runtime session):
workspace/ # symlink to project root
shared_workspace/ # runtime-owned symlink to shared space
.teams_runtime/ # runtime-owned symlink for state and receipts
communication_protocol.md # seeded runtime context
file_contracts.md # seeded runtime context
COMMIT_POLICY.md # seeded runtime context
workspace_context.md # seeded runtime context
각 role 디렉터리(orchestrator, planner, designer, architect, developer, qa)에는
세션 생성 시 기본 코디네이션 파일이 존재하며, 공통으로 AGENTS.md, todo.md, history.md,
journal.md, sources/가 남습니다.
Runtime state and generated artifacts are written under:
.teams_runtime/backlog/.teams_runtime/requests/.teams_runtime/sprints/.teams_runtime/role_sessions/.teams_runtime/internal_relay/inbox/<role>/.teams_runtime/internal_relay/archive/<role>/(processed relay archive)logs/agents/logs/discord/logs/operations/shared_workspace/backlog.mdshared_workspace/completed_backlog.mdshared_workspace/current_sprint.mdshared_workspace/sprints/<sprint_folder_name>/shared_workspace/sprint_history/
Package docs stay under docs/ and are not copied into runtime-generated workspaces.
teams_runtime supports two relay modes between roles:
internalpersisted in-runtime handoff with full envelope persistence at<workspace-root>/.teams_runtime/internal_relay/inbox/<role>/<relay_id>.json, then moves processed envelopes to<workspace-root>/.teams_runtime/internal_relay/archive/<role>/<relay_id>.json, and posts a relay summary text in relay channeldiscordexplicit relay-channel envelopes with target mentions for debugging and replay inspection
Select the mode with --relay-transport on run, start, or restart.
Run the test suite with:
python -m unittest discover -s testsUser guides:
Maintainer/reference docs:
- Placeholder Discord IDs in the scaffold are rejected at runtime unless a test-only override is enabled.
- Planner is the only role that persists planner-owned backlog changes (canonical payload:
backlog_items/backlog_item). - Planner persists canonical payload (
backlog_items/backlog_item) andproposals.backlog_writesreceipts. Orchestrator validates persisted payload/receipts and runtime state; it does not re-persist planner proposals. planned_backlog_updatesis compatibility alias for transition compatibility, not a new planning contract.start,run,restartare command-line transport targets for--relay-transport; other commands keep defaults.- Sprint start cannot continue with zero actionable sprint backlog; the runtime blocks with
planning_incompleteinstead. status --sprintstill works as a compatibility alias forsprint status.