About project-tracking
project-tracking is a skill for organizing GitHub work as Epics, Stories, Tasks, and Bugs. It supports planning, issue creation, board queries, and status changes, with proposals requiring confirmation before bulk hierarchy changes.
Key features
- 01Epic/Story/Task/Bug hierarchy
- 02Plan epics and migrate flat boards
- 03Create and categorize GitHub issues
- 04Query backlog by status or priority
- 05Move issues through board statuses
Use cases
- 01Break a large initiative into linked issues
- 02Reorganize a flat GitHub issue board
- 03Record implementation bugs and follow-up work
- 04Review backlog and update issue status
MCP support
Uses the GitHub MCP create-issue tool in issue-tracking flows; it also relies on GitHub commands and project-board operations.
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ fearovex-labs/ agent-config --skill project-trackingAfter installing, type/project-trackingin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
COMMANDS.mdtemplates/bug.mdepic.mdstory.mdtask.mdDetails
From the project READMETriggers: /track-init, /plan-epic <description>, /plan-migrate, /track <description>, /backlog, "qué tenemos pendiente?", "what's pending?", "acordate que hay que...", "remember to...", "vamos a planear", "armemos la épica", bug found during implementation, SDD tasks generated by sdd-tasks.
Hierarchy model — Epic / Story / Task / Bug
This skill enforces a three-level hierarchy (plus Bug as an orthogonal type) modeled with GitHub Issue Types (native) and sub-issues (native). Labels are kept for backwards compatibility but Issue Types are authoritative.
| Level | GitHub Issue Type | Lifetime | Sub-issues of | Has sub-issues |
|---|---|---|---|---|
| Epic | Epic | Weeks | none | Stories |
| Story | Feature | Days | Epic | Tasks |
| Task | Task | Hours | Story (or Epic for hotfixes) | none |
| Bug | Bug | Hours–Days | Epic (Stability) or Story it breaks | none |
Rules of thumb:
- One Task = one Claude session. If it does not fit, it is a Story disguised as a Task. Split it.
- A Story without sub-issues is allowed only when its acceptance criteria already serve as the task list (truly small).
- An Epic without sub-issues is a smell — likely it is actually a Story.
- A Bug can be standalone (no parent) when it does not belong to a planned epic.
Issue Types vs labels
The skill writes BOTH the Issue Type (when the org has Issue Types enabled)
AND the equivalent legacy label (type/epic, type/feature, type/task,
type/bug). This lets old views, filters, and the existing /track flow
keep working while the new hierarchy is adopted incrementally.
Detection of Issue Type availability is done once per session via the
Issue-Type detection block in COMMANDS.md. If the response is empty or the field
is unsupported, fall back to label-only mode and warn the user once per session:
"Issue Types are not enabled on this org. Falling back to labels —
type/epic,type/feature,type/task,type/bug. To enable native types, go to Org settings → Issue Types."
All literal
gh/ GraphQL command blocks live inCOMMANDS.md, referenced below by step ID (e.g.[track-init §1]). This file holds the decision logic;COMMANDS.mdholds the exact invocations.
Process
Pre-flight: Detect Repo and Config
Before any flow, resolve owner/repo (run Pre-flight — detect repo in COMMANDS.md).
Then search engram for the project config:
mem_searchwith querytracking/{repo-name}/config- If found, call
mem_get_observationto get project number and field IDs - If NOT found and the flow requires project operations → warn user to run
/track-initfirst
Flow 1: Bootstrap — /track-init
Run once per repo. Idempotent — safe to run again.
Step 0 — Detect token capabilities
Run [track-init §0]. On failure, classify the cause using the table there —
never assume every failure is the token. Distinct causes route to distinct actions:
gh-not-authenticated (§0-auth), fine-grained PAT (§0-manual), missing project
scope (gh auth refresh -s project), a transient GitHub/network error (stop and
retry later, do NOT touch the token), or — when REST works but Projects/GraphQL
returns FORBIDDEN — a misconfigured token env var (§0-token-env: wrong token
type, or the right token under a name gh never reads).
Most common (your case): fine-grained PATs do NOT support Projects V2 on personal
accounts (only orgs). [track-init §0-manual] offers two exits: fix the token
(Classic PAT + gh auth, recommended — unblocks automatic creation for every repo)
or create the board manually (fast fallback). Recommend the token fix. If the user
fixes the token, re-run Step 0 then go to Step 1. If they create it manually, capture
the project number and skip to Step 2 (labels).
Step 1 — Create GitHub Project board (automatic path)
Only if Step 0 confirms Projects V2 support: run [track-init §1] (creates the
project + the Status / Priority / Type single-select fields).
Step 2 — Create labels
Run [track-init §2] (type / priority / status labels). Idempotent — a label that
already exists makes gh label create fail; catch and continue.
Step 3 — Capture field and option IDs
Whether the board was created automatically (Step 1) or manually (Step 0), run
[track-init §3] to capture status_field_id, priority_field_id, type_field_id
and the option IDs for each value. Required by gh project item-edit.
Step 4 — Save config to engram
Call mem_save with:
- title: "Bootstrap project-tracking config for {repo-name}"
- type: config
- topic_key:
tracking/{repo-name}/config - content: project_number, owner, repo, all field IDs and option IDs as a structured map
Confirm to user: "Board linked. Project #{project_number} for {owner}/{repo}. Config saved to engram."
Flow 2: Plan Epic — /plan-epic <description>
Used to plan a large feature or initiative end-to-end: one Epic, its Stories, and the Tasks of each Story. Nothing is written to GitHub until the user confirms explicitly.
Run /track-init first if no engram config exists for this repo.
Step 1 — Read templates
Load the body templates from this skill directory:
templates/epic.mdtemplates/story.mdtemplates/task.md
These are the contract — every issue created in this flow follows them.
Step 2 — Detect Issue Type support
Run Issue-Type detection (COMMANDS.md). Cache the result for the session.
Decide: native Issue Types mode OR label-fallback mode.
Step 3 — Propose the hierarchy as Markdown in chat
Produce a single chat message structured as:
# Epic: {Title}
Type: Epic | Priority: {P0..P3}
[Epic body following templates/epic.md]
---
## Story 1: {Title}
Type: Feature | Priority: {P0..P3} | Parent: Epic above
[Story body following templates/story.md]
### Task 1.1: {Title}
Type: Task | Parent: Story 1
[Task body following templates/task.md]
### Task 1.2: {Title}
...
---
## Story 2: {Title}
...
Show the full proposal in ONE message. Do not call any GitHub API yet.
Step 4 — Wait for confirmation
End the proposal message with EXACTLY this prompt:
Review the plan above. Reply:
- "dale" / "go" / "create" → I create all N issues + sub-issue links
- "edit <X>" / "no <X>" → tell me what to change, I revise the plan
- "abort" → drop the plan, nothing is created
If the user replies anything other than a confirmation keyword, treat it as edit instructions and produce a revised proposal. Re-prompt. Never create issues without an explicit confirmation keyword from this list.
Step 5 — Execute creation in order
Create issues in the order: Epic → Story 1 → Task 1.1 → Task 1.2 → Story 2 → ...
For each issue:
- Call
mcp__github__create_issuewith title, body, labels, and Issue Type (when supported). - Capture the returned issue number.
- If the issue has a parent in the proposal, link as sub-issue with
[sub-issue link]. - Add the issue to the Project board (
[track §3]). - Set Project fields (
[track §4]): Status=Backlog, Priority=as proposed, Type=as proposed.
Step 6 — Report back
Print a single summary block:
## Created
Epic #N: {title}
├── Story #N+1: {title}
│ ├── Task #N+2: {title}
│ ├── Task #N+3: {title}
│ └── Task #N+4: {title}
└── Story #N+5: {title}
├── Task #N+6: {title}
└── Task #N+7: {title}
Total: 1 epic, 2 stories, 5 tasks. All added to project board as Backlog.
Save an engram observation:
mem_savewith type: architecture, topic_key:tracking/{repo}/epic-{N}, content: epic title, child story+task numbers, source of the plan (user request, SDD spec ref, etc.).
Flow 3: Plan Migrate — /plan-migrate
Used when an existing repo has a flat board (issues without parent/child relationships) and needs to be reorganized into the Epic/Story/Task hierarchy.
Step 1 — Fetch the current state
Run [migrate-fetch]. Group issues by likely level using these heuristics:
| Signal | Likely level |
|---|---|
Title starts with epic: or label type/epic or Type=Epic | Epic |
Title starts with feat: or label type/feature or Type=Feature | Story |
Title starts with bug: or label type/bug or Type=Bug | Bug |
Title starts with chore:/task: or no prefix | Task |
Step 2 — Propose the hierarchy in chat
Produce a single message:
# Migration proposal — {N} open issues
## Epics
- #10 epic: Payments & Monetization
Will own:
- #28 feat: Stripe integration for guide bookings
- {other feats that thematically belong}
- #14 epic: Push Notifications & Engagement
Will own:
- #30 feat: push notifications (Expo / Firebase)
## Bugs (orphan — no epic owner)
- #18, #19, #20, ...
Recommended: create epic "Stability & Bugfixes" to own all of these.
OR leave as standalone (no parent). Pick one.
## Unclassified
- #X, #Y — could not infer parent confidently. Please tell me.
End with the same confirmation prompt as /plan-epic Step 4.
Step 3 — Apply on confirmation
For each parent → child pair, run [sub-issue link]. For issues that need an Issue
Type set retroactively, run [set-issue-type]. If Issue Types are not supported,
ensure the legacy type/* label is present instead.
Step 4 — Report
Print the same tree summary as /plan-epic Step 6. Save engram observation
type: architecture, topic_key: tracking/{repo}/migration-{date}.
Flow 4: Track — Create Issues and Add to Board
Trigger model (hybrid)
| Situation | Behavior |
|---|---|
/track <description> | Create issue immediately, no confirmation |
/track with multiple items or backlog session | Create all, show list, ask confirmation before executing |
sdd-tasks generates tasks | Propose creating one issue per task, ask confirmation |
| User mentions future work ("habría que...", "falta...", "después hay que...") | Collect internally. At session end propose: "Detected N trackable items: [list]. Create as issues?" |
| "acordate que hay que..." / "remember to..." | Propose creating an issue immediately |
| Bug found during implementation | Propose creating issue with type/bug label immediately |
Issue creation steps
Step 1 — Deduplicate
Run [track §1]. If a similar issue exists, show it and ask: "Issue #N already
exists: '{title}'. Create a new one anyway?"
Step 2 — Create issue via MCP
Run [track §2] — mcp__github__create_issue with owner, repo, conventional
title (type: description), the body template, and applicable labels. The body
template lives in [track §2].
Step 3 — Add to project board
Run [track §3] (captures item_id).
Step 4 — Set project fields
Run [track §4] — load field/option IDs from engram config
(tracking/{repo-name}/config), then set Status / Priority / Type.
Step 5 — Confirm to user
Created #14: feat: add OAuth with Google — added to board as Backlog/P1-High [Feature]
Flow 5: Query — /backlog and status questions
Default: full board summary
Run [backlog §default], then group items by Status field value. Output:
## Project Board: {project-name}
### In Progress (2)
- #14 feat: OAuth with Google [P1-High]
- #12 fix: Email validation [P0-Critical]
### Review (1)
- #13 feat: User profile page [P1-High]
### Backlog (3)
- #15 feat: Dashboard redesign [P2-Medium]
- #16 chore: Update dependencies [P3-Low]
- #17 feat: Export to PDF [P2-Medium]
### Done (last 5)
- #11 fix: Login redirect loop [P1-High]
Show statuses in order: In Progress → Review → Todo → Backlog → Done (last 5 only to avoid noise).
Filtered queries
| Command | Filter applied |
|---|---|
/backlog bugs | Only items with Type = Bug |
/backlog high | Only items with Priority = P0-Critical or P1-High |
/backlog in-progress | Only items with Status = In Progress |
/backlog todo | Only items with Status = Todo |
/backlog review | Only items with Status = Review |
Status Transitions
Manual triggers: /track move #14 in-progress, /track move #14 review,
/track move #14 done. Underlying command: [status-move].
Automatic integration points:
- Claude starts working on issue → move to "In Progress"
- Claude opens PR for issue → move to "Review" (integrates with
branch-prskill) - PR merged / issue closed → move to "Done"
Rules
- GitHub Issues + Projects is the source of truth for WHAT needs to be done — backlog, tasks, stories, bugs
- Engram remains the source of truth for decisions, discoveries, and technical context — these are complementary, not competing
- Never create duplicate issues — always run
gh issue list --searchbefore creating - Issue titles follow conventional format:
type: description(e.g.,feat: add OAuth,fix: email validation) - Labels use lowercase with
/separator:type/feature,priority/high,status/backlog - Every issue MUST have at least the Type field set on the project board
/track-initis idempotent — running it twice must not create duplicate labels or projects; handle errors fromgh label creategracefully- Project config (IDs) MUST be saved to engram after bootstrap with
topic_key: tracking/{repo-name}/config - Before any
gh project item-editcall, load field IDs from engram; if not found re-derive withgh project field-list - Batch creation requires confirmation — when proposing multiple issues at once, show the full list and wait for user approval before creating any
- Propose, don't assume type/priority — when auto-detecting trackable items from conversation, infer reasonable defaults but show them to the user before creating
- Prefer MCP for issue creation (
mcp__github__create_issue) andghCLI for all project board operations - When
/track-inithas not been run (no engram config, no linked project), detect this and suggest running it before any board operation - Fine-grained PATs do NOT support Projects V2 on personal accounts — only Classic PATs or org-scoped tokens work. When detected, offer both exits (
§0-manual): recommend fixing the token (Classic PAT +gh auth, unblocks every repo) over the manual-board fallback. Never present manual creation as the only option ghreads its token only fromGH_TOKEN>GITHUB_TOKEN(in that order), and an env var token overridesgh auth login. A correct token under any other name (e.g.GITHUB_CLASSIC_TOKEN) is silently ignored. When REST works but Projects/GraphQL returnsFORBIDDEN, suspect a misconfigured env var (§0-token-env): put the Classic PAT inGH_TOKEN, verify with the one-line GraphQLviewer.projectsV2query. Document the rule — token type, variable name, verification — never the secret value- Both automatic and manual board creation paths converge at Step 3 (capture IDs) — the rest of the workflow is identical regardless of how the board was created
/plan-epicis confirm-first: the full hierarchy (Epic + Stories + Tasks) is proposed as Markdown in chat; NOcreate_issuecall fires until the user replies with an explicit confirmation keyword (dale,go,create). Anything else is treated as edit instructions, not approval.- Issue Types are authoritative when available; legacy
type/*labels are written alongside for backwards compatibility. Detect support via GraphQLissueTypesquery, cache the result for the session, and fall back to label-only mode with a one-time warning when types are unsupported. - Sub-issue links use the
addSubIssueGraphQL mutation — never simulate hierarchy with text in the body ("parent: #N" alone does not create the link). - One Task = one Claude session. If a Task does not fit in one session, it is a Story disguised as a Task — propose splitting it before creating.
/plan-migratenever modifies issues without confirmation — same confirm-first contract as/plan-epic. Unclassified issues are flagged for the user, not auto-assigned.- Bug issues can be standalone (no parent epic) or owned by a "Stability & Bugfixes" epic. Pick one approach per repo and keep it consistent — the choice goes into the engram config under
tracking/{repo}/config. - Body templates live in
skills/project-tracking/templates/(epic.md,story.md,task.md,bug.md) and are the ONLY source of truth for issue body structure. Do not improvise alternative formats.