/SKILL.md
Spawn and orchestrate an ntm multi-agent session from within Claude Code. Plans work distribution, sends targeted prompts, monitors progress via polling, handles coordination through Agent Mail, collects results, and synthesizes a summary. Knows when to ask for human direction. Keywords: spawn agents, ntm session, orchestrate, multi-agent, fan out work.
npx skillsauth add emptyaltoidstin/ntm-orchestrator ntm-orchestratorInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are the orchestrator — the general who plans, dispatches, monitors, and collects. You never do implementation work yourself. You drive external agents via ntm and coordinate them through Agent Mail.
You also know when to ask for direction. Not every decision is yours to make.
--robot-* flags for NTM commands. Three exceptions where subcommands are required: ntm send (robot-send doesn't submit), ntm kill (no robot-kill), ntm save (no robot-copy). Always use --json with subcommands for structured output.bv — it launches interactive TUI and blocks. Prefer ntm --robot-plan or use bv --robot-* flags.<runtime>/<session>/pane-<N>.md and use --file (ntm send) or --msg-file (robot-send).${NTM_ORCH_RUNTIME_DIR:-${XDG_RUNTIME_DIR:-/tmp}/ntm-orch-$(id -u)}) — never pollute the project tree.All orchestrator interactions with NTM use robot mode. This is the stable automation interface.
Runtime directory shorthand used below:
RUNTIME_DIR="${NTM_ORCH_RUNTIME_DIR:-${XDG_RUNTIME_DIR:-/tmp}/ntm-orch-$(id -u)}"
| Action | Command |
|--------|---------|
| Spawn session | env -u CLAUDECODE ntm --robot-spawn=<session> --spawn-cc=N --spawn-cod=M |
| Send prompt (file) | ntm send <session> --pane=N --file=/path/to/prompt.md --json |
| Send prompt (inline) | ntm send <session> --pane=N "short message" --json |
| Send with narrow immutable context (rare) | ntm send <session> --pane=N --file=/path -c file1 -c file2 --json |
| Status (JSON) | ntm --robot-status |
| Session health | ntm --robot-health=<session> |
| Terse status | ntm --robot-terse |
| Tail output | ntm --robot-tail=<session> --panes=1,2 --lines=30 |
| Save all output | ntm save <session> -o /path/to/dir |
| Execution plan | ntm --robot-plan |
| Kill session | ntm kill <session> --force |
| Interrupt pane | ntm --robot-interrupt=<session> --panes=N |
| Snapshot (full state) | ntm --robot-snapshot |
| Wait for idle | ntm --robot-wait=<session> --wait-until=idle |
| Preflight prompt | ntm preflight --file=/path/to/prompt.md --json |
| Agent health (detailed) | ntm --robot-agent-health=<session> --panes=N |
See references/ntm-commands.md for detailed documentation.
Maintain this block in your working memory and persist to disk after every phase transition and every poll cycle.
SKILL: ntm-orchestrator
PHASE: [0-Planning | 0.5-ArchValidation | 1-Spawn | 2-Distribute | 3-Monitor | 4-Collect | 5-Synthesize | 6-Teardown]
SESSION: <name>
AGENTS: <total> total, <active> active, <complete> complete, <failed> failed
TASKS: <total> total, <assigned> assigned, <complete> complete
LAST_POLL: <ISO timestamp>
LAST_TERSE: <raw terse output or hash>
NEXT_POLL: <ISO timestamp>
INTERVENTIONS: <count>
REFRESHES: {pane0: 0, pane1: 0, ...}
ESCALATION_NEEDED: [none | scope-ambiguity | priority-conflict | systemic-failure | security | timeout | destructive-op | quality-bypass]
ESCALATION_REASON: <if applicable>
After every phase transition and every poll cycle, write the state as JSON:
RUNTIME_DIR="${NTM_ORCH_RUNTIME_DIR:-${XDG_RUNTIME_DIR:-/tmp}/ntm-orch-$(id -u)}"
# Write to: $RUNTIME_DIR/<session>/orchestrator-state.json
Schema:
{
"skill": "ntm-orchestrator",
"phase": "3-Monitor",
"session": "<name>",
"agents": {"total": 10, "active": 8, "complete": 1, "failed": 1},
"tasks": {"total": 10, "assigned": 10, "complete": 1},
"last_poll": "<ISO>",
"last_terse": "<hash>",
"next_poll": "<ISO>",
"interventions": 2,
"refreshes": {"pane0": 0, "pane1": 1},
"escalation_needed": "none",
"escalation_reason": null,
"updated_at": "<ISO>"
}
If you have no memory of your current orchestration state (e.g. after context compaction), read these files to resume:
<runtime>/<session>/orchestrator-state.json — your last known state<runtime>/<session>/manifest.json — the task manifestfetch_inbox(project_key, agent_name="Orchestrator") — any messages received while context was compactingResume from the phase recorded in orchestrator-state.json. Re-read per-pane state files to reconcile agent progress.
When ESCALATION_NEEDED is not none, pause all other work and invoke AskUserQuestion immediately.
| Trigger | Example | Why |
|---------|---------|-----|
| Scope ambiguity | "Should auth changes include the migration?" | Prevents scope creep |
| Priority conflict | Two P0 beads compete for same file | Human judgment needed |
| Systemic failure | 3+ agent failures in 5 minutes | Likely API outage or bad base state |
| Security-sensitive | Agent wants to modify .env, secrets, auth | Per AGENTS.md security rules |
| Timeout approaching | 50min of 60min elapsed, 40% incomplete | Human decides: extend or stop |
| Destructive operation | Agent wants to delete tests, drop tables | Irreversible actions need approval |
| Quality gate bypass | Agent asks to skip typecheck/lint/test | Gates are non-negotiable |
| Manifest uncertainty | Unclear how to decompose user's request | Better to ask than guess wrong |
| Situation | Action |
|-----------|--------|
| Routine file reservation conflict | Arbitrate: earlier assignment wins |
| Single agent crash | NTM auto-restarts; only escalate after 3+ crashes |
| Simple code questions from agents | Answer from context or codebase |
| Git rebase instructions | Standard recovery pattern |
| Agent needs file context | Instruct agent to search/read in assigned scope first; use -c only for immutable references |
ESCALATION: <trigger-type>
SITUATION: <what happened>
OPTIONS:
A) <option with tradeoffs>
B) <option with tradeoffs>
C) <option with tradeoffs>
RECOMMENDATION: <A/B/C or "need your judgment">
Determine what work to distribute. Three input modes:
br ready --json
ntm --robot-plan
Prefer ntm --robot-plan over direct bv calls. NTM is the integration hub and handles bv compatibility.
ntm --robot-plan returns parallel execution tracks as advisory input. The plan may suggest parallelizable work, but you enforce non-overlapping file scopes — this is orchestrator policy, not a guaranteed property of any tool's output.
⚠️ CRITICAL: Never run bare bv — it launches TUI and blocks. If you must call bv directly, always use bv --robot-* flags.
The user describes work in natural language. Decompose into discrete tasks:
The user provides a file path. Read it, extract task assignments, map each to an agent slot.
Regardless of mode, produce and present:
TASK MANIFEST
Session: <session-name>
Agent mix: <N> Claude Code, <M> Codex
Architecture: <discovery doc status>
Scope policy: Non-overlapping file scopes enforced by orchestrator
─────────────────────────────────────────────────────────────────
# | Task ID/Label | Agent | File Scope | Description
1 | bd-101i | cc | packages/shared/src/* | Refactor crypto types
2 | bd-102i | cc | packages/extension/src/ | Fix sidepanel layout
3 | improve-tests | cod | packages/shared/__tests__/| Add coverage
...
Quality gates: bun run typecheck && bun run lint && bun run test
Estimated duration: <X> minutes
Wait for user confirmation before proceeding. Use AskUserQuestion if:
Default agent mix: --spawn-cc=7 --spawn-cod=3. Adjust based on task count and complexity.
Also write a machine-readable copy of the manifest to:
<runtime>/<session>/manifest.jsonThis is used for audit/handoff and for hook-based validation.
Before spawning, run a scope-overlap check on the manifest:
RUNTIME_DIR="${NTM_ORCH_RUNTIME_DIR:-${XDG_RUNTIME_DIR:-/tmp}/ntm-orch-$(id -u)}"
MANIFEST="$RUNTIME_DIR/<session>/manifest.json"
jq -r '.tasks[] | .task_id as $id | .file_scope[] | "\($id)\t\(.)"' "$MANIFEST" | \
awk -F'\t' '{for(i=1;i<=n;i++){split(a[i],p,"\t"); if(index($2,p[2])==1||index(p[2],$2)==1){print "OVERLAP\t"p[1]"\t"$1"\t"p[2]"\t"$2; bad=1}} a[++n]=$0} END{exit bad}'
If this check reports overlap, revise scopes and do not proceed to Phase 1.
Skip if: Familiar codebase, user confirms architecture is known, or tasks are trivial/isolated.
Run if: Unfamiliar codebase, tasks span multiple components, no recent discovery docs.
if [ -f docs/architecture/discovery.md ]; then
age=$(( $(date +%s) - $(stat -c %Y docs/architecture/discovery.md 2>/dev/null || echo 0) ))
if [ $age -lt 3600 ]; then
echo "Discovery valid (${age}s old)"
else
echo "Discovery stale (${age}s old)"
fi
else
echo "No discovery document"
fi
Options:
For large manifests or unfamiliar codebases, send templates/plan-space-validation.md to an agent before proceeding to Phase 1. Fill {{manifest_or_bead_summary}} with the task manifest. Catching problems in plan-space is far cheaper than fixing them after implementation.
Robot mode is required for this skill. Do a non-destructive capability check before proceeding:
# Non-destructive check: confirm robot interface exists
ntm --help | grep -q "--robot-" || {
echo "NTM robot mode not available in this environment" >&2
exit 1
}
# Optional sanity check: list sessions via robot interface
ntm --robot-status >/dev/null
If robot mode is unavailable, do not fall back to subcommands. Escalate to the user (AskUserQuestion) to upgrade/install the correct NTM.
register_agent({
project_key: '<project-slug>',
program: 'claude-code',
model: 'opus-4.6',
name: 'Orchestrator',
task_description: 'ntm session orchestrator for <session-name>'
})
env -u CLAUDECODE ntm --robot-spawn=<session> --spawn-cc=<N> --spawn-cod=<M> --spawn-dir=/path/to/project
env -u CLAUDECODE is required when spawning from within a Claude Code session. CC 2.1.45+ sets CLAUDECODE=1 in its environment; without stripping it, spawned panes inherit the var and refuse to launch a nested CC instance. This is intentional — the orchestrator is the coordinator, not a peer agent.
If spawn fails, escalate (systemic failure) and stop.
Operational note: The PreToolUse hook writes runtime markers at <runtime>/<session>/state.json (session-scoped) and <runtime>/active-session.json (global index) on successful --robot-spawn. On ntm kill, these marker files are cleared via exact-path deletion. The Stop hook reads the global index to prevent accidental exit while a session is active.
Runtime invariant: Keep all orchestration artifacts under <runtime>/<session>/ and avoid wildcard cleanup.
ntm --robot-health=<session>
Parse JSON response. All agents must report healthy. If any fail, wait 10s and retry. After 3 failures, escalate (systemic failure).
Parse spawn/health output for pane indices. Map each pane to a task. Initialize:
REFRESHES: {pane0: 0, pane1: 0, ...}LAST_TERSE: ""For each task in the manifest:
Use templates from templates/:
agent-prompt-bead.md for Mode Aagent-prompt-freeform.md for Mode Bagent-prompt-plan.md for Mode CFill variables: {{task_id}}, {{task_description}}, {{file_scope}}, {{acceptance_criteria}}, {{pane_name}}, {{session_name}}, {{project_slug}}, {{quality_gates}}.
Prompt requirements for every worker:
cm context "<task description>" --json before editing<runtime>/<session>/<pane>-state.json with the required schemaFILE_RESERVATION_CONFLICT, stop edits immediately and notify orchestratorMid-session templates (used during monitoring and collection, not initial assignment):
post-implementation-review.md — self-review before orchestrator accepts completionagent-peer-review.md — cross-agent review (uses {{review_target_pane}}, {{review_target_task_id}}, {{review_target_file_scope}})intelligent-commit-grouping.md — logical commit grouping as a final stepplan-space-validation.md — manifest review during Phase 0.5Write to <runtime>/<session>/pane-<N>.md.
Before sending, validate each prompt file:
ntm preflight --file=<runtime>/<session>/pane-<N>.md --json
Preflight checks prompt structure, length, and DCG safety. Fix any issues before sending.
Use ntm send (not --robot-send) — robot-send pastes text but doesn't submit it.
ntm send <session> --pane=<N> --file=<runtime>/<session>/pane-<N>.md --json
Use -c context attachments only when pointing at immutable or tiny reference files:
ntm send <session> --pane=<N> --file=<runtime>/<session>/pane-<N>.md -c docs/protocol.md --json
Wait 2 seconds between sends to avoid thundering herd.
After all prompts sent, wait 30 seconds:
ntm --robot-status
Confirm all agents active. If any idle, re-send prompt once.
Authoritative monitoring source order:
<runtime>/<session>/<pane_name>-state.json)--robot-status JSON for session-level health--robot-tail only when state files are stale/missing/invalidWorker state schema:
{task_id,status,files_modified,gates_passed,last_update_ts,blocker}
--robot-terse remains a cheap change detector, not a structured source.
| Window | Interval | Primary Tool | On Change |
|-----------|----------|------------------|-------------------------------------------|
| 0–2 min | No poll | — | — |
| 2–10 min | 120s | --robot-terse | --robot-status + pane state-file reads |
| 10–30 min | 180s | --robot-terse | --robot-status + state-file anomaly triage |
| 30+ min | 300s | --robot-terse | --robot-status + --robot-health + --robot-agent-health |
Check escalation state. If ESCALATION_NEEDED != none, wait for user response.
Cheap change detection:
RUNTIME_DIR="${NTM_ORCH_RUNTIME_DIR:-${XDG_RUNTIME_DIR:-/tmp}/ntm-orch-$(id -u)}"
current_terse=$(ntm --robot-terse)
if [ "$current_terse" != "$LAST_TERSE" ]; then
ntm --robot-status > "$RUNTIME_DIR/<session>/status.json"
# Parse JSON for authoritative state
fi
LAST_TERSE="$current_terse"
Read per-pane state files first:
"$RUNTIME_DIR/<session>/<pane_name>-state.json" for each active panelast_update_ts is stale (>5 min), or file missing/invalid, mark pane anomalyInterpret status from JSON + state files:
error_count > 0 → --robot-health=<session>--robot-tail fallbackcompletion_pct == 100 → Phase 4Inbox check: fetch_inbox(project_key, agent_name="Orchestrator")
[context-warning] messages immediately — initiate context refresh procedure (see patterns/context-refresh.md)Agent context health (30+ min window only):
ntm --robot-agent-health=<session> --panes=<all_active_panes>
If any agent's context is below 30%, proactively initiate the context refresh procedure even if the agent hasn't self-reported yet.
Update state tracking — write orchestrator-state.json
Check escalation triggers
Calculate next poll time
| Signal | Action |
|--------|--------|
| Agent asks domain question | Reply if clear; escalate if uncertain |
| Agent asks scope expansion | ALWAYS escalate |
| FILE_RESERVATION_CONFLICT | Worker must stop edits immediately; arbitrate/reassign |
| Agent crash | Auto-restart handles; escalate after 3+ |
| Agent stall (>10 min idle) | Nudge, inspect pane state; tail fallback only if needed |
| Agent completes task | Send post-implementation-review.md before accepting |
| Agent idle after completion | Redeploy with agent-peer-review.md to review another agent's work |
| [context-warning] inbox message | Initiate context refresh: interrupt → capture → continuation prompt |
| Context exhaustion (behavioral) | Nudge first; if unresponsive, initiate context refresh |
| --robot-agent-health context < 30% | Proactively initiate context refresh even if agent hasn't reported |
| Investigation exceeds threshold | Delegate anomaly triage to a short-lived sub-agent |
| Quality gate failure | Agent must fix; do not accept completion |
| Destructive action request | ALWAYS escalate |
Do not deep-dive implementation details in the orchestrator context.
status.json, pane state JSON, latest inbox message)See patterns/context-refresh.md for the full procedure. Condensed flow:
--robot-interrupt); skip if agent sent [context-warning]git diff --stat + last Agent Mail messagetemplates/agent-prompt-continuation.md with captured state/clear (Claude Code) or /new (Codex)Track in REFRESHES[pane]. After 2 refreshes without progress → escalate.
Before accepting completion:
cat <runtime>/<session>/<pane_name>-state.json
Require gate evidence in pane state JSON and completion message. If pane state is stale/missing/invalid, use fallback diagnostics:
ntm --robot-tail=<session> --panes=<N> --lines=80
Also require completion evidence to include:
cm context rule ids/summary (or explicit cm unavailable)If gates didn't pass:
ntm send <session> --pane=<N> "Quality gates required. Run: <gates>" --jsonIf agent asks to bypass → ESCALATE
If agents have uncommitted work, send templates/intelligent-commit-grouping.md to have them organize changes into logical, well-documented commits before capture.
ntm save <session> -o ./outputs
Creates per-pane timestamped files in the output directory.
git log --oneline --since="<session_start_iso>"
br ready --json
release_reservation({
project_key: '<slug>',
agent_name: '<pane_name>',
paths: [<reserved_paths>]
})
Generate report using templates/status-report.md:
Present to user. Ask:
Ask user: kill session or keep running?
ntm kill <session> --forcentm attach <session>Runtime marker cleanup is handled by hook-managed exact-path deletion on ntm kill.
| Bad | Good |
|-----|------|
| ntm spawn <session> | ntm --robot-spawn=<session> |
| ntm status | ntm --robot-status |
| ntm health <session> | ntm --robot-health=<session> |
| --robot-send --msg-file=... (doesn't submit) | ntm send --pane=N --file=... --json |
| --robot-kill=session (doesn't exist) | ntm kill session --force |
| --robot-copy=session (doesn't exist) | ntm save session |
| Bare bv | ntm --robot-plan or bv --robot-* |
| Parse terse for data | Use terse as change detector, JSON for state |
| Treat tail as primary state | Use pane state JSON first; tail as fallback |
| Assume bv guarantees non-overlap | Enforce scope policy yourself |
| Inline 3000-char prompts | Write to file, use --file |
| Poll every 30s | Follow cadence table |
| Accept completion without gates | Verify gates or require remediation |
| Make scope decisions | Escalate scope ambiguity |
| Tool | Tokens/call | Frequency (30min) | Total |
|------|-------------|-------------------|-------|
| --robot-terse | ~100 | ~12 | ~1,200 |
| --robot-status | ~300 | ~6 | ~1,800 |
| fetch_inbox | ~200 | ~12 | ~2,400 |
| --robot-tail | ~800 | ~3 | ~2,400 |
| --robot-health | ~300 | ~2 | ~600 |
| Collection | ~3,000 | 1 | ~3,000 |
| Synthesis | ~2,000 | 1 | ~2,000 |
| Total | | | ~14,400 |
Your own context can exhaust during long sessions. Before that happens, write a handoff:
orchestrator-state.json — this should already be current from periodic writes (see State Tracking). Verify it's up to date.send_message({
project_key: '<slug>',
sender_name: 'Orchestrator',
to: ['Orchestrator'],
subject: '[orchestrator-handoff]',
body_md: `
Phase: <current phase>
Session: <session name>
Active agents: <count> (<pane list>)
Incomplete tasks: <task ids>
Pending escalations: <any>
State file: <runtime>/<session>/orchestrator-state.json
Manifest: <runtime>/<session>/manifest.json
`
})
br is available):
br create --title "Resume orchestration: <session>" --json
Signs you are approaching context limits:
When in doubt, write the handoff proactively. The cost of an unnecessary handoff is low; the cost of losing orchestration state is a stranded session.
development
Systematic codebase exploration that maps architecture, components, and dependencies. Use when you need to understand how a feature works across a codebase, explore an unfamiliar project's architecture, trace data flow through multiple layers, or plan changes that span several components. Maps the high-level structure first, then dispatches parallel agents to explore each area in depth. Produces a synthesis with file:line references, execution flows, and actionable recommendations.
development
Maintainer-only workflow for handling GitHub Secret Scanning alerts on OpenClaw. Use when Codex needs to triage, redact, clean up, and resolve secret leakage found in issue comments, issue bodies, PR comments, or other GitHub content.
development
Maintainer workflow for OpenClaw releases, prereleases, changelog release notes, and publish validation. Use when Codex needs to prepare or verify stable or beta release steps, align version naming, assemble release notes, check release auth requirements, or validate publish-time commands and artifacts.
development
Run, watch, debug, and extend OpenClaw QA testing with qa-lab and qa-channel. Use when Codex needs to execute the repo-backed QA suite, inspect live QA artifacts, debug failing scenarios, add new QA scenarios, or explain the OpenClaw QA workflow. Prefer the live OpenAI lane with regular openai/gpt-5.4 in fast mode; do not use gpt-5.4-pro or gpt-5.4-mini unless the user explicitly overrides that policy.