Skills
Practical guidance on core team skills: self management, clear communication, expectations for senior/lead engineers, and what managers should cover in 1:1s. Skim the sections you need and add to it when you find gaps.
- Self Management
- Clear Communication
- Senior Engineers
- Manager responsibilities
- Writing
- Efficient Meetings
- Big head/little head
- Customer Communications and Relationship Management
- Push vs pull model
Self Management
This is a quick guide to staying organized in a calm, easy-to-manage way. It borrows from Getting Things Done without requiring any specific tool.
Principles
- Anything which must be done must have at least one next task. That task must have an owner. That owner is responsible for follow-through.
- If you do not trust the owner for follow through, you should keep track of the task as well.
- All tasks should be written down somewhere. It is OK if they are referenced in multiple locations, but there should be one master location for detailed notes.
- Each individual should have one central location for all tasks they must follow through on. This may include references/links to other locations.
- Each individual should train themselves to regularly create tasks in their own tracker, refer to their tracker, and check off tasks when completed.
- A tracker is separate from a calendar, which should be always up to date and indicate times for meetings and other highly-time-sensitive activities.
- Ideally, messaging systems (Slack notifications, emails, etc) should be kept clear. If a message or email necessitates handling, create a task for your follow up. Use “snooze” or similar features as necessary.
- Ultimately, the goal is that among your inbox, calendar, and personal tracker, there is a clear view of what you should be focused on at any given time.
- Make tasks achievable, well defined, complete them, and move on.
The tracker
Use any todo list that you will actually maintain. Todoist is one good option with sync, priorities, and comments.
There will almost certainly not be a central tracker for all work. We have personal lives. We have FP Complete issue trackers on Gitlab. There are separate customer issue trackers.
Do not let the perfect be the enemy of the good. This problem typically results in engineers seeking a way to “fix” the problem and unify everything, or create some automated system to show a unified dashboard. Don’t do that! Copy a link, stick it in your tracker, move on. The cost of doing anything else isn’t worth it.
Complete tasks
Make sure all tasks are actionable. “Improve code” isn’t a task, it’s a goal. A task is actionable if there’s a way to say “this has been completed.” “Provide a write-up on the improved code goals” is an action item.
If a task can’t be completed: close it. Open tasks are a distraction. Each one presents cognitive overhead.
If a task seems valuable, but there’s nothing actionable to be done, find some actionable subcomponent and turn that into an issue.
If you’d completed 70% of a task, but there’s more work to be done, close the open task, and create a new one focused on the pieces that remain.
You get a dopamine hit from completing a task. Use that!
Communicate clearly
If a meeting happens and nothing is written down, the meeting didn’t happen. Write down action items, ideally in a shared tracker. Ensure everyone is clear on who the owner is. If you are waiting for someone to do something, ensure you’ve clearly communicated that fact. All too often two people are silently waiting on others.
Some people are not good about following up on items they own. This especially applies to our customers, but sometimes to our team members too. Use your own tracker to schedule follow-ups on such topics. If you repeatedly have issues with someone dropping issues, raise it as a concern with them, and/or discuss with their manager.
Clear Communication
The ability to clearly communicate with others is a multiplier skill: it makes any other skill you possess more valuable. Together with self management, it forms the basis of leadership potential and a reliable team member.
A basic idea could be seen at The No Hello Club but that is just a bare minimum.
This document cannot teach all nuances of clear communication. Instead, it is intended to give a strong overview of goals you should strive for in improving your communication. It provides some techniques which, if followed, will help you communicate better. In addition to these points, you should ask for feedback and recommendations from team members, especially your manager, leads, and people you believe communicate effectively.
Identify goals
In any medium of communication, your first question should be: what are you attempting to achieve? Too often, engineers in particular have a tendency to communicate what they believe to be useful information, but in reality means nothing to the receiver.
Here are some examples of good goals for communication:
- I am having an issue with this technical challenge, and I would like assistance in resolving it.
- I have a concern about the customer’s expectations, and I need to raise the issue so that someone on the customer relationship team will address it.
- We are doing well on a project and expect to hit deadlines.
Here are some contrary examples of bad goals for communication:
- I want to tell you about what I’ve been working on this week.
- There may be a place for this in the sense of “I just want to share this with someone.” But this should be explicit. Providing a stream of details will likely confuse the listener as to what they need to try and glean from the discussion.
- I want to tell you that I’m concerned about the project.
- Unlike the good goals above, this one has no clear objective. Sharing the information is not the goal in and of itself. There should be some objective such as “please advise me on what to do next” or “can you double-check if my read on the situation is accurate?”
Concision
There are two competing goals here:
- Provide sufficient information to express the point
- Do not provide too much information to waste time or drown out the point
Concision is highly context specific. Consider the case of an async exception bug affecting a customer’s Haskell codebase. If you are two Haskell developers both familiar with the codebase, you will be able to communicate less information to each other than a developer explaining the situation to a non-technical customer relationship manager. With concision, the important points are:
- Attempt to identify how much context is necessary
- Confirm with the listener that they understand what you are saying
- Provide opportunities for the listener to tell you that they already understand these points
Communication media
We have many different forms of communication available to us:
- Slack
- Documents
- Voice chat
- Video chat
- Blog posts
Choosing the correct form of communication is important. In general, especially on a distributed team like ours, asynchronous and text based communication should be preferred. If something can be expressed in an email, Slack message, or document, it typically should be.
Video and voice chats place higher demands on synchronicity and time from participants. They also provide for faster feedback and more bandwidth of communication. They are certainly warranted in many cases. And in cases where text communication is leading to confusion or frustratration, a voice or video call is practically required. That said:
- Some people rely too heavily on video or voice chat to avoid the hard work of communicating clearly. It can be easier and lazier to take up 30 minutes in an open-ended video call that could have been achieved with 10 minutes of thinking about what to say, and 5 minutes of typing.
- A very negative side effect of video chat is often the lost meeting. When no notes or action items are taken from a video call, everyone walks away with a different understanding of the meeting. Or sometimes no memory of the meeting at all.
A basic guide to communication media is:
- Decisions and action items should be recorded in a document, issue in an issue tracker, or similar
- Exploratory discussions should start as a Slack thread, and result in something more concrete at the end
- If the topic is unwieldy on Slack, resort to a video chat
Private communications
The cornerstone of our ability to operate well as a globally distributed team is shared, asynchronous communication. Put simply: unless you have a strong reason to do otherwise, please communicate in topic-appropriate channels instead of private messages.
Many team members, especially newer team members, have a tendency to rely on one-on-one messages in Slack, or to wait for a call to discuss topics. People have different reasons for doing this, such as not wanting to ask "stupid" questions in a public channel. However, private communications greatly and negatively impact the team:
- It creates silos of knowledge that cannot be shared across the team
- It places unnecessary burden on the receiver of the messages to be the only person who can answer questions
- Due to the variety of timezones we're in, it causes delays in delivery
- Public discussions--especially technical discussions--are the cornerstone of building a company culture. It's a distributed team's equivalent of the water cooler.
Private communications do of course make sense in many cases: friendly chats, discussing personal issues, raising a concern that shouldn't be on the public record, and more. However, these cases tend to be far less prevalent than many people believe. Default to public unless there is a clear reason not to.
If you're unsure if something should be private or public, ask (and probably ask privately). If you receive a message that you believe should better be handled in a public channel, you can ask that the discussion be moved to a public channel (and a link to this section may be a helpful way to reinforce that).
Senior Engineers
This section describes what it means to be a senior engineer. Titles are lightweight; the goal is to set expectations and give concrete growth goals.
- Express to other team members what you can expect from a coworker
- Give concrete growth goals to team members looking to advance
Skill stacks
Your work relies on more than one single skill. For example, when working on a server-generated HTML web application, you will need technical skills including the server side language, HTML, CSS, Javascript, potentially SQL, some DevOps knowledge around deployment, etc. A common mistake in assessing someone’s skills is to assume all skills are equivalent.
As an example, it’s entirely feasible that an engineer may be very strong as Haskell, HTML, and SQL, but have weak skills on DevOps, CSS, and Javascript. As a result, it’s entirely possible for someone to be more senior in their abilities for some tasks than others.
In addition, all of the skills above are technical skills. There are many other non-technical skills related to your work: requirements gathering, clear communication, self organization, etc. A large part of being a senior engineer, and especially a lead engineer, is improving these soft skills in addition to technical skills.
Skill levels
Roughly speaking, for each individual skill, people can be classified into level 1 to 4. The basic breakdown of these levels is:
- Level 1 The person needs detailed guidance on how to complete the task
- Level 2 The person knows the basic outline of how to complete the task, but needs detailed oversight
- Level 3 The person has strong capabilities in the task, but may require some review of details, and lacks confidence for complete ownership
- Level 4 The person is an expert at this task, and requires little oversight or guidance
Leads and managers at FP Complete are trained to assess skill levels along these lines, and adapt leadership style for each person accordingly.
The final important piece worth reiterating: these skill levels may be different for each skill. In the example above, the same person may be a level 4 Haskell developers, and a level 2 Javascript developer. Care must be taken by both the person being managed and the manager to note this difference, and ensure there is appropriate guidance.
Skills expected of senior engineers
Senior engineers are expected to be at skill level 3 or 4 on the majority of skills related to their job. For example, a senior DevOps engineer should be at skill level 3 or 4 for Terraform, AWS, Kubernetes, and Docker. It is not necessary to be at skill level 3 for development tasks. The same would apply the other way: a senior Haskell engineer may be skill level 4 at Haskell, but skill level 1 or 2 with Terraform.
Senior engineers are expected to have the ability to self assess and identify weaknesses in skills. No person on the FP Complete team is expected to be an expert on all topics. However, each senior person must be capable (at skill level 4) of realizing when their skills on a topic are insufficient, and be able to ask for assistance from other team members.
Senior engineers are generally expected to have architect skills: design, plus documenting and communicating a solution. This involves requirements gathering as well.
In addition, the following skills are less technical, but no less important, for a senior engineer:
- Clear communication. Both written and verbal communication must be clear, concise, and comprehensive. See the clear communication section for more.
- Self management. Senior engineers must be capable of tracking their own work items, tasks assigned to others on their team, items they are blocked on customers for, meeting times, etc. See the self management section for more.
- Regular team tasks, such as status reporting, hours entry, security checks, etc. Senior engineers are expected to be fully autonomous on such activities, and require little to no assistance in the form of reminders to regularly perform such tasks. These tasks may be boring, but senior engineers must understand the need for such activities on a team, and be capable of taking responsibility for such activities.
Lead level skills
Engineering leads have additional responsibilities above senior engineers. While senior engineers are expected to own and complete tasks, lead engineers also:
- Identify the tasks that must be completed
- Break up tasks into meaningful milestones
- Assign tasks to team members based on skills
- Aggregate status across a team and update a customer
- Understand the deeper requirements coming from a customer and propose solutions
You’ll notice that little of the additional skill set here is technical. What distinguishes a lead engineer is stronger communication and coordination skills, rather than raw technical talent.
Manager responsibilities
NOTE This document is primarily targeted at managers, but all engineers will benefit from reading.
FP Complete generally follows a "matrix management" approach to engineer management. The general idea is that we split up responsibilities between:
- Project lead: responsible for prioritizing work items, answering questions about requirements, providing technical mentorship, etc.
- Manager: responsible for day to day guidance, development of soft skills, logistical questions, and growth trajectory.
Lead responsibilities are in many ways more clear-cut; this section is just about the manager aspect.
Generally speaking, managers should have a regular (once every 1-2 weeks) call with each person reporting to them. This is a good time to touch base on high-level concerns and questions (which we'll discuss below). But you should strongly encourage anyone reporting to you not to wait for a meeting to bring up questions. FP Complete is an async-heavy organization, and it's important to foster clear text-based, async communication skills. (See clear communication for more details.)
As a manager, your primary goals should be:
- Engineers must know what project they are supposed to be working on, and how many hours to be dedicating to that.
- As a manager, you should know, overall, what tasks they are being assigned on that project. You should be in regular communication with project leads to get an overview of this. You don't need to be familiar with all the details of every task, but should at least know the general requirements and the skills necessary to achieve that.
- Understand which technical skills the engineer is interested in acquiring. We can't always guarantee that projects will be available for training up on specific skills, but we try to tailor the workload to allow for skill acquisition.
- The general rule is: 80% of someone's work should be in technical areas they're already proficient with, and 20% stretch skills. This won't always be possible, but it's a good goal to keep in mind.
- Identify soft skills (improved communication, organization, etc.)
- Speak with project leads and other team members to understand the engineer's strengths and weaknesses.
- Provide feedback to the engineer about performance (more on that below).
Status updates
One of your most useful tools will be status updates. An easy failure mode as a manager is to not notice when an engineer is failing to make progress on a task. You should regularly ask for, either in writing or in a weekly call, a status update including the following:
- What have you accomplished since the last status update? This shouldn't be a laundry list of all work items, and shouldn't include things like "attended a meeting." These are demonstrable deliverables. "Worked on X, not yet completed" works here too. Generally, this should be a list of somewhere between 3 and 8 items.
- What you're planning on working on next. In an ideal world, everything from this list will end up on next week's "accomplished" list.
- Blockers: anything which blocks you from being able to complete your work. This could be "couldn't figure out how to do X," "didn't have permissions to access system Y," "blocked on feedback from person Z," etc.
Another important failure mode: blockers should generally not wait until a weekly call! There's a fine line to be walked between asking for help as soon as you hit any difficulties and stubbornly trying to hammer a square peg into a round hole. Be prepared to provide some feedback of "please spend more time trying to figure this out on your own." But you should help engineers reporting to you avoid a situation of identifying a blocker and then waiting multiple days before pointing it out.
Time boxing
Time boxing means to set a maximum amount of time to work on a task before touching base again. Time boxing has two valuable aspects to it:
- It prevents an engineer from spending unlimited time on a task.
- It's a communication tool between manager and engineer about how much time you think the task will take.
For example, without time boxing, imagine Alice (the manager) asks Bob (the engineer) to update the button on the homepage from red to green. Alice thinks this is a five minute task, but doesn't say anything about it. Bob decides the best implementation is to write a new AWS Lambda service which will generate a new version of the button's image using whatever color was specified in a query string parameter. Bob spends the next three weeks working on this, perfecting color gradient rules, optimizing the rendering, implementing a static file caching solution, etc. With great joy, Bob shows Alice the completed work. And Alice is horrified at the wasted time.
All that could have been avoided with a quick time boxing discussion, or at the very least an effort estimate. For example:
Alice: How much time do you think this task will take?
Bob: About three weeks.
Alice: Three weeks to change a button color? Why?
Bob: Well, we keep needing to change the images, so I figured I'd automate the process with an AWS Lambda service. I just need to spend some time learning Python first.
Alice: Let's just manually change the image this time.
When you timebox, follow these steps:
- Discuss the overall task
- Estimate how long both parties think the task will take, including "best case" and "worst case" analyses
- Set a timebox. This number doesn't necessarily need to be "time it will take to complete all the work." Instead, the timebox value could be "time before we should review work." It should never be longer than the worst case estimate, and is usually around or less than the best case estimate.
- After you've worked on the task for the given timebox time, touch base with your manager on your progress and discuss next steps.
Organization
An important aspect of FP Complete work is self managing. Have explicit discussions with your engineers about how to stay organized, especially for engineers who are new to remote work. Cover topics like:
- Where do you track your work items?
- Make sure to regularly check your company email.
- Set up notifications for messaging platforms (especially Slack).
- How do you get notified of meetings? Do you have calendar notifications enabled?
Performance review
We tend to be relatively lax about performance reviews at FP Complete. There is value in tracking performance and setting goals, so it's worth having at least informal discussions around performance. Some guidelines:
- When writing up performance reviews, be direct and personal.
- Good: "Your Rust coding skills are improving, but you're still having a hard time with understanding lifetimes."
- Bad: "The engineer demonstrates an overall proficiency in programming skills, with Rust being the primary target language. However, the engineer is still attempting to fully internalize usage of lifetimes."
- You should include both the good and the bad in performance reviews. Generally, the "shit sandwich" approach works best: provide positive feedback, negative feedback, and a positive tie-off. Example: "You've provided lots of valuable feedback on our team calls. Unfortunately, your attendance has been poor, missing at least half of the project meetings. Please work to ensure you show up on time to meetings going forward, your input has greatly improved the success of the project."
- Establish goals for the next period, usually 6-12 months. Goals should combine what the engineer wants to achieve with the needs of FP Complete. "Improve your skills with Kubernetes" would be a good starting point with a goal, though when possible defining something more concrete is best, e.g. "Demonstrate expertise with Kubernetes by setting up a new high availability deployment of the frobnicator application."
- Don't forget to include soft skills in performance. Engineers love working on improving technical skills, but often non-technical skills can make a much larger impact than you'd expect. Skill with writing, talking with customers, or making architecture diagrams would all fit in this.
Writing
This is a short guide and collection of tips for how to write blog posts and other kinds of marketing material for FP Complete.
How to write
Always identify, before you begin writing a blog post:
- Who is the target audience? You'll write a post quite differently if the audience is an experienced Haskeller versus a non-programmer
- What action you would ideally like this person to take.
- What this person should understand from reading the blog post.
- What this person should believe from reading the blog post.
From a business perspective, the goal of writing blog posts is to:
- Maximize the stream of people coming to our website
- Optimize the end state of those people when they finish with our website
Therefore, from a business perspective, we should judge the merit of a blog post on how many people we expect it realistically to attract, and the expected next actions for those people.
Blog posts should always include calls to action. The value of the blog post is judged on what we expect people to do, not the call to action itself. For example, if we have a call to action "give $1,000,000 to FP Complete for no reason at all," we have a low expectation that someone is going to do it.
Consult with the sales and marketing team to identify what business goals we should try to achieve with blog posts, based on current company objectives.
Efficient Meetings
With groups over 3, use live meetings for interactive discussion toward a clearly stated outcome, not for disseminating routine information. Keep attendee lists and meeting durations compact. Keep the meeting on topic and moving along. Send out information in advance rather than in the meeting. Be respectful of others’ time and logistics.
One of our strengths is our efficient, results-focused engineering culture. This includes efficient group communication and decision making. Much of our work is done asynchronously through documents, emails, instant messages, issue tickets, and shared repositories. Sometimes a live meeting with another person is the best way to make progress, whether in-person, by video, or by phone. We do these whenever helpful, and sometimes just to check in.
Larger meetings are different: their cost grows with duration and with number of attendees, and they become inefficient if not well organized. As our team has grown, meetings are more common, and should be run well. For any real-time meeting involving more than 3 people, effective immediately please follow these principles.
-
Disseminate information at least 24 hours in advance, not in the meeting. This allows time to read and consider. Meetings are for interactive discussion, problem solving, and decision – not for delivering fundamental information. (An exception may be made for very dense project management or scrum meetings, which are all about sharing fresh information in a highly structured and rapid manner.)
-
Arrive prepared. Check your email for notes you are expected to read in advance. Read them and gather your thoughts. Make notes if that helps. Send minor comments to the author rather than using up meeting time.
-
State the goal of the meeting. Declare in advance the decisions or creative outcomes that are needed by the end of the meeting, and that therefore drive the agenda of topics. Accomplishing the goal defines success for the meeting. A meeting whose goal is accomplished (or cannot be identified) should be ended (or canceled), the time used for other work tasks.
-
Choose a chairperson to run the meeting, keeping it on-topic and on-schedule. This person (the “chair” of the meeting) respectfully but clearly moves the discussion onward if an item is running long, is off-topic, is stuck on a less-important detail, or is ready to be delegated to a smaller group for post-meeting action.
-
State the duration of the meeting, usually an hour or less. Longer meetings may be broken into separate meetings, each with shorter attendee lists.
-
Keep the attendee list compact, freeing up as many as people as possible to do other work. Minor contributors (whose insights are not central to the meeting’s purpose) can send materials in advance, or answer short questions afterward, rather than having to attend the meeting. Also, attendees not needed for the remainder are free to leave.
-
Allow attendance by telecom, to avoid imposing time-consuming travel on your remote colleagues. For better communication use video where available, not just audio. Prefer in-person meetings for building relationships and for situations involving strong emotions.
-
Cancel unnecessary meetings, creating instead a document or online resource that delivers needed information and provides a place for colleagues to contribute feedback and ask questions. Often, most or all issues are resolved online and though 1-on-1 discussions.
-
Respond to meeting requests accurately, and let the organizer know if a time conflict arises. Rescheduling may disrupt a colleague’s schedule, so be considerate.
Meetings that might be longer or less organized include brainstorming sessions, social occasions, and off-topic but interesting lectures. These should be identified as such, and attendance is usually voluntary.
Our #1 goal is always to ensure project success. With well-organized meetings we can make well-informed decisions promptly, while making very efficient use of everyone’s time and skills. Use some of the time you save to have deeper conversations with one or two colleagues at a time, and of course to do your own personal work.
Big head/little head
These phrases (borrowed from Hebrew) refer to two different ways of relating to a task. “Big head” tries to see the large picture, adjust the specific task to meet the larger goals, and ask lots of clarifying questions. “Little head” does exactly what its told, without question.
There are times for both of these. But as smart engineers on the FP Complete team, we usually are expected to follow “big head” standards. This means that, when giving a task to another team member, you should give enough context for the team member to understand why he/she is performing that task. And when assigned a task, ask those clarifying questions, and propose alternatives as you see appropriate.
There is a cut-off point where there is too much analysis paralysis, and ultimately discussions need to halt. Also, there are times when there is significant time pressure, and we must simply jump into execution mode. Those cases should be exceptions, not the rule.
Customer Communications and Relationship Management
Most of the points and comments shared here are common practices and all of use these on a day-to-day basis. The purpose of the document is to refresh our day to day practices and allow us to be even better in day to day customer and relationship management.
-
Providing Cost and Time Estimates
It is best practice to not communicate any time or cost estimates to the customer if it relates to a new task, milestone or a project. Please gather all requirements to the best of your ability and arrange a short meeting slot with the Customer Success team to help create a proposal and / or agreement for the customer. Providing an estimate in writing or verbally to any customer can create customer relationship issues in future incase our estimates provided during a normal conversation are not accurate. -
Disagreement with the customer
If at any point a customer identifies a method, programming language or criteria which you don't agree with, politely advise that you'll check with the team and will get to them. Allow the customer to talk and share their feedback. At any point when it is imperative for you to share your disagreement with the customer, please provide your feedback and request or Customer Thoughts and feedback right away. It is a best practice that customer feels the ownership of what was originally. -
Stay in contact
It is best practice to stay in contact with the customer. If you are using an instant messaging tool like slack it is best to provide a summary of what was accomplished during the day. If you are working with a Lead engineer, it is best to provide a summary of accomplished work to the team lead so he can provide an update to the customer. -
ETA Management
It is always a best practice to provide an ETA to your clients for the task you are working on. Please be careful to add a buffer within your ETA as well stating that "provided no technical hurdles are encountered, my ETA will be.... (which should still include a buffer)" -
Customer Care
Customer Care 101: Use empathy statements to show you understand the customer's feelings or frustrations. -
Overreaction / Do not React
Never respond to angry comments. Allow the customer to voice their opinion and interject with helpful redirection when appropriate. -
Focus on the Goal
When a customer is upset for any reason, redirect the conversation back to the important issues and focus his attention on constructive solutions. -
Verbal Communication
Use words like "likely", "typically", "perhaps", "sometime", "possibly" or "occasionally" with customers who might not respond well to categorical words like "always" or "never". -
Agreement with the Customers
Find something to agree with the customer about. An agreement will result in collaboration and cooperation
Push vs pull model
FP Complete runs on a pull model. This model is collaborative, driven by ownership and focused on delivery. This means:
- Everyone should understand the broader goals, not just their individual tasks.
- Team members should take initiative to get what they need, instead of waiting for things to be handed to them with all details - be it information, context, support or new work.
- They should be proactive: ask questions, raise concerns early, propose ideas and keep things moving.
- While they are not expected to know everything, they are expected to clearly identify and manage dependencies. The task they own is their responsibility from start to finish, until it is formally handed off to someone else.
- Each person is a partner in the process, not just a task-taker. They help shape the work, co-own outcomes and contribute to the team's momentum.
- When this mindset is missing, it does not just appear as a lack of ownership, it impacts deliveries and productivity of the team.
- Lastly, team members are expected to make a reasonable effort to find answers before asking questions. Reaching out without any prior research shows a lack of initiative and creates unnecessary dependencies.