Skip to content

Commit f655e2f

Browse files
committed
updated finance origins
1 parent 4760ec4 commit f655e2f

272 files changed

Lines changed: 17484 additions & 8584 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

design-py/src/osr_scenario/network_readme.py

Lines changed: 486 additions & 160 deletions
Large diffs are not rendered by default.

design-py/tests/test_osr_scenario.py

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -135,22 +135,22 @@ def test_generated_file_in_repo_matches_regenerated() -> None:
135135
)
136136

137137

138-
def test_finance_stack_defaults_are_grant_first() -> None:
138+
def test_finance_stack_defaults_are_grant_free() -> None:
139139
stack = _funding_stack({})
140-
assert stack.grant_frac == pytest.approx(0.40)
141-
assert stack.multi_frac == pytest.approx(0.50)
140+
assert stack.grant_frac == pytest.approx(0.00)
141+
assert stack.multi_frac == pytest.approx(0.80)
142142
assert stack.bond_frac == pytest.approx(0.0)
143-
assert stack.equity_frac == pytest.approx(0.10)
143+
assert stack.equity_frac == pytest.approx(0.20)
144144
assert stack.multi_rate == pytest.approx(0.020)
145145
assert stack.tenor == 40
146146

147147

148-
def test_country_finance_inherits_grant_first_defaults() -> None:
148+
def test_country_finance_inherits_grant_free_defaults() -> None:
149149
stack = _funding_stack(_load_country_finance("IQ"))
150-
assert stack.grant_frac == pytest.approx(0.40)
151-
assert stack.multi_frac == pytest.approx(0.50)
150+
assert stack.grant_frac == pytest.approx(0.00)
151+
assert stack.multi_frac == pytest.approx(0.80)
152152
assert stack.bond_frac == pytest.approx(0.0)
153-
assert stack.equity_frac == pytest.approx(0.10)
153+
assert stack.equity_frac == pytest.approx(0.20)
154154
assert stack.multi_rate == pytest.approx(0.020)
155155

156156

@@ -169,14 +169,24 @@ def test_readme_nets_operating_surplus_against_gov_debt_support() -> None:
169169
)
170170
assert (
171171
"| Operating surplus applied to debt support | "
172-
"-$18 M / yr | -$18 M / yr | **$0 k / yr** |"
172+
"-$28 M / yr | -$28 M / yr | **$0 k / yr** |"
173173
in text
174174
)
175175
assert (
176176
"| **Net gov repayable-debt support + residual OPEX subsidy** | "
177-
"$0 k / yr | $0 k / yr | **$18 M / yr** |"
177+
"$0 k / yr | $0 k / yr | **$28 M / yr** |"
178178
in text
179179
)
180+
assert (
181+
"| Green concessional loan | 80% | $708 M | 2.0% | "
182+
"40 y, 5 y grace | $28 M / yr |"
183+
in text
184+
)
185+
assert (
186+
"| Government equity (no debt service) | 20% | $177 M |"
187+
in text
188+
)
189+
assert "| Climate / development grant" not in text
180190
assert (
181191
"Dedicated utility-scale solar plant / contracted offsite PPA asset: "
182192
"**63.3 MW**"
@@ -204,16 +214,46 @@ def test_readme_nets_operating_surplus_against_gov_debt_support() -> None:
204214
in text
205215
)
206216
assert (
207-
"| Labour (400 FTE) | driverless roster: OCC/remote 65, "
208-
"station/platform 127, passenger service 36, fleet maintenance 64"
217+
"| Labour (408 FTE) | driverless roster: OCC/remote 65, "
218+
"station/platform 127, passenger service 44, fleet maintenance 64"
219+
in text
220+
)
221+
assert (
222+
"| Practical service capacity used | 50% | 80% | 17% |"
223+
in text
224+
)
225+
assert (
226+
"| Annual paid trips | 63.1 M | 100.9 M | 20.8 M |"
227+
in text
228+
)
229+
assert "| Daily active riders |" not in text
230+
assert "| Daily paid trips |" not in text
231+
assert "| Paid trips / active rider |" not in text
232+
assert "## Broad economic benefits (planning proxy)" in text
233+
assert (
234+
"| **Annual quantified benefit / activity proxy** | "
235+
"**$80 M / yr** | **$129 M / yr** |"
236+
in text
237+
)
238+
assert (
239+
"| Education | 3 education anchors | 9,065 trips/school day; "
240+
"2.0 M access-events/yr | 14,505 trips/school day; "
241+
"3.2 M access-events/yr |"
242+
in text
243+
)
244+
assert (
245+
"| Healthcare | 10 healthcare anchors | 15,951 trips/day; "
246+
"5.8 M access-events/yr | 25,521 trips/day; "
247+
"9.3 M access-events/yr |"
209248
in text
210249
)
211250
assert (
212-
"| Daily active riders | 52,795 | 95,031 | 28,489 |"
251+
"| CAPEX retained in local procurement / payroll | $466 M | "
252+
"53% of $885 M CAPEX using bucket local-content shares |"
213253
in text
214254
)
215255
assert (
216-
"| Daily paid trips | 105,590 | 190,062 | 56,977 |"
256+
"| Construction employment supported | 25,536 job-years |"
217257
in text
218258
)
219259
assert (

designs/central-africa/DR Congo/Bukavu/README.md

Lines changed: 64 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ Corridor polylines + stations as GeoJSON for GIS / alignment tooling: [`bukavu.c
6262
- **Network peak throughput (all lines, both directions):** 3 lines × 2 directions × 7,200 = **43,200 passengers/hour**
6363
- **Daily theoretical capacity (peak × 10):****432,000 passenger-trips/day**
6464
- **Practical daily service capacity** (80% load factor): ≈ **345,600 passenger-trips/day**
65-
- **Planning daily ridership scenario** (25-45% active-rider uptake of catchment (capped by practical service capacity)): ≈ **300,500345,600 paid trips/day** (150,250 – 172,800 daily active riders at 2 trips/rider/day)
65+
- **Planning annual paid-trip scenario** (capacity-led): ≈ **63.1100.9 M paid trips/year** at 50%–80% practical capacity utilisation
6666

6767
## Catchment
6868

@@ -205,31 +205,29 @@ Planning-grade financing model anchored to country financial parameters from [`l
205205

206206
### Government commitment summary (budgetable)
207207

208-
Bottom line for next year's budget submission. Construction phase runs **years 1–10** (public equity drawdown + interest-only grace on repayable debt; grant disbursements are non-repayable); steady-state operation begins **year 11** and runs for **30 years** until the loans amortise.
208+
Bottom line for next year's budget submission. Construction phase runs **years 1–10** (public equity drawdown + interest-only grace on repayable debt; no climate-development grant assumed); steady-state operation begins **year 11** and runs for **30 years** until the loans amortise.
209209

210210
| Phase | Annual gov / municipal commitment | Per resident / yr |
211211
|---|---|---|
212-
| Construction (years 1–10) | **$18 M / yr** | $18 |
213-
| Steady-state, low-ridership (year 11+) | **$12 M / yr** | $12 |
214-
| Steady-state, high-ridership (year 11+) | **$7.3 M / yr** | $7 |
215-
| Steady-state, operating-neutral revenue case | **$21 M / yr** | $21 |
216-
| Lifecycle envelope (yr 1–40, low scenario) | **$546 M cumulative** | $546 |
217-
| Lifecycle envelope (yr 1–40, high scenario) | **$401 M cumulative** | $401 |
218-
| Lifecycle envelope (yr 1–40, operating-neutral after opening) | **$799 M cumulative** | $799 |
212+
| Construction (years 1–10) | **$33 M / yr** | $33 |
213+
| Steady-state, low capacity-use (year 11+) | **$38 M / yr** | $38 |
214+
| Steady-state, high capacity-use (year 11+) | **$27 M / yr** | $27 |
215+
| Steady-state, operating-neutral revenue case | **$33 M / yr** | $33 |
216+
| Lifecycle envelope (yr 1–40, low scenario) | **$1.47 bn cumulative** | $1,472 |
217+
| Lifecycle envelope (yr 1–40, high scenario) | **$1.14 bn cumulative** | $1,139 |
218+
| Lifecycle envelope (yr 1–40, operating-neutral after opening) | **$1.31 bn cumulative** | $1,315 |
219219

220-
_Population basis: 1,000,000 (catchment per `lib/city-batches/world-sample.toml`). After year 40, debt service drops to zero; steady-state commitments below are net of any operating surplus applied to repayable-debt support. The operating-neutral case already covers steady-state OPEX from fares, station shops, and advertising. Low/high residual OPEX shortfall before debt is $0 k / yr → $0 k / yr; surplus applied to debt support is $8.4 M / yr → $13 M / yr._
220+
_Population basis: 1,000,000 (city population per `lib/city-batches/world-sample.toml`). After year 40, debt service drops to zero; steady-state commitments below are net of any operating surplus applied to repayable-debt support. The operating-neutral case already covers steady-state OPEX from fares, station shops, and advertising. Low/high residual OPEX shortfall before debt is $5.2 M / yr → $0 k / yr; surplus applied to debt support is $0 k / yr → $5.9 M / yr._
221221

222222
### CAPEX funding stack
223223

224224
| Tranche | Share | Principal | Rate | Tenor | Annual debt service (post-grace) |
225225
|---|---|---|---|---|---|
226-
| Climate / development grant (non-repayable) | 40% | $367 M ||||
227-
| Green concessional loan (World Bank / AfDB / ADB / GCF class) | 50% | $459 M | 2.0% | 40 y, 10 y grace | $21 M / yr |
228-
| Sovereign / project bonds (fallback only) | 0% | $0 k | 13.0% | 40 y, 10 y grace | $0 k / yr |
229-
| Government equity (no debt service) | 10% | $92 M ||||
230-
| **Total** | **100%** | **$918 M** | | | **$21 M / yr** |
226+
| Green concessional loan | 80% | $735 M | 2.0% | 40 y, 10 y grace | $33 M / yr |
227+
| Government equity (no debt service) | 20% | $184 M ||||
228+
| **Total** | **100%** | **$918 M** | | | **$33 M / yr** |
231229

232-
_During the 10-year grace period the public sponsor pays interest only on repayable debt — concessional loan $9.2 M / yr + fallback bonds $0 k / yr = **$9.2 M / yr** total. The $367 M grant tranche carries no repayment or coupon. Government equity is drawn across construction ($9.2 M / yr × 10 yr). Principal repayment begins in year 11 on a 30-year amortisation schedule._
230+
_During the 10-year grace period the public sponsor pays interest only on repayable debt — green concessional loan $15 M / yr = **$15 M / yr** total. The base case assumes no climate-development grant. Government equity is drawn across construction ($18 M / yr × 10 yr). Principal repayment begins in year 11 on a 30-year amortisation schedule._
233231

234232
### Annual OPEX (steady state)
235233

@@ -239,7 +237,7 @@ _During the 10-year grace period the public sponsor pays interest only on repaya
239237
| Civil + station + depot maintenance | 2 % of fixed-asset CAPEX | $6.9 M |
240238
| Residual train-control wayside maintenance | 5 % of residual signalling CAPEX | $145 k |
241239
| Traction energy (143.7 GWh / yr) | 30,378 scheduled train-km/day × 365 d/yr × 108% depot/deadhead factor; 3 cars × 4.0 kWh/car-km; on-site PV 33.4 GWh/yr + dedicated solar plant 69.5 MW / 126.9 GWh/yr (100% coverage); residual grid/PPA top-up 0.0 GWh/yr @ $0.10/kWh; solar plant O&M 1.5%/yr | $834 k |
242-
| Labour (430 FTE) | driverless roster: OCC/remote 65, station/platform 131, passenger service 51, fleet maintenance 70, infrastructure/energy 77, admin/training 36; no train drivers × country median × 12 × engineer-premium 1.4 | $795 k |
240+
| Labour (423 FTE) | driverless roster: OCC/remote 65, station/platform 131, passenger service 44, fleet maintenance 70, infrastructure/energy 77, admin/training 36; no train drivers × country median × 12 × engineer-premium 1.4 | $782 k |
243241
| **OPEX subtotal** | | **$25 M / yr** |
244242

245243
_Annual service work: 30,378 scheduled train-km/day × 365 d/yr × 108% depot/deadhead factor = 12.0 M train-km / yr (35.9 M car-km / yr). On-site PV covers 33.4 GWh/yr and the dedicated solar plant adds 126.9 GWh/yr against 143.7 GWh/yr traction demand before residual grid/PPA top-up (0.0 GWh/yr). Driverless labour follows RFC 0015: train drivers are not counted, but OCC remote-assist, platform presence, passenger service, and fleet/energy maintenance scale with the larger service._
@@ -257,30 +255,64 @@ Country median monthly income: **$110 USD** (per [`lib/templates/country-finance
257255

258256
### Revenue & operating neutrality
259257

260-
Planning ridership bracket = daily active riders at 25-45% of catchment, converted to paid trips at 2 trips/rider/day and capped by practical service capacity (345,600 trips/day). Annual paid trips multiply daily paid trips by 365 service-days at the operating-neutral fare. The operating-neutral column solves annual paid trips so **farebox + station-shop leases + advertising = steady-state OPEX**. Gross post-grace repayable-debt service remains visible in the CAPEX funding stack, while any operating surplus is netted from the budgetable government support line.
258+
Planning revenue is capacity-led: annual paid trips are calculated from practical daily service capacity (345,600 trips/day) × 365 service-days × capacity utilisation. The low/high bracket uses 50%–80% of that practical capacity. The operating-neutral column solves the capacity utilisation needed so **farebox + station-shop leases + advertising = steady-state OPEX**. Gross post-grace repayable-debt service remains visible in the CAPEX funding stack, while any operating surplus is netted from the budgetable government support line.
261259

262260
| | Low scenario | High scenario | Operating-neutral target |
263261
|---|---|---|---|
264-
| Daily active riders | 150,250 | 172,800 | 110,945 |
265-
| Daily active riders / catchment | 25% | 29% | 18% |
266-
| Paid trips / active rider | 2 | 2 | 2 |
267-
| Daily paid trips | 300,500 | 345,600 | 221,891 |
268-
| Daily paid trips / city population | 30% | 35% | 22% |
269-
| Annual paid trips | 109.7 M | 126.1 M | 81.0 M |
270-
| Farebox revenue | $32 M / yr | $37 M / yr | $24 M / yr |
262+
| Practical service capacity used | 50% | 80% | 64% |
263+
| Annual paid trips | 63.1 M | 100.9 M | 80.9 M |
264+
| Annual paid trips / city resident | 63 | 101 | 81 |
265+
| Farebox revenue | $19 M / yr | $30 M / yr | $24 M / yr |
271266
| Station shop leases | $589 k / yr | $589 k / yr | $589 k / yr |
272267
| Advertising boards | $842 k / yr | $842 k / yr | $842 k / yr |
273-
| **Total revenue** | **$34 M / yr** | **$38 M / yr** | **$25 M / yr** |
274-
| Revenue / OPEX recovery | 133% | 153% | 100% |
268+
| **Total revenue** | **$20 M / yr** | **$31 M / yr** | **$25 M / yr** |
269+
| Revenue / OPEX recovery | 79% | 123% | 100% |
275270
| Country farebox-only policy target (diagnostic) | 30% | 30% | 30% |
276-
| Gross repayable-debt service + residual OPEX subsidy | $21 M / yr | $21 M / yr | **$21 M / yr** |
277-
| Operating surplus applied to debt support | -$8.4 M / yr | -$13 M / yr | **$0 k / yr** |
278-
| **Net gov repayable-debt support + residual OPEX subsidy** | $12 M / yr | $7.3 M / yr | **$21 M / yr** |
279-
| Operating surplus after OPEX (before debt support) | $8.4 M / yr | $13 M / yr | $0 / yr |
271+
| Gross repayable-debt service + residual OPEX subsidy | $38 M / yr | $33 M / yr | **$33 M / yr** |
272+
| Operating surplus applied to debt support | $0 k / yr | -$5.9 M / yr | **$0 k / yr** |
273+
| **Net gov repayable-debt support + residual OPEX subsidy** | $38 M / yr | $27 M / yr | **$33 M / yr** |
274+
| Operating surplus after OPEX (before debt support) | $0 k / yr | $5.9 M / yr | $0 / yr |
280275

281276
_Commercial-revenue assumptions: 5,576 m² of station shop/kiosk leases at $10/m²/month and 1,072 advertising boards at $77/board/month, with occupancy derates applied._
282277

283-
**Caveats:** The grant-first funding stack, the 8 % operating-neutral fare target, the 25-45% daily-active-rider bracket, and the station-commercial assumptions are project-level defaults. Real deployments will negotiate the capital split with financing institutions and tune fares, retail mix, advertising inventory, and service frequency iteratively from boarding data. Treat the numbers above as a first-iteration sanity check, not as a bid-ready financial close.
278+
**Caveats:** The grant-free funding stack, the 8 % operating-neutral fare target, the 50%–80% capacity-utilisation bracket, and the station-commercial assumptions are project-level defaults. Real deployments will negotiate the capital split with financing institutions and tune fares, retail mix, advertising inventory, and service frequency iteratively from boarding data. Treat the numbers above as a first-iteration sanity check, not as a bid-ready financial close.
279+
280+
## Broad economic benefits (planning proxy)
281+
282+
This is a broad-benefit screen, not a bankable benefit-cost analysis. The rows quantify useful channels for discussion — travel time, road externalities, access to essential services, station-area activity, and local CAPEX recirculation — but some channels overlap and should not be treated as audited fiscal revenue. Assumptions are loaded from [`lib/templates/economic-benefits.toml`](../../../../lib/templates/economic-benefits.toml).
283+
284+
### Annual benefit / activity proxy
285+
286+
| Channel | Low scenario | High scenario | Basis |
287+
|---|---:|---:|---|
288+
| Travel time + reliability dividend | $5.3 M / yr | $8.5 M / yr | 16 min/trip × $0.32/h value-of-time proxy |
289+
| Avoided road congestion | $14 M / yr | $22 M / yr | 171 M - 273 M vehicle-km/yr avoided × $0.08/vehicle-km |
290+
| Avoided CO2e | $2.5 M / yr | $3.9 M / yr | 30.8–49.2 ktCO2e/yr after rail residual-grid emissions × $80/t |
291+
| Local air / noise / safety externalities | $6.8 M / yr | $11 M / yr | avoided road vehicle-km × $0.04/vehicle-km |
292+
| Station-area commerce turnover supported | $21 M / yr | $33 M / yr | 22% of paid trips × $1.50 local spend proxy |
293+
| Entertainment / community activity supported | $10 M / yr | $16 M / yr | 11% of paid trips × $1.50 local spend proxy |
294+
| **Annual quantified benefit / activity proxy** | **$59 M / yr** | **$95 M / yr** | sum of rows above; use as a screening envelope, not audited revenue |
295+
296+
### Access to education, healthcare, commerce, and entertainment
297+
298+
| Access channel | Anchored stations / signal | Low scenario | High scenario |
299+
|---|---:|---:|---:|
300+
| Education | 3 education anchors | 10,411 trips/school day; 2.3 M access-events/yr | 16,658 trips/school day; 3.7 M access-events/yr |
301+
| Healthcare | 7 healthcare anchors | 16,718 trips/day; 6.1 M access-events/yr | 26,749 trips/day; 9.8 M access-events/yr |
302+
| Commerce | 21 major/terminal/interchange nodes | 37,946 trips/trading day; 12.5 M access-events/yr | 60,714 trips/trading day; 20.0 M access-events/yr |
303+
| Entertainment / community | 20.5 h/day service span | 18,317 trips/activity day; 5.5 M access-events/yr | 29,307 trips/activity day; 8.8 M access-events/yr |
304+
305+
### Local recirculation of initial CAPEX
306+
307+
| Channel | Value | Basis |
308+
|---|---:|---|
309+
| CAPEX retained in local procurement / payroll | $480 M | 52% of $918 M CAPEX using bucket local-content shares |
310+
| Construction-phase local economic activity | $768 M | retained CAPEX × 1.6 local supplier / wage multiplier |
311+
| Annualised during construction | $77 M / yr | spread across 10 construction / grace years |
312+
| Construction employment supported | 90,881 job-years | retained CAPEX ÷ (4.0 × median annual income) |
313+
| Annual paid-trip capacity used in revenue model | 63.1 M - 100.9 M trips/yr | 50%-80% of practical service capacity |
314+
315+
_Interpretation: the strongest fiscal result remains the farebox + commercial revenue table above. The broader rows here capture welfare, access, avoided external costs, and local supplier circulation that usually matter to a finance ministry, city authority, or development bank even when they do not appear as railway revenue._
284316

285317
## Files
286318

0 commit comments

Comments
 (0)