diff --git a/lectures/_static/quant-econ.bib b/lectures/_static/quant-econ.bib
index eaa1b26a..ae7b6900 100644
--- a/lectures/_static/quant-econ.bib
+++ b/lectures/_static/quant-econ.bib
@@ -3872,3 +3872,32 @@ @article{ThomasWorrall1994
pages = {81--108},
year = {1994}
}
+
+@article{Armington1969,
+ author = {Armington, Paul S.},
+ title = {A Theory of Demand for Products Distinguished by Place of Production},
+ journal = {IMF Staff Papers},
+ volume = {16},
+ number = {1},
+ pages = {159--178},
+ year = {1969}
+}
+
+@article{HuoLevchenkoPandalaiNayar2025,
+ author = {Huo, Zhen and Levchenko, Andrei A. and Pandalai-Nayar, Nitya},
+ title = {International Comovement in the Global Production Network},
+ journal = {Review of Economic Studies},
+ volume = {92},
+ number = {1},
+ pages = {365--403},
+ year = {2025}
+}
+
+@article{BonadioEtAl2026,
+ author = {Bonadio, Barth{\'e}l{\'e}my and Huo, Zhen and Kang, Elliot and Levchenko, Andrei A. and Pandalai-Nayar, Nitya and Toma, Hiroshi and Topalova, Petia},
+ title = {Playing with Blocs: Quantifying Decoupling},
+ journal = {Journal of International Economics},
+ volume = {163},
+ pages = {104204},
+ year = {2026}
+}
diff --git a/lectures/_toc.yml b/lectures/_toc.yml
index 3c916a06..dbc15ef7 100644
--- a/lectures/_toc.yml
+++ b/lectures/_toc.yml
@@ -96,6 +96,7 @@ parts:
- file: dovis_accounting_mf
- file: gradual_trade_agreements
- file: organizational_equilibrium
+ - file: gradual_liberalization_network
- caption: Other
numbered: true
chapters:
diff --git a/lectures/gradual_liberalization_network.md b/lectures/gradual_liberalization_network.md
new file mode 100644
index 00000000..634e213a
--- /dev/null
+++ b/lectures/gradual_liberalization_network.md
@@ -0,0 +1,1141 @@
+---
+jupytext:
+ text_representation:
+ extension: .md
+ format_name: myst
+ format_version: 0.13
+ jupytext_version: 1.17.1
+kernelspec:
+ display_name: Python 3 (ipykernel)
+ language: python
+ name: python3
+---
+
+(gradual_liberalization_network)=
+```{raw} jupyter
+
+```
+
+# Gradual Liberalization in a Global Production Network
+
+```{contents} Contents
+:depth: 2
+```
+
+## Overview
+
+{doc}`organizational_equilibrium` computed organizational equilibrium tariffs in the two-country,
+two-sector model of {cite:t}`BassettoHuoRiosRull2024`.
+
+{cite:t}`BassettoHuoRiosRull2026` take the same question to a quantitative model of the G7 economies with 30
+sectors, trade in final and intermediate goods, workers attached to sectors, and internationally mobile
+capital.
+
+Two ideas make their model tractable.
+
+* **Static separability**: every static quantity is proportional to the world capital stock, so the
+ dynamic policy problem depends on the static economy only through two functions of the tariff, worker
+ welfare $\chi(\tau)$ and the gross return to capital $G(\tau)$, just as in
+ {doc}`organizational_equilibrium`.
+* **Exact hat algebra**: $\chi(\tau)$ and $G(\tau)$ can be computed from observed expenditure and
+ production shares, without estimating technologies, tastes, or the sizes of labor forces
+ {cite}`DekleEatonKortum2008`.
+
+Their model belongs to a family of global production network models that
+{cite:t}`HuoLevchenkoPandalaiNayar2025` use to study how business cycles spread across countries and that
+{cite:t}`BonadioEtAl2026` use to quantify the recent reorganization of world trade into blocs.
+
+This lecture builds a small version of the model, with three countries and five sectors.
+
+We do not use the data of {cite:t}`BassettoHuoRiosRull2026`.
+
+Instead we use illustrative shares, chosen so that the model's Markov and best constant tariffs, 14.5 and
+1.2 percent, are close to theirs, about 12 and 1.3 percent.
+
+Matching their tariffs requires wages to be very unequal across home's sectors, and we explain why.
+
+The lecture
+
+* sets out the model, shows why it is separable, and solves it in changes from a baseline,
+* decomposes how a tariff affects the welfare of home's workers,
+* derives a simple condition that tells when a tariff is worth its cost to capital accumulation,
+* computes Markov, Ramsey, and organizational equilibrium tariffs and their responses to a protectionist
+ shock, and
+* relates the model to the recent formation of trade blocs.
+
+We use the following imports.
+
+```{code-cell} ipython3
+import numpy as np
+import matplotlib.pyplot as plt
+from collections import namedtuple
+from scipy.interpolate import CubicSpline
+from scipy.optimize import brentq, minimize, minimize_scalar
+```
+
+## The economy
+
+There are $N$ countries, indexed by $m$ and $n$, and $J$ sectors, indexed by $i$ and $j$.
+
+Each country-sector pair produces a distinct good, so buyers treat goods from different countries as
+imperfect substitutes {cite}`Armington1969`.
+
+Time is discrete, and we drop time subscripts when nothing is lost.
+
+### Tariffs
+
+A lead country, which we call home and number $1$, chooses a tariff $\tau$ on all imports, and every other
+country responds with the same tariff on its own imports.
+
+A buyer in country $n$ therefore pays $D_{mn} p_{mj}$ for a sector-$j$ good that sells for $p_{mj}$ in
+country $m$, where
+
+$$
+D_{mn} = 1 + \tau \, \mathbb{1}\{m \neq n\}
+$$
+
+is the gross tariff wedge.
+
+### Final goods
+
+Country $n$'s final good, which is used for both consumption and investment, is a Cobb–Douglas aggregate
+of sector bundles with expenditure shares $\Phi_j$.
+
+Each sector bundle is a CES aggregate of the goods of all origins with elasticity of substitution
+$\varepsilon$.
+
+The price of country $n$'s final good is
+
+$$
+P_n = \prod_j \left(Q^c_{nj}\right)^{\Phi_j}, \qquad
+Q^c_{nj} = \left[ \sum_m \Omega^c_{mnj} \left(D_{mn} p_{mj}\right)^{1 - \varepsilon}
+\right]^{1/(1 - \varepsilon)} ,
+$$
+
+where the weights $\Omega^c_{mnj}$ capture tastes and trade costs other than tariffs.
+
+Origin $m$ receives the share
+
+$$
+\pi^c_{mnj} = \Omega^c_{mnj} \left(\frac{D_{mn} p_{mj}}{Q^c_{nj}}\right)^{1 - \varepsilon}
+$$
+
+of country $n$'s final spending on sector $j$.
+
+### Production
+
+Sector $j$ in country $n$ produces with capital $k_{nj}$, labor $\ell_{nj}$, and a bundle $x_{nj}$ of
+intermediate inputs, where labor equals the fixed number $L_{nj}$ of workers attached to the sector:
+
+$$
+y_{nj} = A_{nj} K_n^{\alpha_{\ell, j}} k_{nj}^{\alpha_{k, j}} \ell_{nj}^{\alpha_{\ell, j}}
+x_{nj}^{\alpha_{x, j}}, \qquad \alpha_{k, j} + \alpha_{\ell, j} + \alpha_{x, j} = 1 ,
+$$
+
+where $K_n = \sum_j k_{nj}$ is the capital stock used in country $n$, which firms take as given.
+
+This externality makes output proportional to capital, as in an $AK$ growth model.
+
+The input bundle $x_{nj}$ is a Cobb–Douglas aggregate of sector bundles with shares $\Xi_{ji}$, and each
+sector bundle is a CES aggregate across origins with the same elasticity $\varepsilon$.
+
+For simplicity, all buyers of inputs from sector $i$ in country $n$ split their purchases across origins in
+the same shares $\pi^x_{mni}$.
+
+Let $e_{nj} = p_{nj} y_{nj}$ be the revenue of sector $j$ in country $n$.
+
+Cost minimization gives
+
+$$
+R k_{nj} = \alpha_{k, j} e_{nj}, \qquad W_{nj} L_{nj} = \alpha_{\ell, j} e_{nj}, \qquad
+P^x_{nj} x_{nj} = \alpha_{x, j} e_{nj} ,
+$$
+
+where $R$ is the rental rate of capital, $W_{nj}$ is the wage in sector $j$ of country $n$, and
+$P^x_{nj}$ is the price of the input bundle.
+
+### Workers
+
+Workers are attached to their sector and do not save.
+
+Each worker receives an equal share of the country's tariff revenue $T_n = T^c_n + T^x_n$, collected on
+imports of final goods and of intermediate inputs, so a worker in sector $j$ of country $n$ consumes
+
+$$
+C_{nj} = \frac{W_{nj} + T_n / L_n}{P_n} ,
+$$
+
+where $L_n = \sum_j L_{nj}$.
+
+### The world capitalist
+
+A world capitalist owns the world capital stock $K$ and rents it to firms in all countries at the common
+rate $R$.
+
+The capitalist buys a Cobb–Douglas composite of the countries' final goods with expenditure shares
+$\mu_n$ and price $P^K = \prod_n P_n^{\mu_n}$, and divides it between consumption $C^K$ and new capital:
+
+$$
+C^K_t + K_{t+1} = G_t K_t, \qquad G_t = 1 + \frac{R_t}{P^K_t} - \delta_k ,
+$$
+
+where $\delta_k$ is the depreciation rate.
+
+The capitalist maximizes $\sum_t \beta^t (C^K_t)^{1 - \sigma} / (1 - \sigma)$, which gives the same Euler
+equation for the saving rate $s_t = K_{t+1} / (G_t K_t)$ as in {doc}`organizational_equilibrium`.
+
+The capitalist's spending on final goods, $R K$, is divided across countries in the proportions $\mu_n$.
+
+### The policymaker
+
+Home's policymaker maximizes the welfare of home's workers,
+
+$$
+\sum_{t=0}^\infty \beta^t \sum_j \lambda_j \log C_{1j, t} ,
+$$
+
+where $\lambda_j = L_{1j} / L_1$ is the share of home's workers employed in sector $j$.
+
+## Static equilibrium and separability
+
+Given the tariff and the world capital stock, a static equilibrium is a set of prices and allocations at
+which firms and buyers optimize and all markets clear.
+
+Country $n$'s spending on final goods consists of its workers' income and the capitalist's spending
+there,
+
+$$
+E_n = \sum_j \alpha_{\ell, j} e_{nj} + T^c_n + T^x_n + \mu_n \kappa, \qquad
+\kappa = R K = \sum_{n, j} \alpha_{k, j} e_{nj} .
+$$
+
+Tariff revenues are
+
+$$
+T^c_n = E_n \sum_j \Phi_j \sum_{m \neq n} \frac{\tau}{1 + \tau} \pi^c_{mnj}, \qquad
+T^x_n = \sum_j \alpha_{x, j} e_{nj} \sum_i \Xi_{ji} \sum_{m \neq n} \frac{\tau}{1 + \tau} \pi^x_{mni} .
+$$
+
+The revenue of each country-sector equals what buyers spend on its good, net of tariffs:
+
+```{math}
+:label: gln-market
+e_{mi} = \sum_n \frac{\pi^c_{mni}}{D_{mn}} \Phi_i E_n
++ \sum_{n, j} \frac{\pi^x_{mni}}{D_{mn}} \Xi_{ji} \alpha_{x, j} e_{nj} .
+```
+
+Given the shares, {eq}`gln-market` is a homogeneous linear system in revenues, so we normalize world
+revenue to $\sum_{n, j} e_{nj} = 1$.
+
+{cite:t}`BassettoHuoRiosRull2026` show that the static equilibrium is **separable** in world capital.
+
+Suppose we multiply the world capital stock by $a > 0$, multiply every quantity of capital, inputs, and
+output by $a$, divide every price by $a$, and leave wages unchanged.
+
+Because the externality makes each production function homogeneous of degree one in capital, inputs, and
+the country's capital stock, the scaled quantities are feasible.
+
+Because all goods prices and the rental rate move together, no expenditure share changes, and revenues,
+wages, and tariff revenues are unchanged.
+
+So revenues, shares, and tariff revenues depend on the tariff but not on $K$, and prices are proportional
+to $1/K$.
+
+It follows that each worker's consumption is proportional to world capital, $C_{nj} = K \psi_{nj}(\tau)$,
+and that the real rental rate $r = R / P^K$ depends only on the tariff.
+
+The policymaker's payoff therefore has the form that it has in {doc}`organizational_equilibrium`,
+
+$$
+U_t = \frac{\log K_t}{1 - \beta} + \sum_{k=0}^\infty \beta^k H(\tau_{t+k}, s_{t+k}), \qquad
+H(\tau, s) = \chi(\tau) + \frac{\beta}{1 - \beta} \left[ \log s + \log G(\tau) \right] ,
+$$
+
+with $\chi(\tau) = \sum_j \lambda_j \log \psi_{1j}(\tau)$ and $G(\tau) = 1 + r(\tau) - \delta_k$.
+
+Once we know $\chi$ and $G$, everything in that lecture's analysis of tariffs carries over.
+
+## Solving in changes
+
+{cite:t}`BassettoHuoRiosRull2026` compute $\chi$ and $G$ by solving the static equilibrium in changes
+from a baseline equilibrium with tariff $\tau_0$.
+
+Write $\hat z = z' / z$ for the ratio of a variable's value at a new tariff to its value at the baseline,
+and let $d_{mn} = D'_{mn} / D_{mn}$.
+
+Origin shares and price indices for final goods change according to
+
+$$
+\pi^{c\prime}_{mnj} = \frac{\pi^c_{mnj} (d_{mn} \hat p_{mj})^{1 - \varepsilon}}
+{\sum_r \pi^c_{rnj} (d_{rn} \hat p_{rj})^{1 - \varepsilon}}, \qquad
+\hat P_n = \prod_j \left[ \sum_m \pi^c_{mnj} (d_{mn} \hat p_{mj})^{1 - \varepsilon}
+\right]^{\Phi_j / (1 - \varepsilon)} ,
+$$
+
+and those for intermediate inputs change in the same way.
+
+The weights $\Omega^c_{mnj}$ have dropped out, because baseline shares summarize them.
+
+Solving the production function for the price at which revenue $e_{nj}$ is consistent with cost
+minimization, and dividing by its baseline value, gives
+
+```{math}
+:label: gln-price
+\hat p_{nj} = \hat\kappa^{\alpha_{k, j}} \, \hat e_{nj}^{\alpha_{\ell, j}} \,
+\left(\hat P^x_{nj}\right)^{\alpha_{x, j}} \, \hat\vartheta_n^{-\alpha_{\ell, j}} ,
+```
+
+where $\vartheta_n = \sum_j \alpha_{k, j} e_{nj} / \kappa$ is country $n$'s share of world capital; the
+technologies $A_{nj}$ and the numbers of workers $L_{nj}$ have dropped out too.
+
+Given baseline shares and revenues, the new shares, {eq}`gln-price`, and {eq}`gln-market` determine the
+new equilibrium, which we compute by iterating on prices and revenues.
+
+Worker welfare needs only home's employment shares, since
+$\psi_{1j} \propto (\alpha_{\ell, j} e_{1j} / \lambda_j + T_1) / P_1$, with a factor of proportionality
+that is the same for all sectors.
+
+The gross return needs one more number, the baseline real rental rate $r_0$, because the changes give only
+$r(\tau) / r_0$.
+
+Like {cite:t}`BassettoHuoRiosRull2026`, we choose $r_0$ so that capital grows at 2 percent a year in the
+long run of the organizational equilibrium.
+
+### Illustrative shares
+
+The shares are deliberately illustrative.
+
+Our world has three countries, home, $A$, and $B$, and five sectors.
+
+Home is strongest in advanced manufacturing and business services, $A$ in agriculture, and $B$ in light
+manufacturing.
+
+All countries have the same sectoral spending shares $\Phi_j$, input–output shares $\Xi_{ji}$, and factor
+shares, which roughly resemble those of advanced economies, with labor receiving about 57 percent of
+home's value added.
+
+Origin shares come from a gravity-like formula, $\pi_{mnj} \propto s_{mj} b_j^{\mathbb{1}\{m = n\}}$,
+where $s_{mj}$ measures country $m$'s strength in sector $j$ and $b_j$ is a home bias that is large for
+services, which are barely traded.
+
+Final and intermediate buyers use the same origin shares.
+
+We set the capitalist's spending shares $\mu_n$ equal to each country's share of world capital income at
+the baseline, so that the capitalist spends in each country what capital earns there.
+
+As {cite:t}`BassettoHuoRiosRull2026` do, we take the baseline tariff to be 5 percent, and baseline
+revenues solve {eq}`gln-market`.
+
+Home is a dual economy: agriculture employs 42 percent of its workers but pays them less than a tenth of
+the average wage.
+
+We explain {ref}`below ` why the model needs such unequal wages to deliver tariffs like the
+ones that Bassetto, Huo, and Ríos-Rull find.
+
+The next cell sets up the model and the market-clearing system {eq}`gln-market`, written as $e = B e$.
+
+```{code-cell} ipython3
+Network = namedtuple('Network', ('α_k', 'α_l', 'α_x', 'Φ', 'Ξ', 'πc', 'πx',
+ 'μ', 'λ', 'ε', 'D_0', 'e'))
+
+countries = ['home', 'A', 'B']
+sectors = ['agriculture', 'light manufacturing', 'advanced manufacturing',
+ 'business services', 'other services']
+
+def tariff_wedges(τ, N=3):
+ "Gross tariff wedges D[m, n] when every country taxes all imports at rate τ."
+ return 1 + τ * (1 - np.eye(N))
+
+def origin_shares(strength, home_bias):
+ "Shares π[m, n, j] of origin m in country n's purchases of sector j goods."
+ N, J = strength.shape
+ π = np.empty((N, N, J))
+ for n in range(N):
+ w = strength.copy()
+ w[n] = w[n] * home_bias
+ π[:, n, :] = w / w.sum(axis=0)
+ return π
+
+def revenue_system(πc, πx, D, model):
+ """
+ The matrix B in the market-clearing conditions e = B e, the final-use tariff
+ revenue g[n] per unit of final spending, and the intermediate-use tariff
+ revenue θ[n, j] per unit of spending on inputs.
+ """
+ α_k, α_l, α_x, Φ, Ξ, μ = model.α_k, model.α_l, model.α_x, model.Φ, model.Ξ, model.μ
+ N, J = πc.shape[1], len(Φ)
+ tax = (D - 1) / D # tariff share of a purchase from m by n
+ g = np.einsum('j,mn,mnj->n', Φ, tax, πc)
+ θ = np.einsum('ji,mn,mni->nj', Ξ, tax, πx)
+ # final spending E = A_E @ e, from E_n = labor income + T^x_n + μ_n κ + g_n E_n
+ A_E = np.outer(μ, np.tile(α_k, N))
+ for n in range(N):
+ A_E[n, n*J:(n+1)*J] += α_l + α_x * θ[n]
+ A_E /= (1 - g)[:, None]
+ C = np.einsum('mni,mn,i->min', πc, 1 / D, Φ).reshape(N * J, N)
+ X = np.einsum('mni,mn,ji,j->minj', πx, 1 / D, Ξ, α_x).reshape(N * J, N * J)
+ return C @ A_E + X, g, θ
+
+def solve_revenues(B):
+ "Revenues e with e = B e and world revenue normalized to one."
+ M = np.eye(len(B)) - B
+ M[-1] = 1
+ rhs = np.zeros(len(B))
+ rhs[-1] = 1
+ return np.linalg.solve(M, rhs)
+
+def create_network(λ=(0.42, 0.13, 0.04, 0.08, 0.33), ε=3.5, τ_0=0.05):
+ α_k = np.array([0.25, 0.15, 0.15, 0.20, 0.15]) # capital shares
+ α_l = np.array([0.15, 0.15, 0.15, 0.25, 0.30]) # labor shares
+ α_x = 1 - α_k - α_l # intermediate shares
+ Φ = np.array([0.05, 0.15, 0.15, 0.20, 0.45]) # final spending
+ Ξ = np.array([[0.30, 0.15, 0.15, 0.25, 0.15], # row j: inputs of sector j
+ [0.15, 0.40, 0.10, 0.25, 0.10],
+ [0.02, 0.15, 0.48, 0.25, 0.10],
+ [0.01, 0.06, 0.13, 0.60, 0.20],
+ [0.05, 0.15, 0.10, 0.35, 0.35]])
+ strength = np.array([[1.0, 0.6, 1.5, 1.5, 1.0], # home
+ [1.2, 0.8, 1.2, 1.0, 1.0], # A
+ [0.8, 2.0, 0.8, 0.6, 1.0]]) # B
+ home_bias = np.array([24.0, 15.0, 12.0, 60.0, 240.0])
+ π = origin_shares(strength, home_bias)
+ N, J = strength.shape
+ model = Network(α_k, α_l, α_x, Φ, Ξ, π, π.copy(), np.full(N, 1 / N),
+ np.array(λ), ε, tariff_wedges(τ_0, N), None)
+ for i in range(1000): # capitalists spend where capital earns
+ B, _, _ = revenue_system(model.πc, model.πx, model.D_0, model)
+ e = solve_revenues(B).reshape(N, J)
+ μ = (α_k * e).sum(axis=1) / (α_k * e).sum()
+ if np.abs(μ - model.μ).max() < 1e-14:
+ break
+ model = model._replace(μ=μ)
+ else:
+ raise RuntimeError("the capitalist's spending shares did not converge")
+ return model._replace(e=e)
+
+model = create_network()
+```
+
+Here is the baseline seen from home.
+
+```{code-cell} ipython3
+wage_bill = model.α_l * model.e[0]
+relative_wage = wage_bill / model.λ / wage_bill.sum()
+print("shares of world revenue: " + ", ".join(
+ f"{c} {x:.2f}" for c, x in zip(countries, model.e.sum(axis=1))))
+print(f"\n{'sector':24s}{'employment':>12s}{'wage':>8s}{'revenue':>10s}{'home goods':>12s}")
+for j, name in enumerate(sectors):
+ print(f"{name:24s}{model.λ[j]:12.2f}{relative_wage[j]:8.2f}"
+ f"{model.e[0, j] / model.e[0].sum():10.2f}{model.πc[0, 0, j]:12.2f}")
+```
+
+The columns give each sector's share of home's employment, its wage relative to home's average wage, its
+share of home's revenue, and the share of home's purchases of the sector's goods that are produced at home.
+
+The next function solves for the equilibrium at new tariff wedges by iterating on {eq}`gln-price` and
+{eq}`gln-market`.
+
+```{code-cell} ipython3
+def solve_changes(D, model, start=None, tol=1e-12, max_iter=10_000, damp=0.5):
+ """
+ The equilibrium at tariff wedges D, relative to the baseline in model.
+ Returns changes p in producer prices and P in final-good prices, levels of
+ revenues e, origin shares, world capital income κ, and tariff revenues.
+ """
+ α_k, α_l, α_x, Φ, Ξ, ε = model.α_k, model.α_l, model.α_x, model.Φ, model.Ξ, model.ε
+ d = D / model.D_0
+ p, e = (np.ones_like(model.e), model.e.copy()) if start is None else start
+ κ_0 = (α_k * model.e).sum()
+ ϑ_0 = (α_k * model.e).sum(axis=1) / κ_0
+ for i in range(max_iter):
+ a = (d[:, :, None] * p[:, None, :])**(1 - ε) # a[m, n, j]
+ sum_c, sum_x = (model.πc * a).sum(axis=0), (model.πx * a).sum(axis=0)
+ πc, πx = model.πc * a / sum_c, model.πx * a / sum_x
+ P = np.exp(np.log(sum_c) @ Φ / (1 - ε)) # final goods
+ P_x = np.exp(np.log(sum_x) @ Ξ.T / (1 - ε)) # input bundles
+ κ = (α_k * e).sum()
+ ϑ = (α_k * e).sum(axis=1) / κ
+ p_new = ((κ / κ_0)**α_k * (e / model.e)**α_l * P_x**α_x
+ * (ϑ / ϑ_0)[:, None]**(-α_l))
+ B, g, θ = revenue_system(πc, πx, D, model)
+ e_new = solve_revenues(B).reshape(e.shape)
+ error = max(np.abs(np.log(p_new / p)).max(), np.abs(e_new - e).max())
+ p = p**(1 - damp) * p_new**damp
+ e = (1 - damp) * e + damp * e_new
+ if error < tol:
+ break
+ else:
+ raise RuntimeError("the iteration did not converge")
+ T_x = (α_x * θ * e).sum(axis=1)
+ E = ((α_l * e).sum(axis=1) + T_x + model.μ * κ) / (1 - g)
+ return dict(p=p, e=e, P=P, πc=πc, πx=πx, κ=κ, T_c=g * E, T_x=T_x)
+```
+
+Two checks confirm that only baseline shares matter.
+
+At the baseline tariff, the solver returns the baseline.
+
+And solving from the 5 percent baseline directly to a 30 percent tariff gives the same equilibrium as
+solving first to 15 percent and then, treating the 15 percent equilibrium's shares as a new baseline, on
+to 30 percent.
+
+```{code-cell} ipython3
+same = solve_changes(model.D_0, model)
+print(f"at the baseline: max |p - 1| = {np.abs(same['p'] - 1).max():.1e}, "
+ f"max |e - e_0| = {np.abs(same['e'] - model.e).max():.1e}")
+
+direct = solve_changes(tariff_wedges(0.30), model)
+mid = solve_changes(tariff_wedges(0.15), model)
+rebased = model._replace(πc=mid['πc'], πx=mid['πx'], e=mid['e'], D_0=tariff_wedges(0.15))
+via = solve_changes(tariff_wedges(0.30), rebased)
+print(f"direct vs two steps: max |Δe| = {np.abs(direct['e'] - via['e']).max():.1e}, "
+ f"max |Δ log P| = {np.abs(np.log(direct['P'] / (mid['P'] * via['P']))).max():.1e}")
+```
+
+## How tariffs affect home's workers
+
+We solve the model on a grid of common tariffs and record what $\chi$ and $G$ need: home's wages, its
+tariff revenues, its price level, and the real return to capital relative to the baseline,
+$\rho(\tau) = r(\tau) / r_0$.
+
+```{code-cell} ipython3
+τ_grid = np.linspace(0, 0.6, 121)
+κ_0 = (model.α_k * model.e).sum()
+wages, T_c, T_x, P_home, ρ = [], [], [], [], []
+start = None
+for τ in τ_grid:
+ eq = solve_changes(tariff_wedges(τ), model, start)
+ start = (eq['p'], eq['e']) # warm start for the next tariff
+ wages.append(model.α_l * eq['e'][0] / model.λ) # L_1 times each sector's wage
+ T_c.append(eq['T_c'][0])
+ T_x.append(eq['T_x'][0])
+ P_home.append(eq['P'][0])
+ ρ.append(eq['κ'] / κ_0 / np.exp(model.μ @ np.log(eq['P'])))
+wages, T_c, T_x, P_home, ρ = map(np.array, (wages, T_c, T_x, P_home, ρ))
+
+λ = model.λ
+ψ = (wages + (T_c + T_x)[:, None]) / P_home[:, None] # consumption, up to a constant
+χ_grid = np.log(ψ) @ λ
+χ_s, ρ_s = CubicSpline(τ_grid, χ_grid), CubicSpline(τ_grid, ρ)
+```
+
+{cite:t}`BassettoHuoRiosRull2026` decompose the change in $\chi$ in two ways.
+
+The first separates the change in workers' real wages from the rebates of the two kinds of tariff
+revenue.
+
+Let $f(T) = \sum_j \lambda_j \log(W_{1j} + T / L_1)$, so that
+$\chi = [f(0) - \log P_1] + [f(T^c + T^x) - f(0)]$, up to a constant.
+
+The first bracket is the real-wage term.
+
+The second is split between final-use and intermediate-use revenue by averaging over the two orders in
+which they can be added, so that the final-use term is
+$\tfrac12 \left\{ [f(T^c) - f(0)] + [f(T^c + T^x) - f(T^x)] \right\}$.
+
+The second decomposition separates average consumption from its dispersion,
+
+$$
+\chi = \log \bar\psi - \mathcal{D}, \qquad \bar\psi = \sum_j \lambda_j \psi_{1j}, \qquad
+\mathcal{D} = \log \bar\psi - \sum_j \lambda_j \log \psi_{1j} \ge 0 ,
+$$
+
+where the mean log deviation $\mathcal{D}$ is zero only when all workers consume the same amount.
+
+```{code-cell} ipython3
+---
+mystnb:
+ figure:
+ caption: Decompositions of worker welfare
+ name: fig-gln-decomposition
+---
+f = lambda T: np.log(wages + T[:, None]) @ λ
+zero = np.zeros_like(T_c)
+real_wage = f(zero) - np.log(P_home)
+R_c = 0.5 * ((f(T_c) - f(zero)) + (f(T_c + T_x) - f(T_x)))
+R_x = 0.5 * ((f(T_x) - f(zero)) + (f(T_c + T_x) - f(T_c)))
+mean_term = np.log(ψ @ λ)
+dispersion = mean_term - χ_grid
+
+x = 100 * τ_grid
+fig, axes = plt.subplots(1, 2, figsize=(12, 4.5))
+axes[0].plot(x, real_wage - real_wage[0], lw=2, label="real wages")
+axes[0].plot(x, R_c, lw=2, label="final-use revenue")
+axes[0].plot(x, R_x, lw=2, label="intermediate-use revenue")
+axes[0].plot(x, χ_grid - χ_grid[0], 'k--', lw=2, label=r"total $\chi(\tau) - \chi(0)$")
+axes[1].plot(x, mean_term - mean_term[0], lw=2, label=r"average consumption $\log \bar\psi$")
+axes[1].plot(x, dispersion[0] - dispersion, lw=2,
+ label=r"equality $\mathcal{D}(0) - \mathcal{D}(\tau)$")
+axes[1].plot(x, χ_grid - χ_grid[0], 'k--', lw=2, label="total")
+for ax in axes:
+ ax.axhline(0, color='k', lw=0.6)
+ ax.set_xlabel("common tariff (percent)")
+ ax.legend()
+plt.tight_layout()
+plt.show()
+
+i_5, i_10 = [np.argmin(np.abs(τ_grid - x)) for x in (0.05, 0.10)] # grid indices
+print(f"χ(5%) - χ(0) = {χ_grid[i_5] - χ_grid[0]:.3f}; worker welfare peaks at "
+ f"{100 * τ_grid[np.argmax(χ_grid)]:.0f} percent")
+```
+
+A tariff lowers home's real wages slightly, because it raises the price of imported goods and inputs and
+diverts production from home's strongest sectors.
+
+The rebates of tariff revenue more than make up for it over a wide range of tariffs, and revenue from
+imported inputs contributes more than revenue from imported final goods, because firms buy more imports
+than final users do.
+
+Nearly all of the gain is in the equality term: an equal rebate is worth much more, in proportion, to a
+low-paid worker than to a high-paid one, while average consumption hardly changes.
+
+These are the two findings that {cite:t}`BassettoHuoRiosRull2026` emphasize for the G7, where worker
+welfare rises by roughly $0.05$ between free trade and a 5 percent tariff and peaks at about 40 percent.
+
+The next figure shows how a rise in the tariff from 5 to 10 percent changes consumption in each sector,
+with sectors ordered by their workers' baseline consumption.
+
+```{code-cell} ipython3
+---
+mystnb:
+ figure:
+ caption: Consumption changes by sector
+ name: fig-gln-sectors
+---
+change = 100 * (ψ[i_10] / ψ[i_5] - 1)
+order = np.argsort(ψ[i_5])
+fig, ax = plt.subplots(figsize=(8, 4))
+ax.bar(range(len(order)), change[order], color='C0')
+ax.set_xticks(range(len(order)))
+ax.set_xticklabels([sectors[j].replace(' ', '\n', 1) for j in order])
+ax.axhline(0, color='k', lw=0.6)
+ax.set_ylabel("consumption change (percent)")
+plt.tight_layout()
+plt.show()
+```
+
+The three lowest-paid groups gain, by amounts that fall steeply with baseline consumption, and the two
+best-paid groups lose.
+
+{cite:t}`BassettoHuoRiosRull2026` find the same pattern across quintiles of 30 sectors, with consumption
+rising by 4.3 percent in the lowest quintile and falling by 0.3 percent in the highest.
+
+## Dynamic tariff policy
+
+The dynamic analysis needs only $\chi$, $G$, and the parameters of {cite:t}`BassettoHuoRiosRull2026`:
+annual periods, $\beta = 0.96$, $\sigma = 0.5$, and $\delta_k = 0.10$.
+
+We collect them in a `Policy` tuple and define the objects of {doc}`organizational_equilibrium` in terms of
+it.
+
+```{code-cell} ipython3
+Policy = namedtuple('Policy', ('χ', 'G', 'β', 'σ'))
+β, σ, δ_k = 0.96, 0.5, 0.10
+
+def make_policy(r_0, χ=χ_s, ρ=ρ_s):
+ return Policy(χ=χ, G=lambda τ: 1 - δ_k + r_0 * ρ(τ), β=β, σ=σ)
+
+def argmax(f, lo=0.0, hi=0.6):
+ return minimize_scalar(lambda τ: -f(τ), bounds=(lo, hi), method='bounded',
+ options={'xatol': 1e-10}).x
+
+def markov_tariff(pol):
+ return argmax(lambda τ: pol.χ(τ) + pol.β / (1 - pol.β) * np.log(pol.G(τ)))
+
+def best_constant_tariff(pol):
+ return argmax(lambda τ: pol.χ(τ) + pol.β / (pol.σ * (1 - pol.β)) * np.log(pol.G(τ)))
+
+def s_const(τ, pol):
+ "The saving rate when the tariff is τ forever."
+ return (pol.β * pol.G(τ)**(1 - pol.σ))**(1 / pol.σ)
+
+def H(τ, s, pol):
+ return pol.χ(τ) + pol.β / (1 - pol.β) * (np.log(s) + np.log(pol.G(τ)))
+
+def growth_gap(r_0):
+ "Long-run growth at the best constant tariff, minus 2 percent."
+ pol = make_policy(r_0)
+ τ_B = best_constant_tariff(pol)
+ return s_const(τ_B, pol) * pol.G(τ_B) - 1.02
+
+r_0 = brentq(growth_gap, 0.05, 0.5)
+pol = make_policy(r_0)
+τ_M, τ_B = markov_tariff(pol), best_constant_tariff(pol)
+print(f"Markov tariff {100 * τ_M:.1f} percent, best constant tariff {100 * τ_B:.1f} percent")
+print(f"growth at the Markov tariff {100 * (s_const(τ_M, pol) * pol.G(τ_M) - 1):.2f} percent")
+```
+
+```{code-cell} ipython3
+---
+mystnb:
+ figure:
+ caption: Capital returns and tariff objectives
+ name: fig-gln-objectives
+---
+fig, axes = plt.subplots(1, 2, figsize=(12, 4.5))
+grid = np.linspace(0, 0.4, 201)
+axes[0].plot(100 * grid, 100 * (pol.G(grid) - 1), lw=2)
+axes[0].set_ylabel("net return to capital (percent a year)")
+for weight, name in [(β / (1 - β), "Markov"), (β / (σ * (1 - β)), "best constant")]:
+ objective = pol.χ(grid) + weight * np.log(pol.G(grid))
+ axes[1].plot(100 * grid, objective - objective.max(), lw=2, label=f"{name} objective")
+axes[1].set_ylabel("objective relative to its maximum")
+for ax in axes:
+ ax.axvline(100 * τ_B, color='C2', ls='--', lw=1, label=r"$\tau^B$")
+ ax.axvline(100 * τ_M, color='C3', ls=':', lw=1.5, label=r"$\tau^M$")
+ ax.set_xlabel("common tariff (percent)")
+ ax.legend()
+plt.tight_layout()
+plt.show()
+```
+
+The net return to capital falls from 5.2 percent a year at free trade to 4.5 percent at a 40 percent
+tariff.
+
+The level at free trade is pinned down by the growth target, as it is in {cite:t}`BassettoHuoRiosRull2026`,
+but the decline is an independent result, and it is close to the decline they report.
+
+A Markov policymaker, who takes the current saving rate as given, weighs this fall against the static gain
+in $\chi$ and chooses a tariff of 14.5 percent.
+
+The best constant tariff puts $1/\sigma = 2$ times as much weight on $\log G$, and is only 1.2 percent.
+
+(gln_condition)=
+### When does a tariff pay?
+
+A first-order approximation at free trade explains why the model needs unequal wages to make tariffs
+attractive.
+
+Write $w_j = W_{1j}$ for the wage in home's sector $j$ and $\bar w = \sum_j \lambda_j w_j$ for home's
+average wage.
+
+Suppose that world imports are a fraction $x$ of world value added, and raise the common tariff from zero
+by $d\tau$.
+
+Tariff revenue rises by $x \, d\tau$ times world value added.
+
+If free trade is efficient, a small tariff changes world output only to second order, so this revenue
+comes out of factor incomes.
+
+If, in addition, all factor prices fall in the same proportion, real wages and the real return to capital
+all fall by $x \, d\tau$ in proportion.
+
+Suppose that home imports the same fraction $x$ of its own value added, and let $\eta$ be labor's share of
+home's value added.
+
+The rebate per home worker then rises by $x \, d\tau / \eta$ times the average wage $\bar w$, which is
+worth $x \, d\tau \, \bar w / (\eta w_j)$ in proportion to a worker in sector $j$.
+
+Averaging logs over home's workers gives
+
+$$
+d\chi = x \, d\tau \left( \frac{\mathcal{I}}{\eta} - 1 \right), \qquad
+d \log G = - x \, d\tau \, \frac{r}{G} , \qquad
+\mathcal{I} = \sum_j \lambda_j \frac{\bar w}{w_j} ,
+$$
+
+where $\mathcal{I} \ge 1$ is the ratio of the average wage to its harmonic mean, which equals one only when
+all wages are equal.
+
+A Markov policymaker raises the tariff above zero when $d\chi + \frac{\beta}{1 - \beta} d \log G > 0$,
+and the best constant tariff is positive when the same holds with weight $\frac{\beta}{\sigma(1 - \beta)}$:
+
+```{math}
+:label: gln-condition
+\tau^M > 0 \iff \frac{\mathcal{I}}{\eta} > 1 + \frac{\beta}{1 - \beta} \frac{r}{G} , \qquad
+\tau^B > 0 \iff \frac{\mathcal{I}}{\eta} > 1 + \frac{\beta}{\sigma(1 - \beta)} \frac{r}{G} .
+```
+
+Openness $x$ has dropped out: what matters is how unequal consumption is across home's workers, and how
+much of value added goes to them rather than to capital.
+
+The next cell computes both sides of {eq}`gln-condition` at free trade.
+
+```{code-cell} ipython3
+free = solve_changes(tariff_wedges(0.0), model)
+η = (model.α_l @ free['e'][0]) / ((model.α_l + model.α_k) @ free['e'][0])
+w_0 = wages[0] / (λ @ wages[0]) # relative wages at free trade
+I = λ @ (1 / w_0)
+r_free, G_free = pol.G(0) - 1 + δ_k, pol.G(0)
+print(f"I = {I:.2f}, η = {η:.2f}, I / η = {I / η:.2f}")
+print(f"thresholds: {1 + β / (1 - β) * r_free / G_free:.2f} for τ_M > 0, "
+ f"{1 + β / (σ * (1 - β)) * r_free / G_free:.2f} for τ_B > 0")
+```
+
+With $\beta = 0.96$, $\sigma = 0.5$, $\delta_k = 0.10$, and a 2 percent growth rate, a positive best
+constant tariff requires $\mathcal{I}/\eta$ to exceed about 8, or $\mathcal{I}$ to exceed about 4.5 when
+labor receives 57 percent of value added.
+
+That is a lot of inequality: if all of home's workers but a low-paid group earned the same wage, a group
+making up 40 percent of the labor force would need to earn a little less than a tenth of the average
+wage.
+
+Our dual-economy calibration is built to satisfy {eq}`gln-condition`, and {ref}`gln_ex2` checks the
+approximation against exact solutions.
+
+The same approximation suggests that the positive best constant tariff that
+{cite:t}`BassettoHuoRiosRull2026` find for the G7 rests on very unequal consumption across U.S. sectors
+at low tariffs, although they do not report a measure of that inequality.
+
+### Ramsey plan and plans sustained by Markov reversion
+
+We compute the Ramsey plan as in {doc}`organizational_equilibrium`, now over 80 years, with the tariff
+held constant afterward.
+
+```{code-cell} ipython3
+def saving_rates(τ, pol):
+ "Saving rates for tariffs τ_0, ..., τ_N, with τ_N kept forever."
+ s = np.empty(len(τ))
+ s[-1] = s_const(τ[-1], pol)
+ for t in range(len(τ) - 2, -1, -1):
+ ratio = (pol.β * pol.G(τ[t + 1])**(1 - pol.σ))**(-1 / pol.σ) * (1 - s[t + 1])
+ s[t] = 1 / (1 + ratio)
+ return s
+
+def action_payoffs(τ, pol):
+ "Action payoffs V_0, ..., V_N for tariffs τ_0, ..., τ_N, with τ_N kept forever."
+ s = saving_rates(τ, pol)
+ V = np.empty(len(τ))
+ V[-1] = H(τ[-1], s[-1], pol) / (1 - pol.β)
+ for t in range(len(τ) - 2, -1, -1):
+ V[t] = H(τ[t], s[t], pol) + pol.β * V[t + 1]
+ return V
+
+H_B = H(τ_B, s_const(τ_B, pol), pol)
+V_markov = H(τ_M, s_const(τ_M, pol), pol) / (1 - β)
+V_best = H_B / (1 - β)
+
+horizon = 80
+res = minimize(lambda τ: -action_payoffs(τ, pol)[0], np.full(horizon + 1, τ_B),
+ bounds=[(0, 0.6)] * (horizon + 1), method='L-BFGS-B')
+τ_R = res.x
+V_R = action_payoffs(τ_R, pol)
+print("Ramsey tariffs every 5 years (percent):", np.round(100 * τ_R[:35:5], 1))
+print(f"first year of free trade: {np.argmax(τ_R < 1e-4)}")
+print(f"smallest V_t - V_M along the Ramsey plan: {(V_R - V_markov).min():.3f}")
+```
+
+The Ramsey plan starts at the Markov tariff, because the first tariff affects no saving decision, and then
+lowers the tariff by about a percentage point every two years, reaching free trade after 31 years.
+
+Every continuation of the plan is worth more than the Markov equilibrium, so the plan is also the best plan
+sustained by the threat of permanent reversion to the Markov equilibrium, which
+{cite:t}`BassettoHuoRiosRull2026` call the best sustainable equilibrium.
+
+### Organizational equilibrium
+
+As in {doc}`organizational_equilibrium`, the organizational equilibrium keeps the action payoff constant
+at $V^\ast = H^B / (1 - \beta)$, follows the transition map $\tau_{t+1} = \mathcal{T}(\tau_t)$ implied by
+that requirement and the Euler equation, and starts at $\tau_0 = \mathcal{T}(\tau^M)$, the lowest tariff
+that satisfies no delay.
+
+```{code-cell} ipython3
+def s_org(τ, H_B, pol):
+ "The saving rate that keeps H(τ, s) equal to H_B."
+ return np.exp((1 - pol.β) / pol.β * (H_B - pol.χ(τ)) - np.log(pol.G(τ)))
+
+def transition(τ, τ_B, H_B, pol):
+ "Next year's tariff on a path whose action payoff is constant at H_B / (1 - β)."
+ if τ <= τ_B + 1e-8:
+ return τ_B
+ s = s_org(τ, H_B, pol)
+ lhs = ((1 - s) / s)**(-pol.σ)
+ f = lambda τ_next: (pol.β * pol.G(τ_next)**(1 - pol.σ)
+ * (1 - s_org(τ_next, H_B, pol))**(-pol.σ) - lhs)
+ return brentq(f, τ_B, τ) # the root between τ_B and τ
+
+𝒯 = lambda τ: transition(τ, τ_B, H_B, pol)
+
+τ_O = [𝒯(τ_M)]
+for t in range(1500):
+ τ_O.append(𝒯(τ_O[-1]))
+τ_O = np.array(τ_O)
+V_O = action_payoffs(τ_O, pol)
+print(f"max |V_t - V*| over the first 50 years = {np.abs(V_O[:50] - V_best).max():.1e}")
+print("organizational tariffs (percent) in years 0, 10, 20, 50, 100:",
+ np.round(100 * τ_O[[0, 10, 20, 50, 100]], 1))
+```
+
+```{code-cell} ipython3
+---
+mystnb:
+ figure:
+ caption: Transition map and tariff paths
+ name: fig-gln-paths
+---
+n_plot = 51
+fig, axes = plt.subplots(1, 2, figsize=(12, 4.5))
+grid_τ = np.linspace(τ_B, τ_M, 100)
+axes[0].plot(100 * grid_τ, [100 * 𝒯(x) for x in grid_τ], 'C3', lw=2,
+ label=r"$\mathcal{T}(\tau)$")
+axes[0].plot(100 * grid_τ, 100 * grid_τ, 'k', lw=0.8, label="45-degree line")
+axes[0].set_xlabel(r"current tariff $\tau_t$ (percent)")
+axes[0].set_ylabel(r"next tariff $\tau_{t+1}$ (percent)")
+axes[0].legend()
+axes[1].plot(100 * τ_O[:n_plot], 'C3', lw=2, label="organizational equilibrium")
+axes[1].plot(100 * τ_R[:n_plot], 'C0--', lw=2,
+ label="Ramsey plan = best plan sustained by Markov reversion")
+axes[1].plot(np.full(n_plot, 100 * τ_M), 'k:', lw=2, label="Markov equilibrium")
+axes[1].set_xlabel("year")
+axes[1].set_ylabel("tariff (percent)")
+axes[1].legend(loc='center right')
+plt.tight_layout()
+plt.show()
+```
+
+The organizational equilibrium starts at 11.8 percent, below the Markov tariff, and liberalizes gradually:
+the tariff is 7.9 percent after 10 years and 4.8 percent after 50.
+
+The transition map is flat at the Markov tariff and has slope one at $\tau^B$, so liberalization slows
+as the tariff falls, and after a century the tariff is still 3.7 percent.
+
+The Ramsey plan starts higher but liberalizes faster, as in the paths that
+{cite:t}`BassettoHuoRiosRull2026` compute for the G7.
+
+### A temporary protectionist shock
+
+Following {cite:t}`BassettoHuoRiosRull2026`, suppose that in year 20 an unexpected shock sets the tariff
+to 10 percent.
+
+```{code-cell} ipython3
+---
+mystnb:
+ figure:
+ caption: Tariffs after a protectionist shock
+ name: fig-gln-shock
+---
+t_shock, τ_shock = 20, 0.10
+τ_O_shock = list(τ_O[:t_shock]) + [τ_shock]
+while len(τ_O_shock) < n_plot:
+ τ_O_shock.append(𝒯(τ_O_shock[-1]))
+τ_R_shock = np.r_[τ_R[:t_shock], τ_shock, np.full(n_plot - t_shock - 1, τ_M)]
+t_back = np.argmin(np.abs(τ_O - 𝒯(τ_shock)))
+print(f"tariff after the shock: {100 * 𝒯(τ_shock):.1f} percent, close to the undisturbed "
+ f"path's tariff in year {t_back}, a delay of about {t_shock + 1 - t_back} years")
+
+fig, ax = plt.subplots(figsize=(8, 4.5))
+ax.plot(100 * np.array(τ_O_shock), 'C3', lw=2, label="organizational equilibrium")
+ax.plot(100 * τ_R_shock, 'C0--', lw=2, label="best plan sustained by Markov reversion")
+ax.plot(np.full(n_plot, 100 * τ_M), 'k:', lw=2, label="Markov equilibrium")
+ax.axvline(t_shock, color='gray', ls=':', lw=1)
+ax.set_ylim(0, 16)
+ax.set_xlabel("year")
+ax.set_ylabel("tariff (percent)")
+ax.legend(loc='lower right')
+plt.show()
+```
+
+In year 21, the organizational equilibrium resumes from $\mathcal{T}(0.10)$, close to the tariff that the
+undisturbed path reached in year 4, so the shock delays liberalization by about 17 years but leaves its
+destination unchanged.
+
+The plan sustained by Markov reversion instead returns to the Markov tariff forever.
+
+## Trade blocs
+
+{cite:t}`BonadioEtAl2026` use a model of the same family to study the reorganization of world trade since
+2015.
+
+From changes in bilateral trade flows between 2015 and 2023, they infer changes in bilateral trade costs
+and classify countries as moving toward a U.S. bloc, toward a China bloc, or neither.
+
+Trade costs rose between the two blocs but fell within them, and the ratio of world trade to world output
+did not fall: the world economy has been decoupling rather than deglobalizing.
+
+Solving their production network model in changes, they find that the trade-cost changes raised real
+income in the median country by about 0.6 percent, and that many countries would have gained more by
+joining the other bloc, which suggests that motives other than trade are shaping the blocs.
+
+Two features of their analysis bear on the questions of this lecture.
+
+* The trade-cost changes that they measure are bilateral, rising with some partners and falling with
+ others, whereas the lead country of {cite:t}`BassettoHuoRiosRull2026` sets one tariff on all imports,
+ which all other countries match.
+* Their comparison of 2015–2019 with 2015–2023 suggests that the fall in costs within blocs lagged the
+ rise in costs between them, though the pandemic and the war in Ukraine offer another explanation.
+
+Extending organizational equilibrium to several strategic countries, which a bloc structure calls for,
+requires generalizing the equilibrium concept, as {cite:t}`BassettoHuoRiosRull2026` note.
+
+{ref}`gln_ex3` takes a first step by asking how home's Markov and best constant tariffs change when home
+and $B$ tax only each other's goods.
+
+## Connections to other lectures
+
+* {doc}`organizational_equilibrium` defines organizational equilibrium and computes it in the growth
+ model and the two-sector tariff model of {cite:t}`BassettoHuoRiosRull2024`; this lecture reuses its
+ dynamic analysis unchanged.
+* {doc}`gradual_trade_agreements` explains gradual liberalization by the incentive constraints of
+ self-enforcing agreements between countries of different size {cite}`BondPark2002`, rather than by
+ the time inconsistency that drives the tariffs here.
+
+## Exercises
+
+```{exercise}
+:label: gln_ex1
+
+Suppose that home rebates tariff revenue in proportion to wages instead of equally per worker, so that a
+worker in sector $j$ consumes $W_{1j} (1 + T_1 / \sum_k W_{1k} L_{1k}) / P_1$.
+
+The static equilibrium does not change, because the rebate rule changes neither total spending nor its
+composition.
+
+Compute $\chi(\tau)$ under this rule, and the Markov and best constant tariffs, holding $r_0$ fixed.
+
+Explain the result using {eq}`gln-condition`.
+```
+
+```{solution-start} gln_ex1
+:class: dropdown
+```
+
+```{code-cell} ipython3
+χ_prop = (np.log(wages) @ λ + np.log(1 + (T_c + T_x) / (wages @ λ))
+ - np.log(P_home))
+pol_prop = make_policy(r_0, χ=CubicSpline(τ_grid, χ_prop))
+print(f"χ(10%) - χ(0): equal rebate {χ_grid[i_10] - χ_grid[0]:.4f}, "
+ f"proportional rebate {χ_prop[i_10] - χ_prop[0]:.4f}")
+print(f"Markov tariff {100 * markov_tariff(pol_prop):.1f} percent, "
+ f"best constant tariff {100 * best_constant_tariff(pol_prop):.1f} percent")
+```
+
+A proportional rebate raises every worker's consumption by the same proportion, so it does nothing for
+equality.
+
+In {eq}`gln-condition`, it replaces $\mathcal{I}$ by one, and $1/\eta \approx 1.76$ falls far short of
+both thresholds.
+
+Both tariffs are zero: in this model, the motive for protection is redistribution through the equal rebate.
+
+```{solution-end}
+```
+
+```{exercise}
+:label: gln_ex2
+
+Check the approximation {eq}`gln-condition`.
+
+Vary agriculture's share of home's employment from 0.25 to 0.46, scaling the other sectors' shares
+proportionally and holding sectoral wage bills, and so the static equilibrium and $r_0$, fixed.
+
+For each value, compute $\mathcal{I}/\eta$ and the Markov and best constant tariffs, and compare the
+values of $\mathcal{I}/\eta$ at which the tariffs become positive with the thresholds in
+{eq}`gln-condition`.
+```
+
+```{solution-start} gln_ex2
+:class: dropdown
+```
+
+```{code-cell} ipython3
+bills = wages * λ # sectoral wage bills, independent of λ
+thresholds = [1 + β / (1 - β) * r_free / G_free,
+ 1 + β / (σ * (1 - β)) * r_free / G_free]
+results = []
+for λ_ag in np.linspace(0.25, 0.46, 22):
+ λ_i = np.r_[λ_ag, λ[1:] * (1 - λ_ag) / λ[1:].sum()]
+ w_i = bills / λ_i
+ χ_i = np.log(w_i + (T_c + T_x)[:, None]) @ λ_i - np.log(P_home)
+ pol_i = make_policy(r_0, χ=CubicSpline(τ_grid, χ_i))
+ I_i = λ_i @ ((λ_i @ w_i[0]) / w_i[0])
+ results.append((I_i / η, markov_tariff(pol_i), best_constant_tariff(pol_i)))
+results = np.array(results)
+
+fig, ax = plt.subplots()
+ax.plot(results[:, 0], 100 * results[:, 1], 'o-', lw=2, label=r"Markov tariff $\tau^M$")
+ax.plot(results[:, 0], 100 * results[:, 2], 's-', lw=2, label=r"best constant tariff $\tau^B$")
+for value, style, name in zip(thresholds, [':', '--'], [r"$\tau^M$", r"$\tau^B$"]):
+ ax.axvline(value, color='gray', ls=style, lw=1, label=f"approximate threshold for {name}")
+ax.set_xlabel(r"$\mathcal{I} / \eta$")
+ax.set_ylabel("tariff (percent)")
+ax.legend()
+plt.show()
+
+for k, name in [(1, "Markov"), (2, "best constant")]:
+ first = np.argmax(results[:, k] > 1e-4)
+ print(f"{name} tariff first positive between I/η = {results[first - 1, 0]:.2f} "
+ f"and {results[first, 0]:.2f}; threshold {thresholds[k - 1]:.2f}")
+```
+
+The vertical lines mark the two thresholds in {eq}`gln-condition`.
+
+The Markov tariff becomes positive almost exactly at its threshold, and the best constant tariff a little
+above its threshold, at $\mathcal{I}/\eta$ between 8.5 and 8.8 rather than 7.95.
+
+The approximation errs because our countries are not symmetric and wages do not all move in proportion,
+and the error matters more for the best constant tariff, whose larger weight on $\log G$ magnifies any
+error in the return effect.
+
+Beyond the thresholds, both tariffs rise steadily with inequality.
+
+```{solution-end}
+```
+
+```{exercise}
+:label: gln_ex3
+
+Suppose that home and $B$ impose the tariff $\tau$ only on each other's goods, while all other tariffs stay
+at the 5 percent baseline.
+
+1. Write a function that returns these tariff wedges, solve the model on `τ_grid`, and compute
+ $\chi(\tau)$ and $\rho(\tau)$.
+1. Compute home's Markov and best constant bilateral tariffs, holding $r_0$ fixed, and compare them with
+ the common tariffs.
+1. How do the shares of $A$ and $B$ in home's final spending change as the bilateral tariff rises from 5 to
+ 30 percent?
+```
+
+```{solution-start} gln_ex3
+:class: dropdown
+```
+
+```{code-cell} ipython3
+def bilateral_wedges(τ, τ_0=0.05):
+ D = tariff_wedges(τ_0)
+ D[0, 2] = D[2, 0] = 1 + τ
+ return D
+
+w_b, T_b, P_b, ρ_b, from_A, from_B = [], [], [], [], [], []
+start = None
+for τ in τ_grid:
+ eq = solve_changes(bilateral_wedges(τ), model, start)
+ start = (eq['p'], eq['e'])
+ w_b.append(model.α_l * eq['e'][0] / λ)
+ T_b.append(eq['T_c'][0] + eq['T_x'][0])
+ P_b.append(eq['P'][0])
+ ρ_b.append(eq['κ'] / κ_0 / np.exp(model.μ @ np.log(eq['P'])))
+ from_A.append(eq['πc'][1, 0] @ model.Φ)
+ from_B.append(eq['πc'][2, 0] @ model.Φ)
+w_b, T_b, P_b, ρ_b = map(np.array, (w_b, T_b, P_b, ρ_b))
+χ_b = np.log(w_b + T_b[:, None]) @ λ - np.log(P_b)
+pol_b = make_policy(r_0, χ=CubicSpline(τ_grid, χ_b), ρ=CubicSpline(τ_grid, ρ_b))
+
+i_30 = np.argmin(np.abs(τ_grid - 0.30))
+print(f"from 5 to 30 percent: Δχ bilateral {χ_b[i_30] - χ_b[i_5]:.3f}, common "
+ f"{χ_grid[i_30] - χ_grid[i_5]:.3f}; Δ log ρ bilateral "
+ f"{np.log(ρ_b[i_30] / ρ_b[i_5]):.4f}, common {np.log(ρ[i_30] / ρ[i_5]):.4f}")
+print(f"bilateral tariffs: Markov {100 * markov_tariff(pol_b):.1f} percent, "
+ f"best constant {100 * best_constant_tariff(pol_b):.1f} percent")
+print(f"share of home's final spending from A: {100 * from_A[i_5]:.2f} -> "
+ f"{100 * from_A[i_30]:.2f} percent; from B: {100 * from_B[i_5]:.2f} -> "
+ f"{100 * from_B[i_30]:.2f} percent")
+```
+
+A bilateral tariff raises less revenue than a common one, so the gain in worker welfare is about half as
+large.
+
+But it lowers the return to capital much less, about two-fifths as much, because it taxes only the trade
+between home and $B$ and leaves most of world trade untouched.
+
+Since the cost to capital accumulation falls by more than the gain to workers, both tariffs are higher
+than the corresponding common tariffs, and the best constant bilateral tariff is far from free trade.
+
+Home's final purchases from $B$ fall by about a third, mostly in favor of home's own goods; purchases from
+$A$ rise only slightly.
+
+```{solution-end}
+```
diff --git a/lectures/organizational_equilibrium.md b/lectures/organizational_equilibrium.md
index e34079ce..522b33b9 100644
--- a/lectures/organizational_equilibrium.md
+++ b/lectures/organizational_equilibrium.md
@@ -79,6 +79,9 @@ This lecture
equilibrium, including after a temporary protectionist shock, and
* describes connections to other lectures in this section.
+{doc}`gradual_liberalization_network` continues with a multi-country, multi-sector version of the tariff
+model.
+
We use the following imports.
```{code-cell} ipython3
@@ -631,6 +634,29 @@ H(\tau, s) = \chi(\tau) + \frac{\beta}{1 - \beta} \left[ \log s + \log G(\tau) \
Two functions of the tariff alone, worker welfare $\chi(\tau)$ and the gross return $G(\tau)$, summarize
everything that the static equilibrium contributes to the dynamic policy problem.
+The tariff model therefore has the structure of the growth model of {ref}`oe_growth`, with the tariff in
+the role of the saving rate, as the following table shows; we compute the tariff-model objects in its last
+four rows below.
+
+| | growth model | tariff model |
+|---|---|---|
+| action at date $t$ | saving rate $s_t$ | tariff $\tau_t$ |
+| state | capital $k_t$ | capital $k_t$ |
+| action payoff | $V(s_t, s_{t+1}, \ldots)$ | $\sum_{j \ge 0} \beta^j H(\tau_{t+j}, s_{t+j})$ |
+| source of time inconsistency | present bias, $\delta < 1$ | $s_t$ depends on $\tau_{t+1}, \tau_{t+2}, \ldots$ but not on $\tau_t$ |
+| Markov action | $s^M$ | $\tau^M$ |
+| best constant action | $s^B$ | $\tau^B$ |
+| map along constant-payoff paths | $s_{t+1} = q(s_t; V^\ast)$ | $\tau_{t+1} = \mathcal{T}(\tau_t)$ |
+| first organizational action | $q(s^M; V^\ast)$ | $\mathcal{T}(\tau^M)$ |
+
+In the growth model, successive planners disagree because they discount the future differently.
+
+Here they share preferences, but capitalists' saving responds to expected tariffs.
+
+Because the saving rate at date $t$ depends only on later tariffs, the policymaker at date $t$ can protect
+workers without lowering it, while it wants its successors to keep tariffs low so that capitalists save
+more at date $t$.
+
We use the parameter values of {cite:t}`BassettoHuoRiosRull2024`, with a model period of seven years,
and set $\sigma = 0.5$, the value used by {cite:t}`BassettoHuoRiosRull2026`.
@@ -642,8 +668,8 @@ def create_tariff_model(α=0.33, β=0.7, δ_k=0.65, ε=1.1, A=3.5, σ=0.5):
def static(τ, model):
"""
- Worker welfare χ(τ), the gross return G(τ), and the consumption of the two
- groups of workers per unit of capital, ψ_1(τ) and ψ_2(τ).
+ Worker welfare χ(τ), the gross return G(τ), and, per unit of capital, the
+ consumption ψ_i(τ) and real wages ω_i(τ) of the two groups of workers.
"""
α, β, δ_k, ε, A, σ = model
ϕ = 1 / (1 + (A / (1 + τ))**(1 / (1 - α)))
@@ -652,11 +678,11 @@ def static(τ, model):
P = (0.5 * p_1**(1 - ε) + 0.5)**(1 / (1 - ε))
m_2 = (Y_1 + Y_2) / (1 + (1 + τ)**ε) # balanced trade
revenue = τ / (1 + τ) * (m_2 - Y_2)
- ψ_1 = ((1 - α) * p_1 * Y_1 + revenue / 2) / P
- ψ_2 = ((1 - α) * Y_2 + revenue / 2) / P
+ ω_1, ω_2 = (1 - α) * p_1 * Y_1 / P, (1 - α) * Y_2 / P
+ ψ_1, ψ_2 = ω_1 + revenue / (2 * P), ω_2 + revenue / (2 * P)
χ = 0.5 * (np.log(ψ_1) + np.log(ψ_2))
G = α * ϕ**(α - 1) / P + 1 - δ_k
- return χ, G, ψ_1, ψ_2
+ return χ, G, ψ_1, ψ_2, ω_1, ω_2
def χ(τ, model):
return static(τ, model)[0]
@@ -714,7 +740,7 @@ V_markov = H(τ_M, s_const(τ_M, model), model) / (1 - model.β)
V_best = H_B / (1 - model.β)
print(f"Markov tariff {100 * τ_M:.1f} percent, best constant tariff {100 * τ_B:.1f} percent")
-ψ_free, ψ_markov = static(0.0, model)[2:], static(τ_M, model)[2:]
+ψ_free, ψ_markov = static(0.0, model)[2:4], static(τ_M, model)[2:4]
print("consumption at the Markov tariff relative to free trade: export-sector workers "
f"{ψ_markov[0] / ψ_free[0]:.3f}, import-sector workers {ψ_markov[1] / ψ_free[1]:.3f}")
```
@@ -752,6 +778,95 @@ It lowers the return to capital throughout.
The Markov policymaker, who ignores how expected tariffs affect saving, chooses a high tariff; the best
constant tariff is close to free trade.
+{cite:t}`BassettoHuoRiosRull2026` decompose the change in worker welfare in two ways, and both are
+instructive here.
+
+The first separates real wages $\omega_i(\tau)$, measured per unit of capital, from the rebate of tariff
+revenue:
+
+$$
+\chi(\tau) = \tfrac12 \sum_i \log \omega_i(\tau) + \tfrac12 \sum_i \log
+\frac{\psi_i(\tau)}{\omega_i(\tau)} .
+$$
+
+The second separates average consumption from its dispersion:
+
+$$
+\chi(\tau) = \log \bar\psi(\tau) - \mathcal{D}(\tau), \qquad
+\bar\psi = \tfrac12 (\psi_1 + \psi_2), \qquad
+\mathcal{D} = \log \bar\psi - \tfrac12 \sum_i \log \psi_i \ge 0 ,
+$$
+
+where the mean log deviation $\mathcal{D}$ is zero only when the two groups of workers consume the same
+amount.
+
+```{code-cell} ipython3
+---
+mystnb:
+ figure:
+ caption: Decompositions of worker welfare
+ name: fig-oe-decomposition
+---
+τ_wide = np.linspace(0, 1.5, 301)
+parts = np.array([static(x, model) for x in τ_wide])
+χ_w, ψ_w, ω_w = parts[:, 0], parts[:, 2:4], parts[:, 4:6]
+wage_part = np.log(ω_w).mean(axis=1)
+rebate_part = np.log(ψ_w / ω_w).mean(axis=1)
+mean_part = np.log(ψ_w.mean(axis=1))
+dispersion = mean_part - χ_w
+
+fig, axes = plt.subplots(1, 2, figsize=(12, 4.5))
+axes[0].plot(100 * τ_wide, wage_part - wage_part[0], lw=2, label="real wages")
+axes[0].plot(100 * τ_wide, rebate_part, lw=2, label="rebate of tariff revenue")
+axes[1].plot(100 * τ_wide, mean_part - mean_part[0], lw=2,
+ label=r"average consumption $\log \bar\psi$")
+axes[1].plot(100 * τ_wide, dispersion[0] - dispersion, lw=2,
+ label=r"equality $\mathcal{D}(0) - \mathcal{D}(\tau)$")
+for ax in axes:
+ ax.plot(100 * τ_wide, χ_w - χ_w[0], 'k--', lw=2, label=r"total $\chi(\tau) - \chi(0)$")
+ ax.axvline(100 * τ_M, color='C3', ls=':', lw=1.5)
+ ax.axhline(0, color='k', lw=0.6)
+ ax.set_xlabel("tariff (percent)")
+ ax.legend()
+plt.tight_layout()
+plt.show()
+
+χ_M, _, ψ_1M, ψ_2M, ω_1M, ω_2M = static(τ_M, model)
+χ_0, _, ψ_10, ψ_20, ω_10, ω_20 = static(0.0, model)
+print(f"at the Markov tariff: χ(τ_M) - χ(0) = {χ_M - χ_0:.3f}")
+print(f" real wages {0.5 * np.log(ω_1M * ω_2M / (ω_10 * ω_20)):.3f}, "
+ f"rebate {0.5 * np.log(ψ_1M * ψ_2M / (ω_1M * ω_2M)):.3f}")
+print(f" average consumption {np.log((ψ_1M + ψ_2M) / (ψ_10 + ψ_20)):.3f}, "
+ f"equality {dispersion[0] - (np.log((ψ_1M + ψ_2M) / 2) - χ_M):.3f}")
+mld = lambda a, b: np.log((a + b) / 2) - np.log(a * b) / 2 # mean log deviation
+print(f" equality from wage changes {mld(ω_10, ω_20) - mld(ω_1M, ω_2M):.3f}, "
+ f"from the rebate {mld(ω_1M, ω_2M) - mld(ψ_1M, ψ_2M):.3f}")
+print(f"worker welfare peaks at a tariff of {100 * τ_wide[np.argmax(χ_w)]:.0f} percent")
+```
+
+At the Markov tariff, marked by the dotted line, the rebate accounts for most of the rise in worker
+welfare in the first decomposition, and the equality term for nearly all of it in the second.
+
+The tariff appeals to the policymaker mainly because it narrows the gap between the two groups of workers,
+not because it raises their average consumption.
+
+The gap narrows in two ways: protection raises the import-sector wage and lowers the export-sector wage,
+and the equal rebate is worth more, in proportion, to the lower-paid import-sector workers.
+
+The two wage changes nearly offset each other in the average log real wage, which is why the rebate
+dominates the first decomposition, but they account for more of the gain in equality than the rebate
+does.
+
+Worker welfare peaks at a tariff of about 85 percent; beyond it, the tariff's growing cost in efficiency
+outweighs further gains in equality.
+
+In their 30-sector model of the G7, {cite:t}`BassettoHuoRiosRull2026` also find that the gain in worker
+welfare comes almost entirely from equality, but there real wages fall and the equal rebate does the
+narrowing.
+
+{doc}`gradual_liberalization_network` derives a condition on the inequality of consumption across sectors
+under which the Markov and best constant tariffs are positive.
+
### Ramsey plan and plans sustained by Markov reversion
A Ramsey planner at date $0$ chooses the whole sequence of tariffs, taking into account the Euler
@@ -823,6 +938,12 @@ equilibrium as the punishment, is therefore also the Ramsey plan.
### Organizational equilibrium tariffs
+As in the growth model, computing an organizational equilibrium takes three steps:
+
+1. compute the best constant action and its value $V^\ast$;
+1. find the map that takes each action to the next along paths that deliver $V^\ast$ at every date;
+1. choose the first action from the no-delay condition.
+
Along an organizational equilibrium, the action payoff is the same at every date.
We take that value to be $V^\ast = H(\tau^B, s^B)/(1 - \beta)$, the value of the best constant tariff, as
@@ -943,6 +1064,66 @@ that {cite:t}`BassettoHuoRiosRull2024` compare with the decline of the world ave
The Ramsey plan liberalizes much faster, but only because its first policymaker can commit its
successors.
+### Who pays for gradual liberalization
+
+{cite:t}`BassettoHuoRiosRull2024` also compare the consumption of the two groups of workers across
+equilibria that start from the same capital stock.
+
+A worker in sector $i$ consumes $c_{it} = \psi_i(\tau_t) k_t$, and capital evolves according to
+$k_{t+1} = s_t G(\tau_t) k_t$.
+
+```{code-cell} ipython3
+---
+mystnb:
+ figure:
+ caption: Consumption of export-sector and import-sector workers
+ name: fig-oe-consumption
+---
+def log_consumption(τ, model, n, k_0=1.0):
+ "Log consumption of the two groups of workers in the first n periods of the path τ."
+ s = saving_rates(τ, model)
+ k = [k_0]
+ for t in range(n - 1):
+ k.append(s[t] * G(τ[t], model) * k[-1])
+ ψ = np.array([static(x, model)[2:4] for x in τ[:n]])
+ return np.log(ψ * np.array(k)[:, None])
+
+n_plot = 12
+c_markov = log_consumption(np.full(n_plot, τ_M), model, n_plot)
+gaps = {"organizational equilibrium": log_consumption(τ_O, model, n_plot) - c_markov,
+ "Ramsey plan": log_consumption(τ_R, model, n_plot) - c_markov}
+styles = {"organizational equilibrium": 'C3-o', "Ramsey plan": 'C0--s'}
+
+fig, axes = plt.subplots(1, 2, figsize=(12, 4.5))
+for name, gap in gaps.items():
+ for i, ax in enumerate(axes):
+ ax.plot(gap[:, i], styles[name], ms=4, lw=2, label=name)
+for ax, title in zip(axes, ["export-sector workers", "import-sector workers"]):
+ ax.axhline(0, color='k', lw=0.8)
+ ax.set_title(title)
+ ax.set_xlabel("period (seven years)")
+ ax.set_ylabel("log consumption minus Markov equilibrium")
+axes[0].legend()
+plt.tight_layout()
+plt.show()
+
+for name, gap in gaps.items():
+ print(f"{name}: import-sector workers consume more than in the Markov equilibrium "
+ f"from period {np.argmax(gap[1:, 1] > 0) + 1} on")
+```
+
+Lower tariffs raise the return to capital and the saving rate, so capital, and with it every worker's
+consumption, grows faster in the organizational equilibrium than in the Markov equilibrium.
+
+Export-sector workers gain from the start, because liberalization also raises their wage.
+
+Import-sector workers lose protection and part of their rebate, so for the first four periods, 28 years,
+they consume less than in the Markov equilibrium; after that, faster growth more than makes up for it.
+
+The Ramsey plan protects them fully at date $0$ and then liberalizes quickly, so their consumption falls
+further below its Markov level, by about 0.23 in logs in period 3, is back to it in period 5, and exceeds it
+from period 6 on.
+
### Temporary protectionist shocks
The off-path behavior of the two cooperative equilibria differs sharply.
@@ -989,6 +1170,18 @@ change where liberalization ends up.
In the plan sustained by Markov reversion, a one-period disturbance permanently destroys cooperation, a
self-inflicted punishment that later policymakers would want to renegotiate.
+The table summarizes how the three equilibria differ, following {cite:t}`BassettoHuoRiosRull2026`.
+
+| | Markov equilibrium | best plan sustained by Markov reversion | organizational equilibrium |
+|---|---|---|---|
+| tariff path | $\tau^M$ forever | starts at $\tau^M$, falls fast to free trade | starts at $\mathcal{T}(\tau^M)$, falls gradually toward $\tau^B$ |
+| is date $0$ special? | no | yes, $V_0 > V_t$ | no, $V_t = V^\ast$ |
+| after a temporary shock $\tilde\tau$ | $\tau^M$ | $\tau^M$ forever | resumes from $\mathcal{T}(\tilde\tau)$ |
+| punishment of a deviation | none needed | permanent and self-inflicted | the plan resumes from the deviation |
+
+The comparison shows a trade-off: the plan sustained by Markov reversion liberalizes faster when nothing
+goes wrong, while the organizational equilibrium survives occasional departures from the plan.
+
### A quantitative version
{cite:t}`BassettoHuoRiosRull2026` replace the two-sector static block with a model of the G7 economies
@@ -1006,12 +1199,17 @@ They find a Markov tariff of about 12 percent and a best constant tariff of abou
the tariff raises worker welfare mainly by compressing consumption differences across sectors through the
equal rebate of tariff revenue.
+{doc}`gradual_liberalization_network` builds a small version of their model with illustrative shares,
+solves it by exact hat algebra, and recomputes the tariff paths of this section.
+
(oe_connections)=
## Connections to other lectures
Organizational equilibrium adds a fourth equilibrium concept to the three that several lectures in this
section study.
+* {doc}`gradual_liberalization_network` computes organizational equilibrium tariffs in a production
+ network model like the one that {cite:t}`BassettoHuoRiosRull2026` take to G7 data.
* {doc}`gradual_trade_agreements` explains gradual liberalization differently, as a feature of efficient
self-enforcing agreements between countries of different size that are sustained by the threat of a
permanent trade war {cite}`BondPark2002`, the kind of cooperation whose fragility to a single