ЁЯПл The SchoolтА║ЁЯЫая╕П SREтА║ЁЯж║ рдзрдбрд╛ 08 тАФ Incident command: рднреВрдорд┐рдХрд╛, рд▓рдп рдЖрдгрд┐ handoff
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯж║ рдзрдбрд╛ 08 тАФ Incident command: рднреВрдорд┐рдХрд╛, рд▓рдп рдЖрдгрд┐ handoff

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 08 ┬╖ рдорд╛рдЧреЗ: lesson-07-capacity-planning ┬╖ рдкреБрдвреЗ: lesson-09-reliability-math


ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ

рдзрдбрд╛ 07, рдЕрдзрд┐рдХ incident рджрд░рдореНрдпрд╛рди рдкрдердХ рд╕реНрд╡рддрдГрд▓рд╛ рдХрд╕реЗ рд╕рдВрдШрдЯрд┐рдд рдХрд░рддреЗ. Observability school рдЪрд╛ рдзрдбрд╛ 10 severity, incident рдЪреА рдШрдбреНрдпрд╛рд│реЗ (detect, acknowledge, mitigate, resolve) рд╢рд┐рдХрд╡рддреЛ, рдЖрдгрд┐ рддреНрдпрд╛рдЪреЗ рдзрдбреЗ 11тАУ12 root cause рдЖрдгрд┐ postmortem. рд╣рд╛ рдзрдбрд╛ рдореНрд╣рдгрдЬреЗ command рдЪреА рд░рдЪрдирд╛: рдЪрд╛рд░ рднреВрдорд┐рдХрд╛, status-update рдЪреА рд▓рдп, рдЖрдгрд┐ shift рд╕рдВрдкрд▓реНрдпрд╛рд╡рд░рдЪреЗ handoff. sre/crew.py рдордзреАрд▓ IncidentLog рдЖрдгрд┐ sre/demo.py рдордзреАрд▓ command().

ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ

рд░рд╛рддреНрд░реА 23:00 рд▓рд╛ рд╡реЗрд│рд╛рдкрддреНрд░рдХрд╛рдЪреА рдЗрдорд╛рд░рдд рдЕрдВрдзрд╛рд░рд╛рдд рдЬрд╛рддреЗ. ЁЯМС

рдкрд╣рд┐рд▓реА рд░рд╛рддреНрд░ тАФ рдХреЛрдгрддрд╛рд╣реА plan рдирд╛рд╣реА. рдХрддрд░рд┐рдирд╛ рдЖрдгрд┐ рджреАрдкрд┐рдХрд╛ рджреЛрдШреАрд╣реА рджреБрд░реБрд╕реНрддреА рд╕реБрд░реВ рдХрд░рддрд╛рдд. рддреНрдпрд╛ рдПрдХрдореЗрдХреАрдВрдЪреЗ рдХрд╛рдо рдЙрд▓рдЯрд╡рддрд╛рдд. рдЬрд╡рд│рдЬрд╡рд│ рджреЛрди рддрд╛рд╕ рдХреЛрдгреАрдЪ рдореБрдЦреНрдпрд╛рдзреНрдпрд╛рдкрдХрд╛рдВрдирд╛ рдХрд╛рд╣реАрд╣реА рд╕рд╛рдВрдЧрдд рдирд╛рд╣реА. рдордзреНрдпрд░рд╛рддреНрд░реА рдХрддрд░рд┐рдирд╛ рдШрд░реА рдЬрд╛рддреЗ тАФ рдЖрдгрд┐ рддреА рдиреЗрдордХреЗ рдХрд╛рдп рдХрд░рдд рд╣реЛрддреА рддреЗ рдХреЛрдгрд╛рд▓рд╛рдЪ рдорд╛рд╣реАрдд рдирд╕рддреЗ.

рджреБрд╕рд░реА рд░рд╛рддреНрд░ тАФ рдПрдХ plan. рджреАрдкрд┐рдХрд╛ рдореНрд╣рдгрддреЗ: "рдореА incident commander рдЖрд╣реЗ. рдореА рджреБрд░реБрд╕реНрддреА рдХрд░рдд рдирд╛рд╣реА тАФ рдореА рдиреЗрддреГрддреНрд╡ рдХрд░рддреЗ." рддреА рдмреЛрдЯ рджрд╛рдЦрд╡рддреЗ: "рдХрддрд░рд┐рдирд╛, рддреВ рджреБрд░реБрд╕реНрддреА рдХрд░. рдРрд╢реНрд╡рд░реНрдпрд╛, рддреВ рджрд░ рдЕрд░реНрдзреНрдпрд╛ рддрд╛рд╕рд╛рдиреЗ рд▓реЛрдХрд╛рдВрдирд╛ рдХрд╛рдп рдЪрд╛рд▓рд▓реЗ рдЖрд╣реЗ рддреЗ рд╕рд╛рдВрдЧрдд рд░рд╛рд╣рд╛. рдЖрдгрд┐ рд▓рд╣рд╛рди рдЖрд╣реЗ рддреЛрдкрд░реНрдпрдВрдд рдХрд╛рдп рдШрдбрддреЗ рддреЗ рдореАрдЪ рд▓рд┐рд╣реВрди рдареЗрд╡рддреЗ." рдордзреНрдпрд░рд╛рддреНрд░реА рджреАрдкрд┐рдХрд╛рдЪреА shift рд╕рдВрдкрддреЗ. рддреА рдЕрд╢реАрдЪ рдирд┐рдШреВрди рдЬрд╛рдд рдирд╛рд╣реА. рддреА crew-5 рд▓рд╛ рд╕рдЧрд│реЗ рд╕рд╛рдВрдЧрддреЗ тАФ рдХрд╛рдп рдмрд┐рдШрдбрд▓реЗ рдЖрд╣реЗ, рдХрд╛рдп рдХрд░реВрди рдкрд╛рд╣рд┐рд▓реЗ, рдХреЛрдг рдХрд╛рдп рдХрд░рдд рдЖрд╣реЗ тАФ рдЖрдгрд┐ crew-5 рдореНрд╣рдгрддреЗ: "I have command." рддреНрдпрд╛рдирдВрддрд░рдЪ рджреАрдкрд┐рдХрд╛ рдЬрд╛рддреЗ.

рдмрд┐рдШрд╛рдб рддреЛрдЪ. рджреБрд╕рд░реА рд░рд╛рддреНрд░ рд╢рд╛рдВрдд рдЕрд╕рддреЗ, рдЖрдгрд┐ рд▓рд╡рдХрд░ рд╕рдВрдкрддреЗ.

ЁЯЧ║я╕П рдЖрдХреГрддреА

flowchart LR
    ic["ЁЯж║ IC тАФ Dipika<br/>leads, decides, does NOT fix"] --> ops["ЁЯФз ops тАФ Katrina<br/>hands on the system"]
    ic --> comms["ЁЯУг comms тАФ Aishwarya<br/>update every 30 min"]
    ic --> scribe["ЁЯУЭ scribe<br/>the timeline"]
    ic -->|"00:00 handoff:<br/>state, actions, roles"| ic2["ЁЯж║ IC тАФ crew-5<br/>'I have command' тЬУ"]
    bad["without roles: 5 problems<br/>no IC ┬╖ 110 min with no update<br/>Katrina left holding ops"]

ЁЯЧ║я╕П рдХрд╛рдврд▓реЗрд▓реА рдЖрдХреГрддреА + рдПрдХ lab: https://school-edh.pages.dev/sre/lesson-diagrams.html#l08

тЭУ рдХрд╛рдп

ЁЯдФ рдХрд╛

рдХрд╛рд░рдг incident рдордзреНрдпреЗ рдЕрдбрдЪрдг рдмрд╣реБрддреЗрдХ рд╡реЗрд│рд╛ рдмрд┐рдШрд╛рдб рдирд╕рддреЗ тАФ рддреА рддреНрдпрд╛рдЪреНрдпрд╛ рднреЛрд╡рддреАрдЪреЗ рд▓реЛрдХ рдЕрд╕рддрд╛рдд: рджреБрд╣реЗрд░реА рдХрд╛рдо, рдкрд░рд╕реНрдкрд░рд╡рд┐рд░реЛрдзреА рдмрджрд▓, рджрд░ рдкрд╛рдЪ рдорд┐рдирд┐рдЯрд╛рдВрдиреА "рдХрд╛рд╣реА рдмрд╛рддрдореА?" рд╡рд┐рдЪрд╛рд░рдгрд╛рд░реЗ рдиреЗрддреЗ, рдЖрдгрд┐ рдХреЛрдгреА рдШрд░реА рдЧреЗрд▓реНрдпрд╛рд╡рд░ рд╣рд░рд╡рд▓реЗрд▓реА рдорд╛рд╣рд┐рддреА. рднреВрдорд┐рдХрд╛ рдЖрдгрд┐ рд▓рдп рд╕реНрд╡рд╕реНрдд рдЖрд╣реЗрдд, рдЖрдгрд┐ рддреНрдпрд╛рдВрдЪреНрдпрд╛рдореБрд│реЗ рддреЗрдЪ рд▓реЛрдХ рддрд╛рдгрд╛рдЦрд╛рд▓реА рдЦреВрдк рдЪрд╛рдВрдЧрд▓реЗ рдХрд╛рдо рдХрд░рддрд╛рдд.

ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)

sre/crew.py рдордзреАрд▓ IncidentLog(events, update_every=30) events рдШреЗрддреЗ (minute, kind, тАж) тАФ role, update, handoff (role, from, to, acknowledged), leave, resolve тАФ рдорд┐рдирд┐рдЯреЗ 23:00 рдкрд╛рд╕реВрди рдореЛрдЬрд▓реЗрд▓реА. check() рддреНрдпрд╛рд▓рд╛ рд╕рд╛рдкрдбрд▓реЗрд▓реНрдпрд╛ рдЕрдбрдЪрдгреА рдкрд░рдд рджреЗрддреЗ: рдХрдзреАрдЪ рдиреЗрдорд▓реЗрд▓реА рдирд╕рд▓реЗрд▓реА рднреВрдорд┐рдХрд╛, рд▓рдпреАрдкреЗрдХреНрд╖рд╛ рдореЛрдареЗ рджреЛрди updates рдордзреАрд▓ рдЕрдВрддрд░, рднреВрдорд┐рдХрд╛ рд╣рд╛рддрд╛рдд рдЕрд╕рддрд╛рдирд╛рдЪ рдирд┐рдШреВрди рдЧреЗрд▓реЗрд▓реА рд╡реНрдпрдХреНрддреА, acknowledge рди рдХреЗрд▓реЗрд▓реЗ handoff, ops рд╕реБрджреНрдзрд╛ рдХрд░рдгрд╛рд░реА IC. command() рджреЛрдиреНрд╣реА рд░рд╛рддреНрд░реА рддрдкрд╛рд╕рддреЗ.

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛

python3 sre/demo.py command
python3 - <<'EOF'
import sys; sys.path.insert(0, "sre"); from crew import IncidentLog
log = IncidentLog([(0, "role", "Dipika", "IC"), (2, "role", "Dipika", "ops"), (3, "role", "Aishwarya", "comms"),
                   (4, "role", "Katrina", "scribe"), (5, "update"), (50, "update"),
                   (60, "handoff", "IC", "Dipika", "crew-5", False), (61, "leave", "Dipika"), (90, "resolve")])
probs, mins = log.check()
print(f"{mins} min, {len(probs)} problems:")
for p in probs: print(" -", p)
EOF

тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ

command рд╣реЗ рдЫрд╛рдкрддреЗ:

тФАтФА without roles: the timetable service is down at 23:00 ┬╖ resolved after 110 min ┬╖ 5 problem(s)
   тЬЧ 00:00 Katrina went off shift still holding ops тАФ nobody holds it now
   тЬЧ no IC was ever named
   тЬЧ no comms was ever named
   тЬЧ no scribe was ever named
   тЬЧ 23:00 no status update for 110 min (rhythm: every 30)
тФАтФА with incident command: the timetable service is down at 23:00 ┬╖ resolved after 100 min ┬╖ 0 problem(s)

рддреБрдордЪрд╛ snippet рд╣реЗ рдЫрд╛рдкрддреЛ:

90 min, 6 problems:
 - 00:00 IC handoff Dipika тЖТ crew-5 never acknowledged тАФ two people think they lead
 - 00:01 Dipika went off shift still holding IC тАФ nobody holds it now
 - 00:01 Dipika went off shift still holding ops тАФ nobody holds it now
 - 23:05 no status update for 45 min (rhythm: every 30)
 - 23:50 no status update for 40 min (rhythm: every 30)
 - the IC is also hands-on in ops тАФ nobody is watching the whole incident

ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ

рднреВрдорд┐рдХрд╛рдВрдЪреА рдлрдХреНрдд рдирд╛рд╡реЗ рдЕрд╕рдгреЗ рдкреБрд░реЗрд╕реЗ рдирд╛рд╣реА. рддреБрдордЪреНрдпрд╛ snippet рдордзреНрдпреЗ рдкреНрд░рддреНрдпреЗрдХ рднреВрдорд┐рдХрд╛ рдиреЗрдорд▓реА рд╣реЛрддреА, рдЖрдгрд┐ рддрд░реАрд╣реА рддреНрдпрд╛рдд рд╕рд╣рд╛ рдЕрдбрдЪрдгреА рд╣реЛрддреНрдпрд╛: IC рджреБрд░реБрд╕реНрддреАрд╣реА рдХрд░рдд рд╣реЛрддреА, updates 45 рдЖрдгрд┐ 40 рдорд┐рдирд┐рдЯрд╛рдВрдкрд░реНрдпрдВрдд рд▓рд╛рдВрдмрд▓реЗ, рдЖрдгрд┐ handoff рдХрдзреАрдЪ acknowledge рдЭрд╛рд▓реЗ рдирд╛рд╣реА тАФ рдореНрд╣рдгреВрди рджреАрдкрд┐рдХрд╛ рдЧреЗрд▓реНрдпрд╛рд╡рд░ command рдХрд┐рдВрд╡рд╛ ops рдХреЛрдгрд╛рдХрдбреЗрдЪ рдирд╡реНрд╣рддреЗ. рд╢рд╛рдВрдд рд░рд╛рддреНрд░ рдкреНрд░рддреНрдпреЗрдХ рдирд┐рдпрдорд╛рдд рдЙрддреНрддреАрд░реНрдг рдЭрд╛рд▓реА, рддреНрдпрд╛рдд 00:00 рдЪреЗ handoff рд╕реБрджреНрдзрд╛, рдЬреЗ crew-5 рдиреЗ рд╕реНрд╡реАрдХрд╛рд░рд▓реЗ. (рдпрд╛ runs рдордзреАрд▓ resolve рд╣реЛрдгреНрдпрд╛рдЪреЗ рд╡реЗрд│ рдЧреЛрд╖реНрдЯреАрдЪрд╛ рднрд╛рдЧ рдЖрд╣реЗрдд, model рддреЗ рдЧрдгрдд рдирд╛рд╣реА.)

тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд

Handoff рдЪрд╛ template рд╕рдЧрд│реНрдпрд╛рдВрдирд╛ рд╕рд╛рдкрдбреЗрд▓ рдЕрд╢рд╛ рдард┐рдХрд╛рдгреА рдареЗрд╡рд╛ (incident channel рдЪрд╛ pinned message):

IC HANDOFF тАФ timetable outage тАФ 00:00
state:     timetable API 40% errors, database failover done at 23:40, errors falling
tried:     rolled back release 2026.09.27-2 (no change); failed over DB (helped)
next:      confirm replica lag < 5 s, then raise read traffic
roles:     IC crew-5 (from Dipika) ┬╖ ops Katrina ┬╖ comms Aishwarya (next update 00:30) ┬╖ scribe crew-5
incoming:  "crew-5: I have command."

incident.io, PagerDuty, FireHydrant рдЖрдгрд┐ Rootly рд╕рд╛рд░рдЦреА tools incident channel рддрдпрд╛рд░ рдХрд░рддрд╛рдд, рднреВрдорд┐рдХрд╛ рд╡рд╛рдЯрддрд╛рдд рдЖрдгрд┐ chat рдордзреВрди timeline рдареЗрд╡рддрд╛рдд. рдЦрд▒реНрдпрд╛ account рд╡рд░ тАФ PagerDuty рдЪреНрдпрд╛ API (Events API v2) рдиреЗ command line рд╡рд░реВрди incident рдЙрдШрдбрд╛:

curl -s -X POST https://events.pagerduty.com/v2/enqueue -H "Content-Type: application/json" -d '{
  "routing_key": "'"$PD_ROUTING_KEY"'", "event_action": "trigger",
  "payload": {"summary": "timetable API 40% errors", "source": "timetable", "severity": "critical"}}'

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ рдЖрд╣реЗ: рдпрд╛ рдорд╣рд┐рдиреНрдпрд╛рдд 30 рдорд┐рдирд┐рдЯрд╛рдВрдЪрд╛ tabletop exercise рдХрд░рд╛: рдПрдХ рдХрд╛рд▓реНрдкрдирд┐рдХ outage, рдиреЗрдорд▓реЗрд▓реА IC, updates рдЯрд╛рдХрдгрд╛рд░реА comms lead, рдЖрдгрд┐ рдордзреНрдпреЗрдЪ рдПрдХ handoff. рдкрд╣рд┐рд▓реНрдпрд╛рдЪ рд╡реЗрд│реА рдиреЗрд╣рдореА рдПрдЦрд╛рджреА рдЙрдгреАрд╡ рд╕рд╛рдкрдбрддреЗ.

тПня╕П рдкреБрдвреЗ

рднрд╛рдЧ 3: рдЕрдкрдпрд╢ рдЧреГрд╣реАрдд рдзрд░реВрди design. рдЖрдзреА рдЧрдгрд┐рдд: рдЗрдорд╛рд░рддреАрдВрдЪреА рд╕рд╛рдЦрд│реА рдХрд┐рддреА рд╡рд┐рд╢реНрд╡рд╛рд╕рд╛рд░реНрд╣ рдЕрд╕реВ рд╢рдХрддреЗ?

git checkout lesson-09-reliability-math

ЁЯж║ Lesson 08 тАФ Incident command: roles, rhythm and the handoff

ЁЯУН You are here: Lesson 08 of 12 ┬╖ Previous: lesson-07-capacity-planning ┬╖ Next: lesson-09-reliability-math


ЁЯУж What's in this branch

Lesson 07, plus how the crew organises during an incident. The Observability school's lesson 10 teaches severity, the incident clocks (detect, acknowledge, mitigate, resolve) and its lessons 11тАУ12 the root cause and the postmortem. This lesson is the command structure: the four roles, the status-update rhythm, and the handoff when a shift ends. IncidentLog in sre/crew.py and command() in sre/demo.py.

ЁЯзТ Explain like I'm 5

At 23:00 the timetable building goes dark. ЁЯМС

Night one тАФ no plan. Katrina and Dipika both start fixing things. They undo each other's work. Nobody tells the head teacher anything for almost two hours. At midnight Katrina goes home тАФ and nobody knows what she was in the middle of.

Night two тАФ a plan. Dipika says: "I am the incident commander. I don't fix тАФ I lead." She points: "Katrina, you fix. Aishwarya, you tell people what is happening, every half hour. I'll also write down what happens, while it is small." At midnight Dipika's shift ends. She doesn't just leave. She tells crew-5 everything тАФ what is broken, what was tried, who is doing what тАФ and crew-5 says: "I have command." Only then does Dipika go.

Same fault. The second night is calm, and it ends sooner.

ЁЯЧ║я╕П Diagram

flowchart LR
    ic["ЁЯж║ IC тАФ Dipika<br/>leads, decides, does NOT fix"] --> ops["ЁЯФз ops тАФ Katrina<br/>hands on the system"]
    ic --> comms["ЁЯУг comms тАФ Aishwarya<br/>update every 30 min"]
    ic --> scribe["ЁЯУЭ scribe<br/>the timeline"]
    ic -->|"00:00 handoff:<br/>state, actions, roles"| ic2["ЁЯж║ IC тАФ crew-5<br/>'I have command' тЬУ"]
    bad["without roles: 5 problems<br/>no IC ┬╖ 110 min with no update<br/>Katrina left holding ops"]

ЁЯЧ║я╕П Drawn version + a lab: https://school-edh.pages.dev/sre/lesson-diagrams.html#l08

тЭУ What

ЁЯдФ Why

Because in an incident, the problem is often not the fault тАФ it is the people around it: duplicated work, conflicting changes, leaders asking "any news?" every five minutes, and knowledge lost when someone goes home. Roles and a rhythm are cheap, and they make the same people work much better under stress.

ЁЯФз How (in this repo)

IncidentLog(events, update_every=30) in sre/crew.py takes events (minute, kind, тАж) тАФ role, update, handoff (role, from, to, acknowledged), leave, resolve тАФ minutes counted from 23:00. check() returns the problems it finds: a role never named, a gap between updates longer than the rhythm, a person who left still holding a role, an unacknowledged handoff, the IC also doing ops. command() checks the two nights.

ЁЯзк Try it

python3 sre/demo.py command
python3 - <<'EOF'
import sys; sys.path.insert(0, "sre"); from crew import IncidentLog
log = IncidentLog([(0, "role", "Dipika", "IC"), (2, "role", "Dipika", "ops"), (3, "role", "Aishwarya", "comms"),
                   (4, "role", "Katrina", "scribe"), (5, "update"), (50, "update"),
                   (60, "handoff", "IC", "Dipika", "crew-5", False), (61, "leave", "Dipika"), (90, "resolve")])
probs, mins = log.check()
print(f"{mins} min, {len(probs)} problems:")
for p in probs: print(" -", p)
EOF

тЬЕ Verify тАФ what you should see

command prints:

тФАтФА without roles: the timetable service is down at 23:00 ┬╖ resolved after 110 min ┬╖ 5 problem(s)
   тЬЧ 00:00 Katrina went off shift still holding ops тАФ nobody holds it now
   тЬЧ no IC was ever named
   тЬЧ no comms was ever named
   тЬЧ no scribe was ever named
   тЬЧ 23:00 no status update for 110 min (rhythm: every 30)
тФАтФА with incident command: the timetable service is down at 23:00 ┬╖ resolved after 100 min ┬╖ 0 problem(s)

Your snippet prints:

90 min, 6 problems:
 - 00:00 IC handoff Dipika тЖТ crew-5 never acknowledged тАФ two people think they lead
 - 00:01 Dipika went off shift still holding IC тАФ nobody holds it now
 - 00:01 Dipika went off shift still holding ops тАФ nobody holds it now
 - 23:05 no status update for 45 min (rhythm: every 30)
 - 23:50 no status update for 40 min (rhythm: every 30)
 - the IC is also hands-on in ops тАФ nobody is watching the whole incident

ЁЯПБ What you just proved

Having the names of roles is not enough. In your snippet every role was named, and it still had six problems: the IC was also fixing, updates slipped to 45 and 40 minutes, and the handoff was never acknowledged тАФ so when Dipika left, nobody held command or ops. The calm night passed every rule, including a handoff at 00:00 that crew-5 accepted. (The resolve times in these runs are part of the story, not something the model computes.)

тЪая╕П Common mistakes

ЁЯПн In production

Keep a handoff template where everyone can find it (the incident channel's pinned message):

IC HANDOFF тАФ timetable outage тАФ 00:00
state:     timetable API 40% errors, database failover done at 23:40, errors falling
tried:     rolled back release 2026.09.27-2 (no change); failed over DB (helped)
next:      confirm replica lag < 5 s, then raise read traffic
roles:     IC crew-5 (from Dipika) ┬╖ ops Katrina ┬╖ comms Aishwarya (next update 00:30) ┬╖ scribe crew-5
incoming:  "crew-5: I have command."

Tools like incident.io, PagerDuty, FireHydrant and Rootly create the incident channel, assign roles and keep the timeline from chat. On a real account тАФ open an incident from the command line with PagerDuty's API (Events API v2):

curl -s -X POST https://events.pagerduty.com/v2/enqueue -H "Content-Type: application/json" -d '{
  "routing_key": "'"$PD_ROUTING_KEY"'", "event_action": "trigger",
  "payload": {"summary": "timetable API 40% errors", "source": "timetable", "severity": "critical"}}'

ЁЯПн Why this matters in production: run a 30-minute tabletop exercise this month: a made-up outage, a named IC, a comms lead posting updates, and a handoff in the middle. The first one always finds a gap.

тПня╕П Next

Part 3: designing for failure. First, the arithmetic: how reliable can a chain of buildings be?

git checkout lesson-09-reliability-math
тЖР Previouscapacity planningNext тЖТreliability math

This page is the lesson's README from the lesson-08-incident-command branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.