Agile ledger
Skill nunoamorim99/agile-ledger/plugins/agile-ledger/skills/agile-ledger
A Claude code skill for Product Management. Plain-Markdown Scrum & Agile product management - ideas → backlog → sprints → releases, plus bug tracking, all from slash commands. Product management in the source code to make it easily accessible to everyone without distractions
npx -y skills add nunoamorim99/agile-ledger --skill agile-ledgerAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Plain-Markdown Scrum / Agile product-management system for Claude Code. Manage a product backlog of Epics and User Stories, plan and run sprints, drive a board, track velocity, cut Major.Minor releases, and keep GitHub branches/commits/PRs traceable to stories — all from slash commands, with no Jira and no database. Use this skill whenever the user mentions a backlog, epic, user story, sprint, sprint planning, standup, board, story points, velocity, acceptance criteria, definition of done/ready, release, changelog, roadmap, or wants to capture / triage / detail / ship a product idea, plan a sprint, open a PR for a story, or check what merged to main — even if they don't say "Agile-Ledger" explicitly. The `Agile-Ledger/` folder of Markdown files is the single source of truth; keep it true.
SKILL.md
27.2 KB, as published. Nobody here has run it
Agile-Ledger
A product-management system made of plain-Markdown files in an Agile-Ledger/ folder, applying the
Scrum framework so a Product Manager runs the whole lifecycle — backlog → sprint → increment → release
— from the command line, and shares the result with developers who don't need to learn a new tool.
Two-layer model. The team uses GitHub for code (branches, commits, PRs, merges) and Agile-Ledger for the PM layer (backlog, stories, sprints, board, releases). The two are stitched together by one join key — the User Story ID — which travels through every branch, commit, and PR.
Priority of duties, always in this order:
- Bookkeeping is the job — keep the backlog, sprint, board, and release record true.
- Execution is optional — git automation is opt-in; the developer may build however they like and the ledger still stays accurate.
This skill is the brain. The slash commands are thin entry points that delegate here. When natural language matches ("new story", "let's plan the sprint", "what merged to main"), act through these rules.
Golden invariants (never violate)
- Plain Markdown only. No database, no dependencies. This is why a no-Jira team can adopt it.
- Never delete. Nothing is removed — delivered, paused, and discarded items are kept forever; discarded items keep why they were rejected.
- State = physical position, moved only by a command. A status change is a move between sections or board columns, never a silent emoji swap.
- Recompute IDs; never reuse. On every registration, scan all files for the highest existing ID
of that type and use max + 1. A
Next free IDhint may exist but is reconciled, never trusted blindly. - Absolute dates only. Resolve "today"/"yesterday" to a real
YYYY-MM-DDbefore writing. - The human's voice, English ledger (configurable in
Definitions.md). Raw captures may be any language; translate at triage. - Re-read immediately before writing. Makes multi-session capture safe.
- Write entries for readable previews. Put each metadata field on its own bulleted line and separate
logical sections (story, acceptance criteria, dependencies, delivery, notes) with a blank line, so the
rendered Markdown preview stacks them instead of collapsing into one paragraph. Follow
references/entry-templates.mdexactly; never collapse an entry into a single inline paragraph, and never rely on trailing-space line breaks — they are invisible and get lost when an entry is rewritten. - Case-insensitive ID matching across the git boundary: ledger stores canonical
US-014; git uses lowercaseus-014; matching ignores case. - Epic status and rollups are derived from children, never hand-set.
- Confirm before any merge or push. Git execution is opt-in (see Git conventions). Never auto-merge.
- Session start: read all
Agile-Ledger/*.mdfiles first, load state silently, give at most a one-line orientation.
Files & where things live
Agile-Ledger/
├── Ideas.md # 💡 idea inbox — raw captures from /idea. Triage promotes them out of here.
├── Epic-Backlog.md # Epics, each with a lightweight STORY INDEX. Epic dashboard table on top.
├── User-Stories.md # full detail for Ready+ stories, grouped by state. State-summary table on top.
├── Bugs.md # bug reports, grouped by state. Bug dashboard table on top.
├── Sprint.md # current sprint: goal, board (To Do→In PR→Done), assignees, blocked flags, sync cursor
├── Sprints-History.md # closed sprints + velocity (never-delete)
├── Releases.md # 🚧 Increment (Done, unreleased) at top, then Major.Minor history (newest first)
└── Definitions.md # DoD, DoR, INVEST, branch/commit/PR conventions, config (git opt-in, language)
One command, one place — the file each phase writes to:
| Phase | Command(s) | Writes to |
|---|---|---|
| Capture an idea | /idea | Ideas.md (💡 inbox) |
| Triage → register | /triage | reads Ideas.md → writes Epic + suggested story-index in Epic-Backlog.md |
| Detail a story | /detail-us /detail-epic | User-Stories.md (detail) + Epic-Backlog.md (index mirror) |
| Report / fix a bug | /bug /triage-bug /find-bug /done-bug | Bugs.md |
| Plan / run a sprint | /plan-sprint /start-* /review /pr /done-* /close-sprint | Sprint.md (board) + the item's home file |
| Release / report | /release /changelog /status /roadmap | Releases.md (read across all) |
Two-file story model (for scale). Epic-Backlog.md is the epic file — epics plus a one-line
index of each of their stories (US-id · title · state · priority · pts · assignee), so you follow
what's done or not without scrolling through Gherkin. User-Stories.md holds the full story detail
(As-a/I-want/So-that, acceptance criteria, dependencies, notes), grouped by state. Raw ideas live
separately in Ideas.md until /triage promotes them, so the epic backlog stays clean.
- A 📝 Draft story (triaged, not yet detailed) exists only as an index line under its epic in
Epic-Backlog.md. There is nothing to detail yet. /detail-uswrites the story's full entry intoUser-Stories.md(under## ✅ Ready) and flips its epic index line to Ready. From then on the detail lives inUser-Stories.md.- Source of truth: for Ready-and-beyond, the story detail and its lifecycle grouping live in
User-Stories.md; the epic index line inEpic-Backlog.mdis a derived mirror. While a story is in a sprint,Sprint.mdtracks its fine board column (To Do→In PR) by ID; the epic index keeps the coarse state (In Sprint)./ledger-checkreconciles index ↔ detail ↔ board. - Epic index coarse states:
Draft · Ready · In Sprint · Delivered · Paused · Discarded. The live board columns are shown by/board. - Overview tables (top of each file):
Epic-Backlog.mdopens with an epic dashboard (Epic · Title · Status · Stories done/total · Points done/total · Target);User-Stories.mdopens with a state summary (State · Stories · Points). Commands that change a story's state refresh the affected table(s).
If a project starts with no Agile-Ledger/ folder, scaffold all eight files from the
references/*.template.md files before doing anything else.
The ID system (typed hierarchy)
| Type | Shape | Parent field |
|---|---|---|
| Epic | EPIC-001 | — (top level) |
| User Story | US-014 | Parent: EPIC-001 |
| Task (optional) | TASK-031 | Parent: US-014 |
| Bug | BUG-014 | relates to US-xxx / EPIC-xxx (optional) |
- Each type is sequential within its own type, never reused.
- Use parent pointers, never nested numbers (
US-014.3is forbidden — it renumbers on reorder). - Default hierarchy is Epic → User Story. Tasks are off by default — create one only for an explicit sub-unit (unplanned/harder work, or a genuine FE/BE two-developer split).
- Bugs are a separate track (their own file and capture/triage/assess flow, see Bug tracking) but they share the sprint board with stories. A bug relates to a story/epic; it is not a child of one.
- The Inbox is type-agnostic: a raw
/ideahas no type;/triagedecides epic vs story.
Anchors & links (stable, rename-proof navigation)
Every registered entry's heading is its bare ID — ### EPIC-005, #### US-014, ### BUG-014 — and
the human-readable title goes on the line just below. This gives each entry a stable lowercase anchor
(#epic-005, #us-014, #bug-014) that the Markdown preview generates automatically and that does not
change when the title changes. Reference any item as a relative file+anchor link (same Agile-Ledger/
folder):
[US-014](User-Stories.md#us-014)·[EPIC-005](Epic-Backlog.md#epic-005)·[BUG-014](Bugs.md#bug-014)- Anchor = the ID lowercased (hyphen kept). Within the same file you may shorten to
[EPIC-005](#epic-005).
Always write these as live links, not bare text, in: epic story-index lines, a story's Parent,
Dependencies, a bug's relates to, and sprint-board entries — so the reader clicks straight from
the backlog to the detail. This works in GitHub and VS Code preview; custom <a id> anchors are avoided
because they behave inconsistently across viewers. /ledger-check verifies every link resolves.
The two state machines
Shaping states (a story's life before a sprint):
📥 Inbox → 📝 Draft → ✅ Ready (+ ❄️ Paused, 🗑️ Discarded — kept with reason)
- 📥 Inbox: raw capture, no ID, in
Ideas.md. · 📝 Draft: triaged — has ID, parent, priority, index line under its epic inEpic-Backlog.mdonly (not yet detailed). - ✅ Ready: detailed — story sentence + Gherkin AC + estimate, Definition of Ready met (pullable). Full
entry written to
User-Stories.md; epic index line flips to Ready.
For Ready-and-beyond, physical position = state plays out in User-Stories.md: stories are grouped
under ## ✅ Ready, ## 🏃 In Sprint, ## ✅ Delivered, ## ❄️ Paused, ## 🗑️ Discarded, and a state
change is a move between those groups (with the epic index line updated to match).
Sprint.md — board / execution states (only once pulled into a sprint):
To Do → In Progress → In Review → In PR → Done
plus a 🚧 Blocked flag that can sit on a story in any column (a flag, not a column — so a blocked
story never loses its real column; this is also where the dependency gate surfaces). The board tracks the
fine column by ID; the story's detail stays in User-Stories.md (grouped under In Sprint).
The handoffs (all command-gated): /plan-sprint references a Ready story into To Do · /start-us
→ In Progress · /review → In Review · /pr → In PR · /done-us → Done · /close-sprint sends Done
onward to the Increment and unfinished stories back to Ready.
Epics never go on the board (they span many sprints). Follow them via /roadmap.
Bug states (in Bugs.md, a separate track that shares the board):
🐛 Inbox → 🔍 Triaged → 🔬 Confirmed → 🛠️ In Sprint → ✅ Fixed
(+ ❄️ Deferred, 🚫 Won't fix / Can't reproduce — kept with reason)
- 🐛 Inbox: raw report (
/bug). · 🔍 Triaged:/triage-bugset BUG-id, severity, priority. · 🔬 Confirmed:/find-bugreproduced + assessed it from the code. · 🛠️ In Sprint: pulled onto the board. · ✅ Fixed: done. - A bug becomes pullable once Triaged with a priority (Confirmed preferred). On the board it moves
through the same columns as stories (To Do → In PR → Done), with its own
bug-xxxbranch.
Lifecycle at a glance
Inbox → /triage → Draft → /detail-us → Ready
→ /plan-sprint → To Do
→ /start-us → In Progress (branch us-014-slug offered)
→ /review → In Review (code-complete on branch; verify AC + DoD — "is it really done?")
→ /pr → In PR (verified work only; PR opened, AC checklist pre-ticked)
→ …PR approved + merged on GitHub…
→ /done-us → Done (DoD met; recorded into the Increment)
→ /close-sprint (Done → Increment + velocity; unfinished → Ready)
→ /release (Major.Minor cut from the Increment) → /changelog
Commands
Thin entry points; the rules below are authoritative. Always re-read the target file before writing.
Capture & shape the backlog
/idea <text>— Append<text>verbatim (any language) + today's absolute date to the 💡 inbox inIdeas.md. No ID, no dedup, no rewrite, no questions. Instant and safe mid-work./triage— Process each idea inIdeas.md: run duplicate detection (four outcomes below); decide epic or story; assign the next typed ID; setParent, priority, area; rewrite in the user's voice, in English; write it intoEpic-Backlog.mdand clear the line fromIdeas.md. When an idea becomes a new epic, also propose a few suggested 📝 Draft stories (index lines) under it, derived from the epic goal — present them for confirmation, never as truth. When an idea maps to an existing epic, add it as a single 📝 Draft story-index line under it. No AC or estimate yet (that's/detail-us). Reconcile eachNext free ID./detail-us <US-ID>— Fill one story to Ready:As a <role>, I want <goal>, so that <benefit>, Gherkin acceptance criteria, FibonacciEstimate,Layer,Dependencies. Apply INVEST; flag horizontal slicing (see Vertical slicing). Write the full entry intoUser-Stories.mdunder## ✅ Ready, flip the epic index line inEpic-Backlog.mdto Ready, and refresh both top tables. Move to Ready only once the Definition of Ready holds. (Stories are born as Draft index lines at/triage; this is the step that gives them detail — there is no separate create step.)/detail-epic <EPIC-ID>— Run/detail-usacross all of the epic's stories./create-task <US-ID>(optional) — Add aTASK-xxxunder a story (inUser-Stories.md, with the story) carryingParent,Layer,Assignee. Tasks are work splits, not units of value./refine— Refinement pass overEpic-Backlog.md(Draft index) +User-Stories.md(Ready detail): surface under-detailed items, oversized or horizontally-sliced stories, dangling dependencies, stories failing INVEST or the DoR. Report; fix only on request.
Report & fix bugs
/bug <text>— Instant bug capture: append the reporter's symptom verbatim (any language) + today's date to the 🐛 Inbox inBugs.md. No ID, no questions. The symptom stays in the reporter's voice./triage-bug— Process the bug Inbox: duplicate check; assign the nextBUG-xxx; set severity (critical / major / minor / trivial) and priority (🔴🟡🟢); linkrelates to [US-xxx](User-Stories.md#us-xxx)/area; move to 🔍 Triaged; refresh the bug dashboard. Flag acriticalbug as pull-now (it may warrant interrupting the current sprint rather than waiting for planning). Separate from/triageso an empty bug Inbox costs nothing./find-bug <BUG-ID>— Read-only code investigation. Try to reproduce and locate the cause, then fill steps to reproduce, expected vs. actual outcome, and the assessment (suspected root cause / files). Honesty guardrail: write a field only if you confirm it from the code (confirmed) or the reporter supplied it (reported); otherwise mark itunconfirmed — needs inputand ask. Never invent a repro or a root cause. Never edit code. On success the bug moves 🔍 Triaged → 🔬 Confirmed./start-bug <BUG-ID>— Move To Do → In Progress on the board; offer the branchbug-<id>-<slug>(lowercase). Git only if opted in./done-bug <BUG-ID>— Move In PR → ✅ Fixed (gated by the fix verified against the repro). Move the entry to## ✅ FixedinBugs.md, remove it from the board, and record a line in the 🚧 Increment ofReleases.mdtagged Fixed. Refresh the bug dashboard.
Run the sprint
/plan-sprint— Propose a Sprint Goal; pull top-ordered ✅ Ready stories and triaged/confirmed bugs (highest priority first — a 🔴 critical bug sits above stories) whose points fit recent velocity (fromSprints-History.md); optionally setAssignee; write the new sprint header + board intoSprint.mdwith each item in To Do (by ID reference). Move each pulled story to## 🏃 In SprintinUser-Stories.md(mirror its epic index line) and each pulled bug to🛠️ In SprintinBugs.md; refresh all top tables. Honour the dependency gate. Bug points are optional (count toward velocity if set)./board(alias/standup) — Print the current sprint snapshot: the five columns with their items (stories and bugs — ID, title, assignee, points), plus 🚧 blocked items and their reasons. Read-only. This is the async-team daily view./my-work <name>— One developer's slice of the current sprint: their stories, board column, acceptance criteria (fromUser-Stories.md), branch, and any blockers. Read-only. Framed as workload + blockers, never a ranking. If<name>is omitted, use theMe:value fromDefinitions.mdif set./start-us <US-ID>— Run the dependency gate: if any linked dependency is not Done, stop and warn, naming it. Otherwise move To Do → In Progress inSprint.mdonly (the epic index stays coarseIn Sprint; the detail stays inUser-Stories.md) and offer the branchus-014-slug(lowercase). Only run git if execution is opted in; otherwise just hand over the name./review <US-ID|BUG-ID>— Move In Progress → In Review. Work is code-complete on the branch, no PR yet. Generate a verification checklist: for a story, the acceptance criteria as Given/When/Then + the Definition of Done; for a bug, the steps to reproduce now passing + expected outcome restored. This is the "is it really done?" gate./pr <US-ID|BUG-ID>— Move In Review → In PR (verified work only). Generate the PR body from the ledger and the title<title> [US-014](story) or<title> [BUG-014](bug,Fixes BUG-014). Hand it over to paste, or rungh pr createonly if execution is opted in./done-us <US-ID>— Move In PR → Done, gated by the DoD + all acceptance criteria checked. Move the story's entry inUser-Stories.mdfrom## 🏃 In Sprintto## ✅ Delivered(append the delivery line), set its epic index line toDelivered, remove it from theSprint.mdboard, and refresh both top tables. Record a line in the 🚧 Increment ofReleases.md. If the parent epic was previously Done, this re-opens it (derived status); on the epic's return to Done, close a new epic version (see below)./close-sprint— Summarize Done vs. carried-over; ensure Done stories and Fixed bugs are recorded in the Increment; move unfinished stories back to## ✅ ReadyinUser-Stories.md(reset epic index) and unfinished bugs back to 🔬 Confirmed inBugs.md, clearing both fromSprint.md; append the closed sprint + its velocity toSprints-History.md; refresh the tables; offer retro notes./sync-main— Read-only reconcile of gitmainvs. the ledger. Fetch main, list merges since theLast main synccursor inSprint.md, map each commit to its US or BUG id via the bracketed/parenthesized id (case-insensitive), and flag: (1) merged but ledger not Done/Fixed → propose marking it + filling the Increment; (2) merged with no id → the off-plan surprise; surface it so the user back-fills a story/bug or asks. Update the sync cursor + sync log only after review.
Release & communicate
/release [version]— Cut aMajor.Minorversion from the 🚧 Increment inReleases.md. No arg → sweep everything currently in the Increment;[version]overrides the computed number. Move the released lines into a new dated version-history entry (newest at top); leave the Increment clean. Increment to existing functionality ⇒ Minor; brand-new capability/epic ⇒ Major./changelog— Derive user-facing release notes /CHANGELOG.mdfrom the version history, grouped into Added / Changed (from stories & epics) and Fixed (from bugs). Derived only — never edits the ledger./status— The whole picture: counts by shaping state and board column, current sprint progress, velocity trend, blocked items, open bugs by severity/priority, Increment (unreleased) contents, latest version./roadmap— Epics grouped by target version, each with its derived rollup (stories done/total · points done/total) and status. The strategic follow-up; also where epics map to versions./ledger-check— Audit all files for drift: duplicate or mis-sequenced typed IDs (incl.BUG), danglingParent/dependency links, childless epics, board column not matching the recorded state, orphan Increment lines, staleNext free ID, and — for the split files — an epic index line whose state disagrees with the story's group inUser-Stories.md; a Ready+ story with no index line (or vice versa); a detailed story missing fromUser-Stories.md; a Draft story that wrongly has a detail entry; a bug on the board whoseBugs.mdstate isn't In Sprint; stale overview tables. Also audit navigation: every entry heading is a bare ID (so its anchor is stable), and every ID link ([US-xxx](User-Stories.md#us-xxx), parent, dependency, relates-to, board) resolves to an existing anchor in the named file. Report; fix on request.
Duplicate detection (four outcomes)
Before registering anything, scan every section across all files — including Paused/Discarded (re-raising a discarded item is valuable because its reason is right there). Resolve to one and say which:
- Exact match → surface the existing entry; don't duplicate.
- Same thing, improved → a new story under the relevant epic (increments the epic version on ship).
- Related but distinct → register new, cross-linked with a relative ID link.
- Genuinely new → register fresh.
Epic version control & the triage decision
An epic is the permanent home for its stories and carries a History of vN lines — the
"how many times did we increment this capability?" metric (the signature mechanic, lifted from idea to
epic level).
Version-close trigger: the first time an epic reaches Done = v1. Each time it returns to Done after previously being Done = the next version. A round bundles whatever stories shipped before it went green again. An epic increment typically lands as a Minor release; a new epic as a Major.
Increment vs. new epic — decide at triage: does the idea serve the same user goal as an existing epic, or a new goal?
- Same goal → new User Story under that epic (bumps its version on ship). The common "improve something already built" case. Adding a story to a Done epic re-opens it automatically (derived status: ✅ → 🔨), and it returns to ✅ on ship, closing a new version.
- New goal → new
EPIC-xxx, cross-linked[EPIC-xxx](Epic-Backlog.md#epic-xxx).
Never edit an epic's value directly — an epic improves only by delivering a story.
Versioning lives at the epic level only. Delivered stories are one-and-done (kept, not re-versioned); to change what a story did, write a new story under the epic.
Estimation, priority & velocity (two distinct axes)
- Priority (value, PM-owned): 🔴 high · 🟡 medium · 🟢 low, plus backlog order. Descriptive, not a strict queue; capture the rationale.
- Estimate (size, developer-owned): story points on the Fibonacci series (1, 2, 3, 5, 8, 13…).
- Velocity: sum of completed points per sprint, in
Sprints-History.md, used to size/plan-sprint. A team metric. - Assignee (optional): surfaces workload and blockers, never a productivity leaderboard.
Vertical slicing (a guardrail, not just advice)
A user story must be a vertical slice that delivers user value end-to-end (it normally touches both
front-end and back-end). Never split one story into a "frontend story" + a "backend story" — that
horizontal split delivers no value until both integrate and floods the backlog with developer-only
tech stories. When two developers must divide the work, use optional FE/BE tasks under the same
story, plus a Layer tag. If a story keeps wanting to break along FE/BE lines, it is too big — split
it vertically instead (by workflow step, data variation, CRUD operation, or happy-path-then-edges).
/refine flags horizontal slices and suggests vertical splits.
Git & traceability conventions
The US ID is the join key. Strip it and /sync-main becomes guesswork. Bugs follow the same pattern
with BUG- and a fix commit type.
| Artifact | Shape | Rule |
|---|---|---|
| Branch | us-014-google-sso · bug-014-safari-login | lowercase, no type prefix, ID + slug |
| Commit | feat(auth): add Google SSO sign-in (US-014) · fix(auth): … (BUG-014) | Conventional Commits — type kept |
| PR title | Google SSO sign-in [US-014] · Fix Safari login [BUG-014] | no type, ID in brackets |
- Match IDs case-insensitively (
US-014↔us-014↔[US-014]↔(US-014); same forBUG-). - Squash-merge note: a squash subject inherits the type-less PR title, so it won't parse as a Conventional Commit. This does not affect Agile-Ledger (the changelog is ledger-derived), but teams relying on GitHub-side conventional-commit automation should keep the type on the squash subject.
- FE/BE sub-branches (optional, two-dev split):
us-014-fe/us-014-bebranch off the US branch and merge back into the US branch only — never into main, preserving 1 US → 1 PR → main. Ephemeral. - Git execution is opt-in per project via
Definitions.md(default: generate text, don't execute). Never auto-merge; merges happen on GitHub; the skill reconciles after via/sync-main. Always confirm before any push or merge.
Templates (read from references/ when you need the exact shape)
references/entry-templates.md— Epic (with story-index lines) · the overview tables · User Story (the full entry, written inUser-Stories.md) · Bug · Task · acceptance criteria (Gherkin) · PR body · commit · delivery note.references/Ideas.template.md,Epic-Backlog.template.md,User-Stories.template.md,Bugs.template.md,Sprint.template.md,Sprints-History.template.md,Releases.template.md,Definitions.template.md— the eight scaffold files to write when a freshAgile-Ledger/folder is created.
Read the relevant template before scaffolding or registering, so shapes are never re-derived.
Deliberately NOT included
Story-level versioning (epic-level only); tasks by default; the skill facilitating ceremonies (it
produces the material for them); heavy burndown-style dashboards; hard-coded git providers/stacks.
If rigor is added later it must stay opt-in and must never slow down /idea.