Use for delegated work and board lifecycle; small bounded fixes may stay inline without a ticket. Use for tickets, board lifecycle, planning substantial or ambiguous work, and dispatch/integration/recovery.
Installs into .claude/skills of the current project.
Are you the author of Sidequest?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/hanafubuki-sidequest)
---
name: sidequest
description: >-
Use for delegated work and board lifecycle; small bounded fixes may stay inline without a ticket. Use for
tickets, board lifecycle, planning substantial or ambiguous work, and dispatch/integration/recovery.
---
# sidequest
A central ticket store (`~/.claude/sidequest`), live Kanban dashboard, CLI (`bin/sidequest.js`) and
matching MCP tools. Read references only when needed:
- `references/orchestration.md` — decomposition depth, fan-out waves, checkpoints, background
execution, cost levers, agent teams.
- `references/experiment-loop.md` — oracle rounds, branches, verdicts, promotion.
- `references/publishing.md` — delivery modes, publish transaction.
- `references/routing-details.md`, `references/routing-guide.md` — routes and wiring.
- `references/high-stakes.md`
- `references/external-trackers.md`, `references/board-features.md`, `references/category-links.md`, `references/ticket-authoring.md`, `references/invocation-contracts.md`.
- `references/readonly-guidance.md` — candidate reviews, repository audits, shortcut debt, and measurement claims.
- `references/external-trackers.md` — ticket `refs`, `add --github`.
## Choose one owner before adding ceremony
Before dispatching substantial or ambiguous work, pin a contract; see `user-story`. Check feasibility
before expensive implementation or tests for substantial/safety-sensitive work
(`references/ticket-authoring.md`). Small deterministic fixes keep one owner and a focused check;
a plan advisor needs a named architectural risk or contested approach, no mandatory panel.
For substantial work:
0. **One owner by default.** A bounded fix keeps one owner and a focused check; a small fix in a few known files may run inline without a ticket. Read-only investigations need no ticket: on a routed project spawn `route_recipe(category).research` so they run on the category route; native Explore only for unrouted projects.
1. **Story or wave only with a reason.** Require 3+ independently checkable pieces and a stated reason for separate owners. Pin shared interfaces, file boundaries and per-piece verification, then file the complete backlog under a Sidequest story. One-ticket mode stays story-less. A review panel needs a named risk for each lens.
2. **Link dependencies** (`link SQ-4 depends-on SQ-3`); shape a story as design → wave(s) →
integrate so `ready` serializes the phases.
3. **File the whole planned wave backlog before dispatching.** Give every ticket scope, dependencies, and
per-ticket verification; dispatch each ready wave concurrently. Do not drip-file a serial chain.
Dispatch independent pieces together only after the story or wave meets that threshold.
4. **Execute proportionally** — "Route execution down" below.
Trace the real flow, question necessity, then reuse local code, stdlib, native features or installed
dependencies before fixing the shared root. Prefer measured deletion; avoid hypothetical guards,
compulsory extractions and unrelated cleanup. Preserve trust-boundary validation, data-loss prevention,
accessibility, permissions and immutable candidate/review authority.
Answer direct questions and operational requests inline. Small bounded fixes in a few known files may stay inline without tickets; read-only investigations use `route_recipe(category).research` as above.
### INLINE-SAFE direct work
If inline-safe work was already ticketed, the orchestrator may claim `--direct` and edit inline after annotating the ticket, giving a 20+ character reason, and matching this allowlist:
- A failing integration gate pinpoints an exact, known small diff: a strict-TS null guard, an
assertion string synced after a deliberate reword, byte-checked golden regeneration, or a
merge-conflict resolution that preserves both sides' intent.
- Release bookkeeping: release fragments, the cut flow, or closing tickets with evidence.
- A small bounded fix in a few files at known locations, with a focused check.
`direct-ok` is a user signal that gates nothing. Use routed execution when the work exceeds the small bounded path or needs an independent candidate review; dispatched executors keep their claim, scope, verification and submission lifecycle.
## MCP is the executor board interface
Routed executors use **only** the `mcp__plugin_sidequest_board__*` tools for their lifecycle
(`commit`/`submit` take the executor's absolute worktree path). Missing tools → report the
blocker and release through an available board tool, never a command-line fallback.
MCP is the normal interface for board admin/config; the CLI is fallback for git-context operations.
Apply board-only admin changes directly through an available MCP tool, never as a ticket or dispatch. Live
category/profile edits affect only that board, not installation defaults unless the user asks. After a
schema-bumping release, reload plugins before MCP writes. Commands default to the current project;
`--project "<path-or-slug>"` (MCP: `project`) targets another board (creation rules: `references/board-features.md`).
`dispatch <ref>` is **instant**: it returns the ticket's stable executor, a short `spawn` fetch
stub, and a token. Pass every supplied `spawn` field (`name` and `description` too) to Agent
unchanged. Set `Agent.description` to `spawn.description` byte-for-byte, never derived from the
prompt, route marker, title, model, or effort. The executor fetches its
token-gated durable packet as the first action: full description, category route and contract, scope,
state, comment metadata, and absolute attachment paths. It must inspect every readable
attachment and report missing or unreadable ones, while the spawn keeps that content out of this
transcript. Never trust a worker's self-report — the
claim's token and exact executor name are the evidence.
**Workflow callers:** call `route_recipe` or `sidequest route <category> --json`; wire only `recipe.agent` in Agent: `model` and `subagentType` when set, `promptPrefix + prompt`. Never hand-translate route, gateway, marker or effort fields. For a ticketless read-only investigation spawn `recipe.research` (`references/routing-guide.md`). A user-named model for one ticket is that ticket's `route` override; never edit the category route (`references/routing-guide.md`).
**Locations:** CLI: `plugins/sidequest/bin/sidequest.js`; DB: `~/.claude/sidequest/sidequest.db`
(`SIDEQUEST_HOME`). Never scan from root.
## Routing profiles
A board selects one profile plus local ADD/OVERRIDE/DETACH/DISABLE rows. Mutations take one of
`--profile`/`--project`; details: `references/routing-details.md`. Category `readonly` selects the
restricted executor and `done` closeout. `--readonly true|false` overrides it for a prepared dispatch.
Read-only files or changes warn before dispatch. Resolve or override.
## Open the dashboard
`sidequest dashboard` starts the local server and prints the URL. Verify server changes in an isolated
`SIDEQUEST_HOME` on another port, never the shared board.
## File a ticket
`sidequest add -t "Contact form does not send" -d "..." --category <id>` — read the live taxonomy
(`category_list` MCP / `sidequest category list --json`), choose by description and persist its ID.
Use the fallback only when no category fits. `--complexity` is legacy ambiguity fallback;
never set `--model`/`--effort`. Scope, anchors, stories and exact verify: `references/ticket-authoring.md`.
Descriptions/comments render markdown with real newlines, never literal `
`. File a mid-task side issue
with `mcp__plugin_sidequest_board__add` and keep going; filing a ticket is not a request to work it.
## List / update / close
`sidequest list` (this project; `--status todo` for one column) · `projects` (every board) ·
`update SQ-3 --status done` (move; also `-p -t -d -l`) · `rm SQ-3` (delete). `--json` reads data;
`--brief` on `list`/`ready` implies `--json` and drops bodies. **Default to
`--brief` for routine orchestration reads.** "Close / ship it" → `--status done`.
## Work a ticket (safe with other agents)
The board may be shared: claim a ticket before touching it, atomically. **Never work a ticket you
haven't successfully claimed**, even one you just filed.
Lifecycle (executors use the matching MCP tools; CLI forms for inline/admin work):
`next`/`claim SQ-3 --by <you> --direct --reason "why this is inline-safe"` (only for the
INLINE-SAFE allowlist) → `commit` (declared ticket paths only) → run the briefing-supplied `verify-capture` wrapper after the final commit (it records the ticket, command, and checked candidate) → `submit --commit <hash> --verify
"<declared cmd>"` (parks the verified LOCAL commit). Retyped commands or prose cannot replace that capture. Manual and attestation verifiers keep their evidence flow.
or `done --model <model> --effort <level>` (inline/non-repo only) or `release` (drop unfinished,
optionally `--status todo`).
- **`--by` must be genuinely unique to this session** — a random token generated once (e.g.
`claude-<8 hex>`); a generic label lets two sessions silently coexist as one worker.
- **If a claim fails, do not work that ticket.** Retry a denied or unclaimed spawn only when `pulse <ref>`
shows a changed dispatch condition; otherwise record the refusal and surface it to the user. Never both
resume a prior executor and spawn a fresh one for the same ticket.
- **Read the thread before working a ticket** (`sidequest comments <ref>`). Default reads retain all
metadata; pass `--full` only for needed elided bodies.
- **Claims release on observed death, not age**: use `pulse`, never a clock. For work needing a decision, `SendMessage` the same agent. If its name fails, only the ORIGINAL matching host session may send once to authentic `dispatch.agentId` or its exact original Agent-returned identifier; never `claim.by` or a guessed/replacement address. Honor user Pause retries. Missing/mismatched identity stays continuation UNVERIFIED; preserve claim/work. A resume keeps claim, token-file path, and worktree binding. Queued/unknown/completed/absent/failed-send is not death. Never restart terminal executors; confirmed death requires salvage before replacement. Lost binding and died-before-claim recovery: `references/orchestration.md`.
- Agents report automatically. **Never use `TaskOutput`** for a Sidequest task ID or launch name. Liveness comes only from `pulse <ref>` and `changes --since`, read on a notification or user prompt, never right after spawning; a process list is never dispatch evidence. **No TaskStop after terminal evidence**: an executor ends its own run at submit, done, or release. `TaskStop({ task_id: "<agent name>" })` once is host cleanup only for a terminal ticket whose executor the host still lists running (host action, not Sidequest). Never stop a live claim, retained continuation, or candidate awaiting integration; never wake a completed executor or build a cleanup loop. **Never proxy-wait** with a shell/`Monitor`/cron task for an executor or artifact (a one-shot local readiness watch is fine).
**Repository publishing is the orchestrator's, alone.** Executors stop at verified local commits and
`submit` (claim released, parked in `doing`); `submit.body` is the canonical report, so no separate pre-submit
report comment; the terminal comment keeps only commit hash + verification. **Submit is terminal for the executor:** a
submitted ticket cannot be amended by messaging the executor that produced it, however small the
follow-up looks. File a follow-up ticket for changes. Redispatch the existing ticket only when it was
released without a pending submission. The orchestrator is the integrator: choose
`sidequest integrate <ref> --by <who> --mode apply|replay|merge` from the board default, then run the
publish transaction (lock → delivery → merged-tree gate → central version → review → push → reachability → `done`):
`references/publishing.md`.
**BOOKEND SUPERVISION.** Between dispatch and submission, avoid routine pulses, comment reads and
peeks. Explicitly assigned builders and readonly advisors may exchange direct native messages and
inspect authorized snapshots under `references/readonly-guidance.md`. Draft findings are advisory,
never acceptance or claim release; this does not authorize orchestrator source peeking or self-review.
At integration, read the submit report, deliver the range, and run the
merged-tree gate once per wave. Judge by that oracle and the submit report, never by reading diffs. When sized risk or a weak oracle needs independent review, bind a routed `review-audit` ticket with `reviewTarget`; never re-review yourself. Never mark a submitted ticket done without
integrating it; never re-dispatch one (refused as `submitted`). A dead executor's `done` only proves
the board transition, never that work shipped: salvage and close it per `references/publishing.md`.
## Route execution; keep the loop tight
Use read-only recon to pin the improvement, benefit, approach, and boundaries before routing;
routes select execution capacity, not product decisions. Investigations return compressed findings
(~1–2k tokens) as comments. Dispatch implementation fresh; executors own their tickets.
Direct claims require an INLINE-SAFE reason (20+ characters); they cannot legitimize prior investigation.
Native `Explore`, `claude-code-guide`, `Plan`, `statusline-setup`, and any general-purpose or custom
agent whose prompt and description carry no write intent run without a ticket. Ticket refs, route
markers, executor types, and resumed denied writes need a prepared dispatch.
**Loop:** spawn a wave, read executor reports and verified submissions, run each ticket's scoped
verification, then publish with one full-suite gate. Re-plan for the next wave.
Don't accept a green suite as proof of coverage; review execution evidence.
**The ticket is the spec:** include outcome, benefit, approach, boundaries, and implementation detail.
Spawn prompts add logistics; carry the full ticket contract without narrowing it.
**Keep useful work:** retain claims and checkpoints, await `SendMessage` steering for questions or
failed checks, and release only on confirmed death or unsalvageable blockers.
Batch small same-model tickets in one executor, never mix models. Parallel waves spawn one executor
per ticket in a single message.
**Ready** = unclaimed, unblocked, not done, not archived — `sidequest ready --json
--brief` lists exactly this set, partitioned into **parallel-safe waves** by declared file scope.
Fan out one wave at a time; worktrees isolate files, not runtime resources (ports, servers,
databases), so serialize those collisions even inside a wave. A claim under a `--by` you don't
recognize means another session may be working the board; flag it first. With
`CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` on, executors ARE teammates — use the teammate
affordances, don't ignore them: answer scope requests over the mailbox, steer and resume with
`SendMessage`, and never stop→redispatch work a message can fix. Wave mechanics,
liveness, salvage, cost levers, agent teams:
`references/orchestration.md`.
## Category-first routing (ENFORCED)
Sidequest owns ticket routing. Do not recreate a standalone Switchboard (a split-out router could
only ever be a shared library imported by Sidequest). The live taxonomy is the routing authority:
classify from it, persist the ID, and the category route resolves model and effort — never
hand-pick either. Legacy complexity maps to bands at read time (1–3/4–6/7–10 →
`coding.easy`/`normal`/`hard`) without persisting a category.
1. **Classify before claim.** A `category: null` ticket gets stamped via `update --category <id>`
**before** claim or spawn, then re-read. Reads never silently persist a classification.
2. **Trust the category projection.** Inject the read's category contract verbatim into the spawn
prompt alongside the ticket contract; do not narrow, rewrite, or invent around it.
3. **The ticket read tells you exactly what to spawn.** Print `SQ-n · category · Model · effort`,
then spawn the exact `agent` a fresh `dispatch <ref>` returned through native Agent,
pass returned fields unchanged. If Agent omits `name`/`mode`, dispatch `reducedAgentSchema: true`; don't
restore them. First claim: hook `agent_id` + `permission_mode: auto|bypassPermissions`. **Claude routes**:
`model: exec.model` (otherwise it inherits the pricey session model), including Haiku. Use the dispatched
executor/model, never generic Agent. **Codex routes** (`exec.model` null): omit `model`; the route marker
carries the real model and any value runs Anthropic. Effort is verbatim; mismatched claims are refused.
Details: `references/routing-details.md`.
4. **Claim by resolved route:** `next --model X` / `ready --model X` filter by resolved route.
## Comments
`comment SQ-3 -m` (durable handoff, keep working) · `comments SQ-3` (read the thread).
**Comments are cross-actor handoffs**: decisions, constraints, ruled-out approaches, risks, exact
verification command/result, concise findings. **Write findings back after an investigation**: root
cause with evidence (`file:line`), the fix, verification.
## Link tickets
`sidequest link SQ-4 depends-on SQ-3` (stored on both sides) · `blocks` · `related` (non-blocking) ·
`unlink` removes. A blocked ticket is skipped by `next` and excluded from `ready`.
## Guidelines
**Act, then report** the result (ref, status, or URL). **Keep titles tight**; detail goes in `-d`.
**Don't invent tickets**: only file what the user raised. Reminders, stories, human assignment:
`references/board-features.md`.
## Frozen work provenance
Only the main thread can set MCP `dispatch.workProvenance` before preparation. Its `kind` is
`new-behavior`, `behavior-preserving-refactor`, `inherited-read-only`, `docs`, `type-annotation-only`
or `fixture-only`. Each source names a native producer ref, its exact `preparedAt` (current dispatch
or an archived attempt) and an immutable owned `commit`, optionally a `captureId`. Missing
`baseCommit`/`sanctionedCommits` derive from its captures; ambiguity, other gaps or a
submission naming another candidate refuse by name. The board freezes base, scope, byte
and capture identity. The source stays unaccepted on its producer.
Unchanged inherited work and a declared GREEN behavior-preserving refactor do not need invented
new reds. New owned behavior keeps its own control requirements. Source/test byte drift, changed
producer generations, incompatible captures, worker self-grants and late declarations refuse.
The declaration is factual provenance only: execution, quality and admission remain UNVERIFIED.
It cannot rebind an old receipt or exempt held authored code. While its sources match, the
dispatch submits normally with the frozen record; integration runs the pinned verifier.