Skip to content
Back to skills

Conduct

ASecurity

cmux Conductor — routes a work item to the right execution topology. Use when: you have a work item or ticket and want the right amount of cmux (including none), you're choosing between fleet/race/solo execution, you want agents opened under your current workspace, or you want /etk:develop run over cmux panes. Triggers on: conduct, cmux run, run this in cmux, fleet this, race this, orchestrate execution, how many agents, dev fleet, open under this workspace

  • 6 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 6, 2026
ai-agentsgorailsgitapifrontendbackend

Works with

  • terminal
  • api

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned September 6, 2026

npx -y skills add ArieGoldkin/claude-forge --skill conduct --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Conduct?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Conduct
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/ariegoldkin-conduct/badge)](https://www.skillsdirectory.com/skills/ariegoldkin-conduct)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: conduct
description: "cmux Conductor — routes a work item to the right execution topology. Use when: you have a work item or ticket and want the right amount of cmux (including none), you're choosing between fleet/race/solo execution, you want agents opened under your current workspace, or you want /etk:develop run over cmux panes. Triggers on: conduct, cmux run, run this in cmux, fleet this, race this, orchestrate execution, how many agents, dev fleet, open under this workspace"
effort: high
---

# Conduct — the cmux Conductor

Routes a work item to an **execution topology**, the way `/auto-research` routes a goal to
a **skill**. The two compose: auto-research answers *which process*; conduct answers *what
shape that process runs in* (and whether cmux is involved at all). Human writes intent,
agent picks the topology.

**Core discipline — the lowest rung that does the job.** Escalation is a brake, not an
accelerator (`agent-loops/references/dispatch-policy.md` — cite, don't restate). Most work
items route to the leftmost rungs; a fleet must be *earned* by the classification below,
never assumed. Routing everything to a fleet is the fan-out-theater failure mode.

**cmux is optional infrastructure.** Routes that need it require the cmux app + socket
(`etk:cmux` skill — macOS only). When cmux is absent, conduct still classifies and emits;
patterns 1–2 degrade to their non-cmux equivalents (noted per pattern in the routing map).

## Phase 1 — Classify

Read the work item (`$ARGUMENTS`) and score **four axes**:

| Axis | Values | Inferred from |
|---|---|---|
| **Scope** | single task · divisible job · full ticket | Classify on the **deliverable**, in this order: (1) a **research/estimation** deliverable — spike, "research the work needed", "turn X into tickets", "size it", "investigate options" — → **divisible**, *even when it carries a ticket ID*; (2) "audit/map/sweep across…" → **divisible**; (3) a ticket ID **or** "implement/build/fix X end-to-end" → **ticket** (this keeps ordinary bug and feature tickets on row 3/4); (4) otherwise **single**. A ticket ID still implies ticket scope — it just no longer overrides a research deliverable |
| **Lanes** | 1 · 2–3 · 4+ | independent, file-disjoint work streams (backend/frontend/tests…); "and"-chains of separable deliverables |
| **Visibility** | watch · background | "watch", "show me", "I want to see/steer" → watch; quick checks → background |
| **Diversity** | none · best-of-N · race | "compare/multiple takes/which model" → best-of-N; "fast/hotfix/prod down/first wins" → race |
| *(tickets only)* **Kind** | bug · feature | error/regression/broken → bug; build/add/implement → feature |

**Fifth axis — Container (where it lands).** Scored from live cmux state, not the item
text. Outside cmux (`CMUX_WORKSPACE_ID` unset) → `new-workspace` (nothing to nest under).
Inside cmux, read the container BEFORE routing with **`cmux identify`** and take it from
`caller.workspace_ref`, then resolve that against `cmux workspace list --json` (fields
`custom_title`, `current_directory`, `description`) for the name/project you match on.

**Never route on `cmux current-workspace`** — it reports the *focused* workspace, not the
caller's. Semantics, evidence and the reproduction: `etk:cmux` skill §
"`identify` ≠ `current-workspace`".

**Self-check before routing:** if `cmux current-workspace` differs from
`caller.workspace_ref`, surface the divergence in the Phase-3 box. **Diagnostic only —
routing always uses `caller.workspace_ref`.**

Then match the container to the item:

| Container | When | Placement |
|---|---|---|
| **nest-under-current** *(default on match)* | the current workspace IS for this work — same project/repo/ticket family | one workspace = one workflow: the caller's pane orchestrates, each lane is its own `new-pane` (visible split) UNDER it, never a sibling |
| **join-group** | team-scale fleet on matched work | `workspace-group` anchored on the current workspace |
| **new-workspace** *(fallback)* | container mismatch, or outside cmux | the pattern's own named-workspace recipe |

Workspaces are durable and project-scoped in real use ("Platform", "Bug-fixing" live for
weeks) — routing into the EXISTING workspace is the norm; a ticket-named throwaway
workspace is the exception, not the default.

If scope or lanes are genuinely ambiguous, ask **one** clarifying question, then route.

## Phase 2 — Route

First matching row wins (top-down); every pattern's emission template + worked example
lives in `${CLAUDE_SKILL_DIR}/references/routing-map.md` — read it before emitting.

| # | Shape | Pattern | Rung |
|---|---|---|---|
| 1 | diversity = race | **Race + verify gate** (winner must pass `etk:adversarial-verifier`) | L2 |
| 2 | diversity = best-of-N | **Broadcast fan-out + reconcile** | L2 |
| 3 | ticket · 1 lane, or 2–3 lanes background | **Pipeline solo** — `/fix-bug` (bug) / `/develop` (feature); cmux optional watch-pane | L0/L1 |
| 4 | **scope = full ticket** AND (watch requested OR 4+ lanes) | **develop-fleet** — `/develop` as lead pane, worker panes on demand (**one pane at first** — see below) | L2 |
| 5 | divisible job | **Sweep fan-out / fan-in** | L2 |
| 6 | single task · watch | **Single agent in a pane** | L1 |
| 7 | single task · background | **L0 solo** — no cmux; run it (or the fitting skill) directly | L0 |

Fleet-shape default for row 4 is **lead-only, fan out on demand**: boot one primed lead
pane; workers appear only if the pipeline's Phase 4 actually decomposes. Never pre-lay
role panes on assumption.

**Say the pane count at the gate.** Because lead-only is the default, an operator expecting a
visible fan-out sees a single pane and reads it as failure. The Phase-3 box therefore carries a
**"You'll see"** line: either `N panes now` or `1 lead pane now, workers on demand`. Filling it
in is not optional — an unstated lead-only routing is indistinguishable from a broken dispatch.

The pattern row picks the **shape**; the Container axis picks the **placement** — each
cmux pattern in the routing map carries a placement branch (§ Placement branch). The
invariant: **workers are `new-pane` targets — never `new-workspace`, never a background
tab** — with exactly two named exceptions: (1) the race (row 1), whose per-racer
workspaces are how the completion event's `workspace_id` identifies the winner; (2) the
**sidebar-dashboard tier** — 5+ lanes, or a run the operator wants to *watch* as a board —
where each lane gets its own colored workspace because per-lane state pills and progress
bars are workspace-scoped (`set-status`/`set-progress` take no surface target; a pane
can never carry them). Ladder and teardown rules: agent-fleets.md § Visibility. Both
exceptions still confirm at Phase 3 like any multi-session pattern.

## Phase 3 — Confirm

Present the plan and get explicit approval — a fleet or race is a deliberate cost choice:

```
┌───────────────────────────────────────────────┐
│  Conduct Plan                                 │
│  Item:     {work item / ticket}               │
│  Shape:    {scope · lanes · visibility · div} │
│  Pattern:  {name} (rung {L0-L2})              │
│  Container:{nest-under-current · join-group   │
│             · new-workspace} + target ws name │
│  You'll see:{N panes now · 1 lead pane now,   │
│             workers on demand}                │
│  Sessions: {N} ({cost note})                  │
│  Recipe:   {one-line summary of what runs}    │
│  [Run]  [Adjust]  [Cancel]                    │
└───────────────────────────────────────────────┘
```

Row 7 (L0 solo) may confirm inline — one sentence, no box. Do NOT proceed without
approval on any multi-session pattern.

**The cost note is a real number, not a shrug.** Every pane lane is a *cold-start* agent
session: it pays the full system prompt + SessionStart injection before it reads a single
file. Re-measured 2026-07-29 on a second three-lane fleet with **all three cost footers read
directly** (superseding the same day's earlier ~$0.45 figure, which rested on two readable
footers and one truncated one): **64.8–65.1k input tokens and $0.54–$0.60 per lane, $1.71 for
the three**, to return 148–319 output tokens apiece. Quote `Sessions: N (~$0.57+ per lane
cold-start)` so the operator approves a fan-out knowing its floor — this is the arithmetic
behind "the lowest rung that does the job," and it is why a fleet must be earned. The dominant
term is ctk's SessionStart continuity injection, not the task: a one-question lane and a
five-directory lane cost within 10% of each other.

## Phase 4 — Execute (emit-first)

**Conduct emits; it does not silently drive.** Produce the ready-to-run invocation from
the routing map, parametrized with the actual work item / ticket.

- **Outside a cmux session** (no `CMUX_WORKSPACE_ID`): emit the recipe as the deliverable
  and stop — the user runs it where they want it. To start *inside* cmux instead, the
  cold-start launcher `${CLAUDE_SKILL_DIR}/scripts/cmux-conduct.sh "<item>"` boots a
  workspace already running conduct (see its `--help`); by design it refuses to run from
  inside cmux, where the Container axis already governs placement.
- **Inside cmux**: emit per the Container axis — nested placements target the CURRENT
  workspace as a `new-pane --type terminal` (visible split), dispatched with `send` +
  `send-key enter`, never a sibling. **A driven lane is never `--type agent-session`** —
  those surfaces reject `send`, `send-key` and `read-screen` (`invalid_params: Surface is
  not a terminal`), so the lane opens empty and can never be collected from
  (routing-map.md § Placement branch). Offer to run it now. If accepted, drive it per the
  `etk:cmux` skill — `--focus false` everywhere, **file-based completion** (each lane writes
  `$TEAM/<title>-<assignment>.md` with `STATUS:` as its LAST line; collect with `collect_lane`, never by
  grepping `read-screen` — the cmux skill's `references/read-and-notify.md` §1), scoped
  teardown verified with `cmux tree`, and every fleet rule in the cmux skill's
  `references/agent-fleets.md`. Never steal focus; never close panes or surfaces you
  didn't create. **Teardown is not finished when the panes close** — any pill, progress bar
  or log line the run wrote persists on the workspace and must be cleared too
  (agent-fleets.md § Sidebar teardown; verify with `cmux sidebar-state`).
- **Label at dispatch (mandatory when driving).** The orchestrator names every lane AT
  SPAWN — agents never self-label: `rename-tab --surface <the ref new-pane printed>`
  with an emoji role prefix, plus a `set-status` sidebar pill per role. **Never emit a bare
  `rename-tab`** — its targeting flags are optional, so it retitles the caller's own tab
  (routing-map.md § Placement branch). Re-label on hand-off — stale titles misroute
  humans (a pane titled with yesterday's ticket doing today's work is a live failure
  mode). Labels are `<glyph> <Title>·<assignment>` — a lane is a teammate with a job
  title, never an index. The roster (titles, glyphs, file convention) + in-pane
  fallbacks live in agent-fleets.md § Identity — the single source; don't inline a
  copy here.
- Pattern-specific guardrails (race verify gate, worktree isolation for parallel writes,
  single-line dispatch) come from the cited references — apply them, don't reinvent them.

## Phase 5 — Report

One block: shape → pattern → what ran (or what was emitted) → per-lane `collect_lane`
verdicts (read from each lane's result file, never scraped off a screen)
→ synthesis (for broadcast/sweep: the reconciliation IS the deliverable; for race: winner +
verifier verdict, named by approach). End with `STATUS: DONE | DONE_WITH_CONCERNS | BLOCKED`.

**For broadcast/sweep, report the slice census before the aggregate** — `got/expected`, and
every dropped slice by name and reason. An aggregate over an unstated subset is a false
green: five different lane failures all render as a plausible smaller number that is
indistinguishable from a legitimate one. If any slice is missing, the run is
`DONE_WITH_CONCERNS` at best, and the aggregate is withheld, not caveated
(`etk:cmux` → `references/agent-fleets.md` § Fan-in). **Retrying a dropped slice is bounded**
(same ref, § Give-up bound) — name the cause or do not spend the round.

## Safety rails

- **No recursive conduct** — conduct never invokes itself, and never re-routes a routed
  skill's own sub-dispatch (the pipeline's Phase-4 fan-out is `/develop`'s decision).
- **Confirmation is per-run**; there is no unattended mode. A fleet that should run
  unwatched belongs to `/auto-research --unattended` (propose-only), not conduct.
- Routed skills' own gates apply unchanged (develop's phase gates, prepare-pr's approval,
  review-mr's never-auto-post).

Files in this skill

  • SKILL.md12.9 KB
  • references/routing-map.md17 KB
  • scripts/cmux-conduct.sh10.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…