metawsm orchestrates agent work across multiple tickets and workspaces by composing:
docmgrfor ticket/document lifecycle,wsmfor workspace lifecycle,tmuxfor per-agent runtime sessions.
Implemented command surface:
metawsm runmetawsm bootstrapmetawsm statusmetawsm auth checkmetawsm review syncmetawsm watchmetawsm operatormetawsm forum(ask,answer,assign,state,priority,close,list,thread,watch,signal)metawsm resumemetawsm stopmetawsm restartmetawsm cleanupmetawsm commitmetawsm prmetawsm mergemetawsm iteratemetawsm closemetawsm policy-initmetawsm tuimetawsm docsmetawsm serve
Key implementation decisions:
- HSM-driven lifecycle transitions for run/step/agent states.
- SQLite durable state in
.metawsm/metawsm.db. - Declarative policy file at
.metawsm/policy.json. - Tmux session topology is per
agent/workspacepair. - Close flow enforces clean git state before merge.
Initialize policy:
go run ./cmd/metawsm policy-initStart the durable daemon (forum worker + HTTP/WebSocket API + optional UI):
go run ./cmd/metawsm serve --addr :3001Plan a run (no side effects):
go run ./cmd/metawsm run \
--ticket METAWSM-001 \
--repos metawsm \
--doc-home-repo metawsm \
--doc-seed-mode copy_from_repo_on_start \
--agent agent \
--dry-runStart a bootstrap run with interactive intake:
go run ./cmd/metawsm bootstrap \
--ticket METAWSM-002 \
--repos metawsm \
--doc-home-repo metawsm \
--base-branch mainInspect status:
go run ./cmd/metawsm status --ticket METAWSM-003Answer pending guidance from an agent:
go run ./cmd/metawsm forum signal \
--run-id RUN_ID \
--ticket METAWSM-003 \
--agent-name agent \
--type guidance_answer \
--answer "Proceed with the sentinel JSON contract."Review/merge workflow for completed runs:
go run ./cmd/metawsm merge --ticket METAWSM-003 --dry-run
go run ./cmd/metawsm merge --ticket METAWSM-003Send operator feedback and kick off another agent iteration:
go run ./cmd/metawsm iterate --ticket METAWSM-003 --feedback "Address the diff comments and add regression tests."Sync PR review comments and optionally dispatch them into iterate workflow:
# sync only (preview)
go run ./cmd/metawsm review sync --ticket METAWSM-003 --dry-run
# sync + dispatch queued review feedback to agents
go run ./cmd/metawsm review sync --ticket METAWSM-003 --dispatchRestart the latest run for a ticket:
go run ./cmd/metawsm restart --ticket METAWSM-003Run the operator supervision loop:
# supervise all active runs
go run ./cmd/metawsm operator --all --interval 15
# run in assist mode (default from policy)
go run ./cmd/metawsm operator --all --llm-mode assist
# run in auto mode
go run ./cmd/metawsm operator --all --llm-mode auto
# observe only (no actions)
go run ./cmd/metawsm operator --all --dry-runClean up the latest run for a ticket (kills agent tmux sessions and deletes workspaces):
go run ./cmd/metawsm cleanup --ticket METAWSM-003Keep workspaces during cleanup:
go run ./cmd/metawsm cleanup --ticket METAWSM-003 --keep-workspacesRun initial TUI monitor:
# Monitor one run
go run ./cmd/metawsm tui --run-id RUN_ID
# Monitor all active runs
go run ./cmd/metawsm tuiDoc federation view and optional index refresh:
go run ./cmd/metawsm docs --policy .metawsm/policy.json
go run ./cmd/metawsm docs --policy .metawsm/policy.json --refreshDefault policy file: .metawsm/policy.json.
Reference example: examples/policy.example.json.
Important fields:
workspace.default_strategy(create|fork|reuse)tmux.session_pattern(supports{agent}and{workspace})workspace.base_branch(branch used as workspace start-point; defaultmain)health.idle_secondshealth.activity_stalled_secondshealth.progress_stalled_secondsoperator.unhealthy_confirmationsoperator.restart_budgetoperator.restart_cooldown_secondsoperator.stale_run_age_secondsoperator.llm.mode(off|assist|auto)operator.llm.command(V1 default:codex)operator.llm.timeout_secondsoperator.llm.max_tokensgit_pr.mode(off|assist|auto)git_pr.require_all(require all configured checks to pass)git_pr.required_checks(tests|forbidden_files|ticket_workflow|clean_tree)git_pr.test_commands[](shell commands run in each target repo)git_pr.forbidden_file_patterns[](glob patterns blocked in changed files)git_pr.allowed_repos[](optional allow-list for commit/PR workflows)git_pr.default_labels[]andgit_pr.default_reviewers[]git_pr.review_feedback.enabled(enable PR review feedback sync)git_pr.review_feedback.mode(assist|auto)git_pr.review_feedback.include_review_comments(V1 must betrue)git_pr.review_feedback.ignore_authors[](optional commenter ignore list)git_pr.review_feedback.max_items_per_sync(ingest cap per sync pass)git_pr.review_feedback.auto_dispatch_cap_per_interval(operator auto cap)close.require_clean_gitdocs.authority_mode(workspace_active)docs.seed_mode(none|copy_from_repo_on_start)docs.api.workspace_endpoints[](workspace-scoped docmgr API endpoints)docs.api.repo_endpoints[](repo fallback docmgr API endpoints)docs.api.request_timeout_secondsagent_profiles[].runner(currentlycodexorshell)agent_profiles[].base_promptagent_profiles[].skillsagents[].profile(maps each agent to anagent_profilesentry)
Kickoff doc-home selection:
--doc-home-reposelects which workspace repo hoststtmp/for docmgr operations.--doc-reporemains as a legacy alias for compatibility.- Default behavior picks the first
--reposentry.
Run lifecycle signaling is forum-first (no file-signal compatibility path).
Forum commands are daemon-backed and call metawsm serve (--server defaults to http://127.0.0.1:3001).
Control flow conventions:
- Exactly one control thread per
(run_id, agent_name). - Control signal payloads are versioned (
schema_version=1) and posted viametawsm forum signal. - Supported control signal types:
guidance_requestguidance_answercompletionvalidation
Examples:
# agent asks for guidance
go run ./cmd/metawsm forum signal \
--run-id RUN_ID \
--ticket METAWSM-003 \
--agent-name agent \
--type guidance_request \
--question "Need decision on API schema shape"
# agent marks implementation complete
go run ./cmd/metawsm forum signal \
--run-id RUN_ID \
--ticket METAWSM-003 \
--agent-name agent \
--type completion \
--summary "Implemented the requested contract updates"
# agent posts validation result (required for bootstrap close)
go run ./cmd/metawsm forum signal \
--run-id RUN_ID \
--ticket METAWSM-003 \
--agent-name agent \
--type validation \
--status passed \
--done-criteria "tests pass and docs updated"When metawsm operator escalates in environments using docs.authority_mode=workspace_active, it appends escalation summaries to workspace ticket docs:
<workspace>/<doc_home_repo>/ttmp/.../<ticket>/changelog.md
Entries include run id, escalation intent, summary/evidence, and requested operator decision.
metawsm serve hosts:
- HTTP API under
/api/v1/... - WebSocket stream at
/api/v1/forum/stream - Web UI at
/(if UI assets are available)
Core API routes:
GET /api/v1/healthGET /api/v1/runs,GET /api/v1/runs/{run_id}GET/POST /api/v1/forum/threadsPOST /api/v1/forum/threads/{thread_id}/posts|assign|state|priority|closePOST /api/v1/forum/control/signalGET /api/v1/forum/events,GET /api/v1/forum/stats
Development loop:
# terminal 1
make dev-backend
# terminal 2
npm --prefix ui install
make dev-frontendSingle-command dev loop (backend + Vite with hot reload):
make dev-allUse the Vite URL (default http://127.0.0.1:3000) for UI debugging; /api and WebSocket calls are proxied to metawsm serve.
One-shot daemon startup with prerequisites (installs UI deps, builds assets, then runs server):
make serve-allProduction-style build:
go generate ./internal/web
go build -tags embed ./...go test ./...
go build -tags embed ./...- Forum runtime/operations runbook:
docs/how-to-run-forum.md