Issue introspections

When developing software, most developers have a branch that is under development and not yet released. Sometimes it’s simply that set of changes between the last release and whatever is at head/tip, sometimes it’s a completely separate dev branch or branches which haven’t yet been merged. Whatever the mechanism, there is always some gap between what’s released and what’s under development. Even in CI/CD, where code passes through some workflow of automated testing before it makes it into production, there’s a time delay between “code committed” and “code released.”

A common thing in ticketing systems is the ability to change ticket states based on triggers in commit comments. Even the more simple systems, such as Sourcehut’s todo, have the ability to change ticket states between closed and open via keywords (!reopen, !resolve). Jira allows a variety of state change based on configurable keywords; it’s one of the more fundamental ticket tracking features.

It’s curious, then, that most ticketing systems don’t come with a state that represents that twilight state of “done, but not released.” It’s curious because ticketing systems are usually made for developers, by developers, and this is a sort of race condition: users can find and comment on an issue or create new issues about bugs which have already been fixed, but not yet released. Even diligent users who check for duplicates and ensure they’re at the most up-to-date version can hit this race condition; it’s a bit much to ask users to browse through the commit history and try to interpolate between commits and releases to try to figure out whether the version they’re using is supposed to include a given fix.

Some of this is a sort of hubris. OSS gives developers a sort of freedom to not give a shit about their users; users are not paying for the software, and developers have no obligation under most philosophies[^1] to them. If the users can’t be bothered to (1) find a related ticket, and (2) read through all the change logs and release notes for the ticket to see if it’s mentioned, well then they’re lazy and don’t deserve consideration. As a user of software, you’ve experienced this yourself, haven’t you? Trying to find whether a fix is in whatever version you’re using? Every single QA engineer has suffered this at some point, I guarantee.

But I think it’s mostly just a lack of thoughtful design. Developers tend to consider committing the code to be when their jobs end. This certainly a simplification, but it’s mostly true; in many (most?) companies, there’s a “toss it over the wall” mentality: organizations are split into “development” and “operations;” the dev team works on code, gets it through QA, and then hands it off to a release team who deploys it. After that – possibly after some warranty period of a day or two – an ops team takes over and fixes any bugs or issues in the code. I personally believe this is one of the most absolutely bone-headed way of running software development, but the point is that it underscores the fact that many developers have this “committed = job done” attitude, and this is reflected in ticketing system designs.

Eventually, most systems adopt a sort of work around by tagging tickets for target releases. It’s an effective strategy, as it communicates clearly what’s going on. Alternatively, in many ticketing systems such as Redmine and Jira, complex ticket state machines can be created that reflect where tickets are at – although I think this can be confusing to users. It’s another sort of hubris to assume that, just because you’re intimate with your ticketing system, everyone else is, too.

I think the best solution is an interim “done, but not yet released” state. Ideally, when a ticket is included in a release, that ticket would be updated with the release version and properly closed. Target release tagging is acceptable, but I think it is slightly inferior due by perpetuating the idea that, just because code is committed, it’s “done.” If Sapir-Whorf has merit, then “closed (but not yet released)” reinforces the “throw-it-over-the-wall” world-view.

In today’s world, more than ever, we need more willingness to take responsibility and accountability, and a focus on quality. Few companies demand quality as the top priority from their development teams, except in lip-service, and I think it’s common for developers themselves to tend to that “committed-is-complete” mentality anyway – it’s not just evil management driving this. If it were otherwise, I think we’d see more cases where ticketing systems have, in their default workflow, a state that distinguishes between completed and released.

[^1] Except, perhaps, Buddhism, in which if one offers some service to another, they also inherit an obligation to them. C.f. saving a person’s life makes you beholden to them.