In the last few years I've been leading a team that has adopted ensemble programming and pair programming as the main practice to deliver production code. We have evolved cues that have a precise meaning for team members and that make communication more effective, especially when some of these phrases are used every few minutes.
I considered various terms to indicate this set of phrases, and discarded most of them:
- mantra (a slogan repeated frequently, but often to yourself, and with spiritual implications),
- shibboleth (implies a closed group having secret handshakes and hiding from an external force)
- catchprase (a signature phrase associated with a specific character)
- formula (works in other Romance languages but has many other meanings in a English context)
Formula could be considered a loan word from Italian, but I think its original etimology fits:
1630s, "words used in a ceremony or ritual" (earlier as a Latin word in English), from Latin formula "form, draft, contract, regulation;"
To keep with the metaphor of an ensemble of actors or musicians performing, I found cue was fitting too:
the trigger for an action to be carried out at a specific time
A few roles in ensemble programming
![]() |
The rotation of roles visualized on a Miro board |
This experience is in the context of remote ensemble programming, where there is a single audio medium shared across a virtual room, and limited surface space for visual cues such as body language or facial expression. One of two monitors, or part of a monitor, would usually be dedicated to 2 or 3 other camera feeds, with a digital whiteboard or an IDE on a shared screen being the place of operation. This isn't to say that paying attention to your colleagues isn't prioritized; rather than making use of continuously-improved verbal language is one way to achieve that.
Within this setting, a few roles are assumed by the team members participating into a particular ensemble:
- the Driver inputs all changes into a working copy of the codebase.
- the Navigator has the responsibility to coordinate the group into the next decision it needs to take, and verbalize all changes for the Driver to enact.
- other ensemble members assume roles as needed and without even noticing, actively contributing to the discussion. They might help with diagrams or note-taking, or notice code smells or other people dynamics since they can dedicate their attention to something different than the next code change.
In this team, a rotation based on committing and pushing the last change emerged. A strict rotation where a navigator remains in that role for the whole duration of the cycle also emerged, mostly to keep a level playing field across all levels of seniority and giving the space to everyone to lead the next change.
The cycle described here is the one of starting a new screen share session; pulling the latest version of the code; making a change and pushing it to make it available to the rest of the group. This micro-iteration has an associated cycle time, which is where I believe the term came from. After each cycle, the previous Navigator would rotate in to become a Driver; someone else would become a Navigator.
Many of these cues are commonly uttered from the Navigator or the
Driver, but they are not limited to them. Consider this list harvested
in a design patterns sense: extracted from repeated real world
experience; no claim to completeness. It is however limited to a single
team, operating in various context and changing its membership over
time. Crediting Kevin Rutherford
for introducing ensemble programming when this team was newly formed at
the beginning of 2020, and helping the team honing in on particular
solutions over time.
At the beginning of a cycle
"What do you want to see?"
The Driver may start a cycle asking this to the Navigator, to relieve pressure on deciding a direction quickly. To ease into the role of Navigator, there is little downside in spending time observing or understanding some area of the code, rather than attempting to change it immediately.
In the context of new ensemble members, this cue also relinquishes control explicitly to the Navigator. If you are used to the person with control of the keyboard showing what they mean, you will instead seen a Driver waiting for instructions.
"I'm just a pair of hands" or "Waiting for instructions"
Indeed, the Driver uses these or other cues to remark how they are not taking decisions just because they happen to hold the keyboard or the mouse that can perform changes. The Navigator has the responsibility to coordinate. The driver can focus on efficiently executing a move.
"Let's go to the IDE/"the code"/Github/maps/Miro"
At the beginning of a new cycle, or triggering a new cycle, an ensemble member suggests to change the visual support to fit the discussion. This might involve not sharing a screen anymore if that medium supports collaboration natively e.g. Miro as a digital whiteboard.
For example, Github could be useful to navigate unfamiliar repositories; a whiteboard is vital for remote Eventstorming or for diagrams; maps indicate a set of long-lived architectural diagrams for context, dependencies or separation of concerns.
During a cycle
![]() |
I think this is where the phrase comes from. But lack of verbalization of intention should be the exception, not the rule. |
"Make it so"
The group has shared understanding of a change that needs to be applied. For example, we slice a change into many small steps; there is low risk because we already performed a few of these slices; uncertainty might lie more related to what can be discovered from the compiler or a test suite reacting to the change; or a refactoring move may need to be applied to a different part of the codebase, in what we suspect will not require new design decisions.
After having stated the change they'd like to see, the Navigator hands over control to the Driver with this cue, and lets them loose in achieving it with their preferred tooling: VSCode, Vim, grep, even an LLM. The separation of concerns is between the destination, and how to get there.
"Rename the ... class/function/method/variable and all references"
The
Navigator directs the Driver at a high level of abstraction. The Driver
is a intelligent IDE and applies this change predictably as they both
understand what the outcome should look like. In case the Driver runs
into trouble such as unforeseen situations, they stop and ask for more
precise direction.
"Can we scribe on the board something about ...?"
The Driver or the Navigator asks other members of the ensemble to take a note about something that we should look at later. They could just ask to take a note, but we picked the word scribe from Eventstorming practices to identify whoever is currently responsible for creating artifacts to a shared digital board.
Assigning this role, for example, to the third ensemble member in the rotation helps avoiding concurrency clashes, with multiple people trying to take the same note.
"From the back of the room, ..."
Other
roles than Driver or Navigator hand out suggestions or considerations,
without wanting to interrupt or override the navigator's intention. The
Navigator still coordinates making a decision, but the other ensemble
member can contribute specific knowledge or cues that help the group
make progress without taking away the opportunity for the Navigator to
exercise their skills.
The expression comes loosely from the phrase "leading from the back of the room"; I've seen this role referred to as the Rear Admiral in some ensemble programming literature, turning the Driver and Navigator rallying metaphor into a naval one where everyone helps running the ship.
"... can be a rabbit hole"
A problem we face is recognized as something that might be taking away from the momentum of the group, or its overall importance is controversial. It might be more productive to mitigate it now, rather than digging into its ultimate causes. The group can agree to postpone the discussion of this problem, to focus on the next test to write or to make green. If the problem makes it very difficult to make progress, it will keep emerging. Rabbit hole is just internet slang for an engrossing and time-consuming topic such as programming language trade-offs; a troublesome library upgrade; a non-deterministic test; or large-scale architectural changes that require a lot of evidence collection and consideration.
At the end of a cycle
![]() |
Group peer pressure helps doing better than that |
"Anything else for this cycle?"
The Driver is asking the Navigator about whether the intended scope has been achieved. Confirmation will start a commit process if no other checks or changes are necessary.
Sometimes the Driver acts as a preemptive time keeper, reminding everyone uncommitted code is work in progress and the bigger it gets, the higher the risk of progress being lost if it triggers inadvertent behavior changes in the codebase.
"End of cycle" or "Let's rotate"
The Navigator decides it's time to rotate the roles, considering what has been learned in this cycle enough to perform a switch without loss of context. The cycle might have been focused on investigation or reading code, given in this case it ends without a commit. Even if there is an attempted change at play, the knowledge gathered can led to the next cycle to regenerate the same git diff quickly, or to find a safer or easier path through that change.
"make check and commit"
The navigator communicates it's time to commit what we have done. Substitute make check with your local testing command of choice; it's just a team convention to capture a set of compilation, static analysis and tests that we deem acceptable to run before every commit. Other more specific or intensive testing can be left to a Continuous Integration build as a safety net that will constitute a longer feedback loop. Normally, the commit is followed by a push and a default end of the current cycle.
"What [commit] message would you like?"
A Driver understand we are ready to commit a change, and invites the Navigator to summarize and describe it. This is an opportunity, if the team wishes so, to try other cues to repeatedly nudge towards a certain behavior and getting into a new habit. For example, you could experiment with having Drivers ask "Why are we doing this change?" for a whole day.
No comments:
Post a Comment