When the user asks how to dispatch work to DSH workers — tier choice, writing a brief, parallelism, verifying results, guardrails — answer from the playbook below. Point to the relevant section rather than reciting it whole.
DSH Crew — Dispatch Playbook
How to delegate work to DSH workers well. The tool descriptions carry the mechanics; this playbook is the decision layer.
1. Choosing a worker
flash — mechanical, well-scoped work:
- Rename a symbol in one or two files and update the obvious call sites.
- Read a config file and report the values of a few keys.
- Add a unit test for an existing function, following the file's existing style.
pro — multi-file work, debugging, design judgment:
- Refactor a module that is used across the repo and update every caller.
- Diagnose a flaky test or a race condition by reading logs and tracing the code.
- Design a new API or file layout with tradeoffs to weigh, then implement it.
When in doubt, start with flash: escalate_on_failure retries a failed blocking flash run once on pro, so evidence, not guesswork, decides.
worker="agy" / worker="grok" is explicit opt-in. Set it only when the user explicitly asks for that CLI, never as a default. Two caveats to tell the user: grok refuses to start repo-local MCP servers in untrusted folders (global installs are unaffected; change directory or pass --trust), and agy runs with full approval because it has no workspace-scoped permission mode.
2. Writing the brief
The worker has zero conversation context. Every task string must be self-contained:
- Absolute paths for every file and directory involved.
- Exact acceptance criteria: what must be true when done, and how to verify it.
- What NOT to touch (generated files, unrelated modules, lockfiles).
- Never commit, push, or publish unless the user explicitly authorized it — write that into the brief.
Bad: "fix the auth bug". Good: "In /abs/path/repo/src/auth.ts the token refresh throws on 401 when the session expires; make it retry once and fail loudly, add a test in /abs/path/repo/test/auth.test.ts, and run npm test. Touch only auth.ts and its test. Do not commit."
3. Parallelism
- Default: one worker per repo/workspace. The cwd advisory lock enforces this — a second dispatch into a held workspace is refused with the holder's job id, not queued.
- Parallel workers in one repo are only safe with explicitly disjoint file territories AND a named owner for every seam where the two halves meet. Unowned seams are where integration gaps happen; write the seam owner's name into each brief.
- allow_concurrent_cwd: true is only for read-only tasks. It is never a license for two writers.
4. Verifying results
- Trust artifacts, not claims. Check which files actually changed (git status / git diff) and run the verify scripts or tests the brief demanded.
- A hub restart can orphan a job that then looks finished: if a result seems missing or stale, verify against the working tree and re-check dsh_worker_status before trusting the summary.
- Require workers to report unverified claims honestly ("I did not run the tests") rather than simulating success. A "done" summary is not proof.
5. Guardrails you may hit
- Origin-chain depth cap (3): worker→worker nesting deeper than 3 hops is refused; a cycle (the same backend + cwd appearing twice in the chain) is refused too. These refuse rather than queue — the fix is to wait, or to re-scope the task so a worker does not spawn another worker, never to bypass.
- cwd lock refusal: the error names the holder (job id, backend, start time). Fix: wait for that job to settle, cancel it with dsh_worker_cancel, or re-scope to a different workspace. Refusals are readable errors, not bugs.
6. Tool quick reference
| Tool |
One line |
dsh_run_worker |
Run one task and block until it finishes; flash for mechanical work, pro for judgment. |
dsh_spawn_worker |
Start a task in the background for fan-out; returns a job id, not a result. |
dsh_worker_status |
Live progress of all jobs plus the cwd advisory locks. |
dsh_worker_result |
Fetch a job's final result, optionally waiting wait_seconds. |
dsh_worker_cancel |
Terminate a running job and release its cwd lock. |
dsh_worker_config |
Read/set session defaults (default_tier, default_effort, mode, default_timeout_seconds, tier_policy, escalate_on_failure) and list worker_profiles. |
1---2name: dsh-playbook3description: How to dispatch well — choosing flash vs pro, writing self-contained briefs, parallelism, verifying results, and guardrails4---56When the user asks how to dispatch work to DSH workers — tier choice, writing a brief, parallelism, verifying results, guardrails — answer from the playbook below. Point to the relevant section rather than reciting it whole.78# DSH Crew — Dispatch Playbook910How to delegate work to DSH workers well. The tool descriptions carry the mechanics; this playbook is the decision layer.1112## 1. Choosing a worker1314**flash** — mechanical, well-scoped work:15- Rename a symbol in one or two files and update the obvious call sites.16- Read a config file and report the values of a few keys.17- Add a unit test for an existing function, following the file's existing style.1819**pro** — multi-file work, debugging, design judgment:20- Refactor a module that is used across the repo and update every caller.21- Diagnose a flaky test or a race condition by reading logs and tracing the code.22- Design a new API or file layout with tradeoffs to weigh, then implement it.2324When in doubt, start with flash: escalate_on_failure retries a failed blocking flash run once on pro, so evidence, not guesswork, decides.2526**worker="agy" / worker="grok"** is explicit opt-in. Set it only when the user explicitly asks for that CLI, never as a default. Two caveats to tell the user: grok refuses to start repo-local MCP servers in untrusted folders (global installs are unaffected; change directory or pass --trust), and agy runs with full approval because it has no workspace-scoped permission mode.2728## 2. Writing the brief2930The worker has zero conversation context. Every task string must be self-contained:3132- Absolute paths for every file and directory involved.33- Exact acceptance criteria: what must be true when done, and how to verify it.34- What NOT to touch (generated files, unrelated modules, lockfiles).35- Never commit, push, or publish unless the user explicitly authorized it — write that into the brief.3637Bad: "fix the auth bug". Good: "In /abs/path/repo/src/auth.ts the token refresh throws on 401 when the session expires; make it retry once and fail loudly, add a test in /abs/path/repo/test/auth.test.ts, and run `npm test`. Touch only auth.ts and its test. Do not commit."3839## 3. Parallelism4041- Default: one worker per repo/workspace. The cwd advisory lock enforces this — a second dispatch into a held workspace is refused with the holder's job id, not queued.42- Parallel workers in one repo are only safe with explicitly disjoint file territories AND a named owner for every seam where the two halves meet. Unowned seams are where integration gaps happen; write the seam owner's name into each brief.43- allow_concurrent_cwd: true is only for read-only tasks. It is never a license for two writers.4445## 4. Verifying results4647- Trust artifacts, not claims. Check which files actually changed (git status / git diff) and run the verify scripts or tests the brief demanded.48- A hub restart can orphan a job that then looks finished: if a result seems missing or stale, verify against the working tree and re-check dsh_worker_status before trusting the summary.49- Require workers to report unverified claims honestly ("I did not run the tests") rather than simulating success. A "done" summary is not proof.5051## 5. Guardrails you may hit5253- Origin-chain depth cap (3): worker→worker nesting deeper than 3 hops is refused; a cycle (the same backend + cwd appearing twice in the chain) is refused too. These refuse rather than queue — the fix is to wait, or to re-scope the task so a worker does not spawn another worker, never to bypass.54- cwd lock refusal: the error names the holder (job id, backend, start time). Fix: wait for that job to settle, cancel it with dsh_worker_cancel, or re-scope to a different workspace. Refusals are readable errors, not bugs.5556## 6. Tool quick reference5758| Tool | One line |59|---|---|60| `dsh_run_worker` | Run one task and block until it finishes; flash for mechanical work, pro for judgment. |61| `dsh_spawn_worker` | Start a task in the background for fan-out; returns a job id, not a result. |62| `dsh_worker_status` | Live progress of all jobs plus the cwd advisory locks. |63| `dsh_worker_result` | Fetch a job's final result, optionally waiting wait_seconds. |64| `dsh_worker_cancel` | Terminate a running job and release its cwd lock. |65| `dsh_worker_config` | Read/set session defaults (default_tier, default_effort, mode, default_timeout_seconds, tier_policy, escalate_on_failure) and list worker_profiles. |