--- name: how-to-run-a-sprint description: Use before starting implementation work that spans more than one commit or one session - a feature, refactor, migration, or bug-fix campaign - and when resuming or closing that work later. Sprinty tracks it in a git-anchored ledger that survives context loss, compaction, and MCP restarts, so state is recovered with info() and sprint_resume() instead of reconstructed from memory. Triggers on "sprint", "track this work", "plan this feature", "pick up where we left off", or any multi-step build the user will want to watch. --- # How To Run A Sprint A Sprinty sprint is item-driven. Do not keep parallel prose trackers when tools are available. ## Why Use This Instead Of A Scratch Todo List An in-session todo list is cheaper, and for a two-step fix it is the right tool. Reach for Sprinty when any of these are true, because a todo list cannot do them: - **The work outlives your context.** The ledger is on disk. After compaction, a restart, or a handoff to another session, `info({ git_dir })` then `sprint_resume({ git_dir })` restores exactly what was done, what is open, and what is blocked. A todo list is gone. - **You need to not fool yourself about "done".** `item_done` refuses without a commit that actually resolves in the repo, and Sprinty runs the item's gates itself rather than taking your word for it. You cannot check the box on work that is not really finished. - **A human wants to watch without interrupting you.** `sprint_new` returns a live dashboard URL. - **The record has to be auditable.** The ledger is append-only, and `search({ pattern })` queries it. Cost is real: items need a title, description, code locations, and gates, and closing needs a changelog and coverage. Pay it for multi-commit or multi-session work. Skip it for a one-line fix. ## Loop 1. Orient before binding. Call `info({ git_dir })` for the default `/.sprinty` ledger directory, `info({ data_dir })` for an explicit ledger directory, or `info({ workspace_dirs: [...] })` for a compact workspace view. Resume with `sprint_resume({ git_dir, data_dir? })`. Start fresh only with `sprint_new({ goal, git_dir, data_dir?, context_notes })`. 2. Share the dashboard URL returned by `sprint_new({})` or `sprint_resume({})`. Use `dashboard_info({})` to re-read it, `dashboard_restart({})` to refresh it, `overview({})` for compact orientation, and `next({})` for the active work window. 3. Create feature-sized subsprints with `subsprint_new({ description, goals, gates, dependencies })`. 4. Create atomic work with `item_add({ subsprint, title, description, code_locations, gates, gate_timeout_ms, dependencies, high_priority })`. `gate_timeout_ms` defaults to 5000; use a positive integer to customize it or `null` to disable it. If the work is too large, make more items; do not hide scope in notes. 5. Work against one owning item. Every `item_update` requires its item `id` and accepts only allowlisted fields. Use `item_update({ id, gates, gate_timeout_ms })` for open-item execution settings, or `item_update({ id, commit_id })` to correct a completed item's verified commit before sprint close. Structural fields stay immutable. 6. Resolve each item exactly once: `item_done({ id, commit_id, changelog })`, `item_split({ id, description, goals, gates, dependencies })`, or `item_deprecate({ id, reason })`. `item_deprecate` also accepts a subsprint id to drop a whole subsprint and its open items. 7. Use `search({ pattern, context_size:512 })`, `*_list`, and focused `*_get` tools when you need detail. 8. Optionally preview or export the current changelog with `changelog({ path? })`. 9. Close with `sprint_close({ coverage:{ path, format:"lcov", command } })`; Sprinty rechecks gates and writes the canonical changelog automatically. ## Rules - Never invent ids; read minted ids from tool results. - Use explicit `git_dir`; `data_dir` defaults to `/.sprinty` when omitted. Never rely on MCP cwd. - Keep responses compact. Prefer `next`, `overview`, `search`, and list/get pairs over full views. `next({})` returns all available high-priority items, then one normal available item per subsprint by default. - Notes must be bound to an item id. Work needs an item. - Gates prove items. Sprinty runs each executable gate itself at `item_done` and records the real output, so do not pass `gate_results` for them; only `manual` gates take your evidence. A gate that cannot fail (`true`, `echo ok`) is rejected when you declare it. - Item gates run under a 5s default budget. Set `gate_timeout_ms` to a positive integer to customize it or `null` to disable the timeout. A gate that overruns is killed and marked unverified: the item still completes, but nothing was proven. - Every response carries `next_tools`, concrete calls derived from real state. Prefer them over guessing ids. - `item_done` records each item's SemVer changelog verb and line; `changelog({ path? })` previews or exports Markdown from those entries. - `sprint_close` is the final gate: it rejects open items, missing commits/item changelog entries/coverage, or failing executable gates, then writes the canonical changelog automatically. - Every subsprint must end resolved. A subsprint you created but never filled with items still counts as open work; give it items or drop it with `item_deprecate({ id: "S0n", reason })`.