Sprints
A sprint is the time-box your team works in. Team-scoped, holding a mixed backlog of plans and bugs, with per-member capacity recorded against the window. A deliberately small contract that makes room for the team to run their own rhythm.
A sprint is the time-box your team works in. A team picks the window (often two weeks, sometimes one, sometimes three), agrees on a sprint goal, and pulls work into the sprint until the team's capacity is full. The window passes and the sprint completes; the work that finished moves into history, the work that did not gets reconsidered for the next sprint.
A sprint is team-scoped. Every sprint belongs to exactly one team; the team is its required parent, just as a project is the required parent of an initiative. This matters because the work model has two orthogonal hierarchies. Projects, initiatives, and plans live under the what we are building axis (organized by product area); sprints live under the who is doing the work right now axis (organized by team). A sprint reaches across the project hierarchy and pulls plans and bugs from several initiatives into one backlog. The team doing the work cuts across those boundaries, and the sprint is the surface that reflects that reality.
If you are coming from Jira, a sprint is a Sprint, but with a tighter team-scoping (Jira sprints often hop across boards in confusing ways). If you are coming from Linear, a sprint is closer to a Cycle, with a similar timeboxed shape and a similar mixed backlog of issues. A sprint is meant to be the team's working surface; it is not a planning surface for the work itself.
How a sprint sits in the work model
The team is the required parent. Plans and bugs are pulled into the sprint as a mixed backlog through a sprintId on each item, in an order the team controls. Per-member capacity records track who has how much room for the time-box.
How it looks in practice
Continuing the worked example.
Sarah Chen's Analytics team is in the middle of Sprint 24, a two-week window that started 2026-06-03 and ends 2026-06-16. The sprint goal is Ship CSV export end-to-end and get the customer who reported it onto the new flow.
| Field | Value |
|---|---|
| Name | Sprint 24 |
| Team | Analytics |
| Goal | Ship CSV export end-to-end and get the customer who reported it onto the new flow. |
| Status | Active |
| Start | 2026-06-03 |
| End | 2026-06-16 |
| Team days off | 2026-06-10 (company holiday) |
The mixed backlog holds five items, in the order the team dragged them.
| Position | Type | Title | Status | Assignee | Estimate |
|---|---|---|---|---|---|
| 1 | Plan | Reporting page filter polish | Complete | Tom Asare | 2h |
| 2 | Plan | Dashboard load-time fix | In progress | Priya Patel | 5h |
| 3 | Plan | CSV server endpoint | Complete | Priya Patel | 6h |
| 4 | Plan | CSV download button | In progress | Tom Asare | 4h |
| 5 | Bug | Export timeout on large date ranges | In progress | Priya Patel | 2h |
| 6 | Plan | CSV format verification | Draft | Sarah Chen | 3h |
Sprint capacity is recorded for the three engineers and Sarah; the totals appear on the Capacity tab.
| Member | Role | Hours/day | Days off | Window hours |
|---|---|---|---|---|
| Sarah Chen | Lead | 4 | None | 36 |
| Priya Patel | Senior eng | 8 | 2026-06-12, 2026-06-13 | 56 |
| Tom Asare | Eng | 8 | None | 72 |
| Maya Rodriguez | Eng | 6 | 2026-06-05 | 48 |
| Team total | 212 |
The committed estimate from the backlog is 22 hours of plan work plus 2 hours of bug work; the team is well under capacity and has room for one or two more items if scope changes mid-sprint.
Now look at how the sprint connects.
Upward. Sprint 24 belongs to the Analytics team. Anyone on the Analytics team can read and edit the sprint. Sarah, who is not on the Analytics team's day-to-day roster but is its lead, has access through her team-link role. A platform admin from outside the team cannot edit the sprint without joining the team; admin-read still works for support.
Downward. The backlog is a mix of plans and bugs from across the team's initiatives. The four plans and one bug above come from two different initiatives in the Insights project; the Dashboard load-time fix plan and the Reporting page filter polish plan come from older initiatives the team is still wrapping up. The sprint does not own the records; it picks them up by writing a sprintId on each. Clearing the sprintId sends them back to the unscheduled list.
Sideways. The team's working-day calendar (defined on the team) drives the window-hours math. The 2026-06-10 entry on the sprint's Team days off is a company holiday that knocks one day out of every team member's capacity (so Tom drops from 80 to 72 hours, Priya from 64 to 56, Maya from 54 to 48). The personal days off for Priya and Maya are taken as a union with the team days off, so if Priya's personal day fell on 2026-06-10 the system would not double-count the holiday against her capacity.
Rollups at a glance. The Work Items tab shows the team 6 items (5 plans, 1 bug), 2 of them complete, with the grid's total-count caption ("6 items, 2 complete") above the toolbar. The Capacity tab shows 22 hours committed against 212 hours capacity, with the under-capacity gap rendered as a small Room for 190 more hours caption. See Rollups for the full capacity formula, the four-layer cascade for hours per day, and the dual hours-and-points model. The sprint goal itself does not render on the working surface; it lives on the sprint edit dialog and on the team's Sprints tab, which is intentional (the goal is a planning decision, not a triage signal).
Statuses
Three:
- Planned is for a sprint that is being scoped but has not yet started.
- Active is for a sprint that is currently underway.
- Completed is for a sprint that has wrapped.
Status is a label, not a state machine
A plan's status runs through a real workflow with transitions the server enforces. A sprint's status is a label the team adopts; the platform accepts any of the three values at any time. This is deliberate. A sprint is the team's container, not a work item, and a team that wants to flip a planned sprint to active early (because the prior sprint wrapped on day 8 and the team is ready) should not need a special transition to do it.
The conventional path is planned → active → completed. A team that wants to roll over unfinished work into the next sprint usually keeps the old sprint in Active for a day while the new one starts in Planned, then drags the rolled-over items across before flipping the old one to Completed.
Soft-delete and restore
A sprint can be soft-deleted. The detail page's kebab carries the soft-delete action; restoring a sprint happens by re-opening it from the team's deleted-sprint view (using the show deleted toggle on the team's Sprints tab) and calling Restore. A soft-deleted sprint cannot be edited or have items moved into it; the API returns a 410 if you try, and the UI directs you to restore the sprint first before any further changes.
Hard-deleting a sprint is meant for unrecoverable cleanup; it is only allowed once the sprint has been soft-deleted first. The audit log captures who hard-deleted and when. The team's other sprints are not affected.
When you create one
The flow is short.
- Open the team's Sprints tab. From Platform → Teams → the team, open the Sprints tab. (You can also reach a sprint's home from the Planning side rail, but creation lives on the team.)
- Click New sprint. A dialog opens. Name defaults to Sprint N where N is one more than the team's active (non-deleted) sprint count; you can rename it or accept the default.
- Set the window and the goal. Start and end dates are optional but recommended; the capacity math needs them, and the team's working-day calendar fills in the hours per day per member.
- Save. The sprint lands at status Planned. From there you can pull items into the backlog and start filling capacity.
A sprint at status Planned is fully editable; the only gate the platform enforces is the team membership check (you have to be on the team to create or edit one of its sprints). Move the sprint to Active when the team is starting work; move it to Completed when the window wraps.
The distinctive parts
The mixed-entity backlog
This is the part that makes sprints different from project-scoped boards. A sprint's backlog holds a mix of plans and bugs; they share one ordered list, one grid, one board, and one capacity rollup. A team that needs to ship a feature and fix a bug in the same sprint does not have to track those separately.
The grid is the default view; switch to Board in the toolbar for a kanban view of the same items. The board has four columns: Todo, In progress, Blocked, Done. Plans and bugs map onto these columns through a status-mapping that respects each item's own status taxonomy.
Cancelled plans and Canceled bugs are filtered out of the board entirely. Cards in each column are sorted by the sprint backlog's position (the same order as the grid). The plan and bug workflows underneath are unchanged; the board is a presentation over them.
The reason this matters is the daily standup. Every other tool forces a choice between plans-only board (your bug fixes do not sit alongside your features in the standup conversation) and one fake status taxonomy (a blocked state on the bug that does not mean anything to QA). The mixed board lets both shapes coexist with their real semantics intact. The team running the standup talks about the In progress column whether the card is a plan or a bug; the bug's status moves through Triage → In progress as the engineer drags it, while the plan next to it moves Draft → In progress. Two workflows under the hood, one conversation on top.
Bulk add, remove, and reorder
The platform exposes a small set of contracts for bulk backlog operations. The shape matters because a sprint backlog tends to get reorganized in batches at the start of a sprint.
Bulk add takes a list of plan and bug references, and reports back three buckets: added (items now in the sprint), idempotently skipped (items already in this sprint), and failed with a structured reason per item. Failure reasons include not-found, soft-deleted, not-sprintable (the item type is neither plan nor bug), and already-in-other-sprint (mutual exclusion).
Bulk remove unassigns items from the sprint. If the item is in a different sprint it returns which one; if the item was already not in this sprint it returns idempotent success.
Bulk reorder takes a list of moves, each describing where to place an item relative to its new neighbors. The server snaps each item's position with the right spacing and returns the new ordered list. The endpoint is the source of truth for ordering; the grid and the board mutate through the same call.
The partial-success contract matters because batch operations on a sprint that contains 30 items should not fail because of one bad reference. The caller can show three items that succeeded, one that already exists in another sprint, and one that was soft-deleted, all in the same toast.
The sprint picker
The sprint picker is the shared control that appears on plan create, bug create, plan detail, bug detail, and the workspace-wide bulk-edit bar. It loads only the sprints in teams you belong to; sprints in other teams do not appear in the dropdown. This is the working privacy gate in the UI: the picker enumerates the sprints you can actually pick.
Writes to a sprint in another team's space are blocked at the API. If you try to assign a plan or a bug to a sprint whose team you do not belong to, the response is shaped as a 404 rather than a 403. The platform does not reveal that the sprint exists; from your perspective the assignment simply does not land. Reads are tenant-wide on a known sprint ID, but the picker is what surfaces the IDs in the first place, so this rarely comes up in practice.
Cross-team moves
The teamId on a sprint is immutable once the sprint is created. Sprints cannot move between teams. If a team reorganizes (a project moves to a different team), the move happens at the project and team level; the old team's sprints stay in the old team's history, and the new team starts fresh sprints under its own roof.
This is the right model. A sprint is a team's working agreement for a window; transferring that agreement to a different team makes the history harder to read, not easier. The audit trail for what work the Analytics team committed to in Sprint 24 should belong to Analytics, even if Analytics is later renamed or absorbed.
Running a sprint day to day
A sprint is not a planning artefact; it is a working surface the team comes back to every morning. The rhythm tends to look like this.
At the start. The sprint is in Planned status while the team scopes it. The Capacity tab is filled in (Copy from last sprint, then nudge the deltas), the goal is set, the backlog is loaded through bulk-add from the workspace-wide plans and bugs grids. The team flips the sprint to Active and the standups start.
During the sprint. Standup runs off the Board view. The team walks the four columns left to right, talking through what is In progress, what is Blocked (and why), what landed in Done overnight. Cards drag across columns as conversations close; the bug's status moves through the bug workflow as it is dragged, the plan's status through the plan workflow. The team glances at the Capacity tab maybe once a week to read the committed-vs-capacity gap; mid-sprint scope changes show up here as the committed-estimate line moves.
When something new lands. A customer escalation, a regression caught in production, a new request from a stakeholder. The triage owner pulls the item into the sprint with one of the bulk-add patterns: from the workspace Bugs grid (filter + select + assign sprint), from the chat with the agent (file this bug and put it in our sprint), or from the row action on the bug itself. The capacity rollup updates the moment the item lands, so the team can read the new committed-vs-capacity gap and decide whether to drop something to make room.
At the close. The window ends. The team flips the sprint to Completed and starts the next one in Planned. Unfinished work rolls over (covered next). The completed sprint stays in the team's history as a real record: what was committed, what was finished, what the goal was, who was on the team.
Sprint rollovers
A sprint that closes with unfinished work is the normal case. The team rolls those items into the next sprint and runs the retrospective on the delta.
The mechanical move: clear the old sprint's items off the items that did not finish, set the new sprint's ID on them. The platform supports this through the workspace-wide grid (filter to Sprint: Sprint 24, Status: Not Complete, select all matching, bulk-assign to Sprint 25). The items pop into the new backlog at the bottom; the team reorders them into the right position during planning.
The retrospective question: we committed 50 hours, finished 38, rolled 12. What was the 12? The audit log answers the first piece (when did each item land, when did each item move). The bug records with rootCause and resolution answer the second (was the rolled work blocked by a dependency, by scope creep, by a discovery we did not have at sprint start). A team that closes its bugs honestly has the analytical raw material for this retrospective every time.
The platform does not currently provide an automated rollover action. The team performs the move themselves. This is deliberate; a rollover is a conversation, not a button click, and the explicit move forces the team to look at each item before they re-commit to it.
Sprint events
Every meaningful action on a sprint emits a real-time event the rest of the platform listens to. Three lifecycle events (sprint created, sprint updated, sprint deleted, sprint restored) cover the sprint record itself. Three membership events (items added, items removed, items reordered) cover the backlog. The events propagate over the live update stream the data grid and the kanban board listen to, so an engineer dragging a card in the board updates a teammate's grid view within a second.
The events also feed the team's audit trail. Every membership change is recorded with the actor, the timestamp, and the items it affected. A leader reviewing a sprint a quarter later can read who added what, when, and what was reordered into and out of the Done column.
Capacity
Sprints carry a capacity model that records how many hours (or points) each team member has available across the window. The capacity rollup tells the team how much work the sprint can hold against how much has been committed.
Per-member capacity
Each member's capacity is recorded as a row on the sprint's capacity table. Three fields per row:
- Hours per day, with a cascade to the team's role-default and then the team's default-hours-per-day. A senior engineer's role default might be 6 hours of focused time per day even though their official day is 8; the role default fills the row, and the per-sprint override can adjust further (a member who is part-time for one sprint sets 4).
- Points per day is the same shape on the points side, populated only on teams whose primary estimate unit is points.
- Days off is a list of date ranges the member is not available during the sprint window; the math knocks those days out of the per-member total.
Each row also has an Included toggle. Turning it off removes a member from the sprint's capacity without deleting the row, so a member who is out for an entire sprint can be excluded cleanly and brought back next sprint with their settings intact.
Days off as a union
Personal days off and the sprint's Team days off (covered next) are taken as a union when computing a member's effective working days. If a personal day falls on a company holiday, the math does not double-count the absence against the member's capacity. This is small but important: a team where one member's vacation overlaps a holiday should not see that member's capacity over-deducted.
Team days off
The sprint also carries a sprint-wide Team days off list: dates the whole team is out (a company holiday, a planned off-site, the day after the conference). These knock the day out of every member's capacity without the team having to enter it on each row.
The capacity cascade
For each member's hours-per-day, the platform resolves in order: per-sprint override, then the team's role-capacity default for the member's role, then the team's default-hours-per-day, then a global fallback of six hours. The first tier that is set wins.
The role-capacity defaults live on the team record itself (a map of role → default-hours-per-day kept on the team), not on the role definitions. This means changing the default hours for senior engineers on the Analytics team edits the team record without touching the workspace-wide role definitions, which keeps the workspace's role catalog clean. Two teams can run senior engineers at different capacities without inventing a new role.
The points-per-day cascade is shallower in v1: per-sprint override or zero. A team using points sets each member's per-sprint points-capacity directly. A points role default will land once teams have settled on stable per-role velocity numbers.
Capacity vs committed estimate
The capacity rollup is one number; the committed-estimate rollup is the other. The difference between them is the team's headroom, and it is the most useful number to track sprint over sprint.
A team chronically committing 60% of capacity is leaving signal on the table. Either they are over-estimating individual items (the per-item estimates are too pessimistic), or they are holding back deliberately for the unknown (a sustainable buffer). Both are defensible; the team should know which they are doing and adjust on purpose, not by accident.
A team chronically committing 110% of capacity is in burnout territory. The next retrospective should be about scope, not velocity; the team is committing to more work than the math says it can ship, and the unfinished items roll over with frustration attached. The fix is at planning time: pull less in, and look at why the team's individual estimates are landing low.
The Capacity tab surfaces both numbers and a third honesty signal: how many items in the sprint have no estimate at all. The committed number is computed over items that have an estimate; the no-estimate counter says how much of the sprint is missing data. A sprint that commits 22 hours with 4 items unestimated is not a 22-hour sprint; it is at least a 22-hour sprint, and the team should fix the missing data before reading the rollup as fact.
Adjusting capacity mid-sprint
Capacity rows are editable through the sprint window, not just at create time. An engineer who takes three unexpected days off in week two has their days-off entry added on the Capacity tab; the rollup recomputes immediately and the new committed-vs-capacity gap shows up in the live numbers.
A member newly excluded from the sprint mid-flight (a member who pivoted to a different project, or a contractor whose engagement ended) is removed by flipping the Included toggle to off. The platform does not delete the row, so the historical record of that member's contributions to this sprint stays clean. Bringing them back next sprint is a single click; the previous settings (hours-per-day overrides, days off recorded so far) come back too.
When a team member fully leaves the team mid-sprint, their capacity row becomes an orphan: the row is still there, but the member is no longer on the team's roster. The platform silently filters orphan rows out of the rollup at read time, so they do not affect the math. This is the right behavior; the historical row should not vanish, but it should not affect today's numbers either.
Velocity over time
A team's velocity is the most important number a sprint produces, and it is one you can only read after several sprints. The platform records every completed sprint's committed-vs-finished delta in the team's history; reading the delta over the last three to five sprints gives a team a real velocity estimate, expressed in the same unit the team plans in (hours or points).
This is the number to take to next-quarter planning, not the gut-feel one. A team that thinks it ships 80 hours of work a sprint but actually shipped 62 / 58 / 71 / 64 / 60 over the last five sprints should plan to 63, not 80; an honest velocity number prevents a quarter of over-commitment and rolled work. The team's Sprints tab is where this history lives; a future enhancement will surface the velocity series as a sparkline column on the sprints index for one-glance reading.
Copy from last sprint
A common pattern: the team's capacity for this sprint is usually similar to last sprint's, with minor adjustments. From the capacity table's overflow menu the Copy from last sprint action pulls the prior sprint's member list, days off, and overrides into this sprint as a starting point. The team adjusts the deltas and saves.
The same overflow menu has Add all team members, which seeds the table with one row per current team member at the cascade defaults. Useful for a brand-new team's first sprint, or to add a new joiner to a sprint mid-flight without having to add them individually.
The detail page
The sprint detail page has two top-level tabs.
- Work items is the default. The grid (or board, via the toggle in the toolbar) shows the mixed backlog with the standard filter and bulk-edit affordances. The toolbar also has the New plan and New bug actions, which create a record and add it to the sprint in one step.
- Capacity is the per-member capacity editor described above.
The page header carries the sprint name, the status chip, the window dates, and a context row that shows the team. The kebab in the corner has the soft-delete action.
The grid columns and the board card fields are both customizable. Both surfaces read their configuration from the workspace's sprint-backlog workflow, the same way the data grid reads grid columns for every other entity. An admin edits the sprint-backlog workflow once and every sprint backlog in the workspace updates with the change.
The lists
There are two list surfaces for sprints, each meant for a different audience.
The team's Sprints tab at Platform → Teams → the team is where the team works. It shows every sprint for the team in one flat list, ordered by the team's own sprint order, with the status chip on each row and the team's context around it. This is where Sarah's Analytics team goes to find their current sprint and to scroll back through the team's history.
The Planning side rail Sprints index at /planning/sprints is a tenant-wide read-only list. It shows every sprint in the workspace, grouped by status (active → planned → completed), so a leader can scan all the sprints in flight across every team without opening each team's page. The index reads on the workspace's sprints.read scope, so it does not filter by team membership; a leader who can read sprints can see every team's sprint without having a seat on those teams. Writes still require team membership.