Fog Creek

Case Dependencies

For years, Fog Creek’s approach to developing products has been guided by a simple principle elucidated by a fella named Joel Spolsky:

Design, for my purposes, is about making tradeoffs.

The big trade-off we’re always making is between power and complexity. If you want to see the effect of blindly adding features, just open iTunes. (Don’t worry, we’ll wait.)

Many people who first open FogBugz and start using it very quickly come to two questions:

Question 1: How do I delete a case?

It’s not like in nine years of developing FogBugz, we didn’t have time to add a delete button. We just found that closing a case was good enough for 99.9% of eventualities. And solving that last 0.01% would add significant complexity. We can add deletion to satisfy some customers, but not without losing others. A trade-off.

People who need to actually excise cases from their database can do so. Even so, we have thousands and thousands of customers happily using FogBugz On Demand with no ability to excise data, and they never complain about it. We get a request to delete an inadvertently emailed credit card number from a case maybe once a month.

Lack of deletion might confuse you for the first 5 minutes, like the 5 minutes you spent looking for the Off switch on your first iPod. Steve Jobs didn’t include a note with every iPod:

BTW: there’s no Off switch. — luv steve

He knew you’d figure it out.

And those people, the ones who absolutely need the Off switch on their music player or else they can’t use it? Well, they found themselves on the wrong side of a design trade-off.

Question 2: How do I indicate that A needs to be done before B?

We have several good ways of indicating this in FogBugz. Milestones are the primary one. Parent-child relationships can do a pretty good job. The Project Backlog plugin is probably the most granular way we offer.

The venerable open source bug tracker, Bugzilla, though, offers blocking. Blocking seems handy. You can reflect in the system that

“I can’t do this until Jim delivers his logging library.”

It seems very reasonable (like having an Off switch on a music player). It’s the second thing many people think when they open FogBugz for the first time (including your correspondent, years ago).

In the software world, though, these kinds of true dependencies come up very rarely. Even in manufacturing, deciding that something is a dependency too early can be really inefficient. For instance, if you’re making espresso machines, you’re going to need a heating element. Is that a dependency? Yes. Is it blocking? Up to a point. There’s a lot of the espresso machine you can make while you wait for your heating elements to clear customs. When they arrive, you’re already well into the process.

In software development, it’s the same, but moreso. Programmers have mock objects and stub functions. These define an interface but just dumbly return a single (or random) value when you interact with them. These are easy to write, and are the classic way of making progress while you’re waiting on another engineer (or company) to deliver. If you could put a fake heating element into your espresso machine that would magically transform into the real heating element (when they clear customs) without having to take the whole dang thing apart, that would considerably reduce the number of true dependencies in your manufacturing process. (And, you’d probably crush your competitors in the espresso machine business.)

Software engineering can be a pretty parochial endeavor. We left blocking out of FogBugz on purpose. We hoped it would encourage efficiency and cooperation. Stub in a function and stop obsessing over Jim. He’s probably not the one stealing your lunch from the fridge anyway. (It’s actually Margaret.)

But we still kept getting the question, and our answer was always a version of the above. To be honest, we’ve never been thrilled about this trade-off. It’s not as clear-cut as the deletion or required field trade-off.

And then we released a plug-in architecture, and our answer became the above plus, “But if you really, really wanted it, you could write a plug-in.” Even if we didn’t think of this as a bluff, the very talented developers at Quarantainenet called it anyway.

The team at Quarantainenet wrote a Case Dependencies plug-in for their own usage. Version 1 came out last summer, and they’ve continued to improve it. They’ve generously made it available to the world for free. We really think they’ve done an excellent job with the interface work. In filter/grid view, you can filter blocked cases so they’re hidden. You can sort cases by number of cases they rely on, or number of cases they’re blocking.

Filter by various blocking options

One big feature that argues for using the plug-in, even if you’re not going to use it for Bugzilla-style blocking, is the ability to have cases automatically reactivate when all their dependencies are closed. This fills a long-unmet need for customer communication: “Tell me when my fix is released.”

Reactivate resolved cases when dependencies close

On top of that, Quarantainenet has put us to shame by offering comprehensive PDF documentation of their plug-in, something that’s not currently available for FogBugz itself. We’re lucky to have them as customers.

This really highlights the best part of the offering plug-ins. It allows us (and our users) to offer additional functionality without complicating the basic user experience. Anyone who adds the plug-in knows exactly what they’re adding, and is expecting the additional complexity that comes along with a voluntary addition of features.

It also highlights to us the awesomeness of having developers as customers. They have the ability to change things, make things better, if you give them the opportunity.

Marnix and the team at Quarantainenet say Case Dependencies really works great with their workflow and has renewed their love of FogBugz.

You can download the plug-in from our plug-in gallery.