We’re getting into the end game before a big release, and I’m already tired of people whining about unstable and overdue dependencies. Of course they are unstable and overdue, what planet are you from?
Yeah, yeah, a package should only depend upon packages that are more stable than it is (the Stable Dependencies Principle). I’ve pushed this principle countless times. Yet when you work for a big ambitious technology company like Microsoft®, no one wants to wait for cool technology to stabilize before coding against it—at least no executive I’ve ever met.
That means your dependencies are unstable and likely running late. It’s not the fault of the teams you depend upon, and it’s not going to be much better next time. Tough luck—quit whining and deal with it. Don’t know how? I figured.
There are five methods of dealing with unstable dependencies.
1. Convert them from hard dependencies to soft dependencies or knowledge dependencies.
2. Over-communicate and project manage the heck out of them.
3. Get as close as possible to them personally, physically, logistically, and logically.
4. Automate ingestion of their work for you and testing of their work for them.
5. Create multi-release plans, stable interfaces, realistic schedules, and a vision that leads instead of chases.
Hold on, that last method is a pipedream—there are four plausible methods of dealing with unstable dependencies. Let’s break them down.
Unstable and overdue dependencies are avoidable by creating multi-release plans, stable interfaces, realistic schedules, and a vision that leads instead of chases. The teams at Microsoft (and elsewhere) that have figured this out live better lives and deliver great, dependable experiences on a predictable schedule.
These thoughtful teams sacrifice a little bit on timely innovation. However, keep in mind that Apple is widely considered a highly innovative company, yet Apple’s innovations don’t utilize bleeding-edge technology. Instead, they craft innovative new experiences from proven technology.
A hard dependency is one that you literally can’t ship without. If it fails, you fail. A soft dependency is a dependency with a fallback position. If it fails, you can still ship with reduced functionality.
Unstable hard dependencies are a recipe for panic followed by disaster. You want to convert them to soft dependencies by agreeing to a fallback plan. Typically, fallback plans involve shipping with a previous version of the dependency, reducing functionality, taking ownership of the dependency’s module, or some combination.
Fallback plans are wonderful psychologically. They remove the fear and uncertainty around failure. Everyone knows what will happen, and it doesn’t involve bloodshed—only lackluster reviews and a less compelling release. Everyone is still motivated to deliver something great. With raw fear off the table, people collaborate and problem solve far better.
Taking a snapshot of your partner’s code converts a hard or soft dependency to a knowledge dependency. You aren’t actually dependent on the other team for anything but its knowledge and past experience.
Knowledge dependencies are underutilized—they don’t get the respect they deserve. Just because your team may not want to take on any hard or soft dependencies doesn’t mean you can’t take advantage of the knowledge and experience of people who’ve done something similar before. I talked about this in NIHilism and other innovation poison.
When you are dealing with overlapping and overcommitted schedules, like when you’re working on almost any project ever, you need to over-communicate to your partners and project manage them. It doesn’t matter how reliable they are or how well-coordinated you appear to be. Assumptions will be made, and important details will get missed. You need to you say everything to everyone regularly and repeatedly, and track every deliverable.
You’d think all this extra communication would become noise, but it doesn’t when handled properly—with regular face-to-face meetings, item tracking (think Product Studio or TFS®), and formal email for plan changes.
§ Regular face-to-face meetings (once a week or so) are great for coordinating small changes, fixing issues that arise, and doing all-important sanity checks. A sanity check is five minutes spent validating high-level assumptions. (“We’re still getting these key deliverables in two weeks, right? You’re still gainfully employed, right?”)
§ Item tracking in a work-item database, like Product Studio, TFS, or any number of other commercial packages, is perfect for tracking resolution of bugs and work items across teams. Share the database queries you use with your partners so that everyone sees the same status.
§ When your or your partners’ plans change, everyone needs to know. Start with a formal email to everyone involved (scrum masters, leads, managers, and directly impacted team members). If any work items have been dropped, changed, or added, update the work item database accordingly. Follow up at the next face-to-face meeting with a full description of what changed and why it changed. This would appear to be obvious, but one person’s big change is another person’s minor detail. That’s why you also do sanity checks.
Clearly this extra communication and project management is extra work. So is everything else in this column. The extra work typically hits program managers and testers the hardest, but developers are also impacted. The amount of extra work is proportional to the type of dependency (hard, soft, or knowledge) and the level of associated chaos. Plan accordingly.
The easiest way to stay in close contact and resolve issues quickly is to practically join teams.
§ Personally—get to know your partners personally. Meet together, socialize together, and truly understand each other. A good working relationship helps in all sorts of ways. You become committed to each other’s success.
§ Physically—sit with your partners physically. The whole team probably won’t fit, but having one or two individuals spending significant time in your partners’ space will do wonders for catching issues early on both sides.
§ Logistically—tie yourself to your partners logistically. When they deploy, you deploy. When they beta, you beta. When they ship, you ship. Staying in sync will save you oodles of trouble—trust me on this.
Being flexible and agile really pays off in this case. Using short iterations and always being ready to ship not only helps you minimize work in progress and reduces technical debt, it also helps you stay synchronized with your partners’ releases.
§ Logically—engage with your partners’ tools, work item databases, and source code. The deeper you know what’s really going on in their work, the better you’ll foresee, understand, and resolve issues.
Even if your partners haven’t finalized their interfaces, a starter interface can often help you get an early jump on development and testing. You can write your own emulator, use an early drop from your partners, and otherwise code and test against the upcoming interface in advance of receiving the final version.
One critical engagement with your partners’ tools is around handoffs. Before they deploy a new version, they should run a set of build verification tests YOU WROTE—only you know what you are expecting from your partners. After they deploy a new version, you should run a set of ingestion tools THEY WROTE—only they know all the moving parts, tricky ordering, and special steps necessary.
The build verification tests you wrote should quickly check that the new version works the way you intend to use it. Writing these tests can be a bit tricky, because you have to understand your usage patterns, and you have to author the tests in their test system. Of course, all that effort is well worth it when every handoff works as expected.
The ingestion tools they wrote should give you all you need to use the new version. This should include setup, libraries, content, configuration, and validation. Writing these ingestion tools shouldn’t be wasted effort since they help your partners as much as they help you. That said, all the effort is well worth it when they don’t spend two days after every handoff getting your systems functioning again.
Even in the best of circumstances, there are always surprises in any development cycle. Being flexible, using short cycles to react faster, and communicating well with partners, customers, and within your own team does wonders for dealing with the unexpected.
What isn’t constructive is blaming your partners for costly mistakes, even if they were at fault. We’re all human and mess up occasionally. We win and lose together. If you can’t handle the problem or didn’t know about it in time, then you’re at fault too. You all can improve your communication and issue management next time—the issue will recur.
For all the headaches and heartaches that unstable dependencies can cause, they also can be exciting, build a larger sense of team, and bring faster, broader, and bolder innovation to customers.
Don’t play the victim. Create fallback plans, over-communicate, integrate your teams, and automate quality handoffs. You can be part of something big if you embrace the challenge.