Stories and sprints
Status: ShippedA story’s status, sprint, points and assignee are plain fields in its frontmatter. CodeSense reads them; you, your teammates and your agents write them. Sprints are a small registry file plus a sprint: field on each story. There’s no built-in board: when you want one, you build it as a pane that queries your stories.
Status is a field
status: holds one of your team’s status ids. With no custom list, the defaults are Planning, Todo, In progress, Blocked, Review, QA and Done. Statuses and phases covers how to change them.
story_id: LL-233status: todosprint: sprint-14points: 3assigned_to: samEdit the field in the file, ask an agent to, or use the app. Each of these writes the same line.
In the left nav
The left nav shows your epics as folders and your stories inside them:
- Status icon. Each story row shows its status. Click the icon (Change status) to pick another one. CodeSense rewrites
status:in the file. - Progress. Each epic row counts its stories that are done out of the total, including sub-epics.
- Ready. A not-started story whose dependencies are all done is marked ready. Hover it to see “Ready — all dependencies met”, or the stories it’s still blocked by. See Dependencies and readiness.
The sprint registry
Sprints live in your team’s config/sprints.yaml. It syncs through git with the rest of the team’s config. Here are two sprints from the Ledgerline sample:
sprints: sprint-14: state: active goal: "Refunds you can retry, cart tax breakdown" focus_epics: [checkout-v2, invoicing-exports, platform-hygiene] start: "2026-09-14" end: "2026-09-25" sprint-15: state: planning goal: "Wallets, NetSuite export" start: "2026-09-28" end: "2026-10-09"state is planning, active or closed, and it’s the only required field. A closed sprint can record delivered_points and carried_points. A story belongs to a sprint when its frontmatter says sprint: sprint-14. Nothing moves on disk.
To plan, start, or close a sprint, edit this file by hand or ask an agent to. Plan a sprint walks through the whole cycle.
Add stories to a sprint
Right-click a story in the left nav. The menu lists your sprints, the active one first:
- Add to a sprint when the story has none, or Move to another sprint when it has one.
- Remove from sprint clears the field.
Right-click an epic folder and choose Add to sprint… to tag its stories into the active sprint. You can add only the stories with no sprint (Add N unsprinted) or move them all (Re-point all).
Each change writes sprint: into the story file.
Points
points is a story field. Use 1, 2, 3, 5, 8 or 13. The agent tool validate_story flags other values as OFF_FIBONACCI_POINTS.
Build a board pane
A board is a view over these fields, so you build the one you want. A custom right pane is an HTML file in your team’s panes/ folder (or Private/panes/, just for you), and it can query your stories by their metadata through codesense.queryContext (or codesense.subscribeContext, to stay live). Group by status for one column per status, and filter by epic, sprint or assigned_to:
codesense.subscribeContext( { where: { kinds: ["story", "bug", "spike"] }, filters: [{ key: "sprint", op: "eq", value: "sprint-14" }], groupBy: "status", }, (result) => drawColumns(result.groups, result.rows),);To show only the pane’s own team, ask where the pane lives first. codesense.context() resolves {org, team, layer, contentRoot} (team is null in your private space):
const { org, team } = await codesense.context();codesense.subscribeContext( { where: { orgs: [org], teams: [team], layers: ["team"], kinds: ["story"] }, groupBy: "status" }, (result) => drawColumns(result.groups, result.rows),);A card can open its story and change it in place:
codesense.openFile({ path: row.path, newTab })opens the file in the viewer. The path must be inside one of your synced teams’ content; a story in another team switches to that team.openFile({ team, path })takes a path relative to that team’s content.codesense.setField({ path: row.path, field: "points", value: 5 })writes one frontmatter key (points,assigned_to,sprint,rank, or any other). Numbers stay numbers, a list writes a list, andvalue: nullremoves the key. Only that key’s line changes, and every live query re-runs.codesense.act("setStatus", { path: row.path, status })moves a card.
Each row’s relationships.parentEpic is the epic its frontmatter names, and relationships.folderEpic is the epic folder it sits in, as the left nav shows it (add "relationships" to select).
Build yours from the example board in the CodeSense docs: copy examples/dashboards/story-board.html into your panes/ folder and set its epic. Or ask an agent to write one: it can create and open a pane with the MCP tools pane_write and pane_open. Query your context explains the query, and Dashboards and pages covers panes and pages.
For a read-only board inside any Markdown doc, a csquery block is enough:
```csquerytag: sprint=sprint-14view: board```See the csquery reference.
How we know this is accurate 13 sources
Checked against the app at 1b3d5a69d73473db077dfb44f4390b42cded6bd4.
Feature inventory
-
C-17 -
C-19 -
C-20 -
C-21 -
C-22
Code
-
src/features/dashboard/components/status-nav/nav-context-menu.tsx -
src/features/dashboard/components/status-nav/rows.tsx -
src/features/dashboard/lib/nav-ordering.ts -
src/shared/lib/pipeline-graph/sprint-tag-actions.ts -
src/shared/lib/pipeline-graph/sprint-targets.ts -
codesense-docs/getting-started/content/examples/dashboards/story-board.html -
src-tauri/src/commands/sprint_registry.rs -
src-tauri/src/commands/status_taxonomy.rs