Engineering

The handover that actually worked, and the four I botched first

A handover is not a document dump. The test is whether the team ships without you in week one.

MobileByteSensei 10 min read
freelancingdocumentationcareers

TL;DR

My first four handovers were a 20-page document, a two-hour walkthrough, and a cheerful "message me if anything comes up". All four produced the same result: a month of unpaid Slack questions, and in two cases a request to come back and fix something I had explained in week one.

The fifth one worked, and the difference was a single change: instead of explaining the system, I had a member of their team ship a real change while I watched and said nothing useful. Three times, on three different parts of the system, before I left.

The test of a handover is not whether you explained it. It is whether they can do it — and that is only observable by having them do it.

The case this post is about

Handover four, which was my best attempt at the document approach:

HANDOVER.md                    21 pages
  architecture overview        4 pages, with diagrams
  module-by-module walkthrough 9 pages
  deployment runbook           3 pages
  known issues and gotchas     3 pages
  "who to ask about what"      2 pages
walkthrough call               2 hours, recorded
Q&A session                    1 hour

Thorough by any reasonable standard. The team said it was the best handover they had received.

The symptom

Thirty-one Slack messages in the following five weeks:

week 1   11 messages   "where does X live", "how do I regenerate Y"
week 2    8 messages   "the sync is doing something odd"
week 3    6 messages   "can you look at this PR?"
week 4    4 messages   "we broke the iOS build"
week 5    2 messages

About nine hours of unpaid time, and I answered all of it because the alternative was a bad reference.

And the content of the questions was the finding:

answered in HANDOVER.md:        19 of 31   (61%)
answered in the recording:       7 of 31
genuinely new:                   5 of 31

Sixty-one percent of the questions were answered in a document they had read and praised. Not because they were careless — because reading an explanation does not produce the ability to act, and under time pressure asking me was faster than searching 21 pages.

The two call-backs:

"the sync queue is dropping items"  → they had changed the bounded channel's
                                      overflow policy, which page 14 explains
"the iOS framework won't link"      → a target had been removed from the shared
                                      module; page 17 covers the target list

Both were covered. Both recurred. I had transferred information and not capability.

Why the obvious things did not work

"Write a better document." Twenty-one pages was already too long to search under pressure, and the questions were in it. Length was the problem, not the remedy.

"Record more video." The recording answered seven questions and nobody watched it after week one. Video is worse than text for the "where is X" question, which is most of them.

"Hold a longer Q&A." A Q&A answers the questions people can think of while sitting in a meeting. The real questions arrive in week two, with a deadline attached, in a context the meeting did not cover.

"Charge for the post-handover support." I did this on handover three — a retained 2 days/month. It is a reasonable commercial arrangement and it made the dependency permanent rather than transferring it, which is the opposite of the goal.

The actual mechanism

A handover transfers two different things, and I was only doing one:

Information — where things are, how they work, why decisions were made. A document transfers this adequately, and it is the easy half.

Capability — the ability to make a change, verify it, and ship it. This is procedural knowledge, and reading about it does not produce it. It is produced by doing it, with the failure modes encountered and recovered from.

The second one has a property the first does not: it is testable. "Did I explain the deployment process" is unfalsifiable. "Did Priya deploy to staging, unaided, while I sat on a call and said nothing" has a yes or no answer.

Written down, a handover plan is therefore a list of capabilities with a pass condition each, and the scoring rule is what keeps it honest:

from dataclasses import dataclass, field

@dataclass
class Task:
    capability: str
    attempts: list[str] = field(default_factory=list)   # "unaided" | "prompted" | "took-over"

    @property
    def verdict(self):
        if not self.attempts:
            return "untested"
        # Only the LAST attempt counts, and only "unaided" passes. A task I talked
        # someone through is evidence that I can explain it, which is the thing that
        # was never in doubt.
        return "transferred" if self.attempts[-1] == "unaided" else "not-yet"

def readiness(tasks, days_left):
    untested = [t for t in tasks if t.verdict == "untested"]
    not_yet = [t for t in tasks if t.verdict == "not-yet"]

    for t in tasks:
        print(f"  {t.verdict:<12} {t.capability:<34} {' → '.join(t.attempts) or '—'}")

    if untested:
        # An untested capability is the dangerous category: it looks like the others
        # on a document, and nothing has demonstrated it. Never count it as covered.
        return (f"NOT READY — {len(untested)} capability(ies) never attempted, "
                f"{days_left}d left. Schedule these first; they need two attempts each.")
    if not_yet:
        return f"NOT READY — {len(not_yet)} need another unaided attempt"
    return "READY"

With four days left, scored against what had actually happened:

  transferred  deploy to staging                  prompted → unaided
  transferred  roll back a bad release            took-over → prompted → unaided
  not-yet      rotate the signing certificate     prompted
  untested     restore from backup                —
  untested     on-call escalation path            —

NOT READY — 2 capability(ies) never attempted, 4d left. Schedule these first;
they need two attempts each.

Two of five had never been attempted, and both were in the handover document in full prose — which is exactly why the document felt complete. The took-over → prompted → unaided progression on the rollback row is the shape this is looking for, and it took three sessions; the two untested rows needed at least two sessions each, which is a scheduling fact a document cannot surface.

And there is a specific trap in the explanation mode: as the person who built it, I answer questions in about thirty seconds, so asking me is always cheaper for them than developing the capability. Every answered question reinforces the dependency, which is why the Slack volume decayed slowly rather than stopping.

A handover transferring two things: information, which a document conveys adequately and is unfalsifiable, and capability, which is procedural and only produced by doing — with the trap that an available author answers in thirty seconds, so asking is always cheaper than developing the capability and every answer reinforces the dependency

Explaining a system is unfalsifiable. Watching someone use it is a test. A handover without that test has transferred information and left the capability with you.

The fix

Three supervised changes, a one-page document, and a silence rule.

1. Three real changes, shipped by them, in the last week:

## Handover exercises (week 12, with me present and silent)

1. A small feature change end to end
   → add a "retry now" action to the sync screen
   Must: write it, test it, get it reviewed, merge it, deploy to staging.

2. An incident
   → I break staging on Tuesday morning without telling them which part.
   Must: diagnose it from the logs and dashboards, fix it, deploy.

3. A dependency and release task
   → bump the Ktor version and produce a release build for both platforms.
   Must: handle the two breaking changes, run the full matrix, sign the iOS build.

Three exercises, chosen because they cover the three things the previous handovers' questions clustered around: making a change, diagnosing a problem, and releasing.

2. The silence rule, which is the hard part:

## My role during an exercise
I am on the call with my microphone muted. I do not answer questions during the
exercise. If they are stuck for more than 20 minutes, they say so and I give
ONE pointer — to a document or a file, never an answer.

Afterwards we debrief: what was hard, what was missing, what should the
document say.

Twenty minutes of being stuck is where the learning is, and answering at minute three is the habit I had to break. The "one pointer, to a document" constraint is what converts a stuck moment into a documentation fix rather than into another answer only I can give.

3. The document, which got shorter because the exercises told me what belonged in it:

# Handover (1 page)

## Start here
`./scripts/setup.sh` — if it fails, that is a bug, file it.

## The three things you will need in month one
1. Making a change → docs/making-a-change.md  (written by Priya after exercise 1)
2. When it breaks   → docs/runbook.md          (written by Tom after exercise 2)
3. Releasing        → docs/release.md          (written by Priya after exercise 3)

## Decisions you will want the reasons for
docs/adr/ — 14 records. Read 003 (sync queue) and 011 (why SQLDelight) first.

## Things I would do next, in priority order
1. … 2. … 3. …   (my opinion, not a commitment)

They wrote the three procedural documents, not me. That is the detail that made them useful: written by someone who had just done the task for the first time, so they contain the steps a newcomer actually needs rather than the steps I could not see because I knew them.

4. And a bounded support window, stated in the contract:

## Post-engagement support
Two weeks of email support, up to 2 hours total, included.
After that: £400/day, minimum half a day, scheduled.

Bounded and priced rather than open-ended and free. The two-hour limit also gave them a reason to check the document first, which is the behaviour the exercises were building.

How this turned out

Handover five, against the previous four:

                              handovers 1–4 (mean)   handover 5
pages of documentation                  18                 1 + 3 (theirs)
my hours in the handover week            6                12
Slack messages, first 5 weeks           27               4
my unpaid hours after leaving           ~8               0.5
call-backs for paid rework           0.5 (2 of 4)         0

Twelve hours instead of six during the week — the exercises cost me time — and 0.5 unpaid hours afterwards instead of eight.

The four questions in five weeks:

week 1   "is ADR-007 still accurate?"              → yes (2 min)
week 2   "we're adding a target, anything to know?" → pointed at ADR-011 (5 min)
week 4   "would you do X or Y here?"               → an opinion, 20 min
week 6   "thanks, all good"

None was "where does X live". The procedural questions were gone, because they had done each of the three things once.

The exercises themselves, which is where the real value showed:

exercise 1 (a feature change)
  time: 3.5 hours · stuck twice · 1 pointer used
  found: the PR template referenced a lint rule that had been removed
  → fixed, and it is in making-a-change.md

exercise 2 (the incident)
  time: 1 hour 10 min to diagnose, 25 min to fix · 0 pointers
  found: the runbook did not exist; Tom wrote it from what he had just done
  → runbook.md, 1 page, written by the person who needed it

exercise 3 (dependency bump + release)
  time: 5 hours · stuck three times · 2 pointers
  found: the iOS signing step required a credential only I had
  → moved into the team's vault before I left. This would have blocked
    their first release entirely.

Exercise 3 is the one that justifies the whole approach: a credential only I had would have stopped their next release, and no amount of documentation review would have surfaced it. Having someone actually do the release found it in five hours.

One honest limit: this requires the client to allocate two people for roughly two days in the final week, and one engagement since has refused — the team was mid-crunch and could not spare them. I documented the exercises as not done in the handover note and set expectations accordingly, and that handover produced 14 Slack messages. The method works; it needs the client's time, and when they cannot give it, saying so plainly is the next best thing.

What this generalizes to

Explaining is unfalsifiable; observing is a test. This applies to onboarding, to teaching, to training a successor, to any documentation of a process. "Did they understand" has no answer. "Did they do it unaided" does.

Let the person who just learned it write the document. They know which steps are non-obvious, because they were non-obvious an hour ago. An expert writing a procedure omits exactly the parts that make it hard.

An available expert prevents capability transfer. Answering in thirty seconds is always cheaper for the asker than learning, so availability sustains dependency. Being deliberately slow, or silent, is the mechanism — and it is uncomfortable.

The gap you cannot document is the one only an attempt finds. A credential only I held, a lint rule that no longer existed, a missing runbook. None would have appeared in a review of my documentation, and all three appeared within five hours of someone trying to do the work.

Keep reading

This is part of Freelancing & consulting for engineers — the commercial side of the work, written from the mistakes. Follow MobileByteSensei for the rest.

One post a week, no digest

New writing when it lands. No roundups, no course pitch, no "10 tips".

Follow by RSS