workflow-feature
Skill0 starsChanged 17 days agoMITView on GitHub
The workflow a dispatched session runs for a feature, improvement or bug: contract → implement → audit → verify → commit → PR → review (fixes pushed to the PR). Auto-commits, opens a PR, never merges — unless you pass noCommit.
- Reads credentials
1 other project uses a version of this.
Adopted by
Most recently taken up by
- ovargas/virtual-teamtheir own version, first seen Oct 25, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- ovargas/virtual-team★ 14same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository14 other files it gives its agents.
- AGENTS.mdAGENTS.md
- cycler-delegateSkill
- cycler-doctorSkill
- cycler-startSkill
- cycler-stopSkill
- cycler-workflow-bugSkill
- cycler-workflow-featureSkill
- cycler-workflow-intakeSkill
- cycler-workflow-researchSkill
- cycler-workflow-reviewSkill
- workflow-bugSkill
- workflow-intakeSkill
- workflow-researchSkill
- workflow-reviewSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
19 rules. About 0 are common, 7 are distinctive, and 12 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
12
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 12
Use the tools available in your runtime.
- Very specific: line 14
When the native Workflow tool is unavailable (Codex, dsh, or a Claude install without it), run the SAME lifecycle through the portable …
- Very specific: line 22
Do not continue into the native Workflow(...) instructions after this runner completes.
- Distinctive: line 37
Run git status --short (respect in-flight changes — do not touch them).
- Very specific: line 40
Read it with "${CLAUDE_PLUGIN_ROOT}/poller/lin" issue view <KEY> — one Bash call, no tool schema to load.
- Very specific: line 53
If lin fails (no token, revoked app), pass the reference through as-is: the workflow's CONTRACT AUTHOR resolves a reference-only request …
- Distinctive: line 63
Every other Linear write in this skill happens in step 5, *after* the workflow returns — which is 20-40 minutes later.
- Distinctive: line 94
If any of them genuinely could not run, the run is not complete: say so in the PR body and in the Linear comment, in those words — "review …
- Distinctive: line 99
Call the single workflow:
- Very specific: line 121
If a contract already exists and the user wants to use it, pass contractPath instead of task.
- Very specific: line 122
When the user invokes /workflow-feature <ISSUE-KEY> (e.g.
- Very specific: line 141
Never fail the task over Linear: If a write errors, report it and move on.
- Distinctive: line 144
Post nothing else on the issue: No answers to questions, no recaps, no next steps: the human answers in this session, and the board only …
- Very specific: line 146
Read the returned structured result: { status, stage, branch, branchCreated, worktree, lockHeld, cleanupNote, contractPath, changedFiles[], …
- Very specific: line 165
Read the contractPath file.
- Distinctive: line 166
Write it to the plan file path from your plan-mode reminder — that file is the ONLY file you may write in plan mode.
- Very specific: line 168
Call ExitPlanMode — the user reviews the contract as the plan.
- Very specific: line 174
If you set stopAtContract but ExitPlanMode is unavailable (not actually in plan mode), present the contract in a normal message and ask for …
- Distinctive: line 227
NEVER merges — merging is the user's call.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Runtime compatibility (read first)
These instructions apply to Claude Code, Codex and DeepSeek Harness (dsh). Resolve
CYCLER_ROOT from the environment, CLAUDE_PLUGIN_ROOT, or this skill's directory (../..).
CLAUDE_PLUGIN_ROOT in the legacy instructions below is a compatibility alias for that root;
CLAUDE_CODE_SESSION_ID may be replaced with CYCLER_SESSION_ID or the current runtime session ID.
Use the tools available in your runtime; ToolSearch is not a prerequisite for research or Linear.
When the native Workflow tool is unavailable (Codex, dsh, or a Claude install without it),
run the SAME lifecycle through the portable runner and report its result:
node "$CYCLER_ROOT/workflows/run.mjs" --runtime '<claude|codex|dsh>' --cwd "$PWD" --workflow workflow-feature --task '<complete request or issue key>'Pass --contract <path> to reuse a contract; --no-commit leaves changes for inspection.
Do not continue into the native Workflow(...) instructions after this runner completes.
The runner owns independent stages, gate enforcement, GitHub comments and implementer replies.
/workflow-feature — full task lifecycle in a single workflow
Inputs
- The user's request (the current message) — or an existing contract path.
- The request may be a Linear issue URL or bare key instead of a description (see below).
- READ
${CLAUDE_PLUGIN_ROOT}/harness/HARNESS.mdfirst.
Actions (in order)
- Run
git status --short(respect in-flight changes — do not touch them). - If the argument is a Linear reference — a
https://linear.app/<workspace>/issue/APL-1/...URL or a bare key likeAPL-12— resolve it before invoking the workflow:- Read it with
"${CLAUDE_PLUGIN_ROOT}/poller/lin" issue view <KEY>— one Bash call, no tool schema to load. Prefer this over the Linear MCP:ToolSearch+get_issuecosts a schema load and a tool round-trip, and the MCP server is not always connected (in dispatched sessions the Linear MCP never finished connecting, so the follow-up-filing step there was unsatisfiable by construction). linislinear-clireading the OAuth token the Linear poller keeps refreshed. Do not use a pinnedLINEAR_API_KEYor.linear.toml: Linear access tokens expire every 24h, so a copied one works for a day and then fails with a 401 that reads like a network fault.- Pass the issue's title + full description as
task(e.g.task: 'APL-1 — <title>\n\n<description>'). The description is the spec: the issues in this workspace are written with Goal / Evidence / Acceptance sections, which map almost directly onto the contract template. Do not paraphrase or summarise the acceptance criteria — pass them through. - Pass the key as
issueId. It drives the branch (claude/APL-1), the contract filename (apl-1-<slug>.md), the commit subject, and the PR body'sCloses APL-1. - If
linfails (no token, revoked app), pass the reference through as-is: the workflow's CONTRACT AUTHOR resolves a reference-only request itself as a fallback. Say which path you took. - A non-Linear argument is unaffected — pass the request verbatim exactly as before.
- Read it with
- Post a start comment before invoking the workflow (Linear reference only):
"${CLAUDE_PLUGIN_ROOT}/poller/lin" issue comment list <KEY> | grep -q 'workflow run started' \
|| "${CLAUDE_PLUGIN_ROOT}/poller/lin" issue comment add <KEY> --body "'feature' workflow run started in session \`${CLAUDE_CODE_SESSION_ID:0:8}\`."Every other Linear write in this skill happens in step 5, after the workflow returns — which is 20-40 minutes later. Without this one the board shows nothing at all for the whole run, and a delegated issue sitting silent is indistinguishable from a dispatch that never fired. That ambiguity is what the poller's own failure comment exists to remove; the run itself needs the same. The grep makes it idempotent, and a failure here is never a reason not to start the workflow.
- Read the cycler config first, so the run uses this repo's settings rather than defaults:
node "${CLAUDE_PLUGIN_ROOT}/harness/read-config.mjs" repo.base main
node "${CLAUDE_PLUGIN_ROOT}/harness/read-config.mjs" repo.branch_prefix claude/
node "${CLAUDE_PLUGIN_ROOT}/harness/read-config.mjs" repo.path ""
node "${CLAUDE_PLUGIN_ROOT}/harness/read-config.mjs" --json
echo "${CLAUDE_PLUGIN_ROOT}"Pass those as prBase, branchPrefix, cwd, config and pluginRoot below. A repo with no
config gets the defaults, which are the values shown in those commands — nothing breaks,
nothing is silently shaped like somebody else's repo.
cwd and pluginRoot are not optional. The Workflow runtime exposes args, agent,
parallel, pipeline, log, phase and budget — there is no process, so the workflow has
nothing to fall back on and throws immediately if either is missing. It used to fall back to
process.cwd(), which is a ReferenceError in that runtime: the script died on its first line
and every unattended dispatch left no branch and no PR.
The workflow's audit and review stages are subagents, and you must let them run. A repo may carry a rule against spawning subagents to work an issue — that rule is about not spawning a local agent instead of delegating a separate issue, and it is never about your own run's auditor, review lenses or refuters. Those are the only readers in the run that did not write the diff.
If any of them genuinely could not run, the run is not complete: say so in the PR body and in the Linear comment, in those words — "review self-performed, not independent" — so nobody reads an unreviewed diff as a reviewed one. Do not quietly substitute your own judgement for the lenses and report it as a clean review.
- Call the single workflow:
Workflow({ scriptPath: '.claude/workflows/task-orchestration.js', args: {
githubReview: true, // shared standalone harness: publishes GitHub review threads and implementer replies
task: '<the user request verbatim — or, for a Linear reference, the resolved issue title + description>',
cwd: '<repo.path from the cycler config — REQUIRED, the workflow throws without it>',
pluginRoot: '<the ${CLAUDE_PLUGIN_ROOT} you echoed above — REQUIRED, the workflow throws without it>',
config: <the parsed --json output above; omit only when there is no config file>,
executorModel: '<lower Claude model id like "sonnet"/"haiku", or omit to inherit>',
noCommit: <true if the user wants to review before commit; omit for full automation>,
stopAtContract: <true when plan mode is active; omit otherwise>,
prBase: '<repo.base from the cycler config, default "main"; pass the previous task\'s branch when stacking tasks>',
branchPrefix: '<repo.branch_prefix from the cycler config, default "claude/">',
sessionId: '<output of: echo $CLAUDE_CODE_SESSION_ID — names this session in the board comments>',
issueId: '<the tracker issue key when the task is driven from one, e.g. "APL-10" — sets the branch name>',
branch: '<explicit branch override; omit unless you need to force a specific name>',
models: <per-stage overrides, e.g. { verify: 'haiku' }; omit to use the defaults below>,
worktree: <true to run in a dedicated git worktree — REQUIRED when launching runs in parallel>
}})- If a contract already exists and the user wants to use it, pass
contractPathinstead oftask. - When the user invokes
/workflow-feature <ISSUE-KEY>(e.g./workflow-feature APL-10), pass that key asissueId. The workflow also parses an uppercaseABC-123key out of the task text, so this is belt-and-braces — but pass it explicitly whenever you know it. It determines the branch name (<branchPrefix><ISSUE_ID>).
- Perform the Linear writes the workflow planned. The result carries
linearWrites[]— the workflow no longer performs these itself (it used to spend 3-4 subagents per run on writes that failed against an unauthenticated MCP; see HARNESS.md -> Linear round-trip). You hold a working Linear connector, so you do them:- Walk the array in order. Each entry has
kind,issue,stateType,statePreference,assignSelf,links[],body. - Use
${CLAUDE_PLUGIN_ROOT}/poller/lin, not the Linear MCP (see step 2 for why):lin issue comment list <KEY>to check,lin issue comment add <KEY> --body '...'to write,lin issue update <KEY> --state '<name-or-type>'to move state. - Idempotency: list the comments first and skip a write whose
bodyis already present as a comment with identical text. Never add HTML comments or hidden markers to a body. A resumed or re-run workflow must not spam. - States by TYPE:
lin issue updatetakes a state by name or type, so passstatePreferencewhen set and fall back tostateType(started/unstarted/completed). Never hardcode a name that only exists in one team. - Never move the issue to Done — the harness does not merge, so only the human who merges can honestly close it. Never reassign an issue that already has an assignee.
- Never fail the task over Linear. If a write errors, report it and move on; the task's own
outcome is unaffected. Entries with
skipped: trueneed no action — thenotesays why. - Tell the user which writes you performed, and which failed.
- Post nothing else on the issue. No answers to questions, no recaps, no next steps: the human answers in this session, and the board only carries the workflow's own one-line comments.
- Walk the array in order. Each entry has
- Read the returned structured result:
{ status, stage, branch, branchCreated, worktree, lockHeld, cleanupNote, contractPath, changedFiles[], summary, commandJournal[], audit, report, confirmed[], notes, fixLog[], commit, commits[], pr, linearWrites[] }.worktreeisnullonce removed, or a path still on disk.lockHeld: truemeans the shared-tree lock could NOT be released — remove it by hand (path incleanupNote) or the next shared-tree run refuses to start. Note: the workflow self-corrects — audit/verify/review failures loop back to the implementer with the exact issues, up toargs.fixMax(default 2). Ablockedresult means the loop gave up at the failing stage (fixLog+lastFailure), or the implementer/contract stage failed. Ondone,pr.prUrlis the opened pull request (never merged by the harness).
Plan mode: contract-as-plan
Detect plan mode from your own context: a "Plan mode is active" reminder is present and the ExitPlanMode
tool is available. (No env var exists — detection is reading your context; a deterministic alternative via
a hook's permission_mode is documented in HARNESS.md.) When active, pass stopAtContract: true.
The workflow then returns { status: 'plan', stage: 'contract', contractPath, openQuestions } instead of
implementing. Present the contract as the plan:
- Read the
contractPathfile; append anyopenQuestions. - Write it to the plan file path from your plan-mode reminder — that file is the ONLY file you may write in plan mode.
- Call
ExitPlanMode— the user reviews the contract as the plan. - Approved → re-invoke the SAME workflow with
contractPath: <path>and WITHOUTstopAtContract; the implement → audit → verify → review → commit stages run normally. - Rejected → do not re-invoke. The user edits the contract file (or re-runs
/workflow-feature); they may then passcontractPathto continue.
If you set stopAtContract but ExitPlanMode is unavailable (not actually in plan mode), present the
contract in a normal message and ask for approval before re-invoking.
Output
- Relay to the user: stage reached, status (
done/blocked), the gate report, the review verdict (when a review ran), any fix rounds (fixLog), the commit hash(es), and the opened PR url if one was created.
Stop conditions
status === 'plan'→ present the contract as a plan and re-invoke withcontractPathon approval (see Plan mode section). Do NOT start implementing without that approval.status === 'blocked'→ relay the blockers verbatim (with the stage: contract / implement / audit / verify / review). Do NOT auto-retry in a loop. The user fixes or re-runs.status === 'done'→ show the summary + commit hash + PR url (if opened). Then save memory: onlydecision/constraint/failurerecords — never chat history.
Notes
- Models are routed per stage, not one model for the whole run.
contractruns onopus(one agent, but every later stage reads it, and its Non-goals are what let the auditor catch scope creep); the mechanical stagesbranch/commit/prrun onhaiku(fixed command sequences whose success the workflow re-checks itself);review:test-gapsandfollowupsrun onhaiku. Everything else inheritsexecutorModel.verify,auditandrefuteare deliberately NOT downgraded — verify plans the gate before running it, audit is what catches leaked secrets, and a refuter defaults toisReal:falsewhen unsure, so a weak one silently drops real findings. Override any stage withargs.models({ verify: 'haiku' }), or passnullfor a stage to force it back toexecutorModel. - The contract author answers its own questions (APL-47).
openQuestionsblocks the run and waits for a human, so it is reserved for genuine PREFERENCE decisions — a product stance, a trade-off only the user can price. Anything OBSERVABLE (how the code is structured, what copy the feature already uses, what the current screen looks like) the author resolves itself: by reading, or for macOS UI questions by building and running the app and taking a screenshot. Resolved-by-looking decisions are recorded in the contract's Risks & assumptions so a reviewer can challenge the observation. This is what keepsstopOnOpenQuestions: true(the default) affordable — before it, a well-specified UI issue still cost two round-trips. - Parallel runs need
worktree: true(APL-45). Without it a run works in the shared checkout and takes an exclusive lock; a second concurrent run is refused outright, naming the branch that holds the lock — loud, not interleaved. With it, the run gets its own worktree under.claude/worktrees/and every stage is pointed there, so several/workflow-featureruns on different branches are safe at once. Two runs on the SAME branch are still impossible: git refuses to check one branch out in two worktrees, and the harness will not--forcepast that. A clean run removes its worktree; a blocked run keeps it and reports the path inresult.worktree— inspect it, thengit worktree remove --force <path>. Two things worktrees do NOT fix: the token budget is shared across concurrent workflows (pass an explicit budget when batching, or each run's guard sees a pool the others are also spending), and each run still costs up to ~70 agents. - A Branch stage runs before the implementer: it creates or reuses
claude/<ISSUE_ID>off an up-to-dateprBase, and refuses to run if that branch would equalprBase. The harness therefore never commits onto the base branch. See${CLAUDE_PLUGIN_ROOT}/harness/PIPELINE.mdfor the naming convention (and why it differs from Linear's suggestedfeature/apl-N). - A
blockedresult carryingfatal: truemeans a gate stage did not run (an agent returned no result — usually a terminal API error), not that the diff failed. Never re-read it as a pass; re-run. - The workflow commits the gated diff, pushes the branch, and opens a PR to
prBase(defaultmain). It NEVER merges — merging is the user's call. Review-fix rounds add commits to the same PR. - The workflow cannot take user input mid-run by design (single-shot). To keep sign-off control, either
pass
noCommit: true(review the diff, commit/push/PR later manually), or author a contract first and passcontractPath. - Full automation is the default: it commits, opens the PR, and pushes review fixes to it.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

