GitHub Issues own task definition and lifecycle. Simple Issue → PR work stays sprint-free; a local sprint file is added only when complex execution needs shared batching, context, progress, or handoff across issues, actors, or sessions.
dev-backlog adds a local sprint file that carries the plan, decisions, and progress across tasks and sessions. Claude Code, Codex, and humans all read the same file.
No new server. No hidden state. No automatic memory writes. Existing GitHub repositories retain their tracker selection and Issue identities without data migration; the legacy export CLI has the intentional opt-in change documented under Upgrade behavior.
README.md is the product overview and human quick start. The agent execution contract, sprint-file rules, and full script reference live in skills/dev-backlog/SKILL.md.
The zero-adopter local tracker has been removed. GitHub is the only runtime task authority. Backlog.md-compatible files remain an explicit one-way legacy import/export boundary and never become co-authoritative. See the authority and routing contract.
backlog/.tracker: github
|
`-- GitHub Issues (canonical) -> no required task mirror
backlog/sprints/ execution hub: plan, context, progress
^
|
Claude Code / Codex / Human
reads sprint -> knows what to do next
updates progress -> team sees what happened
| Capability | What changes |
|---|---|
| One task authority | Live GitHub Issues own specification, native planning metadata, and lifecycle |
| Complexity-triggered sprint | Simple work stays Issue → PR; admitted complex tracks share one execution plan and may run concurrently when disjoint |
| Non-authoritative compatibility | Legacy task files can be exported for diagnosis/rollback and are never read back as runtime truth |
| Live task reads | Work resolves Issue intent and AC directly; no pull step or background sync |
[ ] / [~] / [x] plan states |
Delegated work stays visible in the sprint file, not buried in PR tabs |
context-hook.sh |
Claude Code can get a one-line sprint summary before edits |
sprint-close.sh |
Close the loop: mark sprint complete, archive checked legacy mirrors only when present, optionally close the milestone |
| Plain Markdown + Bash + Node built-ins | No database, no daemon, no mystery |
npx skills add sungjunlee/dev-backlog -g -y- Claude Code or Codex
ghCLI authenticated withgh auth login(GitHub mode only)- Git
- Node.js 18+
- Bash. On Windows, use Git for Windows Bash; Node-based acceptance tests resolve
it from
git.exeinstead of selecting an ambient WSLbash.exe.
git clone https://github.com/sungjunlee/dev-backlog.gitRun these commands from the project you want to manage, not from the dev-backlog repo itself.
The examples below assume you have this repo available at /path/to/dev-backlog. If you installed the skill with npx skills add, use the installed skill path instead.
For one self-contained Issue, work directly from the live Issue and its PR. Open a sprint only for ordered multi-Issue work, delegated/parallel handoff, cross-Issue or cross-session context, or concurrent-track coordination. Duration, estimate, milestone membership, and Relay presence alone do not require one. The commands below show that admitted complex-work path and its transition-compatible setup.
# 1. Choose the canonical tracker and bootstrap backlog/
node /path/to/dev-backlog/skills/dev-backlog/scripts/setup-dev-backlog.js \
--tracker github --non-interactive
# 2. Create an active sprint from a milestone
node /path/to/dev-backlog/skills/dev-backlog/scripts/sprint-init.js "auth-system" --milestone "Sprint W13"
node /path/to/dev-backlog/skills/dev-backlog/scripts/sprint-init.js "auth-system" --milestone "Sprint W13" --dry-run --json
# 3. See what to do next
bash /path/to/dev-backlog/skills/dev-backlog/scripts/next.sh
bash /path/to/dev-backlog/skills/dev-backlog/scripts/status.sh
# 4. Resolve task intent and AC from the live authority
node /path/to/dev-backlog/skills/dev-backlog/scripts/effective-task-spec.js \
"#42" --repo OWNER/REPO
# 5. Close the sprint when the work is done
bash /path/to/dev-backlog/skills/dev-backlog/scripts/sprint-close.sh backlogFresh GitHub setup creates only backlog/.tracker and backlog/sprints/;
backlog/tasks/ and backlog/completed/ are not required or created.
Backlog.md compatibility is a one-way legacy boundary. Import means a
human-reviewed compatible Markdown record is used to create or amend a GitHub
Issue. Export is the explicit sync-pull.js --legacy-export diagnostic or
rollback snapshot. Runtime execution never reads task files as task truth, and
the Backlog.md CLI or runtime is never required.
For task list, read, create, update, and close, the stable invocation
boundary is the configured adapter exported by scripts/tracker.js. Operators
and agents resolve it with the target backlogDir and call those methods in
the GitHub mode; the exact procedure and signatures are documented in
the process guide.
There is zero automatic tracker-selection migration. A repository with neither
backlog/.tracker nor a legacy tracker: key in backlog/config.yml continues
in GitHub mode with its existing #N, numeric issue_number, milestone,
comment, and closing behavior. When .tracker is
absent, runtime reads a legacy YAML selection as a compatibility fallback.
Only the legacy value github is accepted. Running setup-dev-backlog.js
pins that resolved choice to .tracker
without editing config.yml; setup never migrates task files and runtime never
chooses a tracker from availability or failure.
Existing automation that invokes sync-pull.js without a flag must add
--legacy-export; otherwise the command refuses before provider access or task
materialization. This opt-in preserves rollback/diagnostic exports without
putting them back on the normal workflow. It is an intentional CLI migration,
not an automatic tracker or task-data migration.
The retained compatibility seams, consumer evidence, and subtraction proof
live in docs/compatibility-subtraction.md.
Then use the skill during your coding session:
/dev-backlog orient
/dev-backlog next
/dev-backlog work 42
/dev-backlog sync
For the detailed sprint contract, section semantics, and full script inventory, see skills/dev-backlog/SKILL.md.
Run the same cross-platform checks used by CI:
node --test skills/*/scripts/*.test.js
bash skills/dev-backlog/scripts/smoke-test.shWindows uses Git for Windows Bash. If Git comes from a nonstandard installation,
set DEV_BACKLOG_BASH to its bash.exe before running the Node tests. POSIX mode
symlink-privilege, and open-file replacement race tests are skipped when the
Windows filesystem cannot represent those semantics; the behavior remains
covered by the Ubuntu job.
After editing this repository's skill bundle, run the discovery smoke check from the repository root:
npx --yes skills add . -lExpected: the CLI discovers backlog-triage and dev-backlog. This verifies bundle packaging and frontmatter discovery.
Important if you use dev-relay: sprint files are not fully freeform markdown.
These details are load-bearing for automation:
- section headings such as
## Plan,## Running Context,## Progress - checkbox states
- [ ],- [~],- [x]
If you change those shapes casually, relay automation can stop reading or updating the sprint correctly. Full contract: references/integration-contract.md.
---
milestone: Sprint W13
status: active
started: 2026-03-22
due: 2026-03-28
---
# Auth + API Foundation
## Goal
Users can log in and access protected API endpoints.
## Plan
### Batch 1 - DB + seed
- [x] #38 DB schema setup (~15min)
- [x] #39 Seed data script (~10min)
### Batch 2 - Core auth
- [~] #42 OAuth2 flow (~2hr) -> PR #87 (reviewing)
### Batch 3 - Hardening
- [ ] #43 Rate limiting (~30min)
- [ ] #44 Input validation (~20min)
## Running Context
- argon2 for hashing
- test DB: docker-compose.test.yml
## Progress
- 2026-03-22 AM: Batch 1 done.
- 2026-03-22 PM: #42 in review.[ ] means not started. [~] means in flight, usually a delegated task or open PR. [x] means merged or done.
- Resolve the live task with
effective-task-spec.js; keep its selected source and revision with the work handoff. - If execution complexity meets a sprint-admission trigger, create the active sprint file; otherwise continue directly to its PR.
- For admitted work, read the sprint before you code.
- For admitted work, execute its ordered batches; otherwise implement the Issue directly.
- Update
Running ContextandProgressonly for admitted work. - Re-resolve and verify AC before completion. Close the sprint explicitly only when a sprint was admitted. A task mirror is not required.
GitHub handles task truth. An admitted sprint file handles only complex execution continuity.
Most repos run one active sprint at a time, and nothing changes for them. But two workstreams that touch disjoint code don't have to serialize: since the 2026-07 multi-track change, sprints partition by scope, and multiple disjoint-scope tracks may be status: active at once.
When to open a second track: the new work touches a different component or directory subtree than every current active track, and waiting for that sprint to close would just serialize unrelated work.
Declaring scope (explicit, never inferred — one axis per track):
component: "auth-system" # primary scope key when a capability axis exists
scope: ["src/auth/**"] # explicit path globs otherwise (sprint-init.js --scope)The invariant: no two active tracks may overlap — same component:, or colliding scope: globs (nested paths overlap). Overlap fails loud everywhere: sprint-init.js refuses to create the track, backlog-doctor fails with Active tracks overlap on scope, and JSON reads exit with OVERLAPPING_TRACKS. Once more than one track is active, any track without a declared axis can't be proven disjoint, so the doctor warns (informationally) instead.
Working a portfolio:
bash skills/dev-backlog/scripts/next.sh # portfolio: one stanza per track
bash skills/dev-backlog/scripts/next.sh --track 2026-07-auth # one track, deterministic
bash skills/dev-backlog/scripts/sprint-close.sh --track 2026-07-auth # close just that trackstatus.sh --json / next.sh --json emit schema_version: 2 with active_sprints[]; the single-track fields are retained and byte-compatible, so existing consumers keep working.
The core loop above needs none of these. Add one only when you want its capability — each row prices what it adds and what it requires.
| Extension | Adds | Requires |
|---|---|---|
| Spec axis (charter / system map / capabilities) | Objective/capability alignment for sprints and triage, plus the reassess signal | craftkit skills installed; degrades gracefully when absent |
| dev-relay | delegated-work tracking: [~] in-flight state and PR handoff in the sprint file |
the dev-relay skill |
| backlog-triage | open-issue grooming into an advisory report (classification, stale flags, Alignment, Decision Review) | nothing — ships in this bundle |
| GitHub Projects | optional planning visualization over Issues | a separately configured Project; project-only fields remain non-authoritative |
| Matt Pocock skills | optional shaping or execution techniques (to-tickets templates and ## Agent Brief comments resolve natively; brief AC use bold labels) |
separately installed skills; .scratch/<feature>/issues/ local tickets stay outside dev-backlog's contract — mutually referenceable, never required |
The spec-charter, spec-system-map, and spec-grill authoring skills moved to craftkit — that repo is their canonical home as of 2026-07.
npx skills add sungjunlee/craftkit -g -ydev-backlog and backlog-triage consume spec/charter.md, spec/system-map.md, and spec/capabilities.md as read-only yardsticks (Objective IDs, capability handles, Alignment/Decision Review evidence) and degrade gracefully when those files are absent. Sprint planning and triage keep working against the installed craftkit skills; the spec index lives at spec/README.md.
dev-backlog works fine on its own.
If you also use dev-relay, the sprint file tracks delegated implementation too.
[ ] #42 OAuth2 flow
|
+-> do it yourself ------------------> [x] #42
|
+-> dispatch with dev-relay ---------> [~] #42 -> PR #87 (reviewing)
|
+----------------------------> [x] #42 -> PR #87 (merged)
The [~] state makes in-flight work visible to everyone, and Running Context carries decisions across handoffs without re-explaining.
The contract for that integration lives in references/integration-contract.md.
dev-backlog runs the sprint. backlog-triage grooms the open-issue pile that feeds into it — classification, relationships, stale / obsolete flags, priority proposals, Alignment, and spec-aware Decision Review. It produces one markdown report under backlog/triage/YYYY-MM-DD-report.md that you review, check accepted proposals on, and apply behind an explicit --apply.
SKILL=/path/to/dev-backlog/skills/backlog-triage/scripts
SNAP=backlog/triage/.cache/<ts>.json
# Review phase (read-only, default): collect → analyze → render
node $SKILL/triage-collect.js
node $SKILL/triage-relate.js --snapshot $SNAP --json > /tmp/relate.json
node $SKILL/triage-stale.js --snapshot $SNAP --json > /tmp/stale.json
# model-authored: blocks/depends-on/duplicate edges + priority/milestone actions
node $SKILL/triage-report.js --snapshot $SNAP --relate /tmp/relate.json --stale /tmp/stale.json --model-actions /tmp/model-actions.json
# Apply phase (opt-in): review the report, check accepted proposals, then
node $SKILL/triage-apply.js backlog/triage/<date>-report.md --apply
# Live apply integration coverage (opt-in only; mutates the disposable sandbox repo)
GH_TOKEN="$(gh auth token)" TRIAGE_APPLY_INTEGRATION=1 \
node --test $SKILL/triage-apply.integration.test.jsUse dev-backlog when you know what to work on; use backlog-triage when the open-issue list has grown faster than your attention. When spec/charter.md, spec/capabilities.md, or spec/system-map.md exist, Decision Review uses them as optional evidence for Do Now, Shape First, Defer, and Drop / Close; missing spec files are skipped.
The integration test is excluded from the default node --test path unless you explicitly set TRIAGE_APPLY_INTEGRATION=1. It targets the dedicated sandbox repo sungjunlee/triage-apply-sandbox and requires a GH_TOKEN that can mutate that repo.
All deterministic helpers live under skills/dev-backlog/scripts/.
Use the commands in Quick Start for the common path, and use skills/dev-backlog/SKILL.md as the canonical script/flag reference when you need the full execution contract.
Claude Code hook example
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit|NotebookEdit",
"command": "bash /path/to/dev-backlog/skills/dev-backlog/scripts/context-hook.sh /path/to/repo/backlog"
}
]
}
}Codex workflow example
dev-backlog works well with Codex when the sprint file stays the shared execution state instead of extra chat context.
Start with the cheap deterministic commands:
bash /path/to/dev-backlog/skills/dev-backlog/scripts/status.sh
bash /path/to/dev-backlog/skills/dev-backlog/scripts/next.shThen hand Codex the active sprint as the source of truth:
Read backlog/sprints/_context.md and the active sprint file first.
Tell me the next batch, implement #42, and keep the sprint file updated.
Update Running Context and Progress before you stop.
When GitHub Issue content changes during a session, resolve it again and compare the returned source revision:
node /path/to/dev-backlog/skills/dev-backlog/scripts/effective-task-spec.js \
"#42" --repo OWNER/REPOThe old projection command is rollback/diagnostic export only and requires deliberate opt-in:
node /path/to/dev-backlog/skills/dev-backlog/scripts/sync-pull.js \
--legacy-export --dry-run- GitHub Actions CI runs on push and pull request to
main - 130+ tests cover Node logic and Bash smoke flows
--dry-runexists for risky file-writing operations- Shared Bash and Node libraries keep behavior consistent across scripts
- MIT licensed
| Decision | Why |
|---|---|
| GitHub Issues own task truth | Task specification, native planning fields, and lifecycle have one standalone authority |
| Sprint files are complexity-triggered | One file carries plan, context, and progress only when continuity extends beyond one Issue/PR |
| Task files are optional exports | Legacy mirrors are diagnostic/rollback material, never runtime fallback, authority, or a core-path dependency |
_context.md holds cross-sprint knowledge |
Sprint files stay local to the sprint, project memory stays shared |
| Sync is always explicit | No background process mutates your local state behind your back |
| Backlog.md is optional compatibility | Existing task Markdown follows the Backlog.md shape, but its runtime and conventions are not dependencies |
- Project docs index — PRDs, pilots, and design records
- Agent execution contract
- Authority and routing contract
- Process guide
- File format and config
- GitHub sync patterns
- Workflow patterns
- dev-relay integration contract
- Backlog triage (sibling skill)
Issues and pull requests are welcome.
If you want to change sprint file structure, checkbox patterns, or task file naming, read the integration contract first. Those details are load-bearing for dev-relay interop.
For non-trivial changes, open an issue first so the format and workflow stay coherent.
MIT