Five statuses are enough for a public roadmap
In Review, Planned, In Progress, Shipped, Closed. What each one promises the person who asked, and why the fifth had to be a bucket rather than a verdict.

fedo ships exactly five statuses for a feedback item: In Review, Planned, In Progress, Shipped, and Closed. That is the whole state machine, and it is deliberately smaller than what most teams would design for themselves.
The reason is that a public roadmap status is not a project management field. It is a promise made to a specific person who asked for a specific thing, and promises get less useful the more of them you make.
Four of those five are the happy path: seen, agreed, started, out. The fifth exists because most feedback never finishes that path, and pretending otherwise is what makes public roadmaps quietly dishonest.
Key takeaways#
- Each status answers one question: is anyone going to do this, and has it started?
- Four states cover the path a request takes when it works out. The fifth covers every way a request leaves that path.
- Closed is a bucket, not a verdict - duplicates, merges, out-of-scope requests, stale items, and things solved another way all land there.
- A status is a commitment to the requester, not a column in your sprint board - do not mirror your internal workflow.
- A status cannot carry a reason. Closing without a comment is the one way to make Closed read as rejection.
- Statuses gate what the requester can still edit, so moving an item is not purely cosmetic.
What each one actually promises#
In Review - we have seen it and have not decided. This is the default and the largest bucket. It says a human will look, and nothing more.
Planned - we agreed to build it, and it has not started. This is the only status that is a real commitment, and it should be the hardest to grant.
In Progress - someone is working on it now. It converts an abstract agreement into a thing with momentum, which is why it is worth being separate from Planned.
Shipped - it exists in a release. The item stops being a request and becomes a receipt.
Closed - this item is not going anywhere, and the thread says why. Like Shipped it is terminal, and unlike Shipped it says nothing about whether the idea was any good.
Read as a sequence, the first four answer escalating questions: did you see it, do you agree, has it started, is it out. Closed answers a different one, the one every board eventually has to answer for most of its items: is this still live at all. Every one of them is a question a user actually asks. That is the test for whether a status earns its place.
Why the fifth one is Closed and not Declined#
For a long time the only fifth status I could picture was Declined, and that is why there was no fifth status for a long time.
Declined describes one thing. The bucket holds at least six:
- Duplicate - the same request already exists, usually with more votes.
- Merged - three overlapping requests become one item that covers all of them.
- Out of scope - a real, reasonable request for a different product than the one being built.
- Stale - the app moved and the request no longer describes anything that exists.
- Solved another way - a different feature covered it, or a bug fix removed the need, and nobody is going to build the thing as literally described.
- Declined - we are not doing this.
Only the last of those is a rejection. Name the status Declined and the other five get stamped with a word that does not describe them, and the person who filed a perfectly good duplicate gets told, publicly, that their idea was turned down. That is a board people stop posting to.
Closed describes where the item is. Declined describes what you thought of it. Only one of those is any of the roadmap's business.
The naming test: a public status should describe the item's state, never your opinion of the idea. If a status name would sting to receive, it is carrying a judgement that belongs in a sentence, not a field.
This is also why Closed does not need sub-statuses. Duplicate, Merged, Out of Scope and Wontfix are all attractive as columns and all wrong for the same reason the internal states below are wrong: they split one public fact into several private ones. The distinction is real, but it lives in the closing comment.
Why does the reason live in the thread?#
A status cannot carry a reason. A reply can.
That was true when there were four statuses and it is the entire load-bearing rule now that there are five. "We are not doing this, and here is why" is a sentence, not a state. So is "this is the same request as the one twelve people already voted on, here is the link."
Every close gets one line. Duplicates and merges get a link to the item that survived. Out-of-scope gets the boundary stated plainly, because a clear no about scope is more useful to a requester than an indefinite maybe. Stale gets the change that made it stale.
A close with a reason is a decision. A close without one is a delete key with better manners, and users can tell the difference immediately.
Why not more than five#
The temptation is to add the states your team already uses. In Design. In QA. Blocked. Needs Spec. Up Next.
Each of those is real internally and useless externally, for two different reasons.
The first is that they leak your process to people who did not ask for it. A user who requested dark mode does not benefit from learning it is in code review. From outside, In Design and In QA both mean "in progress," and splitting them creates the appearance of information without adding any.
The second is worse: internal states change for internal reasons. An item bouncing from In QA back to In Progress and forward again generates status churn that, to the requester, looks like the project is in trouble. You have made a public signal out of a private detail, and now it moves without meaning anything.
The test: if a status changes for a reason the requester does not care about, it should not be a public status. Track it internally and map it onto one of the five.
Blocked deserves its own mention because it is the most tempting addition and the most harmful. It looks like transparency. What it actually communicates is "this is stuck and we are not telling you why," which is worse for the requester than any of the five. If work has genuinely stopped for good, that is Closed with a reason. If it has only stopped for now, that is In Review, which is exactly what "we are not currently committed to this" means. Neither case needs a new column.
What Closed fixes, and what it does not#
The four-status version of this board had one real weakness, and it was worth naming rather than hiding: In Review was where things went when the honest answer was "probably never."
Nobody wants to reject a feature request. So items accumulated there - the ones genuinely awaiting a decision, and the ones quietly declined but never marked as such — and over time the largest bucket on the board became the least informative one. In Review meant both "undecided" and "dead," which means it meant nothing.
Closed does not make saying no any more comfortable. What it does is stop In Review from lying. In Review now carries exactly one meaning: undecided, and a human will look.
Two ways this can still go wrong, both worth watching:
Closed becomes the new graveyard. Closing is cheaper than deciding, and a queue can be cleared much faster than it can be triaged. The guard is the closing comment - if you cannot write the one line, you have not actually made a decision yet, and the item belongs in In Review.
Nothing gets closed at all. The status exists, the discomfort remains, and In Review stays a graveyard with a fifth column sitting unused next to it. The guard here is time: an item that sat untouched through two releases is a decision you have already made, and the only question left is whether you are willing to write it down.
I do not know yet which of those I am more likely to fall into. Ask again in six months.
What do statuses gate?#
One thing that is easy to miss: statuses are not purely decorative. Inside the SDK, a user can edit or delete their own feedback when its status allows it.
That constraint exists because an item that has been agreed to or built has other people attached to it. Once something is Planned, its votes were cast on the text as written, and letting the original author rewrite it after the fact means the votes now support something nobody read. Editing a typo in an In Review item is harmless. Rewriting a Planned item changes what a dozen people endorsed.
Closed belongs on the same side of that line, for one more reason on top of the votes: a closed item is the record of a decision, and a record that can be rewritten afterwards is not a record.
So the status field carries a permission as well as a promise. That is a good reason to move items deliberately rather than in a weekly cleanup pass.
Why sort by votes, not status?#
The last thing worth saying is what statuses are not for: they are not a priority order.
The dashboard sorts by vote count, because votes are the signal about what users want and status is the record of what you decided. Keeping those separate is the point. When the top-voted item has been In Review for three months, that is information - a visible gap between what people are asking for and what you agreed to do. Sorting by status would hide exactly that gap behind a tidy set of columns.
Closed items keep their votes, because what people wanted is worth knowing even when the answer was no. A closed item just is not competing for the top of the live list any more - and the top of that list is the part that is supposed to be uncomfortable.
More on how requests get collected in the first place in In-app feedback beats a feedback portal.

