@rallycry/conveyor-agent 10.13.72 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,258 @@
1
+ ---
2
+ name: conveyor-local-loop
3
+ description: Run this machine as a serial local claudespace — pick the session owner's highest-priority Open Conveyor card, claim it, execute its plan to the PR finish line, repeat. Handles single cards AND whole packs (an Open pack parent is driven end-to-end per conveyor-build's pack path, then the loop moves on once the pack's final PR is open). One invocation = one iteration; run continuously with "/loop /conveyor-local-loop" (no interval) and it self-paces (~1-2 min between cards while the queue has work; when the queue is empty it blocks on live board events via conveyor-wait and wakes seconds after a card becomes claimable, with a ~25 min fallback poll). Use when the user says "/conveyor-local-loop", "start the local loop", "work my open cards locally", or wants planned cards executed with full local CPU/RAM instead of spawning claudespaces. For exactly one card, or one pack and nothing else, use conveyor-build.
4
+ ---
5
+
6
+ # Conveyor Local Loop
7
+
8
+ Turn a queue of researched Open cards (usually authored via `/conveyor-plan`)
9
+ into review-ready PRs using this machine, one card at a time. Behave exactly as
10
+ a claudespace agent would: the card IS the spec, task chat is the log, and the
11
+ host repo's CLAUDE.md governs gates, verification, and PR mechanics. This skill
12
+ adds only selection, claiming, cadence, and local-machine hygiene.
13
+
14
+ ## Ground rules
15
+
16
+ - **Conveyor is the state store.** The loop session spans days and gets
17
+ compacted; at each iteration re-derive state from MCP reads, never from
18
+ conversation memory.
19
+ - **All Conveyor tools fully-qualified** (`mcp__conveyor__get_task`; bare names
20
+ fail).
21
+ - **WIP = 1.** At most one card claimed by this loop at a time.
22
+ - **Never `start_task`** — that boots a cloud pod and duplicates the work. Only
23
+ exception: the opt-in offload valve below.
24
+ - **Never approve or merge your own PRs.** Finish line = card in ReviewPR with
25
+ green CI; the user takes it from there.
26
+ - **Only cards created by the session owner** (match against
27
+ `mcp__conveyor__get_connection_context`), status Open, unassigned. Teammates'
28
+ cards and pod-claimed cards are off limits.
29
+ - **Pack cards: claim the whole pack; the parent card stays parked.** An Open
30
+ feature-branch pack parent that passes the claiming filters is claimable as
31
+ a PACK: enter pack mode (below) and drive every child to the final parent
32
+ PR per [conveyor-build's pack path](../conveyor-build/references/pack-path.md). Throughout,
33
+ the parent card itself stays PARKED — never Build/`start_task` it, never
34
+ set it InProgress; the finale `create_pull_request` is what moves it to
35
+ ReviewPR. A parent already InProgress/ReviewPR has (or had) an active
36
+ coordinator — hands off it AND its children: an actively-orchestrating
37
+ parent reads a headless InProgress child as a dead agent environment and
38
+ "recovers" it onto a cloud pod (observed 2026-07-28 — duplicate
39
+ implementation). A NON-feature-branch pack — children PR straight into dev,
40
+ so there is no pack branch to coordinate — is never claimed as a pack:
41
+ conveyor-build's pack path explicitly does not apply to it. Claim those children
42
+ individually, one per iteration, and only while the parent is parked.
43
+ - **Run in the main workspace checkout — never a git worktree.** The fully
44
+ provisioned main workspace (installed `node_modules`, `.env`/direnv auth
45
+ wiring, the running dev stack) is the whole value of local execution;
46
+ worktrees miss all of it and have consistently degraded agent sessions.
47
+ Clean tree before any branch switch is still a hard rule: dirty
48
+ `git status` at iteration start → touch nothing, report, and idle — the
49
+ resolution is the user committing or stashing, not a second checkout.
50
+ - **Push early.** There is no pod WIP-autosync locally; committed-and-pushed is
51
+ the only durable state. Push the branch (`-u origin`) as soon as it exists.
52
+
53
+ ## Iteration order
54
+
55
+ Each invocation does the FIRST of these that produces work, then paces:
56
+
57
+ 1. **Recover** — a card with my `[local-loop] claimed` chat marker still
58
+ InProgress without a PR? Resume it. The branch may already exist locally or
59
+ on origin — check both before re-implementing anything. A pack parent
60
+ whose chat carries my `[local-loop] claimed — driving this pack` marker
61
+ and isn't yet in ReviewPR? Resume pack mode — re-derive where it left off
62
+ from `mcp__conveyor__list_subtasks`, never from session memory. Skip a
63
+ parent whose LATEST marker is `[local-loop] parked:` with no human reply
64
+ after it — that pack yielded the WIP slot and stays yielded until the user
65
+ replies; fall through to the next tier.
66
+ 2. **Babysit** — my loop-opened PRs (ReviewPR cards, pack finale PRs
67
+ included): red CI → fix now (on a pack finale, directly on the pack
68
+ branch); request-changes or unanswered review comments → address now;
69
+ green and quiet → leave alone.
70
+ 3. **Claim** the next card (below).
71
+ 4. **Idle** — nothing claimable: arm the board-event wake (below), then pace long.
72
+
73
+ ## Claiming
74
+
75
+ 1. `mcp__conveyor__list_tasks` with `status: "Open"` — results are already
76
+ priority-then-newest ordered; board priority IS the intelligence, don't
77
+ invent your own ranking. Walk top-down, `mcp__conveyor__get_task` each until
78
+ one passes: created by me, no assignee or active session, an executable
79
+ plan (a pack parent that still needs breakdown is fine — breakdown is
80
+ pack-mode work), all `mcp__conveyor__get_dependencies` blockers Complete,
81
+ no `[local-loop] parked:` chat marker without a later human reply (a reply
82
+ un-parks), and the pack rules hold: a FEATURE-BRANCH pack parent (children
83
+ branch from and PR into a pack branch — including one planned as a pack
84
+ that has no children yet) is claimed as a PACK → pack mode below; a
85
+ non-feature-branch parent, whose children PR straight into dev, is never
86
+ claimable — take its children one at a time instead; a card with a
87
+ `parentTaskId` only while the parent's status is neither InProgress nor
88
+ ReviewPR (see ground rules).
89
+ Skip `followParentStatus` mirror children. A blocker counts as met only
90
+ when merged-or-beyond (ReviewDev/ReviewLive/Complete) or Cancelled — a
91
+ blocker sitting in ReviewPR is NOT met until its PR merges.
92
+ 2. Claim: re-confirm via `get_task` it is still Open, then
93
+ `mcp__conveyor__update_task` → `status: "InProgress"`, then
94
+ `mcp__conveyor__post_to_chat`: `[local-loop] claimed — working locally on
95
+ <hostname>`. Claiming a PACK is different — never set the parent
96
+ InProgress: leave it Open and post the pack claim marker instead (see Pack
97
+ mode). Status changed under you → someone else took it; next
98
+ candidate.
99
+ 3. Plan missing or failing the context-free-reader bar → don't wing it: post
100
+ what's missing to chat, leave the card Open, skip it.
101
+
102
+ ## Execute and finish
103
+
104
+ **Execution is [conveyor-build](../conveyor-build/SKILL.md)** — resolving the
105
+ card, branching from its base, working the plan, gating, and opening the PR
106
+ with an explicit `base:`. That skill is the source of truth; do not re-derive
107
+ its procedure here. It routes a childless card to its task path and a
108
+ feature-branch pack to its pack path automatically.
109
+
110
+ This section adds only what the LOOP changes:
111
+
112
+ - **Chat markers carry the loop's prefix**, `[local-loop]` rather than
113
+ `[build]`, because the Recover tier greps for them to find its own work.
114
+ - **A pack child yields to a live coordinator.** Before opening a child's PR,
115
+ re-check the parent's status; if it went InProgress or ReviewPR, post
116
+ `[local-loop] parked: pack coordinator active — yielding`, leave the branch
117
+ pushed, and let the coordinator take over.
118
+ - **Do not wait on CI.** Confirm it started (read-only `gh pr checks`) and end
119
+ the iteration — the Babysit tier owns it from there. This is the loop's one
120
+ real departure from a standalone build, which stays with its PR.
121
+
122
+ **Parked protocol** — after 2 genuinely different failed approaches, or on a
123
+ decision only the user can make: post `[local-loop] parked: <reason + the
124
+ specific question>`, set status back to `"Open"`, restore the tree
125
+ (`git checkout dev`), move on. The user's next chat reply is the un-park
126
+ signal.
127
+
128
+ ## Pack mode
129
+
130
+ Claiming an Open pack parent means driving the ENTIRE pack, exactly per
131
+ [conveyor-build's pack path](../conveyor-build/references/pack-path.md) —
132
+ setup (pack branch on origin, the `githubBranch` write-through, child breakdown
133
+ if the parent has none yet), children serially in dependency order,
134
+ reviewer-of-record review + merge of each child PR into the pack branch,
135
+ dev→pack sync after every merge, cross-reference, then the finale parent PR
136
+ into dev. That reference is the source of truth for the procedure; this section
137
+ only defines how it embeds in the loop:
138
+
139
+ - The pack occupies the loop's single WIP slot from claim until the finale PR
140
+ opens. Do not interleave unrelated cards mid-pack — that thrashes branch
141
+ state.
142
+ - Claim marker goes to the PARENT chat: `[local-loop] claimed — driving this
143
+ pack locally on <hostname>, pack branch <branch>`. The parent's status
144
+ stays Open (parked); the marker is the claim.
145
+ - Once the finale PR is open (parent in ReviewPR), the pack leaves the WIP
146
+ slot: its PR joins the Babysit tier like any other loop-opened PR, and the
147
+ loop resumes claiming other cards. This is the one difference from
148
+ a standalone conveyor-build pack run, which stops when the pack is done.
149
+ - Parked children follow the pack path's parked protocol. If every
150
+ remaining child is blocked on the user, the pack yields the WIP slot: post
151
+ `[local-loop] parked: <what it is waiting on>` to the PARENT chat — that
152
+ marker is what makes the Recover tier skip the pack — and the loop claims
153
+ other cards. The user's chat reply un-parks it, and the next Recover tier
154
+ retakes the slot.
155
+
156
+ ## Waking on board events
157
+
158
+ An empty queue is not a quiet board. Rather than sleeping blind for 25 minutes,
159
+ arm `conveyor-wait`: a CLI in `@rallycry/conveyor-mcp` that subscribes to the
160
+ project's live card stream and exits the moment a card ENTERS a claimable
161
+ state. A card created Open, a Cancelled card reopened, and a card reassigned to
162
+ you all count; an edit to a card that already matched does not.
163
+
164
+ Arm it on an idle iteration only (tier 4), and only when no wait from an earlier
165
+ iteration is still running:
166
+
167
+ ```bash
168
+ node_modules/.bin/conveyor-wait --scope mine,unclaimed --timeout 1740
169
+ ```
170
+
171
+ Launch it with Bash `run_in_background: true` and end the turn. Its completion
172
+ notification is the wake. The `ScheduleWakeup` you still arm is the fallback for
173
+ the case where the wait dies silently — use the pacing table's background-gate
174
+ row (1200–1800s), not a second, shorter timer.
175
+
176
+ - Prefer `node_modules/.bin/conveyor-wait`. If it is absent, use
177
+ `npx -y -p @rallycry/conveyor-mcp@latest conveyor-wait`. The `-p` form
178
+ matters: inside the conveyor monorepo a bare
179
+ `npx @rallycry/conveyor-mcp` misresolves.
180
+ - Narrow `--types` to whatever focus the user gave the loop invocation —
181
+ "focus on incidents" → `--types incident`. The default watches tasks,
182
+ incidents, and suggestions.
183
+ - `--scope mine,unclaimed` mirrors the claiming filter: cards assigned to the
184
+ session owner plus unassigned cards. Use `--scope all` only when the user
185
+ asked the loop to watch the whole board.
186
+ - `--statuses` defaults to `Open`, which is the claimable lane. Leave it alone
187
+ unless the user asked for something else.
188
+ - Credentials come from the environment, then any `.mcp.json` from the working
189
+ directory up, then `~/.claude.json`. An agent Bash shell does not inherit the
190
+ MCP server's environment, so that file fallback is what makes this work at
191
+ all. Exit 1 means the wait could not run: no credentials, a rejected token, or
192
+ a project it cannot read. Read the stderr line, report it once, fall back to
193
+ plain timed polling, and do not re-arm it every iteration.
194
+
195
+ **The result is advisory — the queue is still the source of truth.** The CLI
196
+ prints one line of JSON and exits 0 in every non-error case:
197
+
198
+ ```
199
+ {"reason":"event","card":{"id":…,"slug":…,"title":…,"type":…,"status":…,"assignedUserId":…}}
200
+ {"reason":"timeout"}
201
+ {"reason":"interrupted"}
202
+ ```
203
+
204
+ On wake, run a normal iteration and re-enumerate with
205
+ `mcp__conveyor__list_tasks`. By then the card may be claimed, cancelled, or
206
+ blocked by a dependency — never claim straight from the wait payload.
207
+
208
+ **Never arm a second wait.** On a wake where a wait process is still in flight
209
+ and the queue is still empty, re-arm the fallback `ScheduleWakeup` and end the
210
+ turn.
211
+
212
+ ## Pacing (dynamic /loop only)
213
+
214
+ Under `/loop` with no interval, end EVERY iteration with exactly one
215
+ `ScheduleWakeup` (prompt = the original /loop input verbatim):
216
+
217
+ | State | Delay | Reason should say |
218
+ |-------|-------|-------------------|
219
+ | A background gate/agent/conveyor-wait is in flight — its completion notification is the real wake | 1200–1800s fallback | "fallback while <gate> runs — its notification wakes me sooner" |
220
+ | ANY actionable work exists: claimable cards or packs, a pack child to implement/merge, a PR still to open, red/pending CI, review comments | 60–90s | queue depth / which item is next |
221
+ | Queue enumerated as empty THIS iteration, all loop PRs green and quiet | 1200–1800s | queue empty; conveyor-wait armed, so this is only the fallback |
222
+ | Loop-fatal: MCP dead after 2 tries, dirty tree, broken repo | notify the user (PushNotification if available), then 1800s — or `stop: true` if continuing is unsafe | what is wrong |
223
+
224
+ The long idle tier is EARNED, never defaulted: it requires having enumerated
225
+ the queue this very iteration and found zero actionable work. When unsure
226
+ which tier applies, take the short one — a wasted 60s wake costs less than a
227
+ 30-minute stall on live work.
228
+
229
+ Invoked bare (no /loop)? Run one iteration, report, and suggest
230
+ `/loop /conveyor-local-loop` — don't self-schedule.
231
+
232
+ ## Offload valve (opt-in)
233
+
234
+ Only with an explicit `offload=N` argument: when 4+ claimable cards queue up,
235
+ `mcp__conveyor__start_task` up to N of the smallest into claudespaces and say
236
+ so in the iteration summary. Without the argument, never — just report backlog
237
+ depth each iteration so the user can offload manually.
238
+
239
+ ## What this is not
240
+
241
+ - Not a reviewer of anything headed for `dev`: never `approve_task`,
242
+ `request_changes`, or `approve_and_merge_pr` on a PR into `dev` — including
243
+ a pack's final parent PR. **The one exception is a pack's CHILD PRs into the
244
+ pack branch**, where you are the reviewer of record because the automated
245
+ reviewer skips that target; the pack path spells out that duty.
246
+ - Not a pod: no sandbox, no WIP snapshots, and the dev DB + dev-server ports
247
+ are shared with the user's interactive sessions — no destructive
248
+ experiments, never reset the dev DB, reuse a running dev stack rather than
249
+ fighting over ports.
250
+ - Not a parallel executor: one card (or one pack) at a time is the point (the
251
+ full machine per gate). Backlogged? That is what claudespaces — or the
252
+ offload valve — are for.
253
+
254
+ ## Improve This Skill
255
+
256
+ If this skill was insufficient or slowed the work down, file it with
257
+ `mcp__conveyor__create_suggestion` on the Conveyor project: the issue,
258
+ evidence, and proposed fix.
@@ -0,0 +1,72 @@
1
+ ---
2
+ name: conveyor-meeting-review
3
+ description: Turn a Conveyor meeting into confirmed cards, packs, and glossary updates — read the meeting and its transcript, cross-reference what already exists, draft proposals at the plan-quality bar, and create only what a human confirms item by item. Use when the user says "/conveyor-meeting-review <meeting>", "turn that meeting into cards", "what should we do about yesterday's call", or asks for the follow-ups from a meeting. Never creates anything unasked.
4
+ ---
5
+
6
+ # Conveyor Meeting Review
7
+
8
+ A meeting becomes work only when a person says which parts should. This skill does the reading, the cross-referencing, and the drafting — and then **stops and asks**.
9
+
10
+ ## The one rule
11
+
12
+ **Never create, edit, or tag anything before a human confirms that specific item.** Not "shall I proceed?" and then everything — item by item, so "create 1 and 3, skip 2" is a normal answer.
13
+
14
+ This is not caution for its own sake. A meeting transcript is full of things that *sound* like decisions: someone thinking out loud, an idea that was argued down two minutes later, a "we should probably…" that nobody agreed to. An agent that creates cards from those is manufacturing work the team never chose, on a board they have to clean up. The summary's `## Proposed Next Steps` is a **starting point, not a mandate** — it was written by a model reading the same ambiguous transcript.
15
+
16
+ ## 1 — Read
17
+
18
+ 1. `mcp__conveyor__get_connection_context` — where you are. Same call in a pod and a local MCP session.
19
+ 2. `mcp__conveyor__get_meeting` — the overview, the decisions, the proposed next steps, and the participants. **This usually answers the question.** It costs a fraction of the transcript.
20
+ 3. `mcp__conveyor__read_meeting_transcript` — only when you need exact wording: a quote, a caveat, the reasoning behind a decision the summary merely states, or a check on whether something was actually agreed. Page with `offset`/`nextOffset` rather than pulling the whole thing.
21
+
22
+ If `status` is `processing` the summary is still being written — read the transcript, or say so and offer to come back. If `status` is `failed`, `summaryError` says why; the transcript is still complete and readable.
23
+
24
+ ## 2 — Cross-reference before drafting anything
25
+
26
+ Skipping this is how a meeting review produces four cards that duplicate work already in flight.
27
+
28
+ - `mcp__conveyor__list_tags` — the project's vocabulary. Use its words in your proposals; a card that names the same thing differently is a card nobody finds.
29
+ - `mcp__conveyor__search_tasks` — **two or three keyword variants per proposed topic**, across `task`, `incident` and `suggestion`. One search misses the card that used the other word for it.
30
+ - `mcp__conveyor__read_task_chat` on anything that looks close. The overlap is usually in the discussion, not the title.
31
+
32
+ Then say what you found, including the negatives: "this one already exists as `fix-the-thing`", "nothing on the board covers this", "there is a suggestion arguing the opposite".
33
+
34
+ ## 3 — Draft at the plan-quality bar
35
+
36
+ Each proposal a context-free reader could execute: what changes, where (file paths where you know them), and how it is verified. The `/conveyor-plan` skill's `references/plan-format.md` is the bar. A one-line card that says "improve onboarding" is not a proposal, it is a note.
37
+
38
+ Classify honestly:
39
+
40
+ - **A card** — one coherent piece of work.
41
+ - **A pack** — a parent plus children, when the work has real internal ordering. Do not inflate a card into a pack for ceremony.
42
+ - **An edit to an existing card** — usually better than a new one when something is already in flight. Say which card and what changes.
43
+ - **A tag update** — the glossary learned a word.
44
+ - **A suggestion** — the meeting raised something worth recording that nobody has decided to do. This is the honest home for "we should look into X someday", and it keeps the board clean.
45
+ - **Nothing** — some meetings produce no work. Say so rather than finding something.
46
+
47
+ ## 4 — Present and wait
48
+
49
+ Number the proposals. For each: the type, the title, one sentence of what it is, and — critically — **what in the meeting supports it**, with a speaker and roughly when. A proposal whose evidence you cannot name is one you inferred, and it should be labelled as such or dropped.
50
+
51
+ Flag separately:
52
+
53
+ - **Decisions that need a human**, which a card cannot settle.
54
+ - **Contradictions** — where the meeting disagreed with itself, or with a card already on the board.
55
+ - **Things you deliberately did not propose**, and why. That is often the most useful part.
56
+
57
+ Then wait. If the reply is partial ("1 and 3"), create exactly those.
58
+
59
+ ## 5 — Create, and stamp the provenance
60
+
61
+ Only the confirmed items, through the normal card tools — `create_task`, `create_subtask`, `add_dependency`, `update_task`, `manage_tags`, `create_suggestion`. There is no meeting-specific write path, on purpose: a card born from a meeting should be indistinguishable from any other card, and reviewable the same way.
62
+
63
+ **Stamp every created card with the meeting link** from `get_meeting`'s `url` field, in the description or the plan. Six weeks later "why does this card exist" is a real question, and the answer should be one click away.
64
+
65
+ Report back with what was created and what was skipped.
66
+
67
+ ## Environment notes
68
+
69
+ - All Conveyor tools are **fully qualified** (`mcp__conveyor__get_meeting`); bare names fail.
70
+ - The meeting tools are **deferred** — reach them via ToolSearch rather than expecting them preloaded.
71
+ - They appear only for a project that HAS meetings. If they are absent, the project has none; say so instead of hunting.
72
+ - A pod and a local MCP session run this identically. The only difference is where you report: in a pod, card chat.
@@ -0,0 +1,177 @@
1
+ ---
2
+ name: conveyor-plan
3
+ description: Produce the plan for a Conveyor card — research-backed and immediately buildable by someone with zero session context. Use when the user says "/conveyor-plan <idea>", "plan this as a conveyor card", "write this up for a claudespace agent", or when a session is asked to plan the card it is on. Runs plan-mode-quality research (codebase + prior Conveyor cards + prod logs), asks clarifying questions only when scope is genuinely ambiguous, then writes the plan onto the card. Works in a cloud pod and a local checkout alike; to execute a plan that already exists use conveyor-build.
4
+ ---
5
+
6
+ # Conveyor Plan
7
+
8
+ Produce ONE artifact: a Conveyor card whose plan an executor with zero session
9
+ context can follow. Everything they need must be ON the card — they never see
10
+ this conversation, and that executor may be a cloud pod, a local session, or
11
+ you tomorrow.
12
+
13
+ The research and drafting below are identical everywhere. Only the two ends
14
+ differ — resolving which project you are in, and where the finished plan lands
15
+ — and both carry an **Environment** note.
16
+
17
+ The division of labor is fixed: **you research and recommend; Conveyor's
18
+ identification decides.** Moving the card to Open fires identification
19
+ automatically (story points, icon, agent, and tags if you set none). Never set
20
+ icon or story points yourself, and never `start_task` unless the user asks.
21
+
22
+ ## Phase 0 — Resolve context
23
+
24
+ 1. `mcp__conveyor__get_connection_context` (all Conveyor tools fully-qualified;
25
+ bare names fail). It also tells you which environment you are in: a pod
26
+ session reports a task binding and no user account.
27
+
28
+ > **Environment.** In a **pod** you are already bound to one project and one
29
+ > card — there is nothing to resolve, and `mcp__conveyor__list_projects`
30
+ > does not exist there. **Locally**, if the connection reports no default
31
+ > project, use `mcp__conveyor__list_projects` and match
32
+ > `githubRepoOwner/Name` to the cwd's `git remote`. Ambiguous → ask.
33
+
34
+ 2. Copy project IDs exactly — a mistyped `projectId` surfaces as
35
+ "Insufficient permissions", not "not found". Verify the ID before
36
+ concluding you lack access.
37
+
38
+ ## Phase 0.5 — What KIND of card is this?
39
+
40
+ The research below is the same for all three, but what counts as a finished
41
+ plan is not:
42
+
43
+ - **Task** — the default. Someone has decided the work should happen; your job
44
+ is to make it executable. Proceed as written below.
45
+ - **Suggestion** — someone thinks this *should* happen. Establish that the ask
46
+ is real and unmet **before** planning it: does the feature already exist in
47
+ some form, was it tried and cancelled before (and why), and is the underlying
48
+ need better served another way? A plan for something already shipped is worse
49
+ than no plan, because it will be built twice.
50
+ - **Incident, or any unverified report** — do **NOT** plan a fix from the
51
+ description. A report names a symptom, and the symptom is often not the bug;
52
+ machine-filed reports carry whatever the throwing code said. If the root
53
+ cause has not been established with telemetry or a reproduction, this card
54
+ needs **`/conveyor-triage`** first. Plan the fix only once triage has named
55
+ the cause.
56
+
57
+ ## Phase 1 — Research (parallelize)
58
+
59
+ Scale to the idea's size; a one-file tweak needs minutes, not a survey.
60
+
61
+ - **Glossary first**: `mcp__conveyor__get_tag` on every tag the idea's text
62
+ mentions (`@[tag:id]` deep-links or plain loaded terms — "task", "school",
63
+ an entity name) before searching the codebase. A tag's overview + linked
64
+ files often replace a grep sweep, and the description catches
65
+ wrong-term-for-the-concept early (`mcp__conveyor__list_tags` shows the
66
+ inventory with hierarchy).
67
+ - **Codebase**: use a code-graph or architecture skill if the repo provides
68
+ one for architecture/flow questions; `rg` for exact strings. Fan out
69
+ Explore subagents for broad sweeps. Investigate deliberately rather than
70
+ reading around: search first and read second, start from 3-5 critical files,
71
+ form a hypothesis, then validate it with targeted reads. Never re-read a file
72
+ already in your context. **Stop when you can cite a specific `file.ts:line`
73
+ and a symbol name for every step your plan will contain** — that is the
74
+ threshold, and more reading past it buys nothing.
75
+ - **Prior art**: `mcp__conveyor__search_tasks` on 2-3 keyword variants
76
+ (`typeFilters` to include incidents/suggestions when relevant), then
77
+ `mcp__conveyor__get_task` on the closest hits. You're looking for duplicates
78
+ (stop and surface), related shipped work (reuse its patterns), and
79
+ cancelled attempts (learn why before re-proposing).
80
+ - **Prod signals** (only when the feature touches live behavior):
81
+ `mcp__conveyor__query_gcp_logs` / `mcp__conveyor__query_grafana_logs` for
82
+ error rates, actual usage, current behavior. **Environment:** these are
83
+ local/MCP only — a pod has no log tools, so state the question the logs would
84
+ answer in the plan's Notes instead of guessing at the answer.
85
+ - **Blast radius**: enumerate callers/consumers of every surface the plan
86
+ touches (shared packages, DB schema, published packages, webhooks, other
87
+ cards in flight on the same files). Unintended impact goes in the plan's
88
+ Notes, not in your head.
89
+
90
+ ## Phase 2 — Clarify (only if needed)
91
+
92
+ Ask the user only decisions that change the plan's shape — scope cuts, UX
93
+ choices, irreversible tradeoffs. Batch them in one round; never drip. Facts
94
+ the repo can answer are yours to find, not theirs.
95
+
96
+ ## Phase 3 — Draft the plan
97
+
98
+ Use the plan format in [references/plan-format.md](references/plan-format.md):
99
+ Objective / Approach / Implementation Steps / Testing / Notes / Builder briefing.
100
+
101
+ Actionability bar — every step must survive a context-free reader:
102
+
103
+ - Name exact repo-relative files and symbols, with the pattern to follow
104
+ ("mirror `apps/api/src/services/task/methods/mutations.ts`").
105
+ - Testing = runnable commands + observable acceptance criteria.
106
+ - Notes = risks, blast radius, dependencies, and decisions already made (so
107
+ the executor doesn't relitigate them).
108
+ - No "as discussed", no links to this chat, no TODOs the executor must
109
+ research from scratch.
110
+
111
+ **Close with the Builder briefing, and write it for the NEXT session.** Every
112
+ other section addresses a reader; this one addresses the agent that will inherit
113
+ this card having read the card and nothing else — no research, no dead ends, no
114
+ memory of this conversation. Four lines, ~10 max: where to start, what is already
115
+ decided (and why, so it is not reopened), which traps look correct and are not,
116
+ and the order to verify in. Write it last, when you know which parts were hard.
117
+
118
+ It is not optional and it is not a summary. It is the only channel your context
119
+ has across the handoff, because handoffs carry the card and never the session.
120
+
121
+ Size it: 1 SP default, 2 multi-file, 3 complex patterns/design, 5 hard. Larger
122
+ → propose a pack (parent + `mcp__conveyor__create_subtask` children) instead of
123
+ one mega-card. **Child→child ordering rides `create_subtask`/`update_subtask`'s
124
+ own `dependsOn` field, NOT `mcp__conveyor__add_dependency`** — on the pod surface
125
+ that tool is scoped to the session's own task and cannot draw an edge between two
126
+ children.
127
+
128
+ Show the user title + description + plan + SP/tag recommendation before
129
+ touching Conveyor, unless they asked you to just ship it.
130
+
131
+ ## Phase 4 — Create and hand off (order matters)
132
+
133
+ > **Environment — a pod plans the card it is already on.** The steps below
134
+ > create a NEW card, which is the local/MCP shape; `mcp__conveyor__create_task`
135
+ > does not exist in a pod. In a pod, the card exists and you are on it: save
136
+ > the plan with `mcp__conveyor__update_task` (`plan`, and `description` if it
137
+ > needs sharpening), post the same recommendation message to chat, and stop —
138
+ > a pod does not promote its own card to Open. If the pod also has to leave
139
+ > plan mode, note that `update_task` carries no story points or risk; those go
140
+ > through `mcp__conveyor__update_task_properties`. Everything in Phases 1-3 is
141
+ > identical in both environments. To break a large pod card into a pack, use
142
+ > `mcp__conveyor__create_subtask` rather than `create_task`, and set child→child
143
+ > ordering through its `dependsOn` field — `mcp__conveyor__add_dependency` is
144
+ > scoped to the session's OWN task in a pod and cannot draw an edge between two
145
+ > children.
146
+ >
147
+ > **In a pod, create every child BEFORE you save the parent plan.** The parent
148
+ > plan save is what triggers the handoff, and the handoff reads the card's child
149
+ > count at that instant to decide what to spawn: children present → a pack
150
+ > coordinator that works them serially; none → a single leaf builder. Save the
151
+ > parent plan first and you hand a whole pack to a leaf builder. Order is
152
+ > therefore: children (with their plans and `dependsOn` edges) → parent plan
153
+ > LAST.
154
+
155
+ Identification fires the moment the card lands beyond Planning and reads task
156
+ chat for your recommendation — so chat BEFORE the status flip:
157
+
158
+ 1. `mcp__conveyor__create_task` — `status: "Planning"`, concise imperative
159
+ title, 2-4 sentence description (the board-card summary), full plan.
160
+ Optionally `tags`: only names from `mcp__conveyor__list_tags` that clearly
161
+ fit (unknown names are rejected; pre-set tags make identification skip tag
162
+ assignment — when unsure, omit and let it choose).
163
+ 2. `mcp__conveyor__post_to_chat` — one message: recommended SP + one-line
164
+ rationale, tag suggestion, any executor warnings.
165
+ 3. `mcp__conveyor__update_task` — `status: "Open"` (+ `risk` when the plan
166
+ touches critical surface). This triggers identification.
167
+ 4. Verify with `mcp__conveyor__get_task`: status Open, `agentId` set. SP and
168
+ tags are NOT in the `get_task` response — confirm on the board if needed.
169
+ 5. Report the card URL (`<project url>/cards/<slug>`), what identification
170
+ filled, and that it's ready for `start_task`. Park-in-Planning instead if
171
+ the user wants to review first; offer (don't run) `start_task`.
172
+
173
+ ## Improve This Skill
174
+
175
+ If this skill was insufficient or slowed the work down, file it with
176
+ `mcp__conveyor__create_suggestion` on the Conveyor project: the issue,
177
+ evidence, and proposed fix.
@@ -0,0 +1,134 @@
1
+ # Conveyor Plan Format & Sizing
2
+
3
+ ## Plan Format
4
+
5
+ ```markdown
6
+ ## Objective
7
+ One sentence: what this task accomplishes and why.
8
+
9
+ ## Approach
10
+ High-level strategy with relevant files/patterns/APIs.
11
+
12
+ ## Implementation Steps
13
+ 1. Concrete step.
14
+ 2. Concrete step.
15
+
16
+ ## Testing
17
+ - Commands and manual checks.
18
+ - Edge cases.
19
+
20
+ ## Notes
21
+ - Dependencies, risks, blockers, or files likely touched.
22
+
23
+ ## Builder briefing
24
+ - **Start here:** the one or two files to open first.
25
+ - **Already decided:** choices the builder should not reopen, one line of why each.
26
+ - **Traps:** what looks right and is not.
27
+ - **Verify in this order:** cheapest disqualifying check first.
28
+ ```
29
+
30
+ ## Citations — ground every code step in the code
31
+
32
+ A plan an executor can follow names locations, not areas. For every step that
33
+ touches code:
34
+
35
+ - Cite the exact location as `path/from/repo/root.ts:lineNumber` (e.g.
36
+ `packages/conveyor-agent/src/execution/mode-prompt.ts:129`). Ranges are fine
37
+ for larger edits (`foo.ts:120-145`); a whole file with no line is not.
38
+ - Name the specific function, class, constant, or JSX element being touched.
39
+ - When behavior hinges on a short piece of code, quote 1–3 lines inline rather
40
+ than paraphrasing it.
41
+ - For a file that does not exist yet, write `NEW: path/to/new-file.ts` and
42
+ describe the module it fits into.
43
+
44
+ ## The Testing section is a definition of done
45
+
46
+ The executor treats it as the acceptance criteria, so enumerate:
47
+
48
+ - The scoped verification for this change — the repo's own lint/typecheck and
49
+ affected-test commands — naming the specific package suites the diff will
50
+ touch. A docs-only plan should say plainly that no local gates are needed and
51
+ that CI validates on the PR.
52
+ - Any task-specific end-to-end check: a manual UI walk-through, an API smoke
53
+ test, a migration dry-run.
54
+
55
+ A planner working read-only is not expected to RUN these. Describe them.
56
+
57
+ ## The Builder briefing is written for the NEXT session
58
+
59
+ The section that closes the plan is the only one not addressed to a reader — it
60
+ is addressed to the session that inherits this card, which has read **this card
61
+ and nothing else**. It has none of your research, none of your dead ends, and no
62
+ memory of the conversation that produced any of it.
63
+
64
+ That is deliberate. Handoffs carry the card, never the session (see the decision
65
+ record in `.claude/rules/agent-modes.md`), so this section is where a planner's
66
+ hard-won context survives the boundary — and it is the whole reason forking the
67
+ planner's session was not needed.
68
+
69
+ Four lines, one each:
70
+
71
+ - **Start here** — where to open the code, not a summary of it.
72
+ - **Already decided** — what NOT to reopen, with one line of why. This is the
73
+ highest-value line: without it a builder re-litigates a choice you already
74
+ made, and usually lands somewhere worse because it has less context.
75
+ - **Traps** — what looks correct and is not. Anything that cost you a wrong
76
+ turn will cost the builder the same one.
77
+ - **Verify in this order** — cheapest disqualifying check first, so a wrong
78
+ approach dies in seconds instead of at the gate.
79
+
80
+ **Bounded at ~10 lines.** If it runs longer, that is a signal about the plan
81
+ body, not about the briefing: something belonged in Approach, Implementation
82
+ Steps, or Testing and did not get there. Do not use it as an appendix, and do
83
+ not restate the steps — a briefing that repeats the plan is one more thing to
84
+ keep in sync.
85
+
86
+ Write it last, when you know which parts were hard.
87
+
88
+ ## Sizing
89
+
90
+ Default **1 SP**. Use **2 SP** for multi-file work, **3 SP** for complex
91
+ patterns/design choices, **5 SP** only for hard work. Split anything larger.
92
+
93
+ ## Packs (parent + child tasks)
94
+
95
+ A **pack** is Conveyor's bundle shape: a parent card with child cards.
96
+ `create_subtask(parentTaskId, ...)` creates a NEW child; to move an EXISTING
97
+ card under a parent (or out of one) use `set_task_parent`. `create_task` /
98
+ `update_task` have no parent field. Each child is a full card
99
+ (own chat, plan, story points). Split into a pack only when the work is
100
+ genuinely multiple independently buildable pieces (8-SP-tier); otherwise keep
101
+ one card.
102
+
103
+ - **Orchestration packs** (future work): `start_task` on the parent boots a
104
+ *pack runner* that works each ready child, honoring dependency edges. Give
105
+ each child a detailed plan with a **Testing / Verification** section —
106
+ identification sizes children like any other card. The parent card's
107
+ `featureBranch` setting (default on) makes children branch off and PR back
108
+ into the parent's branch instead of the default base.
109
+
110
+ **Every child needs a real plan, held to the same bar as a standalone card:**
111
+ a multi-step implementation guide with `file.ts:line` citations, the
112
+ function/symbol names it touches, a pattern to follow where one exists
113
+ ("mirror `src/services/foo.ts`"), testing requirements, and acceptance
114
+ criteria. A one-line description is not a plan, and the executor cannot ask
115
+ you what you meant.
116
+
117
+ **Express cross-child ordering as `dependsOn` metadata, never as prose.**
118
+ Pass `dependsOn` (sibling ids or slugs) on `create_subtask` for any child
119
+ that blocks on another; leave genuinely independent children with none. A
120
+ runner schedules off those edges — "do this after step 2" written in plan
121
+ text is invisible to it, and the child will be picked up out of order.
122
+ - **Mirror packs** (already-done work shipping in ONE PR on the parent's
123
+ branch): create children with **`followParentStatus: true`** — title and a
124
+ plain-language description only. A follower mirrors its parent's status
125
+ automatically through the whole pipeline, identification sizes it, and it
126
+ never posts its own Slack card. Evidence rolls up to the **parent**. Never
127
+ `start_task` a mirror pack's parent, and leave children's PR fields empty —
128
+ the parent owns the PR.
129
+
130
+ ## Status Flow
131
+
132
+ `Planning -> Open -> InProgress -> ReviewPR -> ReviewDev -> ReviewLive -> Complete`
133
+
134
+ `Cancelled` is terminal. A task must be `Open` before `start_task`.