TL;DR
If you are following the Scrum framework, work should be iterative by nature. It should also be time-boxed, so user stories and Product Backlog items should not carry history.
Analysis and Recommendations
Stories Should be Done or Not-Done Within a Single Sprint
My questions is about splitting a story into versions. For example, we might have a story to allow a user to upload a file to a server. The first iteration of the story is usable by the customer but it's quick and dirty, the second adds file validation, the third version adds deltas, and so on.
The point is that these activities are probably too small to be a feature but too big to be a single story. The body of each story will contain all the acceptance criteria and other data, but what should that set of stories be named? Is it okay to say "User can upload file v1", "User can upload file v2", etc?
The way you're describing "splitting" user stories by versioning them is an anti-pattern. It implies that a user story (or, technically speaking, a Sprint Backlog item) maintains relevance beyond the time box of a single Sprint. While epics and themes may take multiple Sprints to fully deliver, a user story or Sprint Backlog item must be done or not-done within a single Sprint.
Tooling issues aside (and I do realize tools like JIRA can force people to think differently about what epics, features, and stories look like) the correct way to think about it is quite different. A "feature" is generally a coherent piece of user-facing functionality, which in your case would be something like:
As a Foo SaaS Server customer,
I want to be able to upload various types of files to the server
so that I can attach more than one attachment type to each ticket or blog post.
In this example, the user might want to be able to upload PDF files, Word documents, Excel spreadsheets, and UML diagrams. Assuming your system has to treat each type of file upload differently—an idea which I would challenge the Developers to reconsider, and perhaps ask the whole Scrum Team if it would make more sense to write a feature for treating all uploads the same instead—then it's okay to have more than one Product or Sprint Backlog item for each portion of the feature. However, according to the INVEST mnemonic and Scrum best practices, each user story should be small and testable, and as independent of the others as possible even though user stories can have prerequisites.
Sprints Should Have Sprint Goals
That said, a user story or other type of backlog item doesn't automatically cross Sprint boundaries. That means any work that's not-done at the end of each Sprint is future work on the Product Backlog that must be re-prioritized, re-estimated, and re-planned in a future Sprint.
The way you incorporate this fundamental fact into your workflow is to create a Sprint Goal each Sprint that contains a central coherence. For example, rather than trying to deliver the entire feature of "file upload support," it's okay to have multiple Sprints with Sprint Goals that deliver potentially-shippable increments of your feature. As an example, you might have three Sprints with Sprint Goals such as:
- Support uploading and parsing PDF files into the user's widgets on the SaaS server.
- Support uploading and parsing Word files into the user's widgets on the SaaS server.
- Support uploading and parsing Excel files into the user's widgets on the SaaS server.
During each Sprint Planning event, the Developers would build a Sprint Backlog around Product Backlog items related to the current Sprint Goal. That way, the increment will be done or not-done at the end of each Sprint, and suitable for Sprint Review and (if properly sliced via INVEST) potentially-shippable as an incremental portion of the larger epic of supporting multiple upload types.
Backlog Items Don't Carry History
A Sprint is an ephemeral time box that gets filled with work items related to a single Sprint Goal. Once a Sprint is finished, it's gone forever; any unfinished work related to that Sprint is either discarded as no longer relevant, or placed back onto the Product Backlog for a future Sprint. In either case, the work done or not-done in the Sprint is not tracked as a first-class item within the system because all that matters is whether or not the Sprint Goal was met, and that only matters to the extent that it impacts the contents and ordering of the Product Backlog. In the end, the maintenance and delivery of goals defined within the Product Backlog has primacy.
For practical purposes, this means that Product Backlog items don't have "versions." They also don't carry metadata like effort-expended deltas, prior planning data that is frequently irrelevant to how to deliver the backlog item from a different starting point in a future Sprint, or other data that isn't directly related to prioritization or value. One could perhaps argue that a Product Backlog item could carry metadata such as:
- Links to an epic or theme for the purposes of grouping or prioritizing on the Product Backlog.
- Value estimates related to the specific item, or earned-value estimates related to the larger epic or theme.
- Level-of-effort estimates to assist with prioritization and cost/benefit analysis that supports placing Product Backlog items into a sequential order.
- Release plan estimates that target a particular release version or release date. NB: Just remember that release planning in Scrum and other agile frameworks is typically iteration-based rather than date- or effort-driven, and represents an estimate rather than a money-back guarantee.
but anything that smacks of carrying history forward from previous Sprints (such as treating incremental work as "story versioning") is likely a way to avoid true incremental or iterative planning based on vertical slicing and time-boxed delivery. In Scrum, all work each Sprint is new work, and must support the just-in-time prioritization and planning that the framework is designed for.
That means that the product itself is intended to be developed through emergent design, and that design may itself change at each inspect-and-adapt point. When you keep that in mind, you quickly realize that "feature versioning" as such is an anti-pattern that works against Scrum's underlying principles, especially since continuous product improvement is already baked into the framework. The type of versioning you describe doesn't provide self-contained, independent, or negotiable information about the related backlog items, and therefore works poorly from both a Product Backlog and a Sprint Backlog perspective.
How to Improve Your Scrum Implementation
Focus on the following, and the rest will take care of itself:
- Treat product development as inherently incremental and iterative.
- The Product Backlog should focus on what needs to be delivered to create value, and leave the implementation decisions (e.g. how the work is implemented) to Sprint Planning.
- Use just-in-time planning as much as possible for the Product Backlog, and as a first-class approach to defining Sprint Goals and the Sprint Backlog.
- Treat product architecture as an emergent design rather than relying on big, upfront planning.
- Defer all design and implementation decisions until the last responsible moment.
Other techniques such as vertical splitting, INVEST, and test-first development all support these core principles, but it's the principles that matter most. If your process doesn't support the principles I laid out immediately above then it's time to reconsider the way Scrum is being implemented by the Scrum Team and identify how it can be streamlined and improved.