ЁЯПл The SchoolтА║ЁЯПЕ Engineering LeadershipтА║ЁЯз╛ рдзрдбрд╛ 07 тАФ Technical debt рдПрдХ portfolio рдореНрд╣рдгреВрди: interest рд╡рд┐рд░реБрджреНрдз principal
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯз╛ рдзрдбрд╛ 07 тАФ Technical debt рдПрдХ portfolio рдореНрд╣рдгреВрди: interest рд╡рд┐рд░реБрджреНрдз principal

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 07 ┬╖ рдорд╛рдЧреЗ: lesson-06-prioritisation ┬╖ рдкреБрдвреЗ: lesson-08-delivery-metrics


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

рдзрдбрд╛ 06, рдЖрдгрд┐ technical debt, рдкреИрд╢рд╛рд╕рд╛рд░рдЦреА рдХрд┐рдВрдордд рд▓рд╛рд╡реВрди: principal (рджреБрд░реБрд╕реНрдд рдХрд░рд╛рдпрд▓рд╛ рд▓рд╛рдЧрдгрд╛рд░реЗ рддрд╛рд╕) рдЖрдгрд┐ interest (рддреЗ рджреБрд░реБрд╕реНрдд рд╣реЛрдИрдкрд░реНрдпрдВрдд рдЯреАрдорд▓рд╛ рджрд░ рдЖрдард╡рдбреНрдпрд╛рд▓рд╛ рд▓рд╛рдЧрдгрд╛рд░реЗ рддрд╛рд╕). рддреЗ рдХрдзреА рдлреЗрдбрд╛рдпрдЪреЗ, рдХрдзреА рдмрд╛рд│рдЧрд╛рдпрдЪреЗ, рдЖрдгрд┐ рддреБрдореНрд╣реА рддреЛ code рдХрд┐рддреА рдХрд╛рд│ рдареЗрд╡рдгрд╛рд░ рдпрд╛рд╡рд░ рдЙрддреНрддрд░ рдХрд╛ рдЕрд╡рд▓рдВрдмреВрди рдЕрд╕рддреЗ. lead/demo.py рдордзрд▓реЗ debt(); lead/models.py рдордзрд▓реЗ debt_plan().

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

рдЧрдгрд┐рдд рд╡рд┐рднрд╛рдЧрд╛рдд рдХрд╛рд╣реА рдЬреБрдиреНрдпрд╛, рдЧреЛрдВрдзрд│рд▓реЗрд▓реНрдпрд╛ рдЧреЛрд╖реНрдЯреА рдЖрд╣реЗрдд: ЁЯз╣

рдХрддрд░рд┐рдирд╛ рдкреНрд░рддреНрдпреЗрдХ рдЧреЛрдВрдзрд│рд╛рдмрджреНрджрд▓ рджреЛрди рдкреНрд░рд╢реНрди рд╡рд┐рдЪрд╛рд░рддреЗ. "рджреБрд░реБрд╕реНрдд рдХрд░рд╛рдпрд▓рд╛ рдХрд┐рддреА рд╡реЗрд│?" тАФ рддреЗ рдореНрд╣рдгрдЬреЗ principal. "рдЖрдкрдг рддрд╕реЗрдЪ рдареЗрд╡рд▓реЗ рддрд░ рджрд░ рдЖрдард╡рдбреНрдпрд╛рд▓рд╛ рддреЗ рдХрд┐рддреА рд╡реЗрд│ рдЪреЛрд░рддреЗ?" тАФ рддреЗ рдореНрд╣рдгрдЬреЗ interest. ЁЯТ╕

Photocopier: рд▓рд╣рд╛рди principal, рдореЛрдареЗ interest. рддреЗ рдЖрддреНрддрд╛ рджреБрд░реБрд╕реНрдд рдХрд░рд╛ тАФ рдХрд╛рд╣реА рдЖрдард╡рдбреНрдпрд╛рдВрдд рдЦрд░реНрдЪ рд╡рд╕реВрд▓ рд╣реЛрддреЛ. рдХрдкрд╛рдЯ: рдореЛрдареЗ principal, рдЕрдЧрджреА рд▓рд╣рд╛рди interest. рддреЗ рддрд╕реЗрдЪ рд░рд╛рд╣реВ рджреНрдпрд╛. рддреЗ рдЖрд╡рд░рдгреНрдпрд╛рдЪрд╛ рдЦрд░реНрдЪ рддреНрдпрд╛рддреВрди рдХрдзреАрд╣реА рд╣реЛрдгрд╛рд▒реНрдпрд╛ рдмрдЪрддреАрдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд рдЕрд╕реЗрд▓ тАФ рдЬреЛрдкрд░реНрдпрдВрдд рд╡рд┐рднрд╛рдЧ рддреЗ рдХрдкрд╛рдЯ рд░реЛрдЬ рд╡рд╛рдкрд░реВ рд▓рд╛рдЧрдд рдирд╛рд╣реА.

рдкреНрд░рддреНрдпреЗрдХ рдЧреЛрдВрдзрд│ рд╕рд╛рдл рдХрд░рдгреНрдпрд╛рдЬреЛрдЧрд╛ рдирд╕рддреЛ. рдкрдг рдЬреЛ рдЧреЛрдВрдзрд│ рджрд░ рдЖрдард╡рдбреНрдпрд╛рд▓рд╛ рд╡реЗрд│ рдЪреЛрд░рддреЛ рддреЛ рдХреЛрдгреА рдлреЗрдбрд╛рдпрдЪреЗ рдард░рд╡реЛ рд╡рд╛ рди рдард░рд╡реЛ, рддреБрдордЪрд╛ рдЦрд░реНрдЪ рдХрд░рддрдЪ рдЕрд╕рддреЛ.

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

flowchart LR
    d["ЁЯз╛ debt items<br/>principal h ┬╖ interest h/wk"] --> f["flaky test suite<br/>24 h ┬╖ 6 h/wk<br/>pays back in 4 wk тЖТ pay"]
    d --> m["manual release steps<br/>40 h ┬╖ 5 h/wk<br/>8 wk тЖТ pay"]
    d --> g["tangled gradebook core<br/>200 h ┬╖ 4 h/wk ┬╖ 50 wk<br/>26-wk horizon: carry ┬╖ 104-wk: pay"]
    d --> o["old report module<br/>120 h ┬╖ 1 h/wk<br/>120 wk тЖТ carry"]
    t["ЁЯТ╕ total interest 16 h/wk<br/>= 10% of 160 h"] --> d

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

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

ЁЯдФ рдХрд╛

рдХрд╛рд░рдг "рдЖрдореНрд╣рд╛рд▓рд╛ tech debt рд╕рд╛рдареА рд╡реЗрд│ рд╣рд╡рд╛" рд╣реЗ рднрд╛рд╡рдирд╛ рдореНрд╣рдгреВрди рд╕рд╛рдВрдЧрд┐рддрд▓реЗ рдХреА рдкреНрд░рддреНрдпреЗрдХ prioritisation meeting (рдзрдбрд╛ 06) рдордзреНрдпреЗ рд╣рд░рддреЗ. рдХрд┐рдВрдордд рдореНрд╣рдгреВрди рд╕рд╛рдВрдЧрд┐рддрд▓реЗ тАФ "flaky test suite рдЖрдкрд▓реЗ рджрд░ рдЖрдард╡рдбреНрдпрд╛рд▓рд╛ 6 рддрд╛рд╕ рдШреЗрддреЛ; рджреБрд░реБрд╕реНрдд рдХрд░рд╛рдпрд▓рд╛ 24 рддрд╛рд╕ рд▓рд╛рдЧрддрд╛рдд" тАФ рдХреА рддреЗ features рд╢реА рдмрд░реЛрдмрд░реАрдиреЗ рд╕реНрдкрд░реНрдзрд╛ рдХрд░рддреЗ. рдЖрдгрд┐ рдХрд┐рдВрдордд рд▓рд╛рд╡рд▓реНрдпрд╛рдиреЗ рдХреЛрдгрддреЗ debt рддрд╕реЗрдЪ рд╕реЛрдбрд╛рдпрдЪреЗ рд╣реЗрд╣реА рджрд┐рд╕рддреЗ: рдХреЛрдгреА рд╣рд╛рдд рд▓рд╛рд╡рдд рдирд╛рд╣реА рдЕрд╕рд╛ code рдкреБрдиреНрд╣рд╛ рд▓рд┐рд╣рд┐рдгреЗ рд╣рд╛ engineering рдЪрд╛ рд╡реЗрд│ рд╡рд╛рдпрд╛ рдШрд╛рд▓рд╡рдгреНрдпрд╛рдЪрд╛ рд╕рд░реНрд╡рд╛рдд рдиреЗрд╣рдореАрдЪрд╛ рдорд╛рд░реНрдЧ рдЖрд╣реЗ.

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

lead/models.py рдордзрд▓реЗ debt_plan(items, horizon) (name, principal hours, interest hours/week) items рдШреЗрддреЗ. рдкреНрд░рддреНрдпреЗрдХрд╛рд╕рд╛рдареА рддреЗ payback period (principal ├╖ interest) рдЖрдгрд┐ horizon рд╡рд░реАрд▓ net рддрд╛рд╕ (interest ├Ч horizon тИТ principal) рдореЛрдЬрддреЗ, рдЖрдгрд┐ net positive рдЕрд╕реЗрд▓ рддрд░ pay рдЖрдгрд┐ рдирд╕реЗрд▓ рддрд░ carry рд╕рд╛рдВрдЧрддреЗ; rows payback рдиреБрд╕рд╛рд░ sorted рдкрд░рдд рдпреЗрддрд╛рдд. lead/demo.py рдордзрд▓реЗ debt() рдЪрд╛рд░ items рдЪреА 26 рдЖрдгрд┐ 104 рдЖрдард╡рдбреНрдпрд╛рдВрд╕рд╛рдареА рдХрд┐рдВрдордд рд▓рд╛рд╡рддреЗ. Interest рдЪреЗ рдЖрдХрдбреЗ рдЕрдВрджрд╛рдЬ рдЖрд╣реЗрдд: рд╡рд┐рдЪрд╛рд░ рдХрд░рдгреНрдпрд╛рдЪреЗ рд╕рд╛рдзрди, рдорд╛рдгрд╕рд╛рдВрд╕рд╛рдареАрдЪреЗ рд╕реВрддреНрд░ рдирд╛рд╣реА тАФ рдЖрдгрд┐ code рд▓рд┐рд╣рд┐рдгрд╛рд▒реНрдпрд╛ рдХреЛрдгрд╛рд▓рд╛рд╣реА рджреЛрд╖ рджреЗрдгреНрдпрд╛рдЪрд╛ рдорд╛рд░реНрдЧ рддрд░ рдХрдзреАрдЪ рдирд╛рд╣реА.

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

python3 lead/demo.py debt
python3 - <<'EOF'
import sys; sys.path.insert(0, "lead"); from models import debt_plan
core = [("tangled gradebook core", 200, 4)]
for horizon in (13, 26, 50, 52, 104):
    name, p, i, payback, net, act = debt_plan(core, horizon)[0]
    print(f"gradebook core, horizon {horizon:>3} weeks тЖТ net {net:>+5} h тЖТ {act}")
for interest in (1, 4, 8):
    r = debt_plan([("core", 200, interest)], 26)[0]
    print(f"interest {interest} h/wk тЖТ pays back in {r[3]:>5.1f} weeks")
EOF

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

debt рдЕрд╕реЗ print рдХрд░рддреЗ (26 рдЖрдард╡рдбреНрдпрд╛рдВрдЪрд╛ horizon, рдордЧ 104):

     flaky test suite         principal  24 h ┬╖ interest 6 h/wk ┬╖ pays back in   4.0 wk ┬╖ net  +132 h тЖТ pay
     manual release steps     principal  40 h ┬╖ interest 5 h/wk ┬╖ pays back in   8.0 wk ┬╖ net   +90 h тЖТ pay
     tangled gradebook core   principal 200 h ┬╖ interest 4 h/wk ┬╖ pays back in  50.0 wk ┬╖ net   -96 h тЖТ carry
     old report module        principal 120 h ┬╖ interest 1 h/wk ┬╖ pays back in 120.0 wk ┬╖ net   -94 h тЖТ carry
     tangled gradebook core   principal 200 h ┬╖ interest 4 h/wk ┬╖ pays back in  50.0 wk ┬╖ net  +216 h тЖТ pay
     old report module        principal 120 h ┬╖ interest 1 h/wk ┬╖ pays back in 120.0 wk ┬╖ net   -16 h тЖТ carry
   total interest 16 h/week out of a team's 160 h/week (10%) тАФ paid every week, whether or not anyone decides to

рддреБрдордЪрд╛ snippet рдЕрд╕реЗ print рдХрд░рддреЛ:

gradebook core, horizon  13 weeks тЖТ net  -148 h тЖТ carry
gradebook core, horizon  26 weeks тЖТ net   -96 h тЖТ carry
gradebook core, horizon  50 weeks тЖТ net    +0 h тЖТ carry
gradebook core, horizon  52 weeks тЖТ net    +8 h тЖТ pay
gradebook core, horizon 104 weeks тЖТ net  +216 h тЖТ pay
interest 1 h/wk тЖТ pays back in 200.0 weeks
interest 4 h/wk тЖТ pays back in  50.0 weeks
interest 8 h/wk тЖТ pays back in  25.0 weeks

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

Flaky test suite 4 рдЖрдард╡рдбреНрдпрд╛рдВрдд рд╡рд╕реВрд▓ рд╣реЛрддреЛ рдЖрдгрд┐ рдЕрд░реНрдзреНрдпрд╛ рд╡рд░реНрд╖рд╛рдд 132 рддрд╛рд╕ рд╡рд╛рдЪрд╡рддреЛ тАФ рддреЛ рдЖрддреНрддрд╛ рдлреЗрдбрд╛. Old report module рджреЛрди рд╡рд░реНрд╖рд╛рдВрддрд╣реА рдХрдзреА рд╡рд╕реВрд▓ рд╣реЛрдд рдирд╛рд╣реА тАФ рддреЛ рдмрд╛рд│рдЧрд╛. Tangled gradebook core рд╣рд╛ рд░рдВрдЬрдХ рдЖрд╣реЗ: 26 рдЖрдард╡рдбреНрдпрд╛рдВрдд рддреЛ рджреБрд░реБрд╕реНрдд рдХреЗрд▓реНрдпрд╛рдиреЗ 96 рддрд╛рд╕ рдЬрд╛рддрд╛рдд, 104 рдЖрдард╡рдбреНрдпрд╛рдВрдд рддреЛ 216 рд╡рд╛рдЪрд╡рддреЛ; break-even рдиреЗрдордХреЗ 50 рдЖрдард╡рдбреЗ рдЖрд╣реЗ. рдореНрд╣рдгрдЬреЗ рдпреЛрдЧреНрдп рдЙрддреНрддрд░ code рдХрд┐рддреА рдХреБрд░реВрдк рдЖрд╣реЗ рдпрд╛рд╡рд░ рдирд╛рд╣реА, рддрд░ рдЖрд░рд╛рдЦрдбреНрдпрд╛рд╡рд░ рдЕрд╡рд▓рдВрдмреВрди рдЖрд╣реЗ. рджрд░рдореНрдпрд╛рди рдЪрд╛рд░рд╣реА items рдЪреА рдХрд┐рдВрдордд рдЖрдард╡рдбреНрдпрд╛рд▓рд╛ 16 рддрд╛рд╕ тАФ рдЯреАрдордЪреНрдпрд╛ 10% тАФ рдЖрд╣реЗ, рдХреЛрдгреА рдард░рд╡реЛ рд╡рд╛ рди рдард░рд╡реЛ рднрд░рд▓реА рдЬрд╛рдгрд╛рд░реА.

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

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

Backlog рд╢реЗрдЬрд╛рд░реА рдПрдХ debt рдиреЛрдВрджрд╡рд╣реА рдЕрд╕рддреЗ, рддреНрдпрд╛рдЪ рдкрджреНрдзрддреАрдиреЗ рдХрд┐рдВрдордд рд▓рд╛рд╡рд▓реЗрд▓реА:

| Debt item              | Principal | Interest/wk | Payback | Evidence                              | Decision (week 14) |
|------------------------|-----------|-------------|---------|---------------------------------------|--------------------|
| Flaky test suite       | 24 h      | 6 h         | 4 wk    | 31% of CI runs re-run last month      | pay now            |
| Manual release steps   | 40 h      | 5 h         | 8 wk    | 2.5 h per release ├Ч 2 releases/wk      | pay this quarter   |
| Tangled gradebook core | 200 h     | 4 h         | 50 wk   | changes take 2├Ч longer than elsewhere | pay if kept 2 yrs  |
| Old report module      | 120 h     | 1 h         | 120 wk  | 3 changes this year                   | carry; revisit Q3  |

Interest рдЪрд╛ рдкреБрд░рд╛рд╡рд╛ рдЕрдиреЗрдХрджрд╛ рдЖрдзреАрдЪ рдЙрдкрд▓рдмреНрдз рдЕрд╕рддреЛ. рдЦрд▒реНрдпрд╛ repository рд╡рд░, рд╕рд░реНрд╡рд╛рдд рдЬрд╛рд╕реНрдд рд╡реЗрд│рд╛ рдмрджрд▓рдгрд╛рд▒реНрдпрд╛ files рдореНрд╣рдгрдЬреЗ рдЬрд┐рдереЗ interest рднрд░рд▓реЗ рдЬрд╛рддреЗ (рдвреЛрдмрд│ рд╕рдВрдХреЗрдд тАФ рдЯреАрдо рдХрд╛рдп рдореНрд╣рдгрддреЗ рддреНрдпрд╛рдЪреНрдпрд╛рд╕реЛрдмрдд рдЬреЛрдбреВрди рдкрд╛рд╣рд╛):

git log --since="6 months ago" --name-only --pretty=format: | sort | uniq -c | sort -rn | head -15

рдЕрдиреЗрдХ рдЯреАрдореНрд╕ рд╡реЗрдЧрд│реНрдпрд╛ "debt sprint" рдРрд╡рдЬреА рдпрд╛ рдХрд╛рдорд╛рд╕рд╛рдареА рдХреНрд╖рдорддреЗрдЪрд╛ рд╕реНрдерд┐рд░ рд╡рд╛рдЯрд╛ рд░рд╛рдЦреВрди рдареЗрд╡рддрд╛рдд (15тАУ20% рд╕рд╛рд░рдЦреЗ рдЖрдХрдбреЗ рдиреЗрд╣рдореАрдЪреЗ рдЖрд╣реЗрдд). рд╡рд╛рдЯрд╛ рдХрд┐рддреАрд╣реА рдЕрд╕реЛ, рддреЛ рдХрд╢рд╛рд╡рд░ рдЦрд░реНрдЪ рдХрд░рд╛рдпрдЪрд╛ рд╣реЗ рдиреЛрдВрджрд╡рд╣реА рдард░рд╡рддреЗ.

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ рдЖрд╣реЗ: рдкреНрд░рддреНрдпреЗрдХ debt item рдЪреА рдХрд┐рдВрдордд рдЖрдард╡рдбреНрдпрд╛рдЪреНрдпрд╛ рддрд╛рд╕рд╛рдВрдд рд▓рд╛рд╡рд╛, рд▓рд╡рдХрд░ рд╡рд╕реВрд▓ рд╣реЛрдгрд╛рд░реЗ рдЖрддреНрддрд╛ рджреБрд░реБрд╕реНрдд рдХрд░рд╛, рдмрд╛рдХреАрдЪреЗ рдкреБрдиреНрд╣рд╛ рдкрд╛рд╣рдгреНрдпрд╛рдЪреНрдпрд╛ рддрд╛рд░рдЦреЗрд╕рд╣ рдЬрд╛рдгреАрд╡рдкреВрд░реНрд╡рдХ рдмрд╛рд│рдЧрд╛ тАФ рдЖрдгрд┐ planning рдордзреНрдпреЗ рдПрдХреВрдг interest рдореЛрдареНрдпрд╛рдиреЗ рд╕рд╛рдВрдЧрд╛, рдХрд╛рд░рдг рддреЗ рдЖрдзреАрдЪ рднрд░рд▓реЗ рдЬрд╛рдд рдЖрд╣реЗ.

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

рд╡рд┐рднрд╛рдЧ рд╕реБрдзрд╛рд░рддреЛ рдЖрд╣реЗ рдХреА рдмрд┐рдШрдбрддреЛ рдЖрд╣реЗ рд╣реЗ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╕реЗ рдХрд│рддреЗ? рдкреБрдвреЗ: delivery metrics тАФ рдЖрдгрд┐ рдПрдЦрд╛рджрд╛ рдЖрдХрдбрд╛ target рдмрдирд▓рд╛ рдХреА рдХрд╛рдп рд╣реЛрддреЗ.

git checkout lesson-08-delivery-metrics

ЁЯз╛ Lesson 07 тАФ Technical debt as a portfolio: interest vs principal

ЁЯУН You are here: Lesson 07 of 12 ┬╖ Previous: lesson-06-prioritisation ┬╖ Next: lesson-08-delivery-metrics


ЁЯУж What's in this branch

Lesson 06, plus technical debt, priced like money: the principal (hours it would take to fix) and the interest (hours it costs the team every week until it is fixed). When to pay it, when to carry it, and why the answer depends on how long you will keep the code. debt() in lead/demo.py; debt_plan() in lead/models.py.

ЁЯзТ Explain like I'm 5

The maths department has some old, messy things: ЁЯз╣

Katrina asks two questions about each mess. "How long to fix it?" тАФ that is the principal. "How much time does it steal every week while we leave it?" тАФ that is the interest. ЁЯТ╕

The photocopier: small principal, big interest. Fix it now тАФ it pays back in a few weeks. The cupboard: big principal, tiny interest. Leave it. Tidying it would cost more than it ever saves тАФ unless the department starts using that cupboard every day.

Not all mess is worth cleaning. But the mess that steals time every week is costing you whether or not anyone decides to pay.

ЁЯЧ║я╕П Diagram

flowchart LR
    d["ЁЯз╛ debt items<br/>principal h ┬╖ interest h/wk"] --> f["flaky test suite<br/>24 h ┬╖ 6 h/wk<br/>pays back in 4 wk тЖТ pay"]
    d --> m["manual release steps<br/>40 h ┬╖ 5 h/wk<br/>8 wk тЖТ pay"]
    d --> g["tangled gradebook core<br/>200 h ┬╖ 4 h/wk ┬╖ 50 wk<br/>26-wk horizon: carry ┬╖ 104-wk: pay"]
    d --> o["old report module<br/>120 h ┬╖ 1 h/wk<br/>120 wk тЖТ carry"]
    t["ЁЯТ╕ total interest 16 h/wk<br/>= 10% of 160 h"] --> d

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

тЭУ What

ЁЯдФ Why

Because "we need time for tech debt" loses every prioritisation meeting (lesson 06) when it is said as a feeling. Said as a price тАФ "the flaky test suite costs us 6 hours every week; fixing it takes 24 hours" тАФ it competes on equal terms with features. And pricing also shows which debt to leave alone: rewriting code nobody touches is one of the most common ways engineering time is wasted.

ЁЯФз How (in this repo)

debt_plan(items, horizon) in lead/models.py takes (name, principal hours, interest hours/week) items. For each it computes the payback period (principal ├╖ interest) and the net hours over the horizon (interest ├Ч horizon тИТ principal), and says pay if the net is positive and carry if not; the rows come back sorted by payback. debt() in lead/demo.py prices four items at 26 and 104 weeks. The interest numbers are estimates: a thinking tool, not a formula for people тАФ and never a way to blame whoever wrote the code.

ЁЯзк Try it

python3 lead/demo.py debt
python3 - <<'EOF'
import sys; sys.path.insert(0, "lead"); from models import debt_plan
core = [("tangled gradebook core", 200, 4)]
for horizon in (13, 26, 50, 52, 104):
    name, p, i, payback, net, act = debt_plan(core, horizon)[0]
    print(f"gradebook core, horizon {horizon:>3} weeks тЖТ net {net:>+5} h тЖТ {act}")
for interest in (1, 4, 8):
    r = debt_plan([("core", 200, interest)], 26)[0]
    print(f"interest {interest} h/wk тЖТ pays back in {r[3]:>5.1f} weeks")
EOF

тЬЕ Verify тАФ what you should see

debt prints (26-week horizon, then 104):

     flaky test suite         principal  24 h ┬╖ interest 6 h/wk ┬╖ pays back in   4.0 wk ┬╖ net  +132 h тЖТ pay
     manual release steps     principal  40 h ┬╖ interest 5 h/wk ┬╖ pays back in   8.0 wk ┬╖ net   +90 h тЖТ pay
     tangled gradebook core   principal 200 h ┬╖ interest 4 h/wk ┬╖ pays back in  50.0 wk ┬╖ net   -96 h тЖТ carry
     old report module        principal 120 h ┬╖ interest 1 h/wk ┬╖ pays back in 120.0 wk ┬╖ net   -94 h тЖТ carry
     tangled gradebook core   principal 200 h ┬╖ interest 4 h/wk ┬╖ pays back in  50.0 wk ┬╖ net  +216 h тЖТ pay
     old report module        principal 120 h ┬╖ interest 1 h/wk ┬╖ pays back in 120.0 wk ┬╖ net   -16 h тЖТ carry
   total interest 16 h/week out of a team's 160 h/week (10%) тАФ paid every week, whether or not anyone decides to

Your snippet prints:

gradebook core, horizon  13 weeks тЖТ net  -148 h тЖТ carry
gradebook core, horizon  26 weeks тЖТ net   -96 h тЖТ carry
gradebook core, horizon  50 weeks тЖТ net    +0 h тЖТ carry
gradebook core, horizon  52 weeks тЖТ net    +8 h тЖТ pay
gradebook core, horizon 104 weeks тЖТ net  +216 h тЖТ pay
interest 1 h/wk тЖТ pays back in 200.0 weeks
interest 4 h/wk тЖТ pays back in  50.0 weeks
interest 8 h/wk тЖТ pays back in  25.0 weeks

ЁЯПБ What you just proved

The flaky test suite pays back in 4 weeks and saves 132 hours in half a year тАФ pay it now. The old report module never pays back within two years тАФ carry it. The tangled gradebook core is the interesting one: over 26 weeks fixing it loses 96 hours, over 104 weeks it saves 216; break-even is exactly 50 weeks. So the right answer depends on a plan, not on how ugly the code is. Meanwhile all four items cost 16 hours a week тАФ 10% of the team тАФ paid whether or not anyone decides to.

тЪая╕П Common mistakes

ЁЯПн In production

A debt register lives next to the backlog, priced the same way:

| Debt item              | Principal | Interest/wk | Payback | Evidence                              | Decision (week 14) |
|------------------------|-----------|-------------|---------|---------------------------------------|--------------------|
| Flaky test suite       | 24 h      | 6 h         | 4 wk    | 31% of CI runs re-run last month      | pay now            |
| Manual release steps   | 40 h      | 5 h         | 8 wk    | 2.5 h per release ├Ч 2 releases/wk      | pay this quarter   |
| Tangled gradebook core | 200 h     | 4 h         | 50 wk   | changes take 2├Ч longer than elsewhere | pay if kept 2 yrs  |
| Old report module      | 120 h     | 1 h         | 120 wk  | 3 changes this year                   | carry; revisit Q3  |

Evidence for interest often already exists. On a real repository, the files that change most often are where interest is paid (a rough signal тАФ pair it with what the team says):

git log --since="6 months ago" --name-only --pretty=format: | sort | uniq -c | sort -rn | head -15

Many teams also reserve a steady share of capacity for this work (numbers like 15тАУ20% are common) rather than a separate "debt sprint". Whatever the share, the register decides what it is spent on.

ЁЯПн Why this matters in production: price each debt item in hours per week, fix the fast-payback ones now, carry the rest on purpose with a date to look again тАФ and say the total interest out loud in planning, because it is already being paid.

тПня╕П Next

How do you know the department is getting better, or worse? Next: delivery metrics тАФ and what happens when a number becomes a target.

git checkout lesson-08-delivery-metrics
тЖР PreviousprioritisationNext тЖТdelivery metrics

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