Developer Guide

Plan work

Turn a piece of work into a DevStride plan the delivery loop can build one item at a time: how work is organized here, dependency links, delivery profiles, and the planning commands.

Plan work

On this page you will turn a piece of work into a plan in DevStride that the delivery loop (the /devstride:* commands that build, review and merge one item at a time) can walk by itself. You will see how this organization arranges its work, hold the planning conversation, date the plan, and add to it as you learn more.

Before you start

  • Your machine is set up. Set up your machine installs the devstride plugin for Claude Code, whose commands all start with /devstride:.
  • Claude Code can reach DevStride. Setup points Claude Code's DevStride connection at the team's shared key; Credentials and access explains it. If a planning command cannot read DevStride, run /devstride:doctor, which checks the plugin, the DevStride connection and the repository's settings, and offers the repairs that are safe to make.
  • You have a parent item to plan under. Create it in DevStride first if it does not exist.
  • Plan in one Claude Code session and build in another. The plugin sorts its commands into two kinds. Planning: plan, comprehend-plan, rationalize-gantt and rebalance (and setup, doctor, ci-audit). Doing: build-item, insert-story, insert-defect, create-story, create-defect, pr, review, push and release. A session that has run one kind refuses the other and says why: every turn re-sends the whole conversation, so mixing the two makes everything after the switch cost more. Run /clear, then the same command again. To stay in the same session on purpose, add --same-session to the command.

How work is organized here

Engineering work in this organization uses four levels of DevStride item. The plugin thinks in three roles, and .claude/ds-config.json maps this organization's names onto them under hierarchyRoles: the release unit is Epic, and the leaves are Story and Defect.

Item typeSits underRole in the delivery loop
Solutionnothing (top level)Grouping item: holds Capabilities
Capabilitya SolutionGrouping item: holds Epics
Epica CapabilityRelease unit. Its Stories collect on the Epic's own branch, where they may be unfinished, and the finished Epic reaches develop in one fully reviewed pull request. So each Epic must be a slice of value a user can see or use on its own, and safe to put in production the moment it merges.
Storyan EpicLeaf. One piece of buildable work; this is what the loop builds.
Defectan EpicLeaf. A bug fix, built exactly like a Story.

The organization has other item types for other teams (support requests, sales, compliance); engineering plans use only this chain. Two placement rules apply here as well:

  • A Story always has an Epic as its parent, never a workstream (a DevStride folder of items) directly, even for a one-off. DevStride allows the workstream route, which is the only way this rule gets broken in practice.
  • Epics go on PI boards, Stories and Defects go on Sprint boards. A PI (program increment) is a planning period that spans several sprints. The repository's ds-board-hygiene skill audits both rules.

Configuration Reference: DevStride hierarchy roles has the setting itself.

A blocked by link says "this item cannot start until that one is Done". Blocks is the same link read from the other end. (The tools call them blocked_by and blocks.)

The loop never chooses what to build by judgement. It takes the highest-priority Story or Defect that is not Done and whose blockers are all Done, inside the earliest-dated open parent item; priority breaks ties, then start date. So a plan's links are its build order.

A good plan has the true shape of the work, not one long line:

  • Foundation work blocks everything that needs it, so it comes first.
  • Work that brings several pieces together is blocked by all of them, so it comes last.
  • Genuinely independent work stays parallel, with no link between the branches.

Every Story and Defect in a plan has at least one link. One with no link and no [N] number (below) looks like a one-off (work outside any plan) to the loop, which then sends it to the support train (the shared branch for one-offs) instead of its Epic's branch.

Parallel branches in a plan describe its shape. The loop still builds one item at a time, on purpose: its DevStride writes are live, and it walks the dependency chain in order.

Pick a delivery profile

One word sets how much rigor the loop spends on each item: how finely the plan is sliced, how deep each spec goes, how broadly each change is reviewed, which review findings are fixed straight away, and which local checks an item must pass before it merges. The four profiles are prototype, standard, extended and enterprise.

  • This repository runs standard, set by profile in .claude/ds-config.json, with a few settings pinned on purpose. For example, a finished Epic always waits for the owner (the person who decides what reaches production) instead of releasing itself.
  • A plan can carry its own profile. Add the word to the command, /devstride:plan I##### prototype, and the plan root (the parent item you plan under) gets a line Delivery profile: prototype at the top of its description. That line wins over the repository setting for everything under that root.
  • The order is: a profile word in the command, then the plan root's line, then the repository setting, then standard. Every command says which profile it is using and where it came from.
  • To change a live plan's profile, run /devstride:rebalance I##### <profile>. It re-slices the items that have not started and rewrites the line in one go. Editing the line by hand would leave items sliced for the old profile; see Rebalancing a plan.

The four profiles side by side are in Choose a delivery profile, and every setting is in the Configuration Reference.

Write the plan: /devstride:plan

/devstride:plan is a conversation, not a document generator. It asks, you decide, and it builds nothing until you have agreed the shape.

  1. Start a fresh Claude Code session in the repository and run, with the parent item's number:
    /devstride:plan I#####
    

    The parent can be any level above the Stories: a Solution, a Capability or an Epic. You can add a short description of what you are planning, and a profile word.
  2. It reads before it asks. It reads everything already under the parent and tells you which case applies: an empty parent (a new plan), an existing plan to extend (existing items are fixed inputs, never rewritten without your say-so), or a thin placeholder plan (it asks whether to flesh it out or replace it).
  3. It asks, in small numbered batches. If you have a design or requirements document, give it first: it reads that before asking anything else. Then it covers scope (what is in, what waits for a later version), the Capabilities and Epics, the Story titles, sequencing (what is truly parallel and what is a hard gate), and risky areas such as the data model or permissions. For each Epic it asks:
    • what a user could do if only this Epic shipped and nothing else (if the answer is "nothing yet", the boundary is wrong);
    • who is exposed on the first day, and what gates it, if anything;
    • whether it adds anything that costs money or is visible outside the company (an owner decision now, not a surprise in a bill);
    • whether any Story would point at something a later Story creates (that breaks the deploy for everyone).

    If you say "you decide", it pushes back once. If you insist, it carries on and labels every assumption it made.
  4. You sign off on the shape. It shows the whole tree with titles only and waits for an explicit "yes, build this". At that moment it makes its first live change: the Delivery profile: line on the parent, unless the parent or an item above it already carries one. It also checks Enable Link Mode (below) now, so you can turn it off while it drafts.
  5. It drafts the specs and shows you a review. Epics get a business description, an architecture overview, a release-safety section answering the questions above, and their delivery order. Stories get a spec detailed enough for an agent to build from, at the depth the profile sets. Nothing else is written until you have seen this review; small corrections are made in place, and an open question goes back to the conversation.
  6. It creates the items, top-down, then wires the dependency links. Every new Story must end up with at least one link.
  7. It dates the plan with /devstride:rationalize-gantt (below), then stamps execution-order numbers into the Story titles.
  8. It reports and hands over: the item counts, the critical path (the longest chain of items that wait on each other), the parallel waves (groups of items that could be built side by side) and the [1]…[N] range. It saves the plan root in Claude Code's project memory on this machine, so a bare /devstride:build-item later picks up this plan.

You can run /devstride:plan on the same parent again later; it treats the second run as an extension and only adds.

What you should see

In DevStride, under your parent item:

  • the parent's description starts with Delivery profile: standard, or the profile you chose (unless an item above it already carried a profile line);
  • Capabilities and Epics with their specs, and every Story titled [N] …;
  • blocked-by and blocks links on every Story;
  • on the roadmap (DevStride's Gantt view), a staircase of one-day items ending today;
  • a container for deferred work directly under the parent (see Deferred work).

Execution-order numbers and item numbers

[N] is the build order, stamped into each Story's or Defect's title, such as [7] Export button on the board toolbar. [1] to [N] are stamped when the plan is written, in the order the loop will build them. Items added later get a dotted number that sorts between their neighbours, such as [7.1]. Nothing renumbers a plan by itself, even when its dates move, so a [N] that disagrees with date order is expected. Only an explicit request from the owner renumbers one.

When you refer to an item, use its item number, never its [N]. The item number is I followed by digits, assigned by DevStride. It never changes, and it is what DevStride's GitHub integration recognises and links. A [N] can be renumbered, and then a sentence that cites it points at a different item. This applies everywhere: descriptions, comments, commits, pull requests and code comments.

Never make up an item number, even as a placeholder. Look the item up and check its title before you write its number anywhere. If the work has no item yet, create the item first and use the number DevStride gives it. A plausible-looking number is the address of someone else's live item.

Date the plan: /devstride:rationalize-gantt

First, turn off the organization-wide auto-scheduler. DevStride has one setting, Enable Link Mode in Settings → Organization, that applies to the whole organization, not to one roadmap or view. While it is on, DevStride moves the dates of items that have blocked-by links by itself and overwrites the dates the planning commands write; it has been seen pushing dependent items far into the future. Every command that writes dates or links reads this setting first and asks you to turn it off if it is on. None of them ever changes it for you.

Then run, with the plan root's number:

/devstride:rationalize-gantt I#####
  1. It confirms the scope before writing: the plan root; whether to re-date completed items too (on a plan that has already shipped items, choose not-done items only, so real completion dates survive); and the rule that every Story counts as one day.
  2. It checks for a cycle, such as A waiting for B while B waits for A. A cycle stops it before it writes a single date. It names the items in the cycle and suggests which link to drop or repoint; fix that link and run it again.
  3. It dates the plan as a cascade. The last items land on today, and every item sits one day before whatever waits for it; parent items span their children. These dates are synthetic: they show how long the chain of dependencies is, not when the work will finish.
  4. It reviews every invalid link, a red line on the Gantt where an item starts before something it waits for has finished. For each it decides, with a reason: remove a redundant link, repoint it at the specific Story that is really needed, or, rarely, keep it and move the waiting item later.
  5. It reports what it changed. Refresh the Gantt to see the result.

It never changes titles, so [N] numbers stay as they are. Run it after any structural change to a plan; /devstride:plan runs it for you. More detail: The Planning Loop.

Add work you discover: /devstride:insert-story and /devstride:insert-defect

When the build or a review turns up new work that belongs in the plan, splice it into the plan rather than leaving it as a sentence in a pull request, which nobody reads once it closes.

/devstride:insert-story I##### <what the story is>
/devstride:insert-defect I##### <the bug: how to reproduce it, expected and actual>

I##### is the parent the new item belongs under; without one, the command asks. Each command:

  1. works out what the loop would build next;
  2. puts the new item under a parent whose theme genuinely fits, reusing one or creating one;
  3. writes an honest spec (for a Defect, the steps to reproduce it and the expected and actual behaviour; it asks if you did not give them);
  4. splices it into the dependency chain just before the item the loop would have built next, and gives it a dotted number between its neighbours;
  5. checks again what the loop would pick next, and tells you if something else still wins. An earlier-dated open parent beats priority, so you may need to accept a later slot or move that parent's dates.

A Defect often deserves to jump ahead of planned Stories. The command asks you before it moves a Defect earlier than a normal insert.

Neither command writes code. Build the new item with /devstride:build-item <its number>, or let the loop reach it. These two count as "doing" commands for the session rule above, so run them in your build session.

Work outside any plan: /devstride:create-story and /devstride:create-defect

For work that belongs to no plan, such as a customer request or a small fix found along the way, create a one-off:

/devstride:create-story <what is needed>
/devstride:create-defect <the bug: how to reproduce it, expected and actual>
  1. It asks where the item goes, before anything else: the parent (for a Story or Defect here, an Epic), the board it should appear on (a Sprint board, by the rule above), and who it is assigned to (you, unless you name someone).
  2. It creates the item with an honest spec, and with no [N] number and no dependency links. That missing splice is what makes it a one-off.
  3. It builds the item once with /devstride:build-item, then stops instead of moving on to another item.

In this repository a one-off lands on the support train, a long-lived branch that every release carries into develop, and it is Done only when the next release does that. The exception is a one-off that changes deploy configuration or database migrations: that ships to develop by its own pull request. Develop and Release cover both routes.

Use insert-story or insert-defect instead when the work belongs in a plan's chain.

Deferred work, and edge cases you do not chase

Two rules keep a plan finishable.

Deferred work never sits under an active Epic. An Epic is released only when it has no open Stories left, so a "later" item parked under it means the Epic either never releases or gets released half-finished, and with develop reaching production within hours there is no time to tidy up in between. Deferred follow-ups, tech debt and postponed fixes go in the plan's deferred-work container instead:

  • It sits directly under the plan root, outside the dependency chain. Its work type is whatever this organization's hierarchy requires there; under a Capability, that is an Epic. The plugin's default title for it is "Deferred defects".
  • Its items have no [N] number. The loop never selects them, and they never count towards an Epic's remaining work. A person can still schedule one later, or build one by naming it.
  • /devstride:create-defect deferred I##### <the finding> files a review finding there, linked back to the item it was found against (I#####), and never builds it.

Do not chase edge cases until they actually happen (the owner's rule). A review finding that needs an unlikely coincidence to occur, such as two people changing the same record within the same second, an input no caller produces, or a race that closes the moment either side saves, is dismissed with a one-line reason in the pull request or commit. It is not fixed "to be safe", and it is not filed as deferred work. File an item only when the problem has actually happened, or is both likely and important. Code written for imagined problems clutters the codebase and slows tests, development and deploys.

New scope that the plan genuinely needs is not deferred work at all. It goes into the chain with insert-story.

Understand a plan before you change it: /devstride:comprehend-plan

Before you change a plan you did not write, or when someone asks "where does this stand?", read it first:

/devstride:comprehend-plan I##### <an optional question>

It only reads. It goes through every item under the root, including descriptions and full comment threads (where decisions and notes on what actually shipped accumulate), and every dependency link. Then it reports:

  • what the plan is really for;
  • where it stands: how many items are Done, in progress and open, the critical path, and the item the loop would build next;
  • what has been deferred, or is waiting on a person;
  • every place where a later comment contradicts a description, which it reports rather than quietly picking one.

Put a question after the item number to get a direct answer to it. It is a planning command for the session rule, so /clear before you go on to insert or build.

A worked example

This example is invented to show the flow. The names, the questions and the answers are made up, and I##### stands for whatever number DevStride shows.

  1. Plan. You are asked to let people export a board to a spreadsheet. A Capability called Board exports exists in DevStride. In a fresh session you run /devstride:plan I##### standard with its number. The skill finds nothing under it yet, says it is planning under standard because you asked, and asks its first batch: is there a design document; what must the first version do; must a weekly email export ship together with the download?
  2. Answer. There is no document. The first version is a CSV download that shows only what the person may see. The weekly email can ship separately. It proposes two Epics and asks about the first: the download button appears for every organization the moment that Epic reaches production, and nothing gates it; is that acceptable? The email export uses the existing email service, so nothing new is billed. You confirm both.
  3. Sign off. It shows the shape, titles only, and you say "yes, build this":
    Capability  Board exports                    Delivery profile: standard
    ├─ Epic     Download a board as CSV
    │  ├─ Story [1] Export endpoint returns the board's visible items as CSV
    │  └─ Story [2] Export button and download on the board toolbar    (blocked by [1])
    ├─ Epic     Weekly export by email
    │  ├─ Story [3] Weekly export schedule in board settings           (blocked by [1])
    │  └─ Story [4] Send the scheduled export by email                 (blocked by [3])
    └─ Epic     Deferred defects                                       (never selected)
    
  4. Draft and create. It drafts the specs and shows a short review; you correct one detail. Then it creates the items, wires the links, dates the plan so that [2] and [4] land on today, and stamps the numbers.
  5. Build, and insert what you learn. You run /clear, then /devstride:build-item (see Develop). After [1] has been built and merged, someone points out that exports must leave out archived items, which nobody planned. In the build session, /devstride:insert-story I##### leave archived items out of board exports, with the first Epic's number, splices a new Story in just before [2], numbered [1.1].
  6. Triage review findings. The risk check on [2] (the short review every Story gets before it merges) raises two things. One happens only if two people press Export within the same second; it is dismissed with a one-line reason. The other, that accented letters look garbled when the file is opened in Excel, is likely and matters, but the owner wants to ship without it. It is filed under Deferred defects with /devstride:create-defect deferred, linked back to [2], so the Epic can still finish.
  7. Handle a one-off. A customer reports a typo in the export button's tooltip. That is not part of the plan, so /devstride:create-defect makes a one-off, which rides the support train to the next release.

When [1.1] and [2] have merged onto the Epic's branch, the first Epic is release-ready (every Story finished, waiting to be released into develop), and Release takes it from there.

When something goes wrong

  • A command refuses because the session already ran the other kind of command. Run /clear and the same command again, or add --same-session to stay where you are.
  • A command cannot read DevStride. Run /devstride:doctor; it names what is missing and the command that fixes it.
  • A command stops because Enable Link Mode is on. Turn it off in Settings → Organization, then run the command again.
  • /devstride:rationalize-gantt stopped on a cycle. It wrote no dates. Fix or remove the link it names, then run it again from the top.
  • After an insert, the loop picks something else. An earlier-dated open parent wins over priority. The insert command tells you when this happens; accept the later slot, or move that parent's dates.

Anything else: Troubleshooting.

Next: Develop, where you build the first item of your plan.