The Priority Pyramid is a tool I use to stay on track with new consulting clients. It prioritizes how, who, and what I engage in at any given time. It can be overwhelming when thrust into a challenging situation, a code base in dire straits, and a frustrated team. You need a strong pillar of guidance.
This article goes over what parts make up the Priority Pyramid from a high level. I’ll talk about what milestones make up each section and how you navigate back and forward between the priorities.
When done, you should know how to engage your client’s team and tackle working on a large code base at a frustrated client site with 99 problems.
Over the years, I’ve prioritized what I need to be doing when working my consulting clients. There are countless things I need beyond “coding”, and all have to do with “people”. Code in its own right is challenging enough. Add people to the mix and it gets more complicated than it already is.
Every engagement is different, even with repeat clients. This is why I like consulting. Meet new people, travel new places, learn new things.
While I enjoy and thrive on improv, what I didn’t like was not having a set of guidelines to deal with each new client. The business blogs & books I’ve read are pretty dry, and don’t really focus on the people issues coders encounter and have to deal with. Most also assume YOU are the one creating & maintaing the app, not fixing/modifying a large one extremely behind schedule. It’s either sales, management, or product management. This includes the consulting books. Some approach it from a larger consulting perspective, where you come in, listen to the client’s problems, write up a plan, and pass it off to India. If you are involved, it’s just to either head off major disaster and/or provide face time for the client.
This is NOT what I, and my colleagues I’ve worked with over the years do. We’re in the trenches, working alongside our clients, playing the politics games whilst coding.
So, I made my own rules for engagement, prioritized based on importance, with verification points to ensure I’m on the right track. If I cannot work towards getting through all tiers of the pyramid, I will not be working for the client long, whether by my choice or theirs. It’s important I flush out these red flags early and tackle them full bore.
That… and it has D&DÂ connotations.
Quantitative vs.Â Qualitative Foundations
I’ve used both quantitative and qualitative results from case studies, white papers, and my own experience to base this set of priorities on.
Mythical Man Month/Brooks’ Law: “Adding manpower to a late software project makes it later”. Some of the bad projects I’ve been on had too many people on them. Your goal at that point is to delegate refactoring to the team to compensate, lead with good architecture, and leverage your trust currency to guide the various teams into a direction you need them to go. Also known as software chaos management. This requires you be at a high enough level to be in charge of various teams. If you’re not, God help you.
Code Review: One person, reading code for up to but not exceeding 1 hour finds more code defects than unit testing. This is not peer review, but that is also effective. Citations: Code Review at Cisco Systems, Klocwork/Forrester “The Value and Importance of Code Reviews”, and some other stats from Code Complete. Keep in mind while most of the studies mention that defects do notÂ significantlyÂ decrease after 1 person, the ability to learn from your peers and getting architecture suggestions are very well documented in the blogosphere.
Cheaper to Find Defects Early: Whether you are ruthless about upfront requirements gathering and/orÂ initialÂ architecture, or are adamant about short development iterations that includes scope reduction, both allow the ability to find more defects early. It’s easier to both find, and fix problems earlier than later for a variety of reasons (code size, feature acceptance, contractual obligations, etc). Beyond the IBM studies back in the 70’s here’s an excerpt from High Quality Low Cost Software Inspections. Also, crazy charts from Capers Jones (they have some other good studies). This is why I’m so adamant about getting the visual design (wireframes/design comps/ux/information architecture, etc.) right from the get go, even if 6 months into the project. Lowest hanging fruit and saves tons of time/money.
DistributedÂ Development (PDF): The result that physical distance between developers doesn’t matter. Different room/building/country… not a big deal at all. What matters is how far the software developer(s) are from the stakeholder(s) in the organization management hierarchy. This is extremely important. I am firm believer in both telecommuting as well as on-site visits with clients for communication & leadership reasons. This is central to identifying the power structure of the organization in Tier #2 and garnering trust with those who can help you talk to who you need to talk to in Tier #3. I’ve been ineffective at more than one consulting engagement because I wasn’t Â high enough to affect the required positive change.
Toyota Production System: Their continuousÂ improvementÂ philosophyÂ and respect for people are what really ring true to me. While It Takes a VillageÂ to build great software, sometimes you have a crowded, drama filled city that you have to work within. Doing your best to get the team motivated to constantly improve, and SEE the improvement occur over time for motivation reinforcement, is just a small way to continually improve. You can only do this if you do in fact respect the people you work with. Empowering leaders amongst those who actually do the work can lead to effective production. You can use these Toyota Process strategies in your own team delegation.
The Priority Pyramid
The 8 steps are in order of importance:
While it implies 4 are about coding, make no mistake: The Priority Pyramid is all about people. It’s built on your relationships with them and those relationships ensure you can do your job.
Lets break down the tiers the following way: What milestones do you need to complete, how to do you move on to the next tier, and when should you move back? I make the assumption if you’re on a team, you’ll divide tasks appropriately.
A Note on Tier Foundations
Each tier works on top of the foundation of the former. If the foundation is weak, it won’t strongly support the one on top. If you don’t have the trust of management and your co-workers, it’sÂ difficultÂ to lead them. If you don’t have a good understanding of the company andÂ peopleÂ who work within it, it becomes veryÂ difficultÂ to affect positive visual design changes to make architecture easier. It’s ok to be in Tier #8 and realize you need more understanding of how the application will be deployed from Tier #2; just like refactoring code over time, you can continue to strengthen the foundation tiers over time as well.
Tier #1: Report
Milestones Before Arriving
- You’ve talked to stakeholder(s) on the project to have an idea of what you’re getting into.
- Verify you actually want to get into it. Some consulting gigs are hard to get out of. Some can reflect poorly on your firm/you even if you do a good job. Make sure you’re willing to make the plunge. We’re looking for red flags here to save you tons of money and stress. I’m not saying be choosy, I’m saying be careful.
- Where you’re going, who you’re supposed to see, and when.
You/your firm has scored a client, you’ve booked your airfare + hotel, and you’re 1st day on-site has arrived. You look sharp, are excited, and looking forward to making a good first impression.
- First question out of your mouth after small talk should be “Who’s do I report to?”. Yes, it’s ok to follow up this question once you’ve scored more rapport with “Great, so… who’s my boss?”. This ensures you don’t do good things that get you in bad trouble.
- Second question: “What will make you happy when I leave?”. This helps verify why you’re really here, and what they’re really paying you for. Sometimes this takes alcohol to get the true answer. Sometimes just a neutral setting outside of the office/building.
Know who you work for and your true goal in life for the next 8 months.
Tier #2: Understanding
The best communicators are good listeners. Your task now is to look people in the eye, lean forward, and listen well.
- Listen: Get people talking, asking questions, and listen to what they say. This is the most important step in the entire pyramid.
- Goals: You need to understand what the goals are for the project, both stated and real. What are you and the client really trying to accomplish? Answering & documenting this will guide your actions for the rest of the project,Â overriddenÂ only by “Who do you report to?”.
- Problems: What are the problems and challenges the company has run into? Do any relate to why you’re here? Do they have a thorough list or are there more? Solving problems earns trust, and helps in the next tier. It also validates your paycheck. Why does the client have those problems? Where do you fit in? Who’s accountable for identifying solution(s) for and solving those problem(s)? These are your first challenges in the game.
- Dissect People: This is also an opportunity for you to start learning who the players are in the game. You need to understand what makes someone tick to best interact with them. Do they like business first, small later or the opposite? Do they have ulterior motives? Can they be trusted? Can they give you valuable intel on the project others won’t? What will it take to make them comfortable enough to tell you more? How can you possibly help them? You’re going to be spending the next 3 to 18 months with these people. Get to know them, make a good first impression, and understand them. These are the people you want on your team, who you want to do certain things for you, who you want to trust you. Once you understand them, you can effectively engage them. Sometimes this is done simply by watching how they interact with others. Ask questions to get them talking; their personality whilst reveal itself. Finally, figure out who reports to whom for real? What is the power structure? You’ll need to play within this framework; best to know how it works for real vs. what the label says on their door.
- Explore: Finally, code stuff. Time for initial reconnaissance. Taken what you’ve learned, it’s time to verify what you heard is recent, relevant, and can be corroborated with the code. This should still be framed from a “learning the company” perspective. You need to:
- Learn the Data Model: The VO’s, the Services it calls, and what those business objects actually mean to the organization.
- Learn The Framework: How is the codeÂ architected; what framework did they use?
- Understand The Story: With another developer, preferably one who worked on the code base and/or your client, ask the developer questions to learn the story. Even the worst code base has a reason how it got there. Like an archeologist, you want to understand this history, the pivotal decisions, or lack thereof, that made it the way it is. You’ll learn the to respect, and pity, even the worst code base once you’re armed with this knowledge.
- Look For Red Flags: Both the currentlyÂ benign, and the “holy eff we’re eff’d”. Whether that’s everything being a hashmap in Java, Angular & Backbone both being used in the same code base, or ActionScript 2. You don’t want surprises, you want to frame your perspective of the code base with your client’s. This is a VERY important step. Don’t say it, but talk about it internally in my mind. Find out why there is aÂ disparityÂ in perception.
- Look For Mines: Like red flags, these are things that down the line of a project, based on what you learned above could go boom. They aren’t aÂ priorityÂ but need to be documented.
- Look For Validation: Did everything you learned in Steps 1 – 4 get validated or where you completely off? If so, continue to dig, and redo steps 1 – 4 to re-verify.
When you firmly understand the client’s reality, the reality the code reflects, and the real reality once you’ve resolved the two, you’re ready to move on. If they still don’t mesh, keep asking questions & researching.
Tier #3: Trust
Assuming you’ve made good first impressions with those you’ve met, it’s now time to validate those initial impressions in those you’ve met. It’s time to start building trust.
- Provide Immediate Value: Check in code into the company’s source control your 1st week there. Preferably the code fixes a bug. Do NOT try to save the world in the code base. Pick some litter instead. If you clean the entire thing in a day, great, but get your feet wet and see what happens. A lot of drama and things you couldn’t predict happen AFTER you’ve checked in code and it goes into production. Start small and work your way up. Just ensure it’s immediate.
- Make Professional Friends: Respect those you work with and get to know them. Whether this is small talk that’s sincere orÂ genuineÂ interest, whatever works to build a positive relationship. People trust those they like. Trust is a currency you’ll sometimes have to spend in buckets to make positive headway so start investing in earning some now.
- Visible Logger: Invest in a visible logger. Even if the code doesn’t currently have problems, when it does, you want it to talk to you. Not only you, but the company. You want to corroborate this communication with your boss. When production explodes, and you know within seconds because your little secret keyboard shortcut debug window shows the error, that inspires confidence. It also provides a kind of transparency to your client when others start using it proactively to find problems. You just empowered a company to work together; well done, that’ll earn some trust. Make the code talk to you so you can trust what it’s saying, then expose this communication channel to your client.
- Provide Transparency: As you start getting your feet wet, whether this is struggling to get your environment setup so you can compile, or are deep in the bowels of fixing your first bug, let your boss know. Keep them appraised of what you’re doing on regular intervals, even if she doesn’t ask. Come across with confidence; you KNOW what you need to be working on, and you’re informing your boss as such. Additionally, she has a chance toÂ re-prioritizeÂ if you need to be working on something more pressing. No communication, and neither of these things happen. If they know and have confidence in you doing what you say you’re going to do, they can play defense and keep their boss off your, and your team’s back.
Do you think people trust you? Have you checked in working code that fixes a problem and your boss has verified this? Can you even compile? Do you know the names of those you’re working with/near? If yes to all, you’re ready to move on.
NOTE: If you ever lose trust, fall back to continually adding immediate value. Trust isn’t given, it’s earned. If you lose it, the only way to get it back to is re-earn it from scratch.
Tier #4: Lead
At this point you know enough about the goals of the project to start formulating plans on moving forward, whether this is how to implement new features or how to fix/refactor existing ones. You’ve provided enough value to earn a modicum of trust. It’s time to lead people forward.
A manager puts people in a line, puts the guy with the machete at the front, and leads people through the jungle effectively. A leader climbs the tree, and tells everyone they need to go left instead.
- Short Term Goals: You’ve assessed the situation and identified priorities that need to be refactored (using my previous article). You need the team to agree on a common logging interface, both in code and visually. Finally, you need the team to agree on an architecture.
- Long Term Goals: You’ve identified architecture holes that need to be plugged. Sometimes there are design problems that if changed could save months of work and hardship. You need to start work and documentation on it now. Solidify the long term goal into something defendable, and get the teams input. Be careful how you go about talking about it. While you need client feedback (remember transparency), it must be attainable to company-relevant, short term steps. You can spend trust currency for longer term refactoring/re-architectureÂ endeavors, but I recommend against it.
- Resources: Sometimes you need to hire additional people, whether from internal client teams, additional consultants/contractors from your firm, or hiring on behalf of your client. This could be staff augmentation or hiring a specificÂ skill setÂ you need/want. Identify these early and ask your boss.
- Divide, Delegate, and Conquer: Whether the client’s employee’s or your firms, you need to divide up the massive amount of work amongst people. Offer up tasks first, and then assign to those you deem appropriate if no volunteers materialize. Building upon Tier 2 and 3, you should have a gut feeling for who’s best for what task. You cannot save the world by yourself. It may seem that you spend more time aiming people in the same direction then actually walking that direction yourself. Don’t fret; you’re on the right track.
- Be Positive: While misery loves company, peopleÂ like and follow positive people. In talking & delegating all of your goals, plans, do so positively. You’re not “fixing a pile of rubbish”, you’re “building an awesome application” or “improving an important machine” or whatever you can say and actually believe when you say it. Eat right,Â exercise, and/or surround yourself with positive influences. Make this the year you commit suicide, reorganize & clean your working environment/home office, or just accomplish a small goal that’s not work related that you use asÂ positivityÂ fuel. Mentor & encourage your team but don’t come off as a know-it-all/holier-than-thou. Play to win.
If you know what you/your team needs to be working on today, next month, you’ve approved the hiring you need, and the team is all tasked up, then it’s time to move on.
Notes on Tier #5 – 8
The latter teirs are development specific, but rely on a strong firm foundation from the first 4. Remember, the human component is your weakest link, not your Factories. Strengthen them; do not enter these 4 latter tiers of first 4 are weak.
Tier #5: Build
You need to easily build the software. This is the most common, and frequent, option you’ll do many times a day, every day. The longer this takes, the longer it takes you to develop. This can also kill your team’s momentum. If something goes wrong, such as someone checking in a bug that breaks the build into source control, or a feature needing be implemented for a presentation by some date, a slow buildÂ exacerbatesÂ time to resolution.
Worse, some developers will start making their own build setup, leading to code that works on some developers machines and not on others. Validation of working code suddenly becomes meaningless which can adversely affect project schedule metrics. Even worse, you can think your code works, but it doesn’t for others. Who’s right?
- Quick: The build needs to run quickly. This obviously anÂ arbitraryÂ metric based on code size, libraries,Â continuousÂ integration setup, etc. If developers say “the build is slow”, then it’s slow. Utilize libraries so the entire thing doesn’t have to compile, inject dependencies at runtime, utilize modules… whatever it takes.
- Easy: If the build is complicated to do, you’ll get developers making a lot of mistakes during code validation time before they check in. They’ll either check in bad code, or make their own setup that allows the code to work on only their machine. They should be able to just click 1 button, run an Ant/Maven script, or do a 1 line command line execution.
- Duplicated: The build should be able to be duplicated on a new developers machine. It’s completely fine to have company standards, such as only Windows 7 PC w/admin rights, Flex SDK 4.6, running Rake 0.8.2. It’s also ok if that takes some time with another developer to setup. What’s not ok is once they do that, it doesn’t work. If there are 3rd party dependencies that cannot effectively be deployed x-machine, find a way to remove them. Solutions include, again, using libraries, modules, development servers vs. local server setup, etc.
If you can run the build multiple times a day without pulling your hair out, it can be run multiple times on the same code base and not break, and anyone on the team can explain to a new developer 90% of the setup, you’re good to go. Another validation includes Developer A checking in code, then Developer B updating to latest and running the build and it works on their machine as well.
Tier #6: Explosions
When things go awry, you need to immediately know where and why. More than aÂ euphemismÂ for errors/exceptions, explosions also include errors in the application that constantly cause fire drills in the company.
- Exceptions Handled: Handle all errors save null pointers. If you have global exception handling capabilities, implement it/them. This doesn’t mean just wrapping something in a try/catch; it means not only logging the catch, but putting something meaningful in the catch so you’ll understand what it means when it happens.
- Logging: You need to centralize all long into a single library. It’s ok if this library is your own that builds on top of the built-in provided one, such as Flex’ ILogger. As long as anyone, anywhere on the team wants to log something, they use that vs. print/trace.
- Visual Log: Optional: A visual window, built into the application itself (SWF/JS, etc), that prints out the log levels. This is done to allow logs to be seen by developers, not users. It also allows non-developers,Â especiallyÂ QA, to proactively find problems and talk directly with thoseÂ responsibleÂ vs. the 1st developer they can find. The value this provides inÂ empowermentÂ and time saved should not be underestimated.
- No More Fire Drills: Wrangling in challenging errors to help prevent fire drills can do 3 things. First, you score a lot of trust in “knowing” why something is wrong vs. 10Â peopleÂ running around aimlessly trying to figure out why. Second, you can clearly cite accountability; is it the server-side team, your team, or the database team? Instead of yelling “I think your stuff broke” you can confidently say it did with helpful data for them to test against. That kind of attitude is much easier to solve problems with. Third, fire drills no longer sabotage your productivity.
If an error occurs and you know where it happened, a general reason of why, and who’s potentially accountable, you’re in insanely good shape. Users don’t see these errors, just null pointers, or those you’ve built a GUI for (ie Alert error dialogue). Bonus points if fire drills happen on other teams that aren’t related to yours… but you have a way of helping through logging to make testing easier.
Tier #7: Diagnostics
Diagnostics form a range of tools, not just code. They are anything that helps provide insight into code issues or runtime errors without costing more overhead inÂ maintenanceÂ than the value they provide. The reason diagnostics is before architecture is that in larger applications,Â especiallyÂ in a consulting context, adding simple diagnostics has a ton of value with little effort whereas architecture takes a ton of effort but tends to have low perceived value (yes, it’s valuable, just harder to sell).
- Unit Test Coverage: Even if you’re not doing TDD, unit tests along help find & prevent bugs as well as improve API’s. Unlike code reviews, they don’t get tired, benefit the entire team, and if written well only slightly add to codeÂ maintenance. Finally, they can be automated. These are also great things to work on in down times such as when JIRA is cleared, you’ve hit a brick wall with another bug, or are waiting on dependencies for a feature.
- Integration Tests: These are my favorite on service layers, more so than unit tests. The reason being is most of the Flex projects that I’ve worked on in a consulting context had some form of service layerÂ problem; ie how they talk to the back-end. Both refactoring the service code and writing unit tests that allowed me to automate the testing. It’s also nice to quickly know what part broke with confidence; client, server, or database. Automating these also makes you feel better when the server guys test new code, you can quickly help them test. There are more to integration tests, but these are the low-hanging fruit of ’em.
- Automated Builds: Expanding upon Tier #5,Â streamliningÂ your build process to be more inline withÂ continuousÂ integration practices. This means designating a resource to setup, and maintain, aÂ continuosÂ build tool like CruiseControl/Hudson/TeamCity, etc. You should know who checked in bad code and when.
- Custom Diagnostics: Some applications have challenging domains of complexity. For example, video; there are TON of things that can go wrong at runtime even if the code compiles just fine. There are also a sequence of events that can cause video to fail, and knowing this sequence is paramount in debugging it, or shrugging it off since there’s nothing you can do (i.e. CDN is down). More importantly, though, sometimes you need a way to glimpse this in a more visual way than a logging window can provide. Conversely, sometimes you need to see environment variables in real-time. This little window can verify your application is running in the mode you think it is for a developer in another country. Simply making a box with a text field in it that showed Flash Player’s sandbox security type saved me 3 days (I lost 3 figuring this out, heh). Additionally, they can help empower others to do testing & diagnostics on their own. Just be careful these are not a security risk for code and/or company information if deployed in production.
If you have good unit test coverage, can automate their running, your build is automated in some fashion (even if just client side only), and you have gui or command lines way to gain insight to your running application to find out more about errors, you’re in awesome shape.
Tier #8: Architecture
While good architecture requires a book full of information + years ofÂ experimentationÂ to get right, what we’re concerned with here is IMPROVING existing architecture. If you are starting a project from scratch and own the architecture, great, use this phase forÂ maintenance. Otherwise, we’re looking for that sweet spot of a 1 day change for a more decoupled, easier to use & test in code system. If something takes longer than 3 days, you’ll be hard pressed to merge it back in and notÂ inconvenienceÂ other developers… unless it’s very little code.
- Tight Factories: Any part of your application which takes outside data into it’s system, such as external JSON/XML as well as user input, needs to be furtherÂ hardened. DRY the code, layer with #moarUnitTests. Form a convention on what happens when parsing/decoding fails; do you throw errors orÂ returnÂ null and log them, thus passing the burden of handling null to your system? Decide as a team.
- DRY: If none of the above can be improved, simply making code more DRY is a good fall back task to more unit test coverage.
- TODO/FIXME/KLUDGE/HACK: Do a find all in the code. If you see those, fix them. #fixBrokenWindows
You never really exit Tier #8; in fact you tend to loop back to either 7 or 6 and 7 and then back to 8. However, if you find yourself working on new features, or fixing bugs with no other drama and the rest of your team is doing the same… then you’re in epic shape.
As you can hopefully see, my priority list helps keep you focused on delivering value to those that matter quickly. Good software development is iterative. Earning trust is also iterative; you don’t take people’s money and disappear for 6 months (that’s called good Capitalism via Waterfall). This whole list, while referring to software development, is all about relationships with people. Excluding code review, your challenge as a leader is delegating the tasks in each tier to divide & conquer, mitigating conflicts, and solving hard software problems in addition the rest of yourÂ responsibilities.
Each tier builds upon the former all the way down the line. While deep in the bowels of fixing explosions in Tier #6, I’m still continuing to build meaningful relationships in Tier #3.
- Report: Know your true boss and what will make her happy.
- Understanding: Listen, learn about the company, the people, and dive into reading the code.
- Trust: Earn trust by providing immediate value.
- Lead: Take the initiative and move the team forward. Delegate, divide, conquer.
- Build: Make the build fast, easy, and capable of being duplicated if need be.
- Explosions:Â When things go awry, you need to immediately know where and why. Prevent fire drills.
- Diagnostics: Get good unit test coverage, integration tests, automate your builds, and build any customÂ diagnosticÂ tools needed.
- Architecture: Decide on a direction/framework, and continue to nurture the code, and developers, in that direction. Loop back to 6 & 7 if need be.