ЁЯПл The SchoolтА║ЁЯПЕ Engineering LeadershipтА║ЁЯЪи рдзрдбрд╛ 10 тАФ Incidents рдЖрдгрд┐ рдХрдареАрдг рдирд┐рд░реНрдгрдпрд╛рдВрдордзреНрдпреЗ рдиреЗрддреГрддреНрд╡
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯЪи рдзрдбрд╛ 10 тАФ Incidents рдЖрдгрд┐ рдХрдареАрдг рдирд┐рд░реНрдгрдпрд╛рдВрдордзреНрдпреЗ рдиреЗрддреГрддреНрд╡

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 10 ┬╖ рдорд╛рдЧрдЪрд╛: lesson-09-team-topologies ┬╖ рдкреБрдврдЪрд╛: lesson-11-writing


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

рдзрдбрд╛ 09, рдЖрдгрд┐ рдЕрд╕реЗ рдХреНрд╖рдг рдЬреЗрд╡реНрд╣рд╛ lead рд╕рд░реНрд╡рд╛рдд рдЬрд╛рд╕реНрдд рджрд┐рд╕рддреЗ: рдПрдЦрд╛рджреЗ incident, рдЖрдгрд┐ рдПрдЦрд╛рджрд╛ рдХрдареАрдг рдирд┐рд░реНрдгрдп. рдЙрд▓рдЯрддрд╛ рдпреЗрдгрд╛рд░реЗ рд╡рд┐рд░реБрджреНрдз рди рдЙрд▓рдЯрддрд╛ рдпреЗрдгрд╛рд░реЗ рдирд┐рд░реНрдгрдп (two-way рдЖрдгрд┐ one-way doors), revisit рддрд╛рд░рдЦрд╛рдВрд╕рд╣ рдирд┐рд░реНрдгрдпрд╛рдВрдЪреА рдиреЛрдВрджрд╡рд╣реА (decision log), incident roles, рдЖрдгрд┐ рдкреБрдвреЗ debug рдХрд░рдд рд░рд╛рд╣рдгреНрдпрд╛рдкреЗрдХреНрд╖рд╛ рдЖрдзреА mitigate рдХрд░рдгреЗ рдХрд╛ рдЪрд╛рдВрдЧрд▓реЗ. incidents() lead/demo.py рдордзреНрдпреЗ; classify(), DecisionLog рдЖрдгрд┐ timeline() lead/models.py рдордзреНрдпреЗ. Operations рдЪреА рдмрд╛рдЬреВ SRE school рдордзреНрдпреЗ рдЖрд╣реЗ.

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

рдкрд░реАрдХреНрд╖реЗрдЪреА рд╕рдХрд╛рд│. рдХрд╛рд▓ рд░рд╛рддреНрд░реА update рдХреЗрд▓реЗрд▓реЗ рдирд╡реЗ online gradebook рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рджреНрдпрд╛рд░реНрдереНрдпрд╛рдЪреЗ рдЧреБрдг рд╢реВрдиреНрдп рджрд╛рдЦрд╡рддреЗ. ЁЯШ▒ рдкрд╛рд▓рдХрд╛рдВрдЪреЗ рдлреЛрди рдпреЗрдд рдЖрд╣реЗрдд.

рд╕рдЧрд│реЗрдЬрдг bug рд╢реЛрдзрд╛рдпрд▓рд╛ screen рднреЛрд╡рддреА рдЧрд░реНрджреА рдХрд░рддрд╛рдд. рдХрддрд░рд┐рдирд╛ рддреНрдпрд╛рдВрдирд╛ рдерд╛рдВрдмрд╡рддреЗ. рддреА рдкреНрд░рддреНрдпреЗрдХреАрд▓рд╛ рдПрдХрдЪ рдХрд╛рдо рджреЗрддреЗ:

рдХрд╛рд▓рдЪреА рдЖрд╡реГрддреНрддреА 15 рдорд┐рдирд┐рдЯрд╛рдВрдд рдкрд░рдд рдпреЗрддреЗ. Bug рдирдВрддрд░ рд╢рд╛рдВрддрдкрдгреЗ рд╢реЛрдзрддрд╛ рдпреЗрддреЛ. рдЬрд░ рддреНрдпрд╛рдВрдиреА рдЖрдзреА bug рд╢реЛрдзрд▓рд╛ рдЕрд╕рддрд╛, рддрд░ рдкрд╛рд▓рдХрд╛рдВрдирд╛ 52 рдорд┐рдирд┐рдЯреЗ рд╡рд╛рдЯ рдкрд╛рд╣рд╛рд╡реА рд▓рд╛рдЧрд▓реА рдЕрд╕рддреА.

рддреНрдпрд╛рдЪ рдЖрдард╡рдбреНрдпрд╛рдд рдирдВрддрд░ рдХрддрд░рд┐рдирд╛ рджреЛрди рдирд┐рд░реНрдгрдп рдШреЗрддреЗ. "Standup рдЪреА рдирд╡реА рдкрджреНрдзрдд рдХрд░реВрди рдкрд╛рд╣рд╛рдпрдЪреА?" рдЙрд▓рдЯрдгреЗ рд╕реЛрдкреЗ тАФ рддреА рдПрдХрд╛ рдорд┐рдирд┐рдЯрд╛рдд рдард░рд╡рддреЗ. "рдЧреБрдг рджреЗрдгреНрдпрд╛рдЪреНрдпрд╛ tool рд╕рд╛рдареА 3 рд╡рд░реНрд╖рд╛рдВрдЪрд╛ contract рдХрд░рд╛рдпрдЪрд╛?" рдЙрд▓рдЯрдгреЗ рдХрдареАрдг тАФ рддреА рддреЗ рд▓рд┐рд╣реВрди рдХрд╛рдврддреЗ, рд▓реЛрдХрд╛рдВрдирд╛ рд╡рд┐рдЪрд╛рд░рддреЗ, рдЖрдгрд┐ рдПрдХ рдЖрдард╡рдбрд╛ рдШреЗрддреЗ. рд╡реЗрдЧрд│реЗ рджрд░рд╡рд╛рдЬреЗ, рд╡реЗрдЧрд│реЗ рд╡реЗрдЧ. ЁЯЪк

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

flowchart LR
    i["ЁЯЪи impact starts, minute 0"] --> d["ЁЯФФ detected, minute 6"]
    d --> r["тПк mitigate first: roll back<br/>users hurt 15 min"]
    d --> f["ЁЯФН debug forward: find and fix<br/>users hurt 52 min"]
    t["ЁЯЪк two-way door<br/>decide now, log it, revisit"] --- o["ЁЯФТ one-way door<br/>write it up, consult, deadline"]
    l["ЁЯУТ decision log<br/>due by week 8: standup format,<br/>exam-week freeze"]

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

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

ЁЯдФ рдХрд╛

рдХрд╛рд░рдг incident рдордзреНрдпреЗ lead рдЪреА рд╕рд╣рдЬ рдкреНрд░рд╡реГрддреНрддреА тАФ "рдЗрдереЗ рдореАрдЪ рд╕рд░реНрд╡реЛрддреНрддрдо engineer рдЖрд╣реЗ, рдорд▓рд╛ рдкрд╛рд╣реВ рджреЗ" тАФ рд╕рд╣рд╕рд╛ рдЪреБрдХреАрдЪреА рдЕрд╕рддреЗ: рдЯреАрдорд▓рд╛ keyboard рд╡рд░ рдЖрдгрдЦреА рдПрдХ рдЬреЛрдбреА рд╣рд╛рдд рдирдХреЛ, рддрд░ рд╕рдордиреНрд╡рдп рдХрд░рдгрд╛рд░реА рдХреЛрдгреАрддрд░реА рд╣рд╡реА. рдЖрдгрд┐ рдмрд╣реБрддреЗрдХ рдирд┐рд░реНрдгрдп two-way doors рдЕрд╕рд▓реНрдпрд╛рдиреЗ, lead рддрд┐рдЪреНрдпрд╛ рдЯреАрдорд▓рд╛ рджреЗрдК рд╢рдХрдгрд╛рд░рд╛ рд╕рд░реНрд╡рд╛рдд рдореЛрдард╛ рд╡реЗрдЧ рдореНрд╣рдгрдЬреЗ рд╣реЗ рд╕реНрдкрд╖реНрдЯ рд╕рд╛рдВрдЧрдгреЗ рдЖрдгрд┐ рдорд╛рд▓рдХрд╛рд▓рд╛ рдард░рд╡реВ рджреЗрдгреЗ тАФ рдЖрдгрд┐ рдЬреЗ рдХрд╛рд╣реА рдереЛрдбреЗ рдирд┐рд░реНрдгрдп рддрд╕реЗ рдирд╕рддрд╛рдд рддреНрдпрд╛рдВрд╡рд░ рдЦрд░реА рдХрд╛рд│рдЬреА рдШреЗрдгреЗ.

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

lead/models.py рдордзреАрд▓ classify(reversible, cost_to_undo_days) рдирд┐рд░реНрдгрдп reversible рдЕрд╕реЗрд▓ рдЖрдгрд┐ 5 рджрд┐рд╡рд╕рд╛рдВрдд рдЙрд▓рдЯрддрд╛ рдпреЗрдд рдЕрд╕реЗрд▓ рддрд░ "two-way door" рдкрд░рдд рджреЗрддреЗ, рдирд╛рд╣реАрддрд░ "one-way door". DecisionLog (week, decision, owner, door, revisit) рдиреЛрдВрджрд╡рддреЗ рдЖрдгрд┐ due(week) рдЬреНрдпрд╛рдВрдЪрд╛ revisit рдЖрдард╡рдбрд╛ рдЖрд▓рд╛ рдЖрд╣реЗ рдЕрд╕реЗ рдирд┐рд░реНрдгрдп рджрд╛рдЦрд╡рддреЗ. timeline(events) рдкрд░рд┐рдгрд╛рдо рд╕реБрд░реВ рдЭрд╛рд▓реНрдпрд╛рдкрд╛рд╕реВрди detect рдЖрдгрд┐ mitigate рдХрд░рд╛рдпрд▓рд╛ рд▓рд╛рдЧрд▓реЗрд▓реА рдорд┐рдирд┐рдЯреЗ рдкрд░рдд рджреЗрддреЗ. lead/demo.py рдордзреАрд▓ incidents() рдЪрд╛рд░ рдирд┐рд░реНрдгрдпрд╛рдВрдЪреЗ рд╡рд░реНрдЧреАрдХрд░рдг рдХрд░рддреЗ рдЖрдгрд┐ incident рд▓рд╛ рджрд┐рд▓реЗрд▓реНрдпрд╛ рджреЛрди рдкреНрд░рддрд┐рд╕рд╛рджрд╛рдВрдЪреА рддреБрд▓рдирд╛ рдХрд░рддреЗ. 5 рджрд┐рд╡рд╕рд╛рдВрдЪреА рд░реЗрд╖рд╛ рдордирдорд╛рдиреА рдЖрд╣реЗ: рд╡рд┐рдЪрд╛рд░ рдХрд░рдгреНрдпрд╛рдЪреЗ рд╕рд╛рдзрди, рд▓реЛрдХрд╛рдВрд╕рд╛рдареАрдЪреЗ рд╕реВрддреНрд░ рдирд╡реНрд╣реЗ.

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

python3 lead/demo.py incidents
python3 - <<'EOF'
import sys; sys.path.insert(0, "lead"); from models import classify, DecisionLog, timeline
for rev, undo in ((True, 0), (True, 5), (True, 6), (False, 1)):
    print(f"reversible={rev!s:<5} undo {undo} days тЖТ {classify(rev, undo).split(' тЖТ')[0]}")
log = DecisionLog()
log.add(3, "new standup format", "Dipika", "two-way", 5)
log.add(3, "PostgreSQL migration RFC accepted", "Katrina", "one-way", 12)
log.add(4, "freeze releases in exam week", "Aishwarya", "two-way", 8)
for w in (4, 5, 8, 12):
    print(f"week {w:>2}: due for review {log.due(w)}")
for det in (2, 6, 20):
    print(f"alert fires after {det:>2} min, rollback takes 9 тЖТ users hurt for {timeline({'impact': 0, 'detected': det, 'mitigated': det + 9})[1]} min")
EOF

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

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

тФАтФА roll back last night's gradebook release     two-way door тЖТ decide now, the owner decides, log it, set a revisit date
тФАтФА move the gradebook from MySQL to PostgreSQL  one-way door тЖТ slow down: write it up, consult, name a decider and a deadline
   decision log: 3 entries ┬╖ due for review by week 8: ['new standup format', 'freeze releases in exam week']
тФАтФА incident, mitigate first (roll back)    detected after 6 min ┬╖ users hurt for 15 min
тФАтФА incident, debug forward (find and fix)  detected after 6 min ┬╖ users hurt for 52 min

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

reversible=True  undo 0 days тЖТ two-way door
reversible=True  undo 5 days тЖТ two-way door
reversible=True  undo 6 days тЖТ one-way door
reversible=False undo 1 days тЖТ one-way door
week  4: due for review []
week  5: due for review ['new standup format']
week  8: due for review ['new standup format', 'freeze releases in exam week']
week 12: due for review ['new standup format', 'PostgreSQL migration RFC accepted', 'freeze releases in exam week']
alert fires after  2 min, rollback takes 9 тЖТ users hurt for 11 min
alert fires after  6 min, rollback takes 9 тЖТ users hurt for 15 min
alert fires after 20 min, rollback takes 9 тЖТ users hurt for 29 min

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

рдЖрдзреА roll back рдХреЗрд▓реНрдпрд╛рдиреЗ users рдирд╛ 15 рдорд┐рдирд┐рдЯреЗ рддреНрд░рд╛рд╕ рдЭрд╛рд▓рд╛; рдкреБрдвреЗ debug рдХрд░рдд рд░рд╛рд╣рд┐рд▓реНрдпрд╛рд╕ 52. Detection рдЪрд╛ рд╡реЗрд│ рдереЗрдЯ рдиреБрдХрд╕рд╛рдирд╛рдд рднрд░ рдШрд╛рд▓рддреЛ: рддреЛрдЪ 9 рдорд┐рдирд┐рдЯрд╛рдВрдЪрд╛ rollback 2 рдорд┐рдирд┐рдЯрд╛рдВрдЪреНрдпрд╛ alert рд╕рд╣ 11 рдорд┐рдирд┐рдЯрд╛рдВрдЪрд╛ рдкрд░рд┐рдгрд╛рдо рджреЗрддреЛ рдЖрдгрд┐ 20 рдорд┐рдирд┐рдЯрд╛рдВрдЪреНрдпрд╛ alert рд╕рд╣ 29. рдирд┐рд░реНрдгрдпрд╛рдВрдЪреА рдиреЛрдВрджрд╡рд╣реА "рдмрдШреВ рдХрд╕реЗ рд╣реЛрддреЗ" рд▓рд╛ рдПрдХрд╛ рддрд╛рд░рдЦреЗрдд рдмрджрд▓рддреЗ: рдЖрдард╡рдбрд╛ 8 рдкрд░реНрдпрдВрдд рджреЛрди рдирд┐рд░реНрдгрдпрд╛рдВрдЪрд╛ рдЖрдврд╛рд╡рд╛ рдШреНрдпрд╛рдпрдЪрд╛ рдЖрд╣реЗ, рдЖрдгрд┐ one-way door рд▓рд╛ рдЖрдард╡рдбрд╛ 12 рдордзреНрдпреЗ рддреНрдпрд╛рдЪреА рд╕реНрд╡рддрдГрдЪреА рддрд╛рд░реАрдЦ рдЖрд╣реЗ. рдЖрдгрд┐ рджрд░рд╡рд╛рдЬрд╛ рд╣реА рддреБрдореНрд╣реА рдирд┐рд╡рдбрд▓реЗрд▓реА рдорд░реНрдпрд╛рджрд╛ рдЖрд╣реЗ тАФ 5 рджрд┐рд╡рд╕рд╛рдВрдд рдЙрд▓рдЯрддрд╛ рдпреЗрдгрд╛рд░рд╛ "two-way" рд╣реЛрддрд╛, 6 рджрд┐рд╡рд╕рд╛рдВрдЪрд╛ рдирд╛рд╣реА.

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

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

рдПрдХ decision record, 10 рдорд┐рдирд┐рдЯрд╛рдВрдд рд▓рд┐рд╣рд┐рддрд╛ рдпреЗрдИрд▓ рдЗрддрдХреЗ рдЫреЛрдЯреЗ:

# 2026-09-14 тАФ Freeze gradebook releases in exam week
- Door: two-way (we can lift it any day)
- Decider: Aishwarya (release owner) ┬╖ Consulted: Katrina, Dipika
- Options: (1) no freeze (2) freeze MonтАУFri of exam week (3) freeze two weeks
- Decision: (2). Reason: last year's exam-week incident; one week limits the backlog
- Revisit: week 8, after the first exam week

Mitigation рдПрдХрд╛ command рдЪреА рдЕрд╕реЗрд▓ рддреЗрд╡реНрд╣рд╛ рд╕рд░реНрд╡рд╛рдд рд╕реЛрдкреА рдЕрд╕рддреЗ. рдЦрд▒реНрдпрд╛ cluster рд╡рд░, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде (Kubernetes school рд╣реЗ рд╕рдордЬрд╛рд╡рддреЗ):

kubectl rollout undo deployment/gradebook      # back to the previous ReplicaSet
kubectl rollout status deployment/gradebook

Incident channel рдЪрд╛ рдкрд╣рд┐рд▓рд╛ message roles рдард░рд╡рддреЛ:

ЁЯЪи INC-231 ┬╖ gradebook shows 0 for all marks ┬╖ started ~09:02
IC: Katrina ┬╖ Ops: Dipika (rolling back) ┬╖ Comms: Aishwarya (next update 09:30)

Service-level objectives, error budgets, on-call рдЖрдгрд┐ postmortems рд╣реЗ SRE school рдЪреЗ рд╡рд┐рд╖рдп рдЖрд╣реЗрдд тАФ рд╣рд╛ рдзрдбрд╛ рддреНрдпрд╛рдЪ рдХреНрд╖рдгрд╛рдВрдЪреА lead рдЪреА рдмрд╛рдЬреВ рдЖрд╣реЗ.

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: рд╕рдордиреНрд╡рдп рдХреЛрдг рдХрд░рдгрд╛рд░, roll back рдХрд╕реЗ рдХрд░рд╛рдпрдЪреЗ, рдЖрдгрд┐ рд▓реЛрдХрд╛рдВрдирд╛ рдХрд┐рддреА рд╡реЗрд│рд╛рдиреЗ update рджреНрдпрд╛рдпрдЪрд╛ рд╣реЗ рдЖрдзреАрдЪ рдард░рд╡рд╛. рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ рдирд┐рд░реНрдгрдп рддреНрдпрд╛рдЪреНрдпрд╛ рджрд░рд╡рд╛рдЬрд╛рдиреБрд╕рд╛рд░ рд╡рд░реНрдЧреАрдХреГрдд рдХрд░рд╛: рдЕрдиреЗрдХ two-way рдирд┐рд░реНрдгрдпрд╛рдВрд╕рд╛рдареА рдЬрд▓рдж, рдореЛрдЬрдХреНрдпрд╛ one-way рдирд┐рд░реНрдгрдпрд╛рдВрд╕рд╛рдареА рд╕рд╛рд╡рдХрд╛рд╢ рдЖрдгрд┐ рд▓рд┐рдЦрд┐рдд.

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

рдирд┐рд░реНрдгрдпрд╛рдВрдЪреА рдиреЛрдВрджрд╡рд╣реА рд╣реЗ рдПрдХ рд▓реЗрдЦрдирдЪ рд╣реЛрддреЗ. Lead рдореЛрдареНрдпрд╛ рдкреНрд░рдорд╛рдгрд╛рд╡рд░ рдЬреЗ рдХрд╛рд╣реА рдЪрд╛рдВрдЧрд▓реЗ рдХрд░рддреЗ рддреЗ рдЬрд╡рд│рдЬрд╡рд│ рд╕рдЧрд│реЗ рдЕрд╕реЗрдЪ рдЕрд╕рддреЗ. рдкреБрдвреЗ: рд▓реЗрдЦрди тАФ design docs, status updates, рдЖрдгрд┐ рдПрдХрд╛ meeting рдЪреА рдХрд┐рдВрдордд.

git checkout lesson-11-writing

ЁЯЪи Lesson 10 тАФ Leading through incidents and hard decisions

ЁЯУН You are here: Lesson 10 of 12 ┬╖ Previous: lesson-09-team-topologies ┬╖ Next: lesson-11-writing


ЁЯУж What's in this branch

Lesson 09, plus the moments when a lead is most visible: an incident, and a hard decision. Reversible vs irreversible decisions (two-way and one-way doors), a decision log with revisit dates, incident roles, and why mitigating first beats debugging forward. incidents() in lead/demo.py; classify(), DecisionLog and timeline() in lead/models.py. The operations side lives in the SRE school.

ЁЯзТ Explain like I'm 5

Exam morning. The new online gradebook, updated last night, shows every pupil's mark as zero. ЁЯШ▒ Parents are phoning.

Everyone crowds around the screen trying to find the bug. Katrina stops them. She gives each person one job:

Yesterday's version is back in 15 minutes. The bug can be found calmly afterwards. If they had hunted for the bug first, parents would have waited 52 minutes.

Later that week Katrina makes two decisions. "Try a new standup format?" Easy to undo тАФ she decides in a minute. "Sign a 3-year contract for a marking tool?" Hard to undo тАФ she writes it up, asks people, and takes a week. Different doors, different speeds. ЁЯЪк

ЁЯЧ║я╕П Diagram

flowchart LR
    i["ЁЯЪи impact starts, minute 0"] --> d["ЁЯФФ detected, minute 6"]
    d --> r["тПк mitigate first: roll back<br/>users hurt 15 min"]
    d --> f["ЁЯФН debug forward: find and fix<br/>users hurt 52 min"]
    t["ЁЯЪк two-way door<br/>decide now, log it, revisit"] --- o["ЁЯФТ one-way door<br/>write it up, consult, deadline"]
    l["ЁЯУТ decision log<br/>due by week 8: standup format,<br/>exam-week freeze"]

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

тЭУ What

ЁЯдФ Why

Because in an incident, a lead's instinct тАФ "I am the best engineer here, let me look" тАФ is usually wrong: the team needs someone coordinating, not another pair of hands on the keyboard. And because most decisions are two-way doors, the biggest speed gain a lead can give her team is to say so, and let the owner decide тАФ while spending real care on the few that are not.

ЁЯФз How (in this repo)

classify(reversible, cost_to_undo_days) in lead/models.py returns "two-way door" if the decision is reversible and can be undone within 5 days, and "one-way door" otherwise. DecisionLog records (week, decision, owner, door, revisit) and due(week) lists decisions whose revisit week has come. timeline(events) returns minutes to detect and to mitigate from the start of impact. incidents() in lead/demo.py classifies four decisions and compares two incident responses. The 5-day line is arbitrary: a thinking tool, not a formula for people.

ЁЯзк Try it

python3 lead/demo.py incidents
python3 - <<'EOF'
import sys; sys.path.insert(0, "lead"); from models import classify, DecisionLog, timeline
for rev, undo in ((True, 0), (True, 5), (True, 6), (False, 1)):
    print(f"reversible={rev!s:<5} undo {undo} days тЖТ {classify(rev, undo).split(' тЖТ')[0]}")
log = DecisionLog()
log.add(3, "new standup format", "Dipika", "two-way", 5)
log.add(3, "PostgreSQL migration RFC accepted", "Katrina", "one-way", 12)
log.add(4, "freeze releases in exam week", "Aishwarya", "two-way", 8)
for w in (4, 5, 8, 12):
    print(f"week {w:>2}: due for review {log.due(w)}")
for det in (2, 6, 20):
    print(f"alert fires after {det:>2} min, rollback takes 9 тЖТ users hurt for {timeline({'impact': 0, 'detected': det, 'mitigated': det + 9})[1]} min")
EOF

тЬЕ Verify тАФ what you should see

incidents prints:

тФАтФА roll back last night's gradebook release     two-way door тЖТ decide now, the owner decides, log it, set a revisit date
тФАтФА move the gradebook from MySQL to PostgreSQL  one-way door тЖТ slow down: write it up, consult, name a decider and a deadline
   decision log: 3 entries ┬╖ due for review by week 8: ['new standup format', 'freeze releases in exam week']
тФАтФА incident, mitigate first (roll back)    detected after 6 min ┬╖ users hurt for 15 min
тФАтФА incident, debug forward (find and fix)  detected after 6 min ┬╖ users hurt for 52 min

Your snippet prints:

reversible=True  undo 0 days тЖТ two-way door
reversible=True  undo 5 days тЖТ two-way door
reversible=True  undo 6 days тЖТ one-way door
reversible=False undo 1 days тЖТ one-way door
week  4: due for review []
week  5: due for review ['new standup format']
week  8: due for review ['new standup format', 'freeze releases in exam week']
week 12: due for review ['new standup format', 'PostgreSQL migration RFC accepted', 'freeze releases in exam week']
alert fires after  2 min, rollback takes 9 тЖТ users hurt for 11 min
alert fires after  6 min, rollback takes 9 тЖТ users hurt for 15 min
alert fires after 20 min, rollback takes 9 тЖТ users hurt for 29 min

ЁЯПБ What you just proved

Rolling back first kept users hurt for 15 minutes; debugging forward, 52. Detection time adds directly to the damage: the same 9-minute rollback costs 11 minutes of impact with a 2-minute alert and 29 with a 20-minute one. The decision log turns "we'll see how it goes" into a date: by week 8, two decisions are due for review, and the one-way door has its own date in week 12. And the door is a threshold you choose тАФ undoable in 5 days was "two-way", 6 days was not.

тЪая╕П Common mistakes

ЁЯПн In production

A decision record, short enough to write in 10 minutes:

# 2026-09-14 тАФ Freeze gradebook releases in exam week
- Door: two-way (we can lift it any day)
- Decider: Aishwarya (release owner) ┬╖ Consulted: Katrina, Dipika
- Options: (1) no freeze (2) freeze MonтАУFri of exam week (3) freeze two weeks
- Decision: (2). Reason: last year's exam-week incident; one week limits the backlog
- Revisit: week 8, after the first exam week

Mitigation is easiest when it is one command. On a real cluster, for example (the Kubernetes school explains it):

kubectl rollout undo deployment/gradebook      # back to the previous ReplicaSet
kubectl rollout status deployment/gradebook

An incident channel's first message sets the roles:

ЁЯЪи INC-231 ┬╖ gradebook shows 0 for all marks ┬╖ started ~09:02
IC: Katrina ┬╖ Ops: Dipika (rolling back) ┬╖ Comms: Aishwarya (next update 09:30)

Service-level objectives, error budgets, on-call and postmortems are the SRE school's subject тАФ this lesson is the lead's side of the same moments.

ЁЯПн Why this matters in production: decide in advance who coordinates, how to roll back, and how often to update people. And sort every decision by its door: fast for the many two-way ones, slow and written for the few one-way ones.

тПня╕П Next

The decision log was a piece of writing. So is almost everything a lead does well at scale. Next: writing тАФ design docs, status updates, and the cost of a meeting.

git checkout lesson-11-writing
тЖР Previousteam topologiesNext тЖТwriting

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