מסמך טכני מיומן המחקר · באנגלית, כפי שנכתב בשלב העבודה
MacroVision: methods notes (simulation model and empirical pipeline, as implemented)
Source: this repository. Script paths are relative to scripts/ unless stated. file:line cites the line that defines each item. The household model is copied into several files (saving_asset_sensitivity_v73, integrated_housing_v76, credit_resolution_v77, corporate_credit_model_v98, corporate_workout_model_v100). The final results use **corporate_credit_model_v98.py (cited as CCM98) and corporate_workout_model_v100.py (CWM100)**. CWM100 matches CCM98 line for line except for the workout additions (§4.4). Its line numbers are +1 from line 10 and +3 from line 45 onward, up to line 137.
All quantities are in normalized units: base-year nominal output = 100, workforce = 1, base price level = 1. They are not currency amounts or a calibrated country (coupled_thesis_v71.py:118). Every output is flagged illustrative: True, calibrated: False.
---
A. Simulation model
1. Time structure and exogenous paths
- The horizon is
years = 20and the transition laststransition_years = 10(coupled_thesis_v71.py:17). Years run from t = 0 to 20, giving 21 annual observations (v71:37). - Automation progress is a_t = min(1, t / 10) (v71:38).
- Unemployment is imposed: u_t = 0.20 · a_t (v71:39;
terminal_unemployment = .20, v71:17). With η = 0 the capital feedback leaves it unchanged, which test_macro_sensitivity_v96.py:20 checks (u_t = 20·min(t/10,1) %). - Efficiency (productivity) is e_t = 1 + g · a_t, with g =
productivity_gain(default .50, grid {.25,.5,1}) (v71:40). - The wage index is w_t = 1 +
wage_gain·a_t, withwage_gain = 0throughout, so w_t = 1 (v71:41, :17). - Year 0 is a reference year. At t = 0 there is no fiscal settlement, no asset trade, no investment and no balance update (CCM98:75, :107–109, :143–144). Year-0 cash flows are computed but are not booked to stocks (
new_cash=dict(cash), CCM98:109).
2. Macro core (coupled_thesis_v71.simulate)
Constants (v71:8–16):
| Constant | Value |
|---|---|
BASE_OUTPUT | 100.0 |
BASE_WAGES | 60.0 |
BASE_PROFITS | 100 − 60 = 40.0 |
WAGE_TAX | .20 |
BASE_PROFIT_TAX | .25 |
INITIAL_GOV_NET_DEBT | 60.0 |
INTEREST (government rate) | .03 |
BASE_REVENUE | .20·60 + .25·40 = 22.0 |
EXISTING_REAL_SPENDING | 22.0 − .03·60 = 20.2 |
Other defaults (v71:17) are pass_through = .75, profit_tax_rate = .25, capture_share = 1., debt_service = 0., and the bounds are at v71:18. The grid (§6) overrides pass-through, tax rate, capture share and productivity gain.
Equations, year t (v71:42–52):
- Real output: Y^r_t = e_t (1 − u_t) (v71:42)
- Price index: P_t = 1 − π · (BASE_WAGES/BASE_OUTPUT) · (1 − w_t / e_t) = 1 − π·0.6·(1 − 1/e_t), where π =
pass_through(v71:43). This is the share of unit-labour-cost savings passed into prices. For example, at g = 1, π = 1 the terminal value is P = 0.7. - Nominal output: Y_t = 100 · P_t · Y^r_t (v71:44)
- Wage bill: W_t = 60 · w_t · (1 − u_t) (v71:45). The nominal wage per employed worker is constant.
- Profits: Π_t = Y_t − W_t (v71:46)
- Profit-tax rate (linear ramp): τ^π_t = .25 + a_t (τ̄^π − .25) (v71:47)
- Capture share (linear ramp): κ_t = 1 + a_t (κ̄ − 1) (v71:48)
- Wage tax: T^w_t = .20 · W_t (v71:49)
- Profit tax: T^π_t = τ^π_t · κ_t · max(0, Π_t) (v71:50)
- Revenue: R_t = T^w_t + T^π_t (v71:51)
- Distributable profit:
potential_profit_after_cash_tax= Π_t − T^π_t (v71:69). All of it is paid out as dividends (§3.3). - Existing government purchases: G_t = 20.2 · P_t (v71:52; repeated in CCM98:67)
- Government interest: 0.03 × outstanding bonds (CCM98:67)
Important: v71 also contains its own benefit and debt recursion (v71:54–62: debt = beginning_debt − overall). The final path calls simulate(p,'budget') (CCM98:47) only for the production and revenue rows. Government debt is rebuilt inside the household model under a no-new-borrowing rule (§3.4), so v71's debt recursion is not used in the final results.
3. Households (fixed cohorts)
3.1 Cohorts, ownership and initial stocks
- Cohort masses (
MASS, household_distribution_v72.py:7):workers.70,displaced_free.10 (no initial consumer debt),displaced_debt.10,owners.10. - Equity ownership schemes (
SCHEMES, v72:12):
- concentrated: owners hold 1.0 unit and everyone else 0. - broad: units equal cohort masses.
REAL_EQUITY = 200.(v72:9). The constant-real quote is q_t = 200·P_t per unit (CCM98:26), and total units start at 1.- Consumer loan:
INITIAL_PRIVATE_LOAN = 20.in aggregate, which is 200 per debtor (v72:10). It is held by owners, owed bydisplaced_debt, and is interest-only atPRIVATE_RATE = .04(v72:11). - Interest due is .04 × the nominal balance (CCM98:66). The loan is not indexed, so the real burden rises when P falls.
- Government bonds of 60 are held by owners (CCM98:49, :54).
- Household cash starts at
INITIAL_CASH = 20.× mass for each cohort, 20 in aggregate (CCM98:12, :48). Other initial stocks:INITIAL_FIRM_CASH = 30.andINITIAL_REAL_CAPITAL = 200.(CCM98:13–14). - Reference disposable income (v72:16–26) is (1 − .2)·60 + capital income + financial income − debt due:
- Capital income = 40·(1 − .25)·share/mass (v72:20). - Owners' financial income = (.03·60 + .04·20)/.1 (v72:22). - Debt due = .04·20/.1 = 8 for displaced_debt (v72:21). - Computed values: concentrated = {workers 48, displaced_free 48, displaced_debt 40, owners 374}; broad = {78, 78, 70, 104}.
3.2 Employment and wages
- Displaced cohorts: employment = 1 − u_t/.2. Workers and owners: employment = 1 (CCM98:63). The 0.2 is hard-coded, so at u = .2 both displaced cohorts are fully unemployed.
- After-tax wage per employed worker: (1 − .2) W_t/(1 − u_t) = 48 (CCM98:64).
3.3 Income components
- Wages: mass · employment · wage (CCM98:77).
- Dividends: (Π − T^π) × units_k / Σunits (CCM98:65).
- Benefits: see §3.4.
- Government interest: paid to owners (CCM98:78).
- Consumer-loan interest:
- debt_resources = cash + gross income + q·units (CCM98:85). - paid = min(due, max(0, debt_resources)); the unpaid part is capitalized into the loan (CCM98:86, :111). - Paid interest is income to owners (CCM98:87).
- Corporate-credit interest: pro rata to claim holders (CCM98:82–83; §4.3).
- Housing income: rent and mortgage interest move from payers to owners (credit_ledger_v77.py:46).
- Net income: gross − contractual due (debtor) + housing income (CCM98:88, :98).
3.4 Benefit rule and government finance
- Required benefit for each displaced cohort k (CCM98:69–71):
B*_k = MASS_k (1 − emp_k) · max(0, P_t·ref_k − div_k/MASS_k + [due/MASS_k if k = displaced_debt]). The target is the price-indexed reference income less own dividends, plus current contractual consumer interest for debtors.
- Fiscal room: avail_t = R_t − G_t − 0.03·bonds_t (CCM98:72).
- Budget-limited fraction: f_t = 1 if ΣB* = 0, otherwise min(1, max(0, avail/ΣB*)) (CCM98:73). Paid benefits are f·B*_k (CCM98:74).
- Settlement,
fiscal_settlement(CCM98:32–35; applied at :75 for t > 0):
- surplus = avail − benefits; - redemption = min(bonds, max(0, surplus)); - bonds ← bonds − redemption; - treasury ← treasury + surplus − redemption.
- The government cannot issue new debt. Treasury cash starts at 0 and earns nothing. If treasury < −1e-8, the path stops (CCM98:76).
- Redemption cash goes to owners (CCM98:89).
- Reported net debt is bonds − treasury (CCM98:159).
3.5 Consumption/saving rule (saving='income_share', the default; the only rule used in the grid)
- Spendable income (CCM98:100) = net income − maintenance − (mortgage principal paid + deficiency paid). Principal is treated as an asset exchange, not consumption.
- Year 0 deducts the scheduled principal instead of the principal paid (CCM98:102). The per-capita reference is
initial_after_housing= max(0, spendable_0)/mass (CCM98:103). - Desired consumption: C*_k = 0.9 · max(0, spendable_k) (
CONSUME_SHARE = .9, CCM98:15, :104). - Cohorts are processed in the order debtor, workers, displaced_free, owners (CCM98:113). Owners' resources include the debtor's principal repayment.
- Actual consumption: C_k = min(C*_k, max(0, cash resource + q·units_k)) (CCM98:115). Households sell equity at q to fund any shortfall below zero cash (CCM98:117–119).
- Any surplus above a cash buffer of
BUFFER_YEARS = .25× C*_k is invested in equity at q (CCM98:121–126). The debtor first repaysREPAY_SHARE = .5× the investable surplus on the consumer loan (CCM98:16–17, :124). - The alternative rule
smooth_reference(CCM98:104) is not used in v96, v98 or v100.
3.6 Housing tenure and stress (credit_ledger_v77.py)
- Tenure options (
TENURES, ledger:9), initial state at ledger:11–16:
- renter: owners own all homes. - owner_free: each cohort owns homes equal to its mass, with no mortgage. - mortgage_fixed and mortgage_reset: like owner_free, but non-owners carry a mortgage of 150 × mass.
- House price: 200·(1 + (H̄ − 1)·a_t) (ledger:25).
- Mortgage rate: .04, or .04 + (r̄ − .04)·a_t for
mortgage_reset(ledger:26). - Rent: 12·(1 + (R̄ − 1)·a_t) per unit mass (ledger:27).
- Maintenance: 2 per home (ledger:34).
- Stresses (H̄, r̄, R̄) are defined at housing_stress_v75.py:8 and ledger:5. The grid uses only
stable(1, .04, 1) andrate_shock(.7, .08, 1).credit_stress(.4, .12, 1) is not used. - Mortgage payment: an annuity recast each year over the remaining term max(1, 26 − t), or 25 at t = 0 (v75:11–13; ledger:37).
- Payment waterfall per non-owner cohort, from resources that include liquidatable equity (ledger:31–42):
1. rent; 2. maintenance; 3. interest; 4. scheduled principal; 5. 20% of remaining resources toward any deficiency.
- Unpaid interest is capitalized (ledger:49) and unpaid rent becomes rent debt.
- The owners cohort is the landlord and mortgage lender. There is no bank.
3.7 Credit resolution (resolution=True, default_years=2, cost_rate=.1, recourse=0.; CCM98:38)
- Mortgage streak: a year counts if the shortfall exceeds max(1e-8, .1·due) (ledger:55).
- After 2 consecutive years, foreclosure (ledger:57–64):
- Collateral = house price × homes; cost = 10% of collateral. - Recovery = min(claim, collateral − cost). Recourse 0 means the remaining gap is written off. - The home transfers to owners and the borrower becomes a renter. Any surplus is paid to the borrower. - The cost is paid by owners as maintenance (ledger:74), so it counts as consumption, i.e. demand for production.
- Rent debt is written off after a 2-year streak (ledger:56, :67–68).
- Consumer loan: written off entirely after 2 consecutive years in which unpaid interest exceeds max(1e-8, .1·due) (CCM98:137–139).
4. Firm side
4.1 Capital feedback, feedback(.3, 0.) (capital_feedback_v74.py:17–35)
- Valid ranges are 0 ≤ α < 1 and |η| ≤ .5 (v74:18). Let k_t = K_t/200, with beginning-of-year capital (v74:22).
- Labour: L = min(1, max(.8, (1 − u)·k^η)) (v74:25). With η = 0, L = 1 − u: the capital–labour channel is switched off, so unemployment stays on the imposed path.
- Output: Y_t ← Y_t · k^α · (L/(1 − u))^(1−α), with α = .3 (v74:26). Capital scales nominal output, while the price index from v71 is unchanged.
- Wages: W_t ← W_t · L/(1 − u), which is unchanged when η = 0 (v74:27).
- Profits are recomputed as Π = Y − W, and profit tax is recomputed with the same ramps (v74:28–30). Revenue, profit after tax and output are overwritten (v74:31–33).
- Ambiguity: the overwritten
real_output_indexis Y/P (v74:31), which is not ×100-normalized as it is in v71. Because base output is 100, the scale happens to coincide.
4.2 Investment and firm cash (t > 0)
- Investment is a residual from the resource identity: I_t = Y_t − G_t − ΣC_k − Σmaintenance (CCM98:128).
- Firm cash: F ← F − I + net equity cash (CCM98:129–130). Net equity cash is the net household purchases of units at q, i.e. issuance minus redemption.
- Capital: K ← K + I/P (CCM98:131).
- Profits are fully paid out, so operating cash equals C + G − W − T − D = −I. That is why only I and equity flows move firm cash.
4.3 Corporate credit (corporate_credit_ledger_v98.py; terms at corporate_credit_v98.py:11)
service, at the start of t > 0 (ledger:4–13; CCM98:82):
- Interest due = rate × claims; paid = min(F, due). - Principal = min(remaining F, amortization × claims). - Unpaid interest is capitalized pro rata.
advance, after investment (ledger:15–20; CCM98:132):
- If F < 0, draw = min(−F, Σ positive household cash, limit − outstanding). - The draw is taken pro rata from household cash, which becomes claims. There is no money creation.
- Wealth consolidation nets the claims against equity holders (CCM98:149).
TERMS, as (limit, rate, amortization):disabled(0, .04, .1),limited_20(20, .04, .1),limited_60(60, .04, .1),rate_08(60, .08, .1).
4.4 Workout (CWM100; corporate_workout_ledger_v100.py)
- A year counts as missed if capitalized interest > 1e-8 or principal paid + 1e-8 < amortization × opening claims (CWM100:140–141).
- When the streak reaches
workout_years∈ {1, 2, 3} and claims > 1e-8, a debt-for-equityexchangetakes place at q (CWM100:142–144):
- Enterprise value V = q × Σunits. - Recovery = min(V, D). - Old holders keep a fraction max(0, 1 − D/V). - Lenders receive Σunits · (recovery/V) · claim_k/D. - Lender mark loss = claim · (1 − recovery/D). - No cash moves and total units are unchanged. Both properties are asserted at workout ledger:4–18.
- After an exchange, credit is closed and the advance limit is 0 (CWM100:135).
- Order of steps: the workout check runs after the failure check and before consumer resolution (CWM100:136–146).
- Fixed terms are limit 60, rate .04, amortization .1 (corporate_workout_v100.py:16). With
workout_years = 0(no workout) the run is identical tolimited_60(test_corporate_workout_v100.py:22–23; asserted for completion at thesis_synthesis_v101.py:31–32).
5. Stop conditions, completion and control
Failure reasons are exact strings, checked in this order:
'No outstanding equity claims': Σunits ≤ 1e-12 (CCM98:60).'Zero equity quote: liquidation unavailable': q ≤ 1e-12 (CCM98:62). This cannot occur underconstant_real, since P ≥ 0.7 > 0.'Existing government commitments lack cash financing': treasury < −1e-8 (CCM98:76).'Lender lacks cash/equity to finance foreclosure services and borrower surplus': raised byResolutionFundingError(ledger:72–73; CCM98:94–95).'Corporate liquidity, real capital or equity-redemption capacity exhausted': after credit advance, firm cash < −1e-8, K < −1e-8, any cohort's units < −1e-8, or Σunits ≤ 1e-12 (CCM98:133–134).
- Completed means no failure and the last row has year = 20 (CCM98:158). Failed paths are truncated and never imputed.
- Control (
control=True, CCM98:44) setsterminal_unemployment = 0andproductivity_gain = 0. As a result u ≡ 0, e ≡ 1, P ≡ 1 and no benefits are paid. The control keeps the tax-rate and capture ramps, ownership, tenure and stress. The repo itself labels it "no-displacement/no-productivity control under matched policies, not a no-policy-change control" (macro_sensitivity_v96.py:63). - Consequence: because the capture ramp is kept, a control with κ̄ = .5 has revenue 12 + .25·.5·40 = 17, which is below G + interest = 20.2 + 1.8. So many controls stop on reason 3.
6. Outcomes, variants and grid
- Consumption index: 100 · (C_k/MASS_k/P_t) / (0.9 ·
initial_after_housing_k) (CCM98:150). This is per-capita real non-housing consumption relative to the cohort's own year-0 consumption, so it equals 100 at t = 0. It is None if the year-0 after-housing income is ≤ 0. - Terminal real consumption: C_k/MASS_k/P at t = 20 (
consumption_real). It is None unless the path completed (v96:39). - **
preserves_90_all_years:** true when the index is non-null and ≥ 90 − 1e-8 in all 21 years. It is None if the path is not completed (v96:41, :64). - Matched-control gap: actual minus control terminal real consumption, computed only when both paths completed (v96:49–50).
- The 576-case grid (
FACTORS, v96:10–14) is the full factorial 3·3·2·2·2·4·2 = 576:
- productivity_gain {.25, .5, 1.} - pass_through {0., .5, 1.} - profit_tax_rate {.25, .35} - capture_share {.5, 1.} - ownership {concentrated, broad} - tenure {renter, owner_free, mortgage_fixed, mortgage_reset} - stress {stable, rate_shock}
- Fixed in the grid (v96:62):
- α = .3, η = 0; - saving = income_share, quote = constant_real; - terminal unemployment .2, horizon 20 years; - resolution on, recourse 0.
- Seven variants (v101:7, :28–29):
no_credit(=disabled),credit_20_04,credit_60_04,credit_60_08, andworkout_1,workout_2,workout_3(60/.04/.1 credit followed by an exchange after 1, 2 or 3 missed years). - Each variant is run as actual and control, giving 576 × 7 × 2 paths. Cases are matched by exact parameter tuple; the script asserts 576 cases in each source (v101:22–24).
- v101 per-cohort classification (v101:10–17), based on the actual paths only:
- no_complete_variant; - partial_completion_unresolved (some variants incomplete); - preserved_in_all; - not_preserved_in_any; - varies_across_complete_variants.
- Gap signs are computed only when all 14 paths of a case complete (v101:34, :38).
- Recorded counts, for context only (read from the stored JSON, not re-run): 202 cases complete in all 7 variants, 18 in some, 356 in none, and 42 are fully paired.
7. Accounting checks and tests
- Money identity: Σ household cash + firm cash + treasury − initial money (= 20 + 30), recorded each year (CCM98:151). The maximum over the path is reported as
max_money_error(CCM98:159). - The v98 and v100 drivers assert
max_money_error < 1e-8and corporate-creditbalance_error < 1e-8on every path (corporate_credit_v98.py:27–28; corporate_workout_v100.py:26–27). balance_erroris closing claims − (opening + capitalized − principal + draw − converted) (CCM98:152; CWM100:163).- The exchange asserts unit and value conservation (workout ledger:14–15).
- Housing
cash_transfer_erroris recorded (ledger:77) but not asserted anywhere. - Tests (all 13 pass; run here with
python -m unittest):
- test_macro_sensitivity_v96.py: control equals an explicit zero-transition run; money error < 1e-8; imposed u path; Y = G + C + I for t > 0 (line 22); failure leads to null terminal outcomes. - test_corporate_credit_v98.py: advance and service arithmetic; disabled reproduces v96; money and credit balances; claims net to zero against equity shares. - test_corporate_workout_v100.py: solvent and underwater exchange waterfalls; workout 0 equals v98 limited_60; no money creation; no draws after a workout. - test_thesis_synthesis_v101.py: a truncated path can never be classified as preserved or failed.
---
B. Empirical pipeline (descriptive, flagged causal_claims_allowed: False)
1. Data sources
- Enterprise AI adoption: Eurostat
isoc_eb_ai, indicatorE_AI_TANY(enterprise uses at least one AI technology), unitPC_ENT(% of enterprises). Coverage: enterprises with 10+ employees (size_emp=GE10), NACEC10-S951_X_K, annual 2023–2025, 14 countries (AT BE CZ DE DK ES FI FR IE IT NL PL PT SE), 42 observations. Three observations carry theb(break) flag: FR-2023, NL-2025, SE-2023 (data/processed/eurostat_ai_14countries_manifest_v148.json). - Occupation employment: Eurostat LFS
lfsa_egai2d, in thousands of persons (THS_PER), ages 15–64, both sexes, ISCO-08 two-digit, 2018–2025, the same 14 countries. The file has 4,816 rows, 259 of them missing, covering 43 occupation groups (eurostat_occupation_verified_manifest_v166.json). - Adjacent-year pairs (occupation_break_policy_v168.py:9–35): 4,214 pairs. A pair is eligible for the primary analysis unless:
- it spans 2020→2021 (IESS break); - either year's flag contains b or u; - employment is missing. - Pairs with only a d flag stay eligible.
- Exposure: ILO Gmyrek et al. (2025), "Generative AI and Jobs: A Refined Global Index of Occupational Exposure", workbook
Final_Scores_ISCO08_Gmyrek_et_al_2025.xlsxfrom the GitHub repo pgmyrek/2025_GenAI_scores_ISCO08 (review_ilo_exposure_workbook_v177.py:10). The 2-digit exposure is the unweighted mean ofmean_score_2025over 427 four-digit occupations, giving 40 groups (aggregate_ilo_exposure_v180.py:30–39). ISCO 01–03 (armed forces) have no score (ilo_eurostat_occupation_panel_v183.manifest.json).
2. Sample construction (ai_adoption_exposure_panel_v190.py:15–52)
- Keep pairs with end year 2024 or 2025: 1,204 pairs (v190:34). Exclusions are applied sequentially:
| Step | Reason | Excluded |
|---|---|---|
| 1 | not primary-eligible (employment_quality, v190:36) | 249 |
| 2 | ISCO missing from exposure (exposure_missing, v190:37) | 33 |
| 3 | adoption missing for t or t−1 (v190:38) | 0 |
| 4 | either adoption year flagged (adoption_source_flag, v190:39) | 74 |
| 5 | employment at start ≤ 0 (v190:43) | 0 |
- Final sample: N = 848 (405 with end year 2024, 443 with end year 2025): 13 countries, 39 occupations, 23 country-year cells.
- France drops out entirely because of LFS
bflags in both transitions. DK-2024 is also excluded bybflags. The 74 adoption-flag exclusions are the NL-2025 and SE-2024 cells. These counts are reproduced by the v191 manifest and test.
3. Variables
- g_cot = 100·(L_end/L_start − 1): annual employment growth in percent (v190:46).
- E_o ∈ [0, 1]: ILO 2025 exposure, fixed over time.
- ΔA_ct = A_ct − A_c,t−1: change in adoption in percentage points (v190:47).
- Regressor: E_o × ΔA_ct (v190:48).
- Sample statistics (computed here): ΔA ranges 0.77–14.45 pp; mean g = 1.04 and SD = 8.22.
4. Estimating equation (ai_adoption_exposure_interaction_v192.py:77–92)
g_cot = α + β (E_o · ΔA_ct) + γ_ct + δ_o + ε_cot.
- Estimated by OLS with dummy-variable fixed effects: country-year (22 dummies) and occupation (38 dummies), one reference category dropped from each (v192:84–86). The country-year effects absorb ΔA and the occupation effects absorb E_o.
- A rank check is applied (v192:87). Minimum coverage is 500 rows, 30 occupations and 20 country-year cells (v192:80).
- Standard errors are cluster-robust by occupation (39 clusters), using a normal approximation (
use_t=False) and statsmodels' default cluster small-sample correction (v192:88). - Recorded result (data/processed/ai_adoption_exposure_interaction_results_v194.json): β = −0.5449, SE 0.5427, p = 0.315, 95% CI [−1.609, 0.519].
5. Robustness (ai_adoption_interaction_robustness_v195.py:14–35)
The same estimator is run on:
- (a) Matched-cell panel: country×occupation cells observed in both 2024 and 2025 (v195:17–22): 368 cells, N = 736.
- (b) Leave-one-country-out: 13 fits (v195:25–28).
- (c) Leave-one-occupation-out: 39 fits (v195:29–32).
The v195 output is archived in data/processed/ai_adoption_interaction_robustness_v195.json (see AI_ADOPTION_ROBUSTNESS_V195_RESULTS.md). An independent numpy replica of the cluster-robust OLS reproduces both v194 and the archived v195 numbers.
| Check | Result |
|---|---|
| Matched-cell panel | β = −0.686, p = 0.473 |
| Leave-one-country-out | β from −0.839 to −0.201; p from 0.082 to 0.712 |
| Leave-one-occupation-out | β from −0.818 to −0.332; p from 0.099 to 0.581 |
No specification reaches p < 0.05, and the sign never changes.
The tests (test_ai_adoption_interaction_v192.py, test_ai_adoption_interaction_robustness_v195.py at the repo root) only check that the design strings are present. They do not check the numbers.
6. Points to state as limitations or ambiguities
- The sim uses v71 only for production and revenue; government debt dynamics come from the no-borrowing settlement.
- Displaced employment is hard-coded as 1 − u/.2.
- The nominal consumer loan versus the falling price level is a built-in channel.
- Investment is a residual, not a decision rule.
- The control keeps the policy ramps.
- The v195 numbers were checked twice: archived CI output and an independent replica agree.
- Exposure is unweighted and fixed in 2025; adoption is measured at the country level and contemporaneous with the employment change.