cassionData Analysis

Lesson 7 of 8

Unit · Someone else runs it

Written for someone with your job and none of your context

A handover is not a description of the code. It is the list of things you know that are nowhere in the repository — why that column is dropped, who to email when the export stops, and which number in the report someone will challenge.

PythonR135 minOECD DAC evaluation criteriaCore Humanitarian Standard (CHS)UNICEF indicator definitions

What a handover is for

Not “here is the code” — the code is in the repository and a competent successor can read it. A handover is the part that is not in the repository, and it is almost entirely a list of decisions and relationships.

The test: your successor gets the monthly export, it looks wrong, and they have to decide what to do. Everything they need for that is what the document contains.

The seven sections

# Handover: nutrition surveillance analysis
Written 2026-03-14 by [name], for whoever holds this next.

## 1. What this produces, and who reads it
A quarterly GAM estimate by commune, in the cluster report and the district
health office's monthly pack. The cluster coordinator reads the commune table
first and asks about anything above 10%.

## 2. Run it
    uv sync && uv run python run.py
Takes about four minutes. Outputs land in outputs/ and are safe to delete.

## 3. Where the data comes from, and who to ask
data/raw/muac-screening-YYYY-MM.csv — exported from the screening database on
the 5th of each month by [name, role, email]. If it does not arrive by the
10th, that is who to chase; it has been late three times in two years and the
cause was a permissions change each time.

## 4. Decisions that are not obvious from the code
- Commune names arrive spelled four ways. Normalisation is in src/clean.py.
  Ungrouped, the worst commune splits into four fragments and none looks
  alarming, which is how this went unnoticed for two rounds.
- Children with no age recorded (about 2%) are excluded from the age-
  disaggregated table but kept in the total. The cluster agreed this in
  March 2025; the alternative was excluding them everywhere, which moved the
  headline by 0.4 points.
- MUAC is the case definition, not weight-for-height. This is a screening
  dataset and there are no heights.

## 5. What breaks, and what it looks like
- A new water_source code stops the pipeline with "Unknown water_source
  values". It is usually a form change; map it in src/clean.py and tell
  [name].
- A row count outside 2,000-3,000 stops it. Usually a truncated download.
- If the report renders but a commune is missing, screening did not happen
  there; that is real and should be stated in the narrative.

## 6. What gets challenged
The commune ranking. Eleven of eleven adjacent communes have overlapping
intervals, so the chart supports "these three are above the district median"
and does not support ranking one commune against its neighbour. The caption
says so; keep it there, because it comes up every quarter.

## 7. What I would do next
The screening register has no follow-up measurement, so the MUAC 125mm
eligibility threshold cannot be evaluated as a discontinuity design. Adding
an eight-week re-measurement on a sample of children just above the cut-off
would make it estimable. I raised this in January; it is not funded.

Sections 4 and 6 are the ones that cannot be reconstructed. Everything else a successor could work out in a week.

Why section 4 is the whole document

Every exclusion, recode and threshold in the pipeline was a decision, and the code records what was decided while losing why. A successor reading df = df[df.age <= 20] knows what it does and not whether they may change it.

# Excluded: 14 children with recorded ages above 20 years in an under-5
# screening. These are data-entry errors (the age field accepts free text).
# Agreed with the screening lead 2025-03; they are excluded everywhere rather
# than corrected, because we cannot tell 2 from 20 from 12.
survey = survey[survey["age_months"] <= 60]
# The comment is the handover. Write it when you make the decision.

Write the comment when you make the decision, not at handover time. At handover time you will remember the decisions and not the reasons, which is exactly backwards.

Section 6, and why it is not defensive

Name the numbers that get challenged and what the answer is. Every recurring analysis has two or three, and a successor who does not know them will either capitulate to a challenge that has already been settled or re-open an argument that was closed.

This is institutional memory, and it is the first thing lost in a handover. It is also the cheapest to write down: three bullets.

Handover is not a document, it is a period

The document is necessary and it is not sufficient.

Have them run it while you are still there. Not watch you run it — run it themselves, from a fresh clone, on their own machine, with you available. Everything that fails is a gap in the repository or the document, and it is the only way to find those gaps.

Have them produce one real output. The next monthly report, not a test run. A successor who has produced one report has done the job once.

Leave the questions channel open for one cycle. One quarter, one month, whatever the cadence is. Most of what they need to ask arrives at the moment it first breaks.

What to write as you go

The handover document is much easier if it is not written at handover time.

Write it When
The decision comment When you make the decision
The “what breaks” entry The first time it breaks
The “what gets challenged” entry The first time it is challenged
The contact and the cadence When you set it up
The “what I would do next” Whenever you think of it

Keep it in the repository, in HANDOVER.md, in version control. A handover in someone’s email is a handover to one person.

The README and the handover are different documents

README Handover
For anyone who opens the repository For the person who takes it over
What it produces, how to run it Why it is the way it is
Stays short Can be long
Updated with the code Updated when a decision is made

A README that has grown into a handover has stopped being read, which loses both.

Report it whole

Continuity

  HANDOVER.md documents the analysis decisions, the upstream contacts and
  cadence, the known failure modes, and the findings that are routinely
  challenged. It is version-controlled and was last reviewed 2026-03-14.

  Every exclusion and recode in src/ carries a comment giving the reason and
  the date it was agreed.

  The incoming analyst ran the March cycle end-to-end from a fresh clone,
  with the outgoing analyst available. Two gaps were found and closed: the
  screening database export permission, and an undocumented commune-name
  variant.

The last paragraph is the evidence that the handover happened. A handover document nobody has executed is a document that has never been tested, and the two gaps it found are what it exists to find.

What comes next

The last lesson turns the course on this platform. Every claim it has made — read-only raw data, a pinned environment, deterministic output, checks that fail loudly, one template many outputs — is checkable in this repository, and the lesson is a tour of where.

Teach this lesson

The lesson as a slide deck, with the prose kept in the speaker notes rather than on the slide. Generated from this page, so it cannot fall out of step with it.

Start the slideshowRead the slides

The PDF needs no software and projects from any machine. The PowerPoint file is there to be edited — add your organisation's branding, cut a section for a shorter session, or merge two lessons into a workshop.