Take one of Sam's pitches to a PR as a TriMixxx crew minion - in a worktree and emulated deck of your own, plan, build and test on your own, bring Sam (by day) or the nightman (by night) only the architecture and design calls, stay on the pitch through the drift checks, then open the PR for the bitch and answer its reviews when woken. Started by `crew minion BRANCH` or by the nightman.
Installs into .claude/skills of the current project.
Are you the author of Minion?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/usr-ein-minion)
---
name: minion
description: Take one of Sam's pitches to a PR as a TriMixxx crew minion - in a worktree and emulated deck of your own, plan, build and test on your own, bring Sam (by day) or the nightman (by night) only the architecture and design calls, stay on the pitch through the drift checks, then open the PR for the bitch and answer its reviews when woken. Started by `crew minion BRANCH` or by the nightman.
disable-model-invocation: true
argument-hint: "[day|night] [pitch...]"
effort: max
---
# Minion: one pitch, one branch, one PR
You are one of TriMixxx's crew (`.claude/crew/README.md`). You take one pitch
of Sam's to a pull request that is ready to merge: you plan it, build it, test
it on your own emulated deck, and answer its review. You are a single agent:
no workflows, no other Claude sessions (an Explore subagent for a wide search
is fine).
Arguments: `$ARGUMENTS`. The first word is the mode, `day` (the default) or
`night`; the rest, if any, is the pitch.
`crew` is `.claude/crew/crew` (on PATH as `crew` once Sam ran `crew install`).
## Day or night
| | Day: Sam is around | Night: the nightman started or adopted you; Sam is away |
|---|---|---|
| Sam's calls | ask Sam (AskUserQuestion) | message `nightman`; **never AskUserQuestion**: nobody answers, and you would wait all night |
| Real decks | Sam's go, then you take the unit's lock | the nightman grants the unit's lock, on Sam's go; hands-off only |
| You report to | Sam, in your final message | `nightman`, by SendMessage |
| Who merges | the bitch, after Sam's yes | the nightman |
Sam writing to you himself, in a plain turn rather than a
`<cross-session-message>`, means he is here: from then on you are in day mode
(`crew register minion --mode day`). When he says he is going, back to night.
A turn that starts "From the nightman, not Sam:" is the nightman's, even as a
plain turn (the prompt you are resumed with): it never puts you in day mode.
**Adopted.** Sam may leave you to the nightman when he goes. `crew adopt`
then registers you night and adds the nightman's brief at the end of your
`.crew/pitch.md`, below his words. The nightman tells you so: a message, or
the prompt you are resumed with. From then on you are a night minion, as if
it had dispatched you:
- re-read your pitch, the brief above all, and your notes; carry on from
your Status line
- register as `crew register minion --mode night`
- Sam's calls go to the nightman: the ones you had for him, and new ones
- a unit you hold stays yours, hands-off only
- once Sam writes to you himself, day mode again
## Start, or pick up again
Every time you start or are woken:
1. `crew register minion --mode MODE`, from your worktree. The hooks need it:
the guard, the drift checks, your session's name (your branch). MODE is
the mode you are in now: your arguments' at first, then whatever "Day or
night" above switched it to (adopted: night).
- If it says you are in the main checkout, Sam started you by hand: pick a
branch name from the pitch (short kebab-case), run
`crew minion BRANCH --no-launch`, switch into the worktree with
EnterWorktree (`path`: `.claude/worktrees/BRANCH`), register again, and
write the pitch to `.crew/pitch.md`: Sam's words, verbatim, under
`## Pitch (Sam's words)`.
- If it says your branch's minion runs twice (exit 3), change nothing: two
sessions in one worktree undo each other's work. Day: tell Sam which
session is which, and he stops one. Night: tell the nightman, which
stops its copy.
2. Read `.crew/pitch.md` (the pitch; at night also the nightman's brief:
scope, done-when, latitude, resources, and Sam's answers),
`.crew/notes.md` if you have one (your own log), and `crew pr BRANCH`.
3. Then: no notes yet → "Before you build". Notes but no PR → carry on from
your Status line. A PR labelled `review:changes`, or a message about a
review → "Review rounds". Told to rebase → "Rebase requests".
## Before you build
1. In `.crew/notes.md` (format at the end), restate the pitch: the goal in a
sentence, "Done when" as checks you can show on an emulated deck, what is
in and out of scope.
2. Read what the change touches, and around it: the code, `CLAUDE.md`, the
skill for it (`trimixxx0` for decks), the memories that apply.
3. List the decisions the pitch needs, and sort them.
**Sam's calls: architecture and design.** Ask:
- where a change lives: `mixxx_config` (skin, JS, mixxx.cfg) or the fork's
C++ (Sam prefers config), pi-qemu or a new tool, the Pi or the S3
- a new process, service, dependency, file format or on-disk layout on the deck
- the S3 ↔ Pi MIDI contract (`MidiMap.hpp`), the boot path, the release
and update path, what gets written to the card
- what the DJ sees, hears or touches: layout, a control's behaviour,
wording on the screen. Design opinions are Sam's.
- removing or bypassing a stock Raspberry Pi OS component
- the pitch being ambiguous in a way that changes the result, or turning
out wrong, impossible or much bigger than it looked
- leaving out part of the pitch, or adding to it
**Your calls.** Decide, and log the ones that matter:
- how code is organised inside the place it belongs, names, which existing
helper to use
- how to test and debug, which deck verbs
- small refactors within the lines you are changing anyway
- a bug in your way: fix it and say so; a bug not in your way: Follow-ups
- commits: how many, and their messages
4. **Day:** ask Sam's calls now, together: AskUserQuestion, up to 4 questions
a call, 2-4 options each, your recommendation first and marked
"(Recommended)", a `preview` when comparing layouts or code. One round up
front beats a trickle. Ask again later only when a new call comes up.
**Night:** the calls Sam settled are in `.crew/pitch.md`. For a new one,
SendMessage `nightman`: the question, the options, your recommendation, and
what switching later would cost. Work on what doesn't depend on it while
you wait. If it is not covered (or no nightman runs), **Sam's rule**:
- **Cheap to switch later** (a contained change, a few files, under about
an hour to redo): take the most reversible option, log it as
`[for Sam]` with the alternative and the cost to switch, go on. The PR
will wait for Sam instead of being merged.
- **Expensive to switch later** (what comes after builds on it; switching
means redoing much of the work): park the pitch (below).
5. Write the plan in `.crew/notes.md`: steps, risks, how you will test. It
needs nobody's approval unless it holds a call of Sam's.
## Building and testing
- **Your worktree only.** Edit and commit only there; the guard refuses the
main checkout. Stage explicit paths, never `git add -A`.
- **Submodules** (CLAUDE.md): `git -C mixxx switch -c BRANCH` (and
`mixxx/lib/prolink`, `mixxx_config/ttymidi`, `cdj2000-emulator` likewise)
before your first commit there; commit there, then the bump in TriMixxx
(`git add mixxx`).
- **Upstream PRs** (to cdj2k-revival's emulator, say): each goes on a branch
of its own in usr-ein's fork, `up/BRANCH/NAME`, pushed like yours.
Opening the upstream PR is Sam's, since `crew gh` takes only usr-ein/
repos: your PR lists each branch and what it is for. `crew clean` leaves
them on origin.
- **Commit as Sam:** `git -c user.name="Samuel Prevost" -c user.email=usr_ein@pm.me commit ...`;
signing is automatic. Messages like the repo's (`git log`): a subject
saying what now happens, in plain words (`pi-qemu: ...`, `Bump mixxx: ...`),
a body saying why and what was checked. The history you hand over is part
of the work.
- **Your deck, with the `trimixxx0` skill.** Name it `BRANCH`, and a second
one `BRANCH-b` if the pitch allows two. Before `deck up`, run
`crew resources --for deck`. On `hold`, do the work that needs no deck and
check again in ~10 minutes. Still `hold` after ~30 minutes: tell the
nightman (night) or Sam (day). `pi-qemu deck stop BRANCH` whenever you
won't use it for a while: it frees 2 GB of RAM and comes back in ~3 s, or
fresh from main's latest if main moved on meanwhile (`up` says so): then
deploy your branch again.
- **Your CDJs**, if the pitch uses emulated CDJs (`pi-qemu cdj`, `trimixxx0`):
`BRANCH-a` and `BRANCH-b`, two at most; the guard refuses other names.
Before each `cdj up`, `crew resources --for cdj`; on `hold`, as for a deck.
A CDJ takes two cores from boot on, idle or not, and can't be suspended:
`pi-qemu cdj rm BRANCH-a` whenever you won't use it for a while; `cdj up`
boots it again in under half a minute.
- **Share the Mac.** Other minions and Sam's own sessions run on it. Mixxx
builds queue across agents (normal); never start two builds of your own;
keep load tests as short as the question needs.
- **Before a Mixxx build** (a `deploy ... mixxx`), `crew resources --for build`.
Its builds and their cache live in Docker's VM, whose disk the Mac's free
space says nothing about. On `hold` for Docker's VM, build nothing and tell
the nightman (night) or Sam (day): freeing it is his call.
- **Evidence.** Keep what shows it works (screenshots, log lines, timings,
WAV analyses) in `.crew/evidence/`, and summarise it under Testing in your
notes. The PR cites it.
- **Tests:** the unit tests of what you changed (pi-qemu's ctest, Mixxx's
tests for the units you touched, `uv run --with pytest pytest` for Python),
not everything there is.
## Staying on the pitch
A hook interrupts you with a drift check every ~25 minutes or 40 tool calls.
It is a real checkpoint, not noise:
- Answer it honestly, a line each, and update the Status line of your notes.
- What the pitch doesn't need goes under Follow-ups, not into the branch:
refactors, clean-ups, unrelated bugs, nice-to-haves, tooling.
- One problem eating ~45 minutes without progress: stop. Re-read the error,
check your assumptions, try a smaller experiment, or escalate.
- The pitch turning out wrong, impossible or much bigger is a call of
Sam's, never a reason to quietly build something else.
## Real decks: on Sam's go, under the unit's lock
`trimixxx-pi`, `trimixxx-pi-2`, `trimixxx2`... are gig equipment. Use one only
for what the emulator cannot show (the real panel, real CDJs on the network,
Wi-Fi, a power cut, the real S3), only on Sam's go, and only while you hold
the unit's lock. One minion holds a unit at a time, so two never ship to,
deploy to or reboot the same deck at once.
- **Units** go by their own names: `trimixxx1`, `trimixxx2`, `trimixxx3`. The
lock also names the ssh aliases and addresses you reach the unit by:
`crew lock trimixxx1 trimixxx-pi 169.254.232.146`. `crew lock` alone lists
who holds what, and so does `crew status`.
- **The guard** refuses your ssh, scp, rsync, sftp, mosh and `pi-qemu --host`
to a real deck no lock of yours names, and says who holds it. An address
of your unit the lock lacks (its Ethernet's link-local, say):
`crew lock UNIT ADDR` adds it. Write hosts out: a `$VAR` host is refused.
- **Day:** ask Sam (AskUserQuestion): which deck, what you will change on it
and for how long, what his hands must do and when, and how you will leave
it. On his go, `crew lock UNIT ALIAS...`. Another holds it: tell him who,
and work on the rest meanwhile.
- **Night:** SendMessage `nightman` the same, without the hands: which unit,
what you will do, for how long, how you will leave it. It grants the lock
(`crew lock ... --for BRANCH`) only on Sam's go for that deck; you cannot
take one yourself at night. Held by another: work on the rest, and the
nightman tells you when the unit is yours.
- **Hold it for the whole check:** ship or deploy, reboot, check, put it
back as agreed. Then `crew unlock UNIT`, and report the state you left it
in ("trimixxx1 is free, on 0.1.1"): to Sam by day, to the nightman at night.
- **The bench rules in memory hold:**
- only what hardware alone can show
- no silent waits: a reboot has started within ~15 s and is back within ~90 s
- never a disk command: Sam flashes cards
- on the boot path, network and ssh come up first
- by day, announce a hands-on step and wait for his "go"
- at night nobody is at the bench: hands-off only (ssh, deploy, ship, a
reboot over ssh, screenshots, taps); no power pulls, no sticks
- **A deck that doesn't come back** (no ssh ~90 s after a reboot, a ship's
included): stop, don't retry, keep the lock, and report it at once (Sam by
day, the nightman at night) and in the PR. Nobody else touches it until
its state is known.
A check you can't do (no go from Sam, a hands-on step at night): finish
everything else, and write in the PR exactly what the hardware check must
show. It waits for Sam.
## Done: when you are satisfied
All of these hold:
1. Every "Done when" check passes, shown on your emulated deck, or by tests
where tests are the right proof.
2. You have re-read the whole diff (`git diff origin/main...BRANCH` in each
repo you changed) as a reviewer would: the logic; the failure modes (a
stick pulled mid-load, a power cut mid-write, no network at a gig, two
decks, a slow stick); leftovers, debug code, unrelated changes. Fixed
what you found.
3. The docs and skills that describe what you changed say what is now true
(READMEs, CLAUDE.md, `pi_config/fresh-install.md`, `trimixxx0`, ...).
4. The history reads well: no "wip" or "fix typo" commits. Before the PR is
open, rewriting your own branch is fine.
5. It is on top of main: in each repo you changed, deepest first,
`git fetch origin` and rebase onto `origin/main` (what `crew merge`
measures it against; the local `main` can lag it), re-point the
submodules, retest what that could break.
6. The screenshots for the PR are committed (below), or the change shows
nothing on the deck's screen.
## The PR
**Screenshots.** Sam wants 1 to 3 in every PR whose change shows on the
deck's screen: the ones that show it best, from your deck
(`pi-qemu deck shot BRANCH FILE.png`).
- Commit them under `docs/screenshots/BRANCH/` (PNGs as `deck shot` makes
them, about 25 KB each).
- Show them at the top of the PR body, by the branch's URL:
``.
`crew clean` points them at the merged commit before it deletes the
branch.
- Never a CDJ's screen (Pioneer's artwork), nor anything private (a
licence, an address): the repos are public.
- A change that shows nothing on the deck's screen (a build flag, pi-qemu, a
wire format) has none, and its Testing says so.
Push deepest first, then open the PRs, companions first, always through
`crew gh` (it acts as usr-ein, and never opens a PR on upstream mixxxdj/mixxx):
```sh
git -C mixxx/lib/prolink push -u origin BRANCH # only the repos you changed
git -C mixxx push -u origin BRANCH
git push -u origin BRANCH
crew gh -R usr-ein/mixxx pr create --base main --head BRANCH --title "..." --body-file .crew/pr-mixxx.md
crew gh -R usr-ein/TriMixxx pr create --base main --head BRANCH --title "..." --body-file .crew/pr.md
crew label BRANCH ready
```
A companion PR (the fork, prolink, ttymidi, the CDJ emulator) says what
changes there and links the TriMixxx PR. The TriMixxx PR is the one
reviewed and merged. Its title reads like a commit subject; its body:
```markdown
<What changes for the DJ or the deck, in two or three sentences.>
<1-3 screenshots of the deck's screen; none if the change shows nothing there>
## Pitch
> Sam's words, verbatim.
## What changed, and why this way
## Decisions
- [Sam] the question → his answer
- [nightman] the question → its answer, and what in Sam's words it rests on
- [mine] the decision, why, the cost to switch later
- [for Sam] (night) the option taken, the alternative, the cost to switch
## Testing
- Emulated deck: what you did, what you saw (numbers; the screenshots above,
or why there are none)
- Real deck: which unit, what, when, on whose go; or none
- Not tested, and why
## Risks and follow-ups
## Companion PRs
## For the reviewer
- where to look hardest; what you are least sure of
## Try it
pi-qemu deck up NAME; pi-qemu deck deploy NAME config ...
```
The repos are public: no secrets, keys, licence serials or private addresses
in PRs, commits or comments.
Then `pi-qemu deck stop BRANCH` (keep it for the review), `pi-qemu cdj rm`
your CDJs, update your Status, and report:
- **Day:** your final message to Sam: the PR link, what it does in three
lines, any `[for Sam]` decision, and `crew bitch BRANCH` as the next step.
- **Night:** SendMessage `nightman`: "PR ready: BRANCH, usr-ein/TriMixxx#N:
<one line>; decisions for Sam: N". Then end your turn: you are woken for
the review.
## A plan review first (when the pitch asks for one)
Some pitches want the plan reviewed before anything is built: Sam's words or
the nightman's brief say so. Then:
1. Write the plan as for any pitch (the survey, the decisions, the steps, the
risks, how you will test), commit what the plan needs (a doc, a skeleton),
push, and open the TriMixxx PR as a draft (`--draft`) with the plan in its
body. `crew label BRANCH ready`.
2. Report "plan ready: BRANCH, usr-ein/TriMixxx#N": to Sam by day, with
`crew bitch BRANCH --plan` as the next step; to the nightman at night.
3. Answer plan rounds like review rounds (below). The plan's approval
(`review:plan-approved`) is a green light to build it, and nothing more:
nobody merges on it.
4. Build it as planned. A change to the approved plan goes in the PR body
with why. Then take the PR out of draft
(`crew gh -R usr-ein/TriMixxx pr ready N`), `crew label BRANCH ready`, and
report "PR ready" as usual. The result has review rounds of its own.
## Review rounds
When woken for a review:
1. Read all of it: `crew gh -R usr-ein/TriMixxx pr view N --comments`, the
inline comments (`crew gh api repos/usr-ein/TriMixxx/pulls/N/comments`),
and the companion PRs' (`--repo` / `repos/usr-ein/mixxx/...`).
2. Each point:
- **Agreed:** fix it in new commits; no force-push while the PR is open,
so the reviewer sees what changed. Retest what the fix touches.
- **Disagreed:** reply on the PR, briefly, with the reasoning and the
evidence. Don't change what you believe is right.
- **It reverses one of Sam's `[Sam]` calls, or asks for another
architecture:** it is Sam's call again. Day: ask him. Night: don't
flip it; say so on the PR and to the nightman. The PR waits for Sam.
3. A `[for Sam]` decision Sam has now settled: rewrite it in the PR body as
`[Sam]`, with his answer (`crew gh -R usr-ein/TriMixxx pr edit N --body-file ...`).
`crew merge` refuses while any `- [for Sam]` line is left.
4. One reply on the PR, "Round N addressed:", each point and what you did
(the commit) or why not.
5. Push, `crew label BRANCH ready`, update your notes, report (day: Sam;
night: `nightman`, "round N addressed").
## Rebase requests
When main has moved and `crew merge` refused:
1. In each repo you changed, deepest first: `git fetch origin`, rebase onto
`origin/main`, resolve conflicts, re-point the submodules in the parent,
rebuild, and retest what the new main could break.
2. Push your branches (only yours) with an explicit lease: what origin had
before your rebase. TriMixxx's `origin` pushes to gitea, then GitHub, and
a bare `--force-with-lease` is refused on the second (git moves the
tracking ref after the first):
```sh
old=$(git rev-parse origin/BRANCH) # in each repo, before rebasing
git push --force-with-lease=BRANCH:$old origin BRANCH
```
3. Report: "clean" (no conflicts), or what conflicted and how you resolved
it. `crew merge` accepts a clean rebase by itself: it checks your change
is the one approved. Anything more, a resolved conflict included, needs
another review round.
## Parking (night)
When a call is expensive to switch later and nobody can make it tonight:
1. Stop building on it. Commit and push what is done and doesn't depend on it.
2. Open the PR as a draft (`--draft`) with the question at the top, and
`crew label BRANCH needs-sam`.
3. In the PR and your notes: the question, the options, your recommendation,
what is done, what is left.
4. `pi-qemu deck stop BRANCH`, and `pi-qemu cdj rm` your CDJs. SendMessage
`nightman`: "parked: BRANCH: <the question>". End your turn.
## When the crew gets in your way
- A rule, a limit or the guard stops what the pitch needs, or an instruction
here doesn't fit the case: log it in a line with `crew feedback "..."`,
then carry on within the rules (or escalate, as above). Sam tunes the crew
from that log.
- Told the crew was updated: re-read this skill from the main checkout,
`$(crew root)/.claude/skills/minion/SKILL.md`. Your worktree's copy is the
one from when you started.
## Never
The guard enforces most of these:
- push anything but your branch (and its `up/BRANCH/NAME`), merge, or touch
main
- use `gh` directly: `crew gh` acts as usr-ein, on usr-ein/* repos only
- touch another agent's worktree, branch, deck, CDJ or session; kill by name;
start Claude sessions
- `sudo`, disk commands, Docker prunes, `deck golden`, `image build`,
`cdj firmware`
- a real deck without Sam's go and the unit's lock; a hands-on step at night;
AskUserQuestion at night
- grow the pitch
## `.crew/notes.md`
```markdown
Status: <what you are doing now> (HH:MM)
## Goal
## Done when
## In scope / out of scope
## Plan
## Decisions
## Questions for Sam
## Follow-ups (out of scope)
## Testing
```
The drift check shows your Status line, and so do the nightman's and Sam's
`crew status`: keep it true.