Epiq Board Workflow
Manage issue board operations through the Epiq MCP tool with validated state synchronization.
Installation
- Make sure Claude is on your device and in your terminal.
Skills load from
~/.claude/skills/when Claude Code starts up β so you need it on your machine first. If you don't have it yet, install it once with the command below, then runclaudein any terminal to verify.One-time setupnpm i -g @anthropic-ai/claude-codeAlready have it? Skip ahead.
- Paste into Claude Code or into your terminal.
This copies the whole skill folder into
~/.claude/skills/epiq-ljtn/β the SKILL.md plus any scripts, reference docs, or templates the skill ships with. Safe default: works for every skill.Faster alternative (instruction-only skills)
Skips the clone and grabs only the SKILL.md file. Don't use this if the skill ships Python scripts, reference markdowns, or asset templates β they won't be downloaded and the skill will fail when it tries to load them.
Quick install (SKILL.md only)Sign up to copy - Restart Claude Code.
Quit and reopen Claude Code (or any other agent that loads from
~/.claude/skills/). New skills are picked up on startup. - Just ask Claude.
Skills auto-activate when your request matches the skill's description β no slash command needed. Trigger phrases live in the skill's own frontmatter; you can read them in the βWhat this skill doesβ section above.
Prefer to read the source first? Open on GitHub.
When Claude uses it
Workflow rules for working the epiq issue board β use the epiq MCP, sync on demand, scope tickets small, keep status/tags accurate, and communicate via comments.
What this skill does
Epiq board workflow
- Never test against the real board. Point any dev server, manual test or test run at a throwaway project, never at this repo's own. Deleting test tickets afterwards does not undo the events. Stop the dev server when you're done rather than leaving it autosyncing.
- Use the epiq MCP tools (
epiq_*) for all board operations β never theepiqCLI or hand-edited state files. - Never edit the state branch directly. Don't check it out, don't write to its worktree, don't touch the event log or any file under it by hand or by script β go through the MCP for every read and write. The event log is the system of record: an edit made outside it bypasses validation and ordering, and can corrupt history in ways no later fix can undo.
- Sync is on-demand only. MCP reads/writes operate on local state and never pull/push automatically. Call
epiq_syncexplicitly when you need the latest remote state or want to publish local changes. - Break work into small, scoped tickets. One ticket per independent unit of work, not one giant ticket for a whole feature/epic. Small tickets move through the board cleanly and are easier to review.
- A small request tightly coupled to a ticket goes into that ticket, not a new one. When the user asks for a tweak that only makes sense as part of work a ticket already covers β halving a limit it just introduced, moving a control it just added β do not file a fresh ticket for it. Record the new requirement as a comment on the original ticket and fold it into the description, move the ticket back to Ongoing if it had already reached Done, prefix the follow-up's commits with that ticket's ref, and add a further
Solution:comment when it lands, so the ticket's own commit list tells the whole story.QPPR7PEis what this avoids: a one-line follow-up toMBB6WY5(halve the log cap it had just introduced) that now lives on a ticket of its own. The original does not have to be the ticket you took this session: any ticket open on the board and assigned to you counts. A new ticket is for work that stands on its own β that someone else could pick up cold, or that needs more than a line or two to describe. - Keep the status column current as work progresses
- Assign the ticket to yourself when you pick it up, alongside moving it to Ongoing β so the board shows who is on what, not just what is in flight.
- A ticket you file for work you will do this session is assigned to you as you file it. Filing it unassigned and picking it up a minute later leaves a window where the board shows nobody on it. Picking up a ticket assigned to somebody else is fine β but ask the user first: it may be mid-flight in another session, and the assignee is what says so.
- Take a name as soon as this skill loads, and say it. Your board identity is
provider/human-nameβ the model provider, a slash, then a short human first name:claude/peter,codex/fred. Announce it as your first line, exactlyAssuming claude/peter, and work under it for the whole session so the log reads "claude/peter did X" rather than signing the user's name to your work. Before inventing one, callepiq_contributor_listand reuse an existing identity for your provider if there is one β a name is permanent once it has authored anything (tombstoneContributorrefuses authors), and each new one adds a contributor and an event log file forever. Keep the name stable across sessions; never rename yourself mid-session. - Make the name true with
epiq_actor_assume, before your first board write. Announcing alone changes nothing: the writes would still be signed with the user's name. The tool takes the identity for the rest of the session and registers it, so the board carriesclaude/peterrather than the sanitizedclaude-peterthe log file name would give. It is idempotent, so re-announcing is free; if it refuses because the server was launched under a name, that name wins β work under the one it reports and say so. Never claim an attribution the tool did not confirm. - Boot your own MCP instance, and never share one.
epiq_actor_assumebinds the name to the server process it is called on, so two sessions on one server β or a session on the user's own instance β would sign every write with whichever name was assumed last, and the log would fold them into one contributor. Every session therefore needs a server process of its own before its first board call: the one Claude Code spawns for the session counts, and if that never connected (aCONNECT_TIMEOUTat boot), start one yourself βnpx -y -p epiq@latest epiq-mcpspeaks MCP JSON-RPC over stdio, so a small script holding that process and forwardingtools/callrequests is enough β rather than waiting on the user or borrowing another session's. Assume the name on that process; a restart forgets it, so assume it again before the next write. Kill what you started when the session ends, including theepiq-mcpchild, which outlives its parent. - When other agents may be running, ask which name to take rather than picking one. Nothing stops two live agents answering to one name β the log is a CRDT and takes concurrent writers happily, so they would converge into one indistinguishable identity rather than fail. Another session is likely whenever there is more than one
epiq-mcpprocess, another worktree with recent changes, or the user says so; in that case list the existing names for your provider fromepiq_contributor_listand ask the user which one is free, beforeepiq_actor_assumeβ a name once assumed binds the server process, and a second name is refused until it restarts. Ask with the names in the question, not "which name?": the user is choosing between identities they can see on the board. - Name the terminal window after the identity. Several sessions look alike; the name in the tab is how the user tells which window is
claude/peter. The session cannot reach the terminal itself β the shell it runs has no tty β so put the request in the announcement line:Assuming claude/peter β please /rename claude/peter so this window carries the name. - **Prefix commits with the ticket ref. **Retrieve the ref programmatically, NEVER DERIVE IT.** Read the
reffield off the MCP response (epiq_issue_listandepiq_board_listinclude it on every entry). This is what link-by-reference feature matches on. - Work in a worktree, and leave the root checkout alone. Take one before the first edit (
EnterWorktree, orgit worktree add .claude/worktrees/<ref>-<slug>for a branch that already exists), and never check a feature branch out at the root: the root is wheremainbelongs and where the user checks it out themselves, and a branch checked out anywhere is unavailable everywhere else. For the same reasonmainnever goes into a worktree. Several sessions share this repository at once, so a shared checkout also means one session'scheckoutorresetquietly discarding another's work. A fresh worktree needs its ownnpm installbefore the hooks and suites will run there. - Never work on main, and never merge into it locally. Every change reaches main through a pull request. Branch before the first edit, push the branch, open the PR, let the gate run, then integrate it. A local merge into
mainlooks like it worked and is invisible to everyone else: the work is on nobody's remote, no PR ran the gate over it, and it is onegit fetch origin +main:mainaway from vanishing from the branch you are sitting on. That has already happened here β a tag-filter feature and a scrubber-URL feature lived only in one machine's localmainfor a day, and disappeared the moment somebody synced main with the remote. If you find yourself with commits on localmain, move them onto a branch and open a PR before doing anything else. - Always rebase onto the target, never merge into it. Rebase the branch onto the target first, then integrate with a rebase merge β
gh pr merge --rebase, never--merge. Main stays a flat sequence of ref-prefixed commits, which is what the commitβticket linking reads. A merge commit adds a subject carrying no ref and buries the branch's commits behind it. - Squashing the branch down first is fine β one commit per ticket ref. A branch's worth of fixups is history nobody needs on main, so collapsing it into a single commit (
git rebase -i, orgh pr merge --squashwith a ref-prefixed subject) is welcome, provided every commit that lands still opens with its ticket's ref. What the linking cannot survive is a squash across refs: fold two tickets' commits into one subject and one of them loses its commits for good. So a branch carrying two refs squashes to two commits, not one β and check the resulting subject before integrating, because--squashdefaults to the PR title, which is only right if the title carries the ref. - The git user is the sole author of every commit you write. Commit under the repo's configured
user.name/user.emailand nothing else: noCo-Authored-By:line, noClaude-Session:line, noπ€ Generated withfooter, and never an--authoroverride naming Claude or a tool. The commit body ends with the last line of prose. This holds for amends and rebases too β checkgit log --format='%an <%ae>%n%b'over the branch before pushing, because a trailer added by a default template survives a rebase and reaches main unnoticed. It does not license rewriting anyone else's authorship: commits by other contributors keep their author, and reassigning them would both misattribute their work and mean force-pushing main. - Tag tickets properly. Reuse existing tags where they fit (check current issues/tags first) instead of inventing near-duplicates.
- Read the ticket's comments before starting, not just its description. The description is what was known when the ticket was written; comments carry later context β narrowed scope, a decision already taken, a dead end someone hit, a correction to the original diagnosis. Working from the description alone risks redoing settled work or implementing something that was already ruled out.
- Use comments to communicate deviations. If the work diverges from what the ticket describes β scope changes, findings, blockers, test results β record it as a comment on the ticket, not just in chat.
- When a ticket is done, Document the outcome in a comment starting with
Solution:. Use that exact prefix as the comment's opening line, so^Solution:finds every resolved ticket on the board. Say what actually resolved it β the commit, the approach taken, and anything a reader would otherwise have to reverse-engineer from the diff; a bare commit hash is not a solution. Use the same prefix when a ticket is closed without a code change, and say why. - Attach a screenshot only when a picture carries what words cannot β a layout that has to be seen, a rendering bug, a chart whose shape is the point. It is the special case, not a routine part of a
Solution:comment: most outcomes are better described than photographed, and a screenshot of something a sentence already covers costs everyone the bytes below. When one does earn its place, useepiq_issue_attachment_add(it takes a file path) and paste themarkdownit returns into the comment. - Crop and compress it first.
epiq_issue_attachment_addstores the file exactly as it finds it β only the GUI compresses on upload β so a raw full-screen capture goes in at full size, up to the 500 KB cap. The blob lands in.epiq/media/on the state branch, replicates to every clone, and is never removed: deleting an attachment writes a tombstone and the bytes stay, so time travel can still resolve them. Crop to the region that makes the point, scale it down, and land well under the cap rather than against it. An oversized image is permanent, for everybody β the same reason the text limits exist. - Be concise. Titles, descriptions, and comments should be scannable, not essays.
- If a ticket is blocked, record the blocker in a comment and move it to Blocked (or tag it blocked if there is no Blocked column).
- If a you decide to take a new approach, make sure to document the fork in a new comment, and tag the ticket with a "fork" tag, update the description to reflect the new plan. Don't leave it as-is and expect readers to infer the change from comments.
- Park decisions that are the user's to make. A design fork, a change with blast radius beyond its ticket, anything you'd want a second opinion on β file a ticket tagged
human-input-needednaming the options and the trade-off, then carry on with whatever doesn't depend on the answer. Settling it alone in chat, while nobody is reading, is a decision the user never made. - Findings from a code review get their own tickets, tagged
from-review, with the description saying which branch or PR the review covered β so the provenance survives even if the tag doesn't.
Related skills
Skill Builder & Optimizer
anthropics
Create, edit, and optimize Claude skills with performance testing and benchmarking.
Org Change Management
alirezarezvani
Guide teams through organizational changes using the ADKAR model and communication strategies.
Audio/Video Transcription
daymade
Transcribe audio and video files to text with fast local or remote processing.
Claude Export Conversation Fixer
daymade
Repair broken line wrapping in Claude Code exported conversation files.