From team-tracking-mcp
Use when you are a specialist subagent executing a single subtask (implementer, test-writer, adversarial reviewer, etc.). Covers acquiring the lock, recording a checkpoint after every git commit, the pulse-update protocol, and how to escalate work that's too complex back to the orchestrator instead of forcing it through.
How this skill is triggered — by the user, by Claude, or both
Slash command
/team-tracking-mcp:team-tracking-executeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You're a specialist running one subtask end-to-end. The orchestrator handed you a `TicketRef`. This skill is the protocol you follow against the team-tracking MCP server. Lower-level tool reference: [`team-tracking-usage`](../team-tracking-usage/SKILL.md).
You're a specialist running one subtask end-to-end. The orchestrator handed you a TicketRef. This skill is the protocol you follow against the team-tracking MCP server. Lower-level tool reference: team-tracking-usage.
You've been dispatched to do exactly one subtask. You have a ref = { project, id } and a clear definition of what "done" looks like for your role.
get_ticket(ref)
Read the body, scope, branch, and prior progress_summary. If lock_state looks live and was last touched recently, stop — there's a concurrency bug upstream. Append a log line and exit; the orchestrator will sort it out.
acquire_ticket(ref, owner="<role>@<dispatch-id>")
→ { lock_token, recovered_checkpoint }
Use an owner a human reading the board can decode (implementer@dispatch-7, adversarial-code-reviewer@dispatch-12).
If recovered_checkpoint != null: a previous specialist crashed mid-run. Their last good state is the SHA in recovered_checkpoint.commit_id. Before doing anything else:
git checkout <branch>
git reset --hard <recovered_checkpoint.commit_id>
Read recovered_checkpoint.update + progress_summary for context, then resume from there.
The orchestrator polls every 5–10 minutes while you work — reading your progress_summary, your update line, and the diff of your last checkpoint SHA. That's how it catches drift, hallucination, and stuck loops early. Two implications:
progress_summary should describe what the diff actually contains. If you claim to have written tests but the diff has none, the orchestrator (and the adversarial reviewer that reads the diff) will catch it — and rightly distrust the rest of your output.The orchestrator can leave directives on your ticket via post_message. You don't poll for them — instead, you keep a background bash process running that delivers events as they arrive.
After acquiring the lock, spawn:
Bash(
team-tracking listen --project <project> --ticket-id <ref.id> \
--since <lastSeen> --timeout-ms 300000,
run_in_background: true
) → handle_N
Initial lastSeen = lock.acquired_at. The CLI:
at > since immediately (handles the race where a message landed between your last cycle and this re-spawn).events envelope, on timeout (5 min default → re-spawn), or on error.Output is JSONL:
{"type":"events","ref":{"project":"P","id":"..."},"events":[...]}
{"type":"timeout"}
{"type":"error","reason":"..."}
When the harness notifies you that the background bash ended, parse the last line, advance your lastSeen cursor to max(events.map(e => e.at)), and act on it.
Round-trip target: a question → response → ack cycle should complete in under 1 min of round-trip wall time (latency is bounded by your own in-flight tool call duration). If 10+ minutes pass with no replies, the orchestrator will treat you as stuck, escalate, or pull the lock on TTL.
For each new event where type == "message" and from is the orchestrator (or any non-executor role):
Read it. Take it at face value — it's the orchestrator's view of where you should be.
Decide. Will you comply, push back, or need to escalate?
ACK or respond. Always reply, even if just to acknowledge:
post_message(ref, {
from: "<your role>@<dispatch-id>",
kind: "ack", // or "response"
in_reply_to: <orchestrator-message-id>,
body: "Confirmed — staying within auth/. Will revert the billing/ change in next commit.",
})
Re-spawn the listener so you don't miss the next event:
Bash(team-tracking listen --since <new-lastSeen> ..., run_in_background: true)
If the orchestrator's directive is wrong (e.g. you have valid context they don't), push back — kind: "response" with reasoning. Don't silently comply with bad guidance.
The harness only surfaces the background-bash completion between your tool calls. So if you're mid-Bash(run tests) when a message arrives, you'll see it after the test command returns. That's fine — the latency floor is your in-flight tool call's duration, which is much better than the old polling cadence.
After every git commit you intend to keep:
commit_checkpoint(ref, {
lock_token,
commit_id, # the SHA you just made
update: "one line, what you just did",
progress_summary: "rolling cumulative state",
})
The server records the SHA without verifying — you must have actually made the commit on branch. The checkpoint is the safe revert point if you crash; it's how the orchestrator's retry flow recovers your work.
Between commits, when you want to surface progress without recording a SHA:
report_progress(ref, {
lock_token,
update: "writing the retry policy",
progress_summary: "queue config done; retry path 60% drafted",
})
For audit-worthy events (decisions, gotchas, recovered errors):
append_log(ref, "switched provider from X to Y because <reason>")
append_log doesn't require a lock token — anyone may write to it.
When the subtask passes its acceptance criteria:
release_ticket(ref, { lock_token, final_status: "Done" })
Don't release as Done unless you can defend the criteria for your role:
If you can't defend Done, see escalation below.
Subtasks sometimes turn out bigger than one specialist session. Don't force it through. Don't silently leave half-done work. Escalate.
Stop. Don't commit half-finished code that won't pass review.
Surface the request via the visible fields:
report_progress(ref, {
lock_token,
update: "ESCALATION: <one-line summary>",
progress_summary: <multi-line: what you tried, where it grew,
proposed split / reassign, what the orchestrator
needs to decide>,
})
Audit the request:
append_log(ref, "ESCALATION: requesting <split | reassign | both>. See progress_summary.")
Release as Blocked:
release_ticket(ref, { lock_token, final_status: "Blocked" })
The orchestrator polls list_board and reads your progress_summary as the briefing. Make it good.
If the subtask should be decomposed further, name the cuts you'd make. Example progress_summary:
Tried "Implement OAuth flow" as one subtask. Two clean cuts emerged:
1. Token exchange + refresh (no UI)
2. Provider config (Google + LinkedIn) — reusable for future SSO
Recommend splitting before re-dispatching. Architect should weigh in
on whether (2) belongs in a separate story.
If the work needs different expertise, say so explicitly:
This subtask is 80% schema design + 20% code. Recommend reassigning
to a specialist with database authority, or pre-approving the schema
with the architect before re-dispatching an implementer.
When the work needs decomposition AND different specialists for each piece, list them together. The orchestrator can act on both signals at once.
| Error | What it means | What to do |
|---|---|---|
EBADTOKEN | Your lock_token doesn't match the active lock | The lock got stolen (TTL expired). Don't retry — return; the orchestrator will redispatch with a fresh one |
ENOTLOCKED | Lock-bound call with no lock held | You released or never acquired. Re-acquire if you still need to work |
ELOCKED | Someone else holds a live lock | Don't fight it. Append a log and exit |
ESTATUS | Tried a status not allowed for the type | Check the type's vocabulary; adjust |
commit_checkpoint without actually making the git commit. The recovery flow assumes the SHA exists on the branch.Blocked + escalation.Done or Blocked with a useful summary.Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub razvanrotaru/team-tracking-plugin --plugin team-tracking-mcp