/member-run
Internal skill for commands. Spawn, hand the next brief to, correct or dismiss ONE named member - any lets:* role - of a team or an execute run, with the members registry (lets members) as the record of who is live. Do not trigger on user conversation; only when /lets:execute or
$ npx -y skills add restarter/lets-workflow --skill member-run --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/member-run
Context preview
The summary Claude sees to decide when to auto-load this skill.
Internal skill for commands. Spawn, hand the next brief to, correct or dismiss ONE named member - any lets:* role - of a team or an execute run, with the members registry (lets members) as the record of who is live. Do not trigger on user conversation; only when /lets:execute or
SKILL.md
member-run.SKILL.mdname: member-run
description: Internal skill for commands. Spawn, hand the next brief to, correct or dismiss ONE named member - any lets:* role - of a team or an execute run, with the members registry (lets members) as the record of who is live. Do not trigger on user conversation; only when /lets:execute or /lets:team runs a member.
user-invocable: false
Member Run
One operation on one named member. The caller (`/lets:execute` Step 5-D, `/lets:team`) owns the plan, the gates, the run record, the diff check, the commits and the tracker; this skill owns only the agent call and its registry entry. It is the single place LETS spawns, resumes, corrects or dismisses a member.
> **IMPORTANT:** If the spec below invokes any deferred tool (e.g. `AskUserQuestion`, `SendMessage`), you MUST load and call it as specified. Never skip the call, never substitute a default answer of your own - the tool invocation is part of the contract. This is critical.
Args
| op | args | does | |---|---|---| | `spawn` | `scope=<s> name=<n> role=<r> brief-file=<path> report-file=<abs path> [model=<m>] [isolation=worktree]` | Step 0 (first spawn of the scope), Step 1 when it applies, then Step 2 | | `next` | `scope=<s> name=<n> brief-file=<path> report-file=<abs path>` | Step 3 - the member's next brief | | `correct` | `scope=<s> name=<n> correct-file=<path> report-file=<abs path>` | Step 3 - an amendment to its current brief | | `dismiss` | `scope=<s> name=<n>` | Step 4 |
- `scope` - the team's callsign, or `run-<RUN>` for an execute run.
- `name` - the member name, `[a-z0-9-]{1,40}`: the bare roster name in a team scope (`architect`, `architect-2`), in an execute scope `impl-<RUN>` (a replacement `impl-<RUN>-r<generation>`), `explorer-<RUN>`, `skeptic-<RUN>`, `architect-<RUN>`.
- `{agent}` below is the name the agent runs under: `<callsign>-<name>` in a team scope (pane names are machine-wide), the bare name in an execute scope - the `agent_name` `lets members` records.
- A member with a recorded `agent_id` - an isolated member, which the harness runs as a background agent reachable only by the id its `Agent` call returned, never by name - is addressed by that id: every `SendMessage` and `TaskStop` below puts the `agent_id` where it says `{agent}`.
- `role` - a shipped `lets:*` agent except `lets:actor`; `lets members add` refuses anything else.
- `brief-file` / `correct-file` - repo-root-relative paths the caller wrote. Every brief crosses as a file path, never inline.
- `model` - `opus` | `sonnet` | `fable` | `haiku`, the values the `Agent` tool accepts. Absent -> the role's own default, except for an implementer (Step 1).
- `report-file` - an absolute path the CALLER named (execute: its pinned `.lets/cache/report-...` path; team: `agent-report op=open` / `op=add`). One file per round; member-run never composes a report path. Required on `spawn`, `next` and `correct`: missing -> stop with `report_file_missing`, nothing sent.
Every operation returns as soon as its call is issued. The member runs in the background; its report arrives later as a `REPORT_WRITTEN` pointer to the round's REPORT_FILE, and the caller reads the FILE through `agent-report` (`op=peek` on every notification, `op=collect` to conclude) - never the message.
Step 0: Binary check (once per scope, before the first spawn)
lets members status --scope {scope} --jsonExit 0 -> continue. An unknown command or any failure -> stop with "this plugin needs a newer lets binary - run /lets:update"; nothing is spawned.
Step 1: Model panel (role=lets:implementer, no model, first spawn of the scope)
The caller has already passed its Start gate - delegation is approved; this only picks the model.
AskUserQuestion(
questions=[{
question: "Which model should the implementers in this run use?",
header: "Model",
options: [
{ label: "Opus (Recommended)", description: "Strong at a mid price; the default for plan implementation" },
{ label: "Fable", description: "Most capable, about twice Opus's price; for the hardest chunks" },
{ label: "Sonnet", description: "Cheaper and faster; good for mechanical chunks" },
{ label: "Haiku", description: "Cheapest; for small, well-specified edits" }
],
multiSelect: false
}]
)**Other** -> accept only `opus`, `sonnet`, `fable` or `haiku`; for anything else, name those four values and ask again. Return the chosen value; the caller records it and passes `model=` on every later `spawn` of the scope.
Step 2: Spawn
1. `lets members status --scope {scope} --json` - read `lead`, and the entry of `name` when there is one.
- A team scope (not `run-*`) whose `lead` is null or not `live` / `rotated`, or whose `lead.session` is not `$CLAUDE_CODE_SESSION_ID` -> stop: `no_lead: {scope} has no live lead, or this session is not it - /lets:start in the team's lead session claims it`. Nothing is spawned. (The registry's add in item 3 refuses the same caller with `lead_held`.)
- An entry of that name that is `live`, `rotated` or `unknown` -> stop: `name_live: {name}`. The caller picks another name.
2. The Agent call:
Agent(
subagent_type="{role}",
name="{agent}",
model="{model}",
description="{role} {name}",
prompt="Your brief is the file {brief-file}. Read it first and follow it; every later NEXT or AMENDMENT names a new file.\nREPORT_FILE: {report-file}"
)Add `isolation="worktree"` only when `isolation=worktree` was passed. Pass no team or permission-mode parameter: the harness documents both as deprecated and ignores them. 3. Right after the Agent call, record it:
lets members add --scope {scope} --name {name} --role {role} --jsonAdd `--model {model}` when a model was chosen. With `isolation=worktree`, add `--isolation worktree --worktree-path {path} --worktree-branch {branch} --agent-id {id}` from what the Agent call reports - the id is the only address of an isol
Read more
name: member-run description: Internal skill for commands. Spawn, hand the next brief to, correct or dismiss ONE named member - any lets:* role - of a team or an execute run, with the members registry (lets members) as the record of who is live. Do not trigger on user conversation; only when /lets:execute or /lets:team runs a member. user-invocable: false
Member Run
One operation on one named member. The caller (`/lets:execute` Step 5-D, `/lets:team`) owns the plan, the gates, the run record, the diff check, the commits and the tracker; this skill owns only the agent call and its registry entry. It is the single place LETS spawns, resumes, corrects or dismisses a member.
> **IMPORTANT:** If the spec below invokes any deferred tool (e.g. `AskUserQuestion`, `SendMessage`), you MUST load and call it as specified. Never skip the call, never substitute a default answer of your own - the tool invocation is part of the contract. This is critical.
Args
| op | args | does | |---|---|---| | `spawn` | `scope=<s> name=<n> role=<r> brief-file=<path> report-file=<abs path> [model=<m>] [isolation=worktree]` | Step 0 (first spawn of the scope), Step 1 when it applies, then Step 2 | | `next` | `scope=<s> name=<n> brief-file=<path> report-file=<abs path>` | Step 3 - the member's next brief | | `correct` | `scope=<s> name=<n> correct-file=<path> report-file=<abs path>` | Step 3 - an amendment to its current brief | | `dismiss` | `scope=<s> name=<n>` | Step 4 |
- `scope` - the team's callsign, or `run-<RUN>` for an execute run.
- `name` - the member name, `[a-z0-9-]{1,40}`: the bare roster name in a team scope (`architect`, `architect-2`), in an execute scope `impl-<RUN>` (a replacement `impl-<RUN>-r<generation>`), `explorer-<RUN>`, `skeptic-<RUN>`, `architect-<RUN>`.
- `{agent}` below is the name the agent runs under: `<callsign>-<name>` in a team scope (pane names are machine-wide), the bare name in an execute scope - the `agent_name` `lets members` records.
- A member with a recorded `agent_id` - an isolated member, which the harness runs as a background agent reachable only by the id its `Agent` call returned, never by name - is addressed by that id: every `SendMessage` and `TaskStop` below puts the `agent_id` where it says `{agent}`.
- `role` - a shipped `lets:*` agent except `lets:actor`; `lets members add` refuses anything else.
- `brief-file` / `correct-file` - repo-root-relative paths the caller wrote. Every brief crosses as a file path, never inline.
- `model` - `opus` | `sonnet` | `fable` | `haiku`, the values the `Agent` tool accepts. Absent -> the role's own default, except for an implementer (Step 1).
- `report-file` - an absolute path the CALLER named (execute: its pinned `.lets/cache/report-...` path; team: `agent-report op=open` / `op=add`). One file per round; member-run never composes a report path. Required on `spawn`, `next` and `correct`: missing -> stop with `report_file_missing`, nothing sent.
Every operation returns as soon as its call is issued. The member runs in the background; its report arrives later as a `REPORT_WRITTEN` pointer to the round's REPORT_FILE, and the caller reads the FILE through `agent-report` (`op=peek` on every notification, `op=collect` to conclude) - never the message.
Step 0: Binary check (once per scope, before the first spawn)
lets members status --scope {scope} --jsonExit 0 -> continue. An unknown command or any failure -> stop with "this plugin needs a newer lets binary - run /lets:update"; nothing is spawned.
Step 1: Model panel (role=lets:implementer, no model, first spawn of the scope)
The caller has already passed its Start gate - delegation is approved; this only picks the model.
AskUserQuestion(
questions=[{
question: "Which model should the implementers in this run use?",
header: "Model",
options: [
{ label: "Opus (Recommended)", description: "Strong at a mid price; the default for plan implementation" },
{ label: "Fable", description: "Most capable, about twice Opus's price; for the hardest chunks" },
{ label: "Sonnet", description: "Cheaper and faster; good for mechanical chunks" },
{ label: "Haiku", description: "Cheapest; for small, well-specified edits" }
],
multiSelect: false
}]
)**Other** -> accept only `opus`, `sonnet`, `fable` or `haiku`; for anything else, name those four values and ask again. Return the chosen value; the caller records it and passes `model=` on every later `spawn` of the scope.
Step 2: Spawn
1. `lets members status --scope {scope} --json` - read `lead`, and the entry of `name` when there is one.
- A team scope (not `run-*`) whose `lead` is null or not `live` / `rotated`, or whose `lead.session` is not `$CLAUDE_CODE_SESSION_ID` -> stop: `no_lead: {scope} has no live lead, or this session is not it - /lets:start in the team's lead session claims it`. Nothing is spawned. (The registry's add in item 3 refuses the same caller with `lead_held`.)
- An entry of that name that is `live`, `rotated` or `unknown` -> stop: `name_live: {name}`. The caller picks another name.
2. The Agent call:
Agent(
subagent_type="{role}",
name="{agent}",
model="{model}",
description="{role} {name}",
prompt="Your brief is the file {brief-file}. Read it first and follow it; every later NEXT or AMENDMENT names a new file.\nREPORT_FILE: {report-file}"
)Add `isolation="worktree"` only when `isolation=worktree` was passed. Pass no team or permission-mode parameter: the harness documents both as deprecated and ignores them. 3. Right after the Agent call, record it:
lets members add --scope {scope} --name {name} --role {role} --jsonAdd `--model {model}` when a model was chosen. With `isolation=worktree`, add `--isolation worktree --worktree-path {path} --worktree-branch {branch} --agent-id {id}` from what the Agent call reports - the id is the only address of an isol
A development workflow plugin for Claude Code Stop babysitting your AI. Start shipping with it.
Repo: restarter/lets-workflow
Other skills on lets-workflow.
goal-test
Local sandbox for experimenting with Claude Code's /goal command (stop-hook condition +…
loop-bb-pr
Compose a /loop that monitors a Bitbucket PR for activity (new comments, review state…
loop-gh-pr
Compose a /loop that watches all open GitHub PRs for activity (new PRs, new commits, new…
loop-test
Local sandbox for experimenting with Claude Code's /loop command (interval +…
actor-fetch-personalit…
Internal skill for commands. Fetch and validate personality from URL or file path for Actor…

