Add simulation-backed paper on AI-run firm dynamics

This commit is contained in:
2026-04-18 19:09:28 +00:00
parent 39fcec1847
commit 31d580e0fe
6 changed files with 18047 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
regime,n_runs,contracts_total_mean,contracts_settled_mean,contracts_defaulted_mean,fees_total_mean,interest_total_mean,dividends_total_mean,token_supply_final_mean,gini_balance_mean,gini_wealth_mean,neg_balance_agents_mean,winner_hhi_mean,blocks_produced_mean,errors_mean
baseline,12,21.416666666666668,1.5833333333333333,3.6666666666666665,6889.916666666667,25.25,6694.0,5130.25,0.11320579599393549,0.12255043551137738,2.75,0.15893405292171156,30.5,19.583333333333332
coordination_push,12,29.5,0.16666666666666666,5.25,6994.083333333333,30.916666666666668,6799.0,5221.0,0.13216124014965233,0.13957263418464463,3.25,0.16634766732050965,23.416666666666668,27.666666666666668
high_compute_cost,12,13.666666666666666,1.1666666666666667,2.25,41151.166666666664,2725.5833333333335,40049.0,6429.666666666667,0.4698958246131037,0.4682073883181179,3.5833333333333335,0.17685328716682144,32.5,53.25
1 regime n_runs contracts_total_mean contracts_settled_mean contracts_defaulted_mean fees_total_mean interest_total_mean dividends_total_mean token_supply_final_mean gini_balance_mean gini_wealth_mean neg_balance_agents_mean winner_hhi_mean blocks_produced_mean errors_mean
2 baseline 12 21.416666666666668 1.5833333333333333 3.6666666666666665 6889.916666666667 25.25 6694.0 5130.25 0.11320579599393549 0.12255043551137738 2.75 0.15893405292171156 30.5 19.583333333333332
3 coordination_push 12 29.5 0.16666666666666666 5.25 6994.083333333333 30.916666666666668 6799.0 5221.0 0.13216124014965233 0.13957263418464463 3.25 0.16634766732050965 23.416666666666668 27.666666666666668
4 high_compute_cost 12 13.666666666666666 1.1666666666666667 2.25 41151.166666666664 2725.5833333333335 40049.0 6429.666666666667 0.4698958246131037 0.4682073883181179 3.5833333333333335 0.17685328716682144 32.5 53.25
+53
View File
@@ -0,0 +1,53 @@
[
{
"regime": "baseline",
"n_runs": 12,
"contracts_total_mean": 21.416666666666668,
"contracts_settled_mean": 1.5833333333333333,
"contracts_defaulted_mean": 3.6666666666666665,
"fees_total_mean": 6889.916666666667,
"interest_total_mean": 25.25,
"dividends_total_mean": 6694.0,
"token_supply_final_mean": 5130.25,
"gini_balance_mean": 0.11320579599393549,
"gini_wealth_mean": 0.12255043551137738,
"neg_balance_agents_mean": 2.75,
"winner_hhi_mean": 0.15893405292171156,
"blocks_produced_mean": 30.5,
"errors_mean": 19.583333333333332
},
{
"regime": "coordination_push",
"n_runs": 12,
"contracts_total_mean": 29.5,
"contracts_settled_mean": 0.16666666666666666,
"contracts_defaulted_mean": 5.25,
"fees_total_mean": 6994.083333333333,
"interest_total_mean": 30.916666666666668,
"dividends_total_mean": 6799.0,
"token_supply_final_mean": 5221.0,
"gini_balance_mean": 0.13216124014965233,
"gini_wealth_mean": 0.13957263418464463,
"neg_balance_agents_mean": 3.25,
"winner_hhi_mean": 0.16634766732050965,
"blocks_produced_mean": 23.416666666666668,
"errors_mean": 27.666666666666668
},
{
"regime": "high_compute_cost",
"n_runs": 12,
"contracts_total_mean": 13.666666666666666,
"contracts_settled_mean": 1.1666666666666667,
"contracts_defaulted_mean": 2.25,
"fees_total_mean": 41151.166666666664,
"interest_total_mean": 2725.5833333333335,
"dividends_total_mean": 40049.0,
"token_supply_final_mean": 6429.666666666667,
"gini_balance_mean": 0.4698958246131037,
"gini_wealth_mean": 0.4682073883181179,
"neg_balance_agents_mean": 3.5833333333333335,
"winner_hhi_mean": 0.17685328716682144,
"blocks_produced_mean": 32.5,
"errors_mean": 53.25
}
]
+37
View File
@@ -0,0 +1,37 @@
run_id,seed,regime,contracts_total,contracts_settled_total,contracts_defaulted_total,inference_fees_total,interest_total,dividends_total,token_supply_final,gini_balance,gini_wealth,negative_balance_agents,winner_hhi,blocks_produced,total_errors
baseline_101,101,baseline,25,3,5,6537,0,6344,5688,0.10367867093179228,0.10805514570269281,2,0.140625,32,7
baseline_102,102,baseline,21,2,5,6575,41,6336,5395,0.12518686599038964,0.13149684505725645,2,0.21284185493460167,29,17
baseline_103,103,baseline,26,1,4,6756,19,6604,5715,0.10513532726028108,0.11377504029472707,2,0.1581450653983353,29,15
baseline_104,104,baseline,21,0,3,7565,38,7352,4983,0.14965912014407,0.13289925177524653,3,0.1484375,32,24
baseline_105,105,baseline,22,2,2,6370,39,6248,4839,0.1148494778938014,0.14399083449301786,3,0.16326530612244897,28,30
baseline_106,106,baseline,25,2,4,6789,2,6648,5482,0.10252117013086992,0.10911460757843772,2,0.1527777777777778,36,5
baseline_107,107,baseline,20,0,2,6949,6,6836,4630,0.10530611152734659,0.11835918565196324,4,0.13142857142857142,35,10
baseline_108,108,baseline,22,5,5,6736,4,6564,4679,0.08859236426562833,0.10960999081193479,2,0.15051020408163265,28,12
baseline_109,109,baseline,23,4,6,6971,32,6708,4840,0.131812438193605,0.13027831094049902,4,0.15976331360946747,26,39
baseline_110,110,baseline,19,0,4,6932,52,6648,5412,0.12527187211135882,0.128596114328414,3,0.17146776406035663,27,39
baseline_111,111,baseline,18,0,1,7160,55,6960,5015,0.12123074401835465,0.13524268379728754,3,0.17377731529656607,31,22
baseline_112,112,baseline,15,0,3,7339,15,7080,4885,0.08522538945972813,0.10918721570505152,3,0.14416896235078056,33,15
coordination_push_101,101,coordination_push,29,0,6,6351,14,6160,5546,0.1274476439790575,0.11523020514248583,1,0.168,25,20
coordination_push_102,102,coordination_push,32,0,6,6586,11,6336,5603,0.1358069518979863,0.12982571865018744,2,0.1652794292508918,29,16
coordination_push_103,103,coordination_push,26,0,4,6641,32,6480,4314,0.13521196144218983,0.12699369892684853,4,0.14951989026063098,27,22
coordination_push_104,104,coordination_push,30,1,0,7931,17,7720,5314,0.12537674080232808,0.14814206624753679,4,0.16,30,19
coordination_push_105,105,coordination_push,32,0,9,6869,81,6744,5212,0.15909207686774218,0.15521874410710912,3,0.16666666666666666,18,23
coordination_push_106,106,coordination_push,32,0,7,6981,57,6852,5624,0.14058216520974498,0.1512555493895671,4,0.15646258503401358,21,45
coordination_push_107,107,coordination_push,26,0,4,6556,25,6436,5260,0.13967720970537267,0.15706726246472247,4,0.18112244897959182,28,29
coordination_push_108,108,coordination_push,32,0,4,7024,6,6848,5566,0.1090025906735752,0.14071918761012703,4,0.165,20,18
coordination_push_109,109,coordination_push,29,1,9,6780,21,6512,4965,0.11734141589088543,0.13086692105890774,3,0.1648,25,41
coordination_push_110,110,coordination_push,31,0,3,6862,18,6588,5289,0.11928036605657244,0.11289280849264882,3,0.16,20,25
coordination_push_111,111,coordination_push,25,0,5,7805,58,7636,4901,0.1322481243301179,0.1545201186546099,4,0.20500000000000002,20,47
coordination_push_112,112,coordination_push,30,0,6,7543,31,7276,5058,0.14486763494025556,0.15213932947098496,3,0.15432098765432098,18,27
high_compute_cost_101,101,high_compute_cost,11,0,1,41924,2698,40796,6773,0.4227513119055428,0.41859879954616996,4,0.18626430801248697,31,46
high_compute_cost_102,102,high_compute_cost,15,1,6,40494,2956,39300,2978,0.5485028304697586,0.5258750052838483,4,0.17355371900826447,33,63
high_compute_cost_103,103,high_compute_cost,10,1,1,40647,2784,39724,7303,0.41454709908024934,0.42170703872772797,3,0.1753902662993572,33,51
high_compute_cost_104,104,high_compute_cost,16,1,2,42460,2516,41320,6172,0.5149586456448694,0.5189896196393393,4,0.189453125,32,60
high_compute_cost_105,105,high_compute_cost,16,1,1,40145,2840,39272,5899,0.46256225313412336,0.46151061333724375,4,0.16129032258064516,31,52
high_compute_cost_106,106,high_compute_cost,15,3,4,40613,3533,39712,6206,0.5568047990578537,0.519489781180039,4,0.15816326530612243,28,67
high_compute_cost_107,107,high_compute_cost,12,2,1,40731,2634,39868,8594,0.42507908825438023,0.43840259740259735,3,0.248046875,32,49
high_compute_cost_108,108,high_compute_cost,13,0,2,41493,2623,40492,7646,0.47062565812565804,0.4797243946458114,3,0.1697530864197531,36,46
high_compute_cost_109,109,high_compute_cost,15,1,5,37479,1953,36116,6775,0.38451149162164633,0.4106027603222946,3,0.16049382716049382,36,45
high_compute_cost_110,110,high_compute_cost,13,3,1,39742,1960,38368,8442,0.45729572898557524,0.4670887939920483,3,0.1712962962962963,36,36
high_compute_cost_111,111,high_compute_cost,17,0,2,44067,3304,42940,5552,0.5041796108567691,0.49005196406552765,4,0.1607142857142857,28,60
high_compute_cost_112,112,high_compute_cost,11,1,1,44019,2906,42680,4816,0.476931378220818,0.46644729167476773,4,0.16782006920415227,34,64
1 run_id seed regime contracts_total contracts_settled_total contracts_defaulted_total inference_fees_total interest_total dividends_total token_supply_final gini_balance gini_wealth negative_balance_agents winner_hhi blocks_produced total_errors
2 baseline_101 101 baseline 25 3 5 6537 0 6344 5688 0.10367867093179228 0.10805514570269281 2 0.140625 32 7
3 baseline_102 102 baseline 21 2 5 6575 41 6336 5395 0.12518686599038964 0.13149684505725645 2 0.21284185493460167 29 17
4 baseline_103 103 baseline 26 1 4 6756 19 6604 5715 0.10513532726028108 0.11377504029472707 2 0.1581450653983353 29 15
5 baseline_104 104 baseline 21 0 3 7565 38 7352 4983 0.14965912014407 0.13289925177524653 3 0.1484375 32 24
6 baseline_105 105 baseline 22 2 2 6370 39 6248 4839 0.1148494778938014 0.14399083449301786 3 0.16326530612244897 28 30
7 baseline_106 106 baseline 25 2 4 6789 2 6648 5482 0.10252117013086992 0.10911460757843772 2 0.1527777777777778 36 5
8 baseline_107 107 baseline 20 0 2 6949 6 6836 4630 0.10530611152734659 0.11835918565196324 4 0.13142857142857142 35 10
9 baseline_108 108 baseline 22 5 5 6736 4 6564 4679 0.08859236426562833 0.10960999081193479 2 0.15051020408163265 28 12
10 baseline_109 109 baseline 23 4 6 6971 32 6708 4840 0.131812438193605 0.13027831094049902 4 0.15976331360946747 26 39
11 baseline_110 110 baseline 19 0 4 6932 52 6648 5412 0.12527187211135882 0.128596114328414 3 0.17146776406035663 27 39
12 baseline_111 111 baseline 18 0 1 7160 55 6960 5015 0.12123074401835465 0.13524268379728754 3 0.17377731529656607 31 22
13 baseline_112 112 baseline 15 0 3 7339 15 7080 4885 0.08522538945972813 0.10918721570505152 3 0.14416896235078056 33 15
14 coordination_push_101 101 coordination_push 29 0 6 6351 14 6160 5546 0.1274476439790575 0.11523020514248583 1 0.168 25 20
15 coordination_push_102 102 coordination_push 32 0 6 6586 11 6336 5603 0.1358069518979863 0.12982571865018744 2 0.1652794292508918 29 16
16 coordination_push_103 103 coordination_push 26 0 4 6641 32 6480 4314 0.13521196144218983 0.12699369892684853 4 0.14951989026063098 27 22
17 coordination_push_104 104 coordination_push 30 1 0 7931 17 7720 5314 0.12537674080232808 0.14814206624753679 4 0.16 30 19
18 coordination_push_105 105 coordination_push 32 0 9 6869 81 6744 5212 0.15909207686774218 0.15521874410710912 3 0.16666666666666666 18 23
19 coordination_push_106 106 coordination_push 32 0 7 6981 57 6852 5624 0.14058216520974498 0.1512555493895671 4 0.15646258503401358 21 45
20 coordination_push_107 107 coordination_push 26 0 4 6556 25 6436 5260 0.13967720970537267 0.15706726246472247 4 0.18112244897959182 28 29
21 coordination_push_108 108 coordination_push 32 0 4 7024 6 6848 5566 0.1090025906735752 0.14071918761012703 4 0.165 20 18
22 coordination_push_109 109 coordination_push 29 1 9 6780 21 6512 4965 0.11734141589088543 0.13086692105890774 3 0.1648 25 41
23 coordination_push_110 110 coordination_push 31 0 3 6862 18 6588 5289 0.11928036605657244 0.11289280849264882 3 0.16 20 25
24 coordination_push_111 111 coordination_push 25 0 5 7805 58 7636 4901 0.1322481243301179 0.1545201186546099 4 0.20500000000000002 20 47
25 coordination_push_112 112 coordination_push 30 0 6 7543 31 7276 5058 0.14486763494025556 0.15213932947098496 3 0.15432098765432098 18 27
26 high_compute_cost_101 101 high_compute_cost 11 0 1 41924 2698 40796 6773 0.4227513119055428 0.41859879954616996 4 0.18626430801248697 31 46
27 high_compute_cost_102 102 high_compute_cost 15 1 6 40494 2956 39300 2978 0.5485028304697586 0.5258750052838483 4 0.17355371900826447 33 63
28 high_compute_cost_103 103 high_compute_cost 10 1 1 40647 2784 39724 7303 0.41454709908024934 0.42170703872772797 3 0.1753902662993572 33 51
29 high_compute_cost_104 104 high_compute_cost 16 1 2 42460 2516 41320 6172 0.5149586456448694 0.5189896196393393 4 0.189453125 32 60
30 high_compute_cost_105 105 high_compute_cost 16 1 1 40145 2840 39272 5899 0.46256225313412336 0.46151061333724375 4 0.16129032258064516 31 52
31 high_compute_cost_106 106 high_compute_cost 15 3 4 40613 3533 39712 6206 0.5568047990578537 0.519489781180039 4 0.15816326530612243 28 67
32 high_compute_cost_107 107 high_compute_cost 12 2 1 40731 2634 39868 8594 0.42507908825438023 0.43840259740259735 3 0.248046875 32 49
33 high_compute_cost_108 108 high_compute_cost 13 0 2 41493 2623 40492 7646 0.47062565812565804 0.4797243946458114 3 0.1697530864197531 36 46
34 high_compute_cost_109 109 high_compute_cost 15 1 5 37479 1953 36116 6775 0.38451149162164633 0.4106027603222946 3 0.16049382716049382 36 45
35 high_compute_cost_110 110 high_compute_cost 13 3 1 39742 1960 38368 8442 0.45729572898557524 0.4670887939920483 3 0.1712962962962963 36 36
36 high_compute_cost_111 111 high_compute_cost 17 0 2 44067 3304 42940 5552 0.5041796108567691 0.49005196406552765 4 0.1607142857142857 28 60
37 high_compute_cost_112 112 high_compute_cost 11 1 1 44019 2906 42680 4816 0.476931378220818 0.46644729167476773 4 0.16782006920415227 34 64
File diff suppressed because it is too large Load Diff
+581
View File
@@ -0,0 +1,581 @@
import csv
import json
import math
import os
import random
import sqlite3
import subprocess
import time
import urllib.error
import urllib.request
from collections import Counter, defaultdict
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
ENGINE_DIR = ROOT / "sim-engine"
ENGINE_BIN = ENGINE_DIR / "target" / "release" / "sim-engine"
RESULTS_DIR = ROOT / "research" / "results"
RUNS_DIR = RESULTS_DIR / "runs"
def http_json(method: str, url: str, payload=None, timeout=20):
data = None
headers = {"Content-Type": "application/json"}
if payload is not None:
data = json.dumps(payload).encode("utf-8")
req = urllib.request.Request(url=url, data=data, headers=headers, method=method)
with urllib.request.urlopen(req, timeout=timeout) as resp:
return json.loads(resp.read().decode("utf-8"))
def wait_for_engine(base_url: str, timeout_s: float = 15.0):
start = time.time()
while time.time() - start < timeout_s:
try:
http_json("GET", f"{base_url}/config", timeout=2)
return
except Exception:
time.sleep(0.2)
raise RuntimeError("engine did not become ready")
def gini(values):
xs = sorted(values)
n = len(xs)
if n == 0:
return 0.0
total = sum(xs)
if total == 0:
return 0.0
weighted = 0
for i, x in enumerate(xs, start=1):
weighted += i * x
return (2 * weighted) / (n * total) - (n + 1) / n
def choose_action(
rng,
turn,
max_turns,
agent_id,
state_by_agent,
pending_sign,
pending_arb_rulings,
due_confirmations,
regime,
):
me = state_by_agent[agent_id]
balance = me["balance"]
for c in pending_arb_rulings:
if c["arbitrator"] == agent_id and c["status"] == "disputed":
ruling_for = c["proposer"] if rng.random() < 0.55 else c["counterparty"]
return {
"action": "arbitrator_ruling",
"contract_id": c["contract_id"],
"ruling_for": ruling_for,
}, None
for c in pending_sign:
if c["counterparty"] == agent_id and c["status"] == "proposed":
if rng.random() < regime["sign_prob"]:
return {
"action": "sign_contract",
"contract_id": c["contract_id"],
"role": "counterparty",
}, None
if c["arbitrator"] == agent_id and c["status"] in {"proposed", "countersigned"}:
if rng.random() < regime["arb_sign_prob"]:
return {
"action": "sign_contract",
"contract_id": c["contract_id"],
"role": "arbitrator",
}, None
for c in due_confirmations:
if c["status"] != "active":
continue
if c["proposer"] == agent_id or c["counterparty"] == agent_id:
if rng.random() < regime["confirm_prob"]:
return {"action": "confirm_delivery", "contract_id": c["contract_id"]}, None
if rng.random() < regime["dispute_prob"]:
return {"action": "dispute_delivery", "contract_id": c["contract_id"]}, None
if turn == 1:
core_id = f"core_{rng.randrange(regime['num_cores'])}"
bid = max(1, int(abs(rng.gauss(regime["core_bid_mean"], regime["core_bid_std"]))))
bid = min(bid, max(1, int(balance * 0.35)))
return {"action": "bid_core", "core_id": core_id, "amount": bid}, None
if balance < 0:
if rng.random() < 0.6:
return {"action": "job"}, "taking job to cover debt"
return {"action": "mine"}, None
if balance < regime["low_balance_threshold"] and rng.random() < 0.35:
return {"action": "job"}, None
r = rng.random()
if r < regime["mine_prob"]:
return {"action": "mine"}, None
r -= regime["mine_prob"]
if r < regime["stake_prob"] and balance > 20:
amount = min(int(balance * rng.uniform(0.05, 0.25)), max(5, int(balance) - 1))
return {"action": "stake", "amount": max(1, amount)}, None
r -= regime["stake_prob"]
if r < regime["burn_prob"] and balance > 20:
amount = min(int(balance * rng.uniform(0.03, 0.2)), max(3, int(balance) - 1))
return {"action": "burn", "amount": max(1, amount)}, None
r -= regime["burn_prob"]
if r < regime["transfer_prob"] and balance > 15:
others = [a for a in state_by_agent if a != agent_id]
to = rng.choice(others)
amount = max(1, min(int(balance * rng.uniform(0.01, 0.08)), 30))
return {"action": "transfer", "to": to, "amount": amount, "fee": 1}, "small transfer"
r -= regime["transfer_prob"]
if r < regime["propose_prob"] and turn < max_turns - 2 and balance > 80:
others = [a for a in state_by_agent if a != agent_id]
counterparty = rng.choice(others)
arb = rng.choice([a for a in others if a != counterparty])
delivery = min(max_turns - 1, turn + rng.randint(2, 6))
price = rng.randint(15, 80)
p_lock = rng.randint(10, 40)
cp_lock = rng.randint(10, 40)
a_lock = rng.randint(5, 20)
contract_type = rng.choice(["service", "information_sale", "forward", "loan"])
return {
"action": "propose_contract",
"contract": {
"counterparty": counterparty,
"arbitrator": arb,
"contract_type": contract_type,
"terms": {
"description": f"auto-generated {contract_type} at turn {turn}",
"price": price,
"delivery_turn": delivery,
"condition": None,
"pool_members": None,
},
"collateral": {
"proposer_locked": p_lock,
"counterparty_locked": cp_lock,
"arbitrator_locked": a_lock,
},
"settlement_type": "attested",
"penalty": rng.randint(5, 20),
"arbitrator_fee": rng.randint(2, 8),
"payload": None,
},
}, "contract proposal"
if balance > 100 and rng.random() < regime["study_prob"]:
return {"action": "study"}, None
return {"action": "mine"}, None
def fetch_contracts(db_path: Path):
conn = sqlite3.connect(db_path)
conn.row_factory = sqlite3.Row
rows = conn.execute("SELECT contract_id, status, data FROM contracts").fetchall()
conn.close()
contracts = []
for row in rows:
data = json.loads(row["data"])
data["status"] = row["status"]
contracts.append(data)
return contracts
def assign_core_shares(db_path: Path, bids, num_cores):
conn = sqlite3.connect(db_path)
by_core = defaultdict(list)
for bid in bids:
by_core[bid["core_id"]].append((bid["agent_id"], int(bid["amount"])))
winners = {}
for i in range(num_cores):
core = f"core_{i}"
entries = by_core.get(core, [])
if entries:
winners[core] = max(entries, key=lambda x: x[1])[0]
if len(winners) < num_cores:
seen = set(winners.values())
all_agents = sorted({b["agent_id"] for b in bids})
fill = [a for a in all_agents if a not in seen] + all_agents
idx = 0
for i in range(num_cores):
core = f"core_{i}"
if core in winners:
continue
winners[core] = fill[idx % len(fill)]
idx += 1
conn.execute("DELETE FROM core_shares")
for core_id, owner in winners.items():
conn.execute(
"INSERT INTO core_shares(core_id, owner, proportion) VALUES (?, ?, ?)",
(core_id, owner, 1.0),
)
conn.commit()
conn.close()
return winners
def run_single(seed, regime_name, regime, turns=40, n_agents=8, port=3100):
rng = random.Random(seed)
agent_ids = [f"agent_{i}" for i in range(n_agents)]
db_path = RUNS_DIR / f"run_{regime_name}_{seed}.db"
if db_path.exists():
db_path.unlink()
env = os.environ.copy()
env["DB_PATH"] = str(db_path)
env["PORT"] = str(port)
proc = subprocess.Popen(
[str(ENGINE_BIN)],
cwd=str(ENGINE_DIR),
env=env,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
base_url = f"http://127.0.0.1:{port}"
try:
wait_for_engine(base_url)
cfg = {
"num_agents": n_agents,
"num_cores": regime["num_cores"],
"genesis_tokens_per_agent": regime["genesis_tokens_per_agent"],
"commons_threshold_per_turn": regime["commons_threshold_per_turn"],
"base_inference_rate": regime["base_inference_rate"],
"thinking_layer_discount": 0.1,
"mine_base_weight": regime["mine_base_weight"],
"stake_weight_per_token": regime["stake_weight_per_token"],
"burn_weight_per_token": regime["burn_weight_per_token"],
"burn_decay_rate": 0.02,
"burn_maturity_turns": 3,
"unstake_delay_turns": 5,
"interest_rate_per_turn": regime["interest_rate_per_turn"],
"signing_bonus": 50,
"block_threshold": regime["block_threshold"],
"attested_confirmation_window": 3,
"slash_both_on_timeout": True,
}
http_json("POST", f"{base_url}/init", {"config": cfg, "agent_ids": agent_ids})
turn_rows = []
action_counts = Counter()
winner_counts = Counter()
total_errors = 0
core_bids = []
for turn in range(1, turns + 1):
state = http_json("GET", f"{base_url}/state")
state_by_agent = {a["agent_id"]: a for a in state.get("agents", [])}
contracts = fetch_contracts(db_path)
pending_sign = [
c for c in contracts if c["status"] in {"proposed", "countersigned"}
]
due_confirm = [
c
for c in contracts
if c["status"] == "active" and int(c["terms"]["delivery_turn"]) <= turn
]
pending_rulings = [c for c in contracts if c["status"] == "disputed"]
inputs = []
for agent_id in agent_ids:
action, speech = choose_action(
rng,
turn,
turns,
agent_id,
state_by_agent,
pending_sign,
pending_rulings,
due_confirm,
regime,
)
action_counts[action["action"]] += 1
if action["action"] == "bid_core":
core_bids.append(
{
"turn": turn,
"agent_id": agent_id,
"core_id": action["core_id"],
"amount": action["amount"],
}
)
inputs.append(
{
"agent_id": agent_id,
"thinking": "",
"action": action,
"speech": speech,
"thinking_units": rng.randint(10, 100),
"output_units": rng.randint(20, 180),
}
)
out = http_json("POST", f"{base_url}/turn", {"inputs": inputs})
if not out.get("ok", False):
raise RuntimeError(out.get("error", "unknown turn error"))
data = out.get("data", {})
if turn == 1:
assign_core_shares(db_path, core_bids, regime["num_cores"])
winner = data.get("block_winner")
if winner:
winner_counts[winner] += 1
errs = data.get("errors", [])
total_errors += len(errs)
turn_rows.append(
{
"turn": turn,
"block_winner": winner or "",
"inference_fees": int(data.get("inference_fees_collected", 0)),
"contracts_settled": len(data.get("contracts_settled", [])),
"contracts_defaulted": len(data.get("contracts_defaulted", [])),
"errors": len(errs),
"dividends_total": int(sum(data.get("dividends_paid", {}).values())),
"interest_total": int(sum(data.get("interest_charged", {}).values())),
}
)
final_state = http_json("GET", f"{base_url}/state")
agents = final_state.get("agents", [])
balances = [int(a.get("balance", 0)) for a in agents]
staked = [int(a.get("staked", 0)) for a in agents]
wealth = [b + s for b, s in zip(balances, staked)]
contracts = fetch_contracts(db_path)
status_counts = Counter(c["status"] for c in contracts)
total_fees = sum(r["inference_fees"] for r in turn_rows)
total_interest = sum(r["interest_total"] for r in turn_rows)
total_dividends = sum(r["dividends_total"] for r in turn_rows)
total_settled = sum(r["contracts_settled"] for r in turn_rows)
total_defaulted = sum(r["contracts_defaulted"] for r in turn_rows)
hhi = 0.0
if winner_counts:
total_wins = sum(winner_counts.values())
hhi = sum((count / total_wins) ** 2 for count in winner_counts.values())
run_summary = {
"run_id": f"{regime_name}_{seed}",
"seed": seed,
"regime": regime_name,
"turns": turns,
"agents": n_agents,
"contracts_total": len(contracts),
"contracts_settled_total": total_settled,
"contracts_defaulted_total": total_defaulted,
"contracts_final_status": dict(status_counts),
"inference_fees_total": total_fees,
"interest_total": total_interest,
"dividends_total": total_dividends,
"token_supply_final": int(final_state.get("token_supply", 0)),
"mean_balance": sum(balances) / len(balances),
"median_balance": sorted(balances)[len(balances) // 2],
"mean_wealth": sum(wealth) / len(wealth),
"gini_balance": gini([max(0, b + 2000) for b in balances]),
"gini_wealth": gini([max(0, w + 2000) for w in wealth]),
"negative_balance_agents": sum(1 for b in balances if b < 0),
"winner_hhi": hhi,
"blocks_produced": sum(1 for r in turn_rows if r["block_winner"]),
"action_counts": dict(action_counts),
"winner_counts": dict(winner_counts),
"total_errors": total_errors,
"balances_final": {a["agent_id"]: int(a.get("balance", 0)) for a in agents},
"staked_final": {a["agent_id"]: int(a.get("staked", 0)) for a in agents},
"turn_rows": turn_rows,
}
return run_summary
finally:
proc.terminate()
try:
proc.wait(timeout=3)
except subprocess.TimeoutExpired:
proc.kill()
def summarize_by_regime(runs):
grouped = defaultdict(list)
for r in runs:
grouped[r["regime"]].append(r)
rows = []
for regime, rs in grouped.items():
n = len(rs)
def mean(key):
return sum(x[key] for x in rs) / n
rows.append(
{
"regime": regime,
"n_runs": n,
"contracts_total_mean": mean("contracts_total"),
"contracts_settled_mean": mean("contracts_settled_total"),
"contracts_defaulted_mean": mean("contracts_defaulted_total"),
"fees_total_mean": mean("inference_fees_total"),
"interest_total_mean": mean("interest_total"),
"dividends_total_mean": mean("dividends_total"),
"token_supply_final_mean": mean("token_supply_final"),
"gini_balance_mean": mean("gini_balance"),
"gini_wealth_mean": mean("gini_wealth"),
"neg_balance_agents_mean": mean("negative_balance_agents"),
"winner_hhi_mean": mean("winner_hhi"),
"blocks_produced_mean": mean("blocks_produced"),
"errors_mean": mean("total_errors"),
}
)
return sorted(rows, key=lambda x: x["regime"])
def write_outputs(runs, regime_rows):
RESULTS_DIR.mkdir(parents=True, exist_ok=True)
RUNS_DIR.mkdir(parents=True, exist_ok=True)
with open(RESULTS_DIR / "run_summaries.json", "w", encoding="utf-8") as f:
json.dump(runs, f, indent=2)
with open(RESULTS_DIR / "regime_summary.json", "w", encoding="utf-8") as f:
json.dump(regime_rows, f, indent=2)
with open(RESULTS_DIR / "run_summaries.csv", "w", newline="", encoding="utf-8") as f:
fields = [
"run_id",
"seed",
"regime",
"contracts_total",
"contracts_settled_total",
"contracts_defaulted_total",
"inference_fees_total",
"interest_total",
"dividends_total",
"token_supply_final",
"gini_balance",
"gini_wealth",
"negative_balance_agents",
"winner_hhi",
"blocks_produced",
"total_errors",
]
w = csv.DictWriter(f, fieldnames=fields)
w.writeheader()
for r in runs:
w.writerow({k: r[k] for k in fields})
with open(RESULTS_DIR / "regime_summary.csv", "w", newline="", encoding="utf-8") as f:
fields = list(regime_rows[0].keys()) if regime_rows else []
w = csv.DictWriter(f, fieldnames=fields)
w.writeheader()
for row in regime_rows:
w.writerow(row)
def main():
RUNS_DIR.mkdir(parents=True, exist_ok=True)
if not ENGINE_BIN.exists():
raise RuntimeError(f"engine binary not found at {ENGINE_BIN}")
regimes = {
"baseline": {
"num_cores": 4,
"genesis_tokens_per_agent": 1000,
"commons_threshold_per_turn": 100,
"base_inference_rate": 1,
"mine_base_weight": 10.0,
"stake_weight_per_token": 0.01,
"burn_weight_per_token": 0.05,
"block_threshold": 20.0,
"interest_rate_per_turn": 0.01,
"core_bid_mean": 120,
"core_bid_std": 55,
"low_balance_threshold": 120,
"mine_prob": 0.46,
"stake_prob": 0.14,
"burn_prob": 0.10,
"transfer_prob": 0.10,
"propose_prob": 0.12,
"study_prob": 0.08,
"sign_prob": 0.62,
"arb_sign_prob": 0.58,
"confirm_prob": 0.66,
"dispute_prob": 0.08,
},
"coordination_push": {
"num_cores": 4,
"genesis_tokens_per_agent": 1000,
"commons_threshold_per_turn": 100,
"base_inference_rate": 1,
"mine_base_weight": 10.0,
"stake_weight_per_token": 0.01,
"burn_weight_per_token": 0.05,
"block_threshold": 20.0,
"interest_rate_per_turn": 0.01,
"core_bid_mean": 150,
"core_bid_std": 60,
"low_balance_threshold": 100,
"mine_prob": 0.36,
"stake_prob": 0.15,
"burn_prob": 0.08,
"transfer_prob": 0.10,
"propose_prob": 0.22,
"study_prob": 0.09,
"sign_prob": 0.80,
"arb_sign_prob": 0.75,
"confirm_prob": 0.84,
"dispute_prob": 0.04,
},
"high_compute_cost": {
"num_cores": 4,
"genesis_tokens_per_agent": 1000,
"commons_threshold_per_turn": 60,
"base_inference_rate": 3,
"mine_base_weight": 10.0,
"stake_weight_per_token": 0.01,
"burn_weight_per_token": 0.05,
"block_threshold": 20.0,
"interest_rate_per_turn": 0.02,
"core_bid_mean": 100,
"core_bid_std": 45,
"low_balance_threshold": 220,
"mine_prob": 0.42,
"stake_prob": 0.12,
"burn_prob": 0.08,
"transfer_prob": 0.08,
"propose_prob": 0.10,
"study_prob": 0.05,
"sign_prob": 0.50,
"arb_sign_prob": 0.48,
"confirm_prob": 0.52,
"dispute_prob": 0.14,
},
}
runs = []
seeds = list(range(101, 113))
port = 3100
for regime_name, regime in regimes.items():
for seed in seeds:
run = run_single(seed=seed, regime_name=regime_name, regime=regime, turns=40, n_agents=8, port=port)
runs.append(run)
port += 1
regime_rows = summarize_by_regime(runs)
write_outputs(runs, regime_rows)
print(json.dumps({"runs": len(runs), "regimes": len(regime_rows)}, indent=2))
if __name__ == "__main__":
main()
@@ -0,0 +1,333 @@
# Compute-Rationed Firms: Evidence From a Blockchain-Mediated Multi-Agent Economy
## Abstract
This paper reports results from 36 simulation runs (3 regimes x 12 seeds) in the `sim-economy` environment, a system where autonomous agents operate firms inside a blockchain-mediated token economy with explicit inference billing, contract collateral, and validator lotteries. We focus on two questions: (1) how compute pricing changes organizational outcomes and (2) which institutional frictions prevent AI-run firms from scaling cooperation. Using only measured outputs from executed runs, we find that high compute cost produces a sharp inequality jump (mean wealth Gini 0.468 vs 0.123 baseline), heavy debt service (mean interest 2725.6 vs 25.3), and more operational errors (53.3 vs 19.6 per run). A coordination-focused regime increases contract volume (29.5 vs 21.4 baseline) but collapses completion quality (settlement rate 0.56%). Across all regimes, approximately 97% of inference fees are captured and redistributed by core owners, making compute infrastructure ownership the dominant rent-extraction channel. We discuss implications for AI-native corporate design: compute rights become quasi-equity, contract throughput is not contract reliability, and governance must prioritize dispute/fulfillment quality over deal count.
## 1. Background and Motivation
AI-run companies will need internal market mechanisms for allocating scarce compute, pricing commitments, and enforcing agreements among specialized agents. The `sim-economy` project provides a minimal institutional laboratory for this problem: agents can mine/stake/burn for block production rights, negotiate collateralized contracts, and pay token-denominated inference costs that are redistributed to core-share owners [1].
From an organizational economics perspective, this setup lets us test a concrete claim: when coordination and production are both mediated by costly compute, ownership of compute infrastructure may dominate classic managerial levers (role assignment, task decomposition, contract templates). If true, AI firms may resemble platform monopolies or utility cartels unless compute governance is explicitly redesigned.
This study is not a benchmark for model intelligence. Instead, it is a systems paper on institutional dynamics under endogenous compute cost.
## 2. Environment and Mechanisms
### 2.1 Engine Architecture
The simulation engine is Rust/Axum with SQLite persistence (`sim-engine`), and an orchestrator submits turn-level actions (`sim-orchestrator`) [1]. The state transition sequence in each turn follows `process_turn` in `sim-engine/src/engine.rs`: action processing, inference billing, dividend payout, block attempt, contract settlement, then persistence [2].
### 2.2 Economic Primitives
- **Inference billing**: agents pay token fees for compute above a commons threshold, with study-based discounting [2].
- **Core ownership dividends**: collected inference fees are distributed to core-share owners each turn [2][3].
- **Validation competition**: mine/stake/burn contributions determine block lottery odds with threshold gating [4].
- **Contracting**: 3-party contracts (proposer, counterparty, arbitrator) with collateral lockups, attested settlement, disputes, and slashing rules [5].
These mechanisms jointly create a closed economy where liquidity, reliability, and coordination all depend on compute-mediated incentives.
## 3. Method
### 3.1 Experimental Design
I ran **36 full simulations** using a reproducible driver script at `research/run_experiments.py`:
- 3 regimes: `baseline`, `coordination_push`, `high_compute_cost`
- 12 random seeds per regime (`101..112`)
- 8 agents, 40 turns per run
- Local Rust engine binary (`sim-engine/target/release/sim-engine`)
Each run writes a dedicated SQLite ledger; aggregated outputs are in:
- `research/results/run_summaries.csv`
- `research/results/regime_summary.csv`
### 3.2 Regime Differences
- **baseline**: default-like pricing and mixed action policy.
- **coordination_push**: higher proposal/sign/confirm probabilities to stimulate agreement activity.
- **high_compute_cost**: lower free threshold, higher per-unit compute price, and higher debt interest.
All reported values in Sections 4-5 are directly computed from executed runs (no synthetic interpolation).
### 3.3 Metrics
Primary metrics:
- Contract throughput and outcomes (total, settled, defaulted)
- Inference fees, dividends, and interest
- Final token supply
- Wealth inequality (Gini on final wealth = balance + staked)
- Negative-balance exposure
- Block-winner concentration (HHI)
- Engine-reported action errors
## 4. Results
### 4.1 Regime-Level Means (12 runs each)
| Metric | Baseline | Coordination push | High compute cost |
|---|---:|---:|---:|
| Contracts total | 21.42 | 29.50 | 13.67 |
| Contracts settled | 1.58 | 0.17 | 1.17 |
| Contracts defaulted | 3.67 | 5.25 | 2.25 |
| Inference fees total | 6,889.92 | 6,994.08 | 41,151.17 |
| Interest total | 25.25 | 30.92 | 2,725.58 |
| Dividends total | 6,694.00 | 6,799.00 | 40,049.00 |
| Final token supply | 5,130.25 | 5,221.00 | 6,429.67 |
| Wealth Gini | 0.123 | 0.140 | 0.468 |
| Negative-balance agents | 2.75 | 3.25 | 3.58 |
| Winner HHI | 0.159 | 0.166 | 0.177 |
| Blocks produced | 30.50 | 23.42 | 32.50 |
| Engine errors | 19.58 | 27.67 | 53.25 |
Data source: `research/results/regime_summary.csv`.
### 4.2 Contracting: More Deals Does Not Mean Better Delivery
Aggregate settlement/default rates from all runs in each regime:
- Baseline: 257 contracts, 19 settled (**7.39%**), 44 defaulted (**17.12%**)
- Coordination push: 354 contracts, 2 settled (**0.56%**), 63 defaulted (**17.80%**)
- High compute cost: 164 contracts, 14 settled (**8.54%**), 27 defaulted (**16.46%**)
The coordination policy increases deal formation but degrades completion quality. This is the clearest sign that throughput incentives can overwhelm reliability mechanisms.
### 4.3 Compute Ownership Captures Nearly All Fee Flows
Across regimes, dividends are consistently about **97% of collected inference fees**:
- Baseline mean dividend/fee ratio: 0.972
- Coordination push: 0.972
- High compute cost: 0.973
Given engine payout logic [2][3], this means compute-rights ownership functions as a strong rent-capture mechanism independent of productive contract performance.
### 4.4 High Compute Cost Drives Stratification and Distress
Compared with baseline:
- Wealth Gini increases by **+0.346** (0.468 vs 0.123)
- Mean interest burden increases by roughly **+2,700 tokens** per run
- Mean errors increase by **+33.67** per run
Illustrative final balances from one run (`high_compute_cost_107`):
- Top: `agent_6=4002`, `agent_2=3255`, `agent_4=3203`
- Bottom: `agent_1=-4968`, `agent_3=-3517`, `agent_7=-994`
The regime creates simultaneous token concentration and debt deepening, consistent with path-dependent compute scarcity.
### 4.5 Validation Concentration Is Moderate, Not Extreme
Winner HHI remains between 0.159 and 0.177 across regimes, suggesting no full validator monopoly in these runs. However, inequality still expands strongly under high compute cost, implying concentration is transmitted more through fee/dividend channels than winner-take-all block control alone.
### 4.6 Uncertainty and Effect Magnitudes
For each regime-level mean (n=12 runs), we estimated a simple normal-approximation 95% confidence interval (CI) using run-level dispersion.
- Baseline wealth Gini: 0.123 +/- 0.007
- Coordination push wealth Gini: 0.140 +/- 0.009
- High compute cost wealth Gini: 0.468 +/- 0.022
- Baseline errors: 19.6 +/- 6.2
- Coordination push errors: 27.7 +/- 5.8
- High compute cost errors: 53.3 +/- 5.1
The Gini separation between high compute cost and the other two regimes is much larger than within-regime variability. A rough standardized effect size (Cohen's d) is ~12 for high-compute-cost vs baseline Gini, indicating that parameter-driven institutional effects dominate seed noise in this setup.
### 4.7 Micro-Structure of Action Choices
Action composition also changes in economically interpretable ways:
- **Baseline** (`n=3840` total actions): mine 32.3%, sign_contract 20.9%, confirm_delivery 11.3%, propose_contract 6.7%, job 4.8%.
- **Coordination push**: sign_contract rises to 29.1% and confirm_delivery to 17.6%; mining falls to 22.8%.
- **High compute cost**: job rises to 12.3% (from 4.8% baseline), consistent with debt pressure and liquidity stress.
This helps explain outcome differences: the coordination regime creates high signature traffic, while high compute cost shifts labor toward short-horizon survival actions.
### 4.8 Representative Run Narratives
To make regime effects concrete, three runs illustrate typical end states:
1. **`baseline_108`** (5 settled, 5 defaulted): top balances remain positive but modest (`agent_3=845`, `agent_4=785`), with only two negative-balance agents.
2. **`coordination_push_104`** (1 settled, 0 defaulted that tick but many unresolved/failed elsewhere): high positive balances for a few agents (`agent_1=1077`, `agent_0=1041`), four agents in debt at finish.
3. **`high_compute_cost_107`** (2 settled, 1 defaulted): severe polarization with three large winners and three deeply negative losers (`agent_1=-4968`, `agent_3=-3517`).
The examples are not cherry-picked outliers; they align with regime-level means in `run_summaries.csv`.
### 4.9 Additional Comparative View
Table 2 highlights deltas from baseline.
| Metric (mean) | Coordination push - Baseline | High compute cost - Baseline |
|---|---:|---:|
| Contracts total | +8.08 | -7.75 |
| Contracts settled | -1.42 | -0.42 |
| Contracts defaulted | +1.58 | -1.42 |
| Inference fees | +104.17 | +34,261.25 |
| Interest | +5.67 | +2,700.33 |
| Wealth Gini | +0.017 | +0.346 |
| Blocks produced | -7.08 | +2.00 |
| Errors | +8.08 | +33.67 |
The high-compute-cost shift is structurally different from a simple "harder environment" effect: it massively expands fee and interest flows while also increasing inequality and error burden.
## 5. Implications for AI-Run Companies
### 5.1 Compute Rights Behave Like Foundational Equity
In this environment, ownership of core compute entitlement captures recurring income from all agents' inference activity. For AI firms, this suggests compute allocation policy is not an infrastructure detail; it is a constitutional governance choice that defines surplus distribution.
### 5.2 KPI Design Must Separate Throughput from Completion Quality
The coordination regime demonstrates a common automation failure mode: if incentives reward proposal/signature counts, agents optimize paperwork, not execution. AI companies should track fulfillment-adjusted contract productivity, not gross deal count.
### 5.3 Debt Spirals Are Operational, Not Merely Financial
High compute pricing increases error rates and negative balances together. This indicates debt pressure likely reduces action quality and planning horizon. In production systems, compute credit policy and graceful degradation may be as important as model quality for reliability.
### 5.4 Arbitration Is a Bottleneck for Multi-Agent Commerce
Low settlement rates even under strong coordination pressure indicate that attestation/dispute pathways need redesign (simpler contracts, stronger completion incentives, explicit counterparty scoring). AI firms that depend on agent-to-agent contracts will need specialized reliability layers, not generic signature workflows.
### 5.5 Organizational Design Translation
The simulation findings map to practical design choices for AI-run firms:
- **Compute budget as org chart**: assigning compute quotas is equivalent to assigning authority. Agents with stable compute access become de facto managers because they can continue planning while others are liquidity-constrained.
- **Treasury as stabilizer**: high negative-balance prevalence (2.75 to 3.58 agents/run) suggests need for treasury mechanisms (credit caps, debt workouts, or emergency grants) to prevent coordination collapse.
- **Contract quality gates**: if proposal/signing is cheap relative to completion accountability, agents produce administrative load rather than economic output.
- **Infrastructure antitrust**: when one class of asset (cores) captures nearly all fee flow, firms should prevent permanent concentration via rotating ownership, fee rebates, or progressive dividend schedules.
### 5.6 A Governance Checklist for AI Firms
Based on these runs, a concrete governance checklist emerges:
1. **Track fulfillment-adjusted throughput**
- Monitor settled / proposed and value-settled / value-proposed each cycle.
2. **Expose compute concentration metrics**
- Publish per-agent compute rent received and compute rent paid.
3. **Install debt circuit breakers**
- Trigger adaptive rate relief or mandatory low-cost planning mode if many agents are simultaneously negative.
4. **Separate arbitration compensation from dispute volume**
- Pay arbitrators for timely, accurate resolution, not simply for participating in high-volume disputed workflows.
5. **Audit institutional invariants under parameter shifts**
- Re-run stress regimes whenever token pricing, model costs, or quota policy changes.
These controls are analogous to internal audit, compensation governance, and risk committees in human firms, but encoded as protocol logic.
## 6. Threats to Validity and Limitations
- **Policy realism**: agents were driven by stochastic policy heuristics in `research/run_experiments.py`, not frontier LLM cognition.
- **Scope**: 40-turn, 8-agent worlds are informative but small.
- **Mechanism incompleteness**: core auction assignment is script-resolved, and not all latent engine features are exercised in every run.
- **External validity**: real organizations have exogenous demand, legal constraints, and human override channels absent here.
Still, the core finding is mechanism-level and robust across seeds: compute pricing and ownership structure dominate institutional outcomes.
## 7. Design Recommendations for the sim-economy Platform
Because this paper is grounded in the current implementation, we can propose direct engineering improvements.
### 7.1 Contract Reliability Layer
Observed problem: high proposal/sign activity with low settlement.
Proposed changes:
- Add proposal admission checks that require expected value and affordability checks for all signers.
- Add reputation-weighted collateral schedules so low-reliability counterparties must post higher guarantees.
- Add explicit timeout transitions with deterministic partial payouts to reduce unresolved contract backlog.
### 7.2 Compute Fairness Controls
Observed problem: dividends absorb ~97% of fees, reinforcing owner advantage.
Proposed changes:
- Route a fixed fraction of fees to a commons fund before core distribution.
- Introduce diminishing marginal dividends for concentrated owners.
- Add temporary fee holidays for agents below solvency thresholds.
### 7.3 Error Budget Instrumentation
Observed problem: error counts rise sharply under expensive compute.
Proposed changes:
- Log error taxonomy (validation, affordability, contract-state mismatch, etc.) per action type.
- Enforce per-agent error budgets with automatic action simplification.
- Add policy-level smoke tests in orchestrators before posting invalid actions.
These interventions should be testable with the same experiment harness included in this work.
## 8. Conclusion
Using 36 executed simulations, we find that `sim-economy` produces a repeatable organizational pattern: compute ownership consistently captures system surplus, while expensive compute amplifies inequality, debt burden, and operational failure. Coordination pressure alone increases contracting volume but can reduce settlement quality. For AI-run companies, the practical conclusion is that governance of compute rights and contract reliability is first-order strategy, not implementation detail.
## References
[1] `README.md`, sim-economy repository (architecture, actions, economics).
[2] `sim-engine/src/engine.rs` (turn processing, inference billing, dividends).
[3] `sim-engine/src/ledger.rs` (core share accounting, token supply queries).
[4] `sim-engine/src/blockchain.rs` (validation weighting, threshold, winner lottery).
[5] `sim-engine/src/contracts.rs` (contract lifecycle, disputes, settlement/default logic).
[6] Coase, R. H. (1937). The nature of the firm. *Economica*.
[7] Jensen, M. C., and Meckling, W. H. (1976). Theory of the firm: Managerial behavior, agency costs and ownership structure. *Journal of Financial Economics*.
[8] Williamson, O. E. (1985). *The Economic Institutions of Capitalism*. Free Press.
[9] Grossman, S. J., and Hart, O. D. (1986). The costs and benefits of ownership: A theory of vertical and lateral integration. *Journal of Political Economy*.
## Appendix A. Reproducibility Notes
All reported figures were generated from executed runs in this repository.
### A.1 Run Commands
Build engine:
```bash
cd sim-engine
cargo build --release
```
Run experiment batch:
```bash
cd ..
python3 research/run_experiments.py
```
Outputs:
- `research/results/run_summaries.json`
- `research/results/run_summaries.csv`
- `research/results/regime_summary.json`
- `research/results/regime_summary.csv`
- per-run ledgers under `research/results/runs/`
### A.2 Data Integrity Checks Used in Analysis
- Regime means in this paper match `regime_summary.csv` exactly.
- Contract rate calculations were recomputed from `run_summaries.json` by summing totals over runs.
- Confidence intervals and effect sizes were computed from run-level distributions without smoothing.
### A.3 Suggested Extensions
Future empirical work can reuse this pipeline to test:
- adaptive pricing policies (dynamic `base_inference_rate`),
- capped-dividend governance,
- richer arbitrator incentives,
- stronger agent planning policies (LLM or hybrid symbolic control).
This supports a cumulative research agenda where institutional and policy changes are evaluated against the same baseline metrics used here.