TV-04: fee gap clamped at year 2 (no ramp), ceilings to six decimals, the batch beside the document

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
igneum-labs 2026-10-09 08:20:21 +00:00
parent 02ce7996d7
commit 397be0746e

View file

@ -183,7 +183,7 @@ def build_model(inp, repo_root=None):
tip_miner = Fraction(route(inp, "R3-tip-miner")["share_percent_num"], 100)
feerep = []
for y in range(1, YEARS_MODELLED + 1):
gap = split[1]["miners"] - split[y]["miners"]
gap = max(0, split[1]["miners"] - split[y]["miners"]) # year 2 pays more than year 1 (no ramp): no tips needed
need = Fraction(gap) / tip_miner
feerep.append({"year": y, "miner_gap_base_units": gap, "tips_needed_exact": need, "tips_needed_bu": need / B})
dec = s["decimals"]
@ -240,7 +240,7 @@ ROLE_ROUTE = {"miners": "R1-miner", "internal provers": "R1-pool", "minimum vali
def meaning(row, model):
H, role = row["horizon"], row["role"]
c = fx(row["ceiling_exact"], 4)
c = fx(row["ceiling_exact"], 6)
mm = f"{fx(Fraction(row['multiple_num'], row['multiple_den']), 2)}x"
if role in ("minimum validators", "maintenance"):
return (f"In year {H} at {mm} the protocol routes nothing to {role}, so any positive minimum cost for the role is in the failure region "
@ -408,7 +408,7 @@ def readme(inp, model, files, root):
rs = [r for r in model["rows"] if r["horizon"] == H and r["role"] == role]
r0 = rs[0]
rt = route(inp, ROLE_ROUTE[role])
ceils = " | ".join(fx(r["ceiling_exact"], 4) for r in rs)
ceils = " | ".join(fx(r["ceiling_exact"], 6) for r in rs)
a(f"| {role} | {rt['id']} ({rt['status']}) | {whole(r0['native_receipts_base_units'])} | {pct(r0['fraction_of_year1']) or 'none (no route)'} | {whole(r0['cumulative_base_units'])} | {ceils} | (empty) | {r0['decision']} |")
a(f"| external jobs | R4, R5 (UNRATIFIED) | 0 | none | 0 | " + " | ".join("0" for _ in scs) + " | (not used) | parameter only |")
a("")
@ -421,7 +421,7 @@ def readme(inp, model, files, root):
if role in ("minimum validators", "maintenance"):
a(f"- {role}: the protocol pays this role nothing in year {H} at any multiple, so it is funded only by a payer D03 has not yet named (B-03, B-04), and any positive minimum cost is in the failure region.")
else:
a(f"- {role}: the role's year-{H} budget buys at most {fx(lo['ceiling_exact'], 4)} BU in the minus-90-percent case, {fx(r['ceiling_exact'], 4)} BU at 1x and {fx(hi['ceiling_exact'], 4)} BU at 10x, so a panel minimum cost above the cell's ceiling is the failure region for that scenario.")
a(f"- {role}: the role's year-{H} budget buys at most {fx(lo['ceiling_exact'], 6)} BU in the minus-90-percent case, {fx(r['ceiling_exact'], 6)} BU at 1x and {fx(hi['ceiling_exact'], 6)} BU at 10x, so a panel minimum cost above the cell's ceiling is the failure region for that scenario.")
a("- external jobs: zero in every scenario by the method; the published rate is unratified (D04) and funds no role here.")
a("")
a("## The verdict per scenario and year")
@ -434,11 +434,11 @@ def readme(inp, model, files, root):
for sc in scs:
mrow = [x for x in model["rows"] if x["horizon"] == H and x["scenario"] == sc["id"] and x["role"] == "miners"][0]
prow = [x for x in model["rows"] if x["horizon"] == H and x["scenario"] == sc["id"] and x["role"] == "internal provers"][0]
a(f"| {H} | {sc['label']} | {fx(mrow['ceiling_exact'], 4)} | {fx(prow['ceiling_exact'], 4)} | 0 (no payer, BLOCKED) | (empty) | viable: funds the minimum required roles without hidden issuance or assumed appreciation; collapse: safe behaviour, not universal profit | NOT RUN |")
a(f"| {H} | {sc['label']} | {fx(mrow['ceiling_exact'], 6)} | {fx(prow['ceiling_exact'], 6)} | 0 (no payer, BLOCKED) | (empty) | viable: funds the minimum required roles without hidden issuance or assumed appreciation; collapse: safe behaviour, not universal profit | NOT RUN |")
a("")
a("## Fee replacement: the tips the miners' year-1 budget would need")
a("")
a("Tips per year, at constant purchasing power, that would bring the miners' receipts back to their year-1 level through the code's 80% tip route. Base fees are burned and restore nothing; provers have no tip route in the code (B-01). The full series is `fee-replacement.csv`.")
a("Tips per year, at constant purchasing power, that would bring the miners' receipts back to their year-1 level through the code's 80% tip route (year 2 pays more than the ramped year 1, so it needs none). Base fees are burned and restore nothing; provers have no tip route in the code (B-01). The full series is `fee-replacement.csv`.")
a("")
a("| Year | Miners' gap to year 1 (coins) | Tips needed per year (coins) | As a fraction of the baseline |")
a("|---|---|---|---|")
@ -450,7 +450,7 @@ def readme(inp, model, files, root):
m1 = model["split"][1]["miners"]
a("## What the result means")
a("")
a(f"Under the ratified cap with zero external jobs, the subsidy that pays the miners and the internal provers falls to {pct(Fraction(e[5], e[1]))} of year 1 in year 5, {pct(Fraction(e[10], e[1]))} in year 10 and {pct(Fraction(e[20], e[1]))} in year 20; at 10x purchasing power the year-20 miner budget buys {fx([x for x in model['rows'] if x['horizon'] == 20 and x['scenario'] == 'm1000' and x['role'] == 'miners'][0]['ceiling_exact'], 4)} BU, and in the minus-90-percent case {fx([x for x in model['rows'] if x['horizon'] == 20 and x['scenario'] == 'm010' and x['role'] == 'miners'][0]['ceiling_exact'], 4)} BU.")
a(f"Under the ratified cap with zero external jobs, the subsidy that pays the miners and the internal provers falls to {pct(Fraction(e[5], e[1]))} of year 1 in year 5, {pct(Fraction(e[10], e[1]))} in year 10 and {pct(Fraction(e[20], e[1]))} in year 20; at 10x purchasing power the year-20 miner budget buys {fx([x for x in model['rows'] if x['horizon'] == 20 and x['scenario'] == 'm1000' and x['role'] == 'miners'][0]['ceiling_exact'], 6)} BU, and in the minus-90-percent case {fx([x for x in model['rows'] if x['horizon'] == 20 and x['scenario'] == 'm010' and x['role'] == 'miners'][0]['ceiling_exact'], 6)} BU.")
a(f"Holding the miners' year-1 budget needs tips of {fx(model['feerep'][9]['tips_needed_bu'], 4)} of the baseline a year by year 10 and {fx(model['feerep'][19]['tips_needed_bu'], 4)} by year 20; the internal provers have no fee route in the node's code, so nothing in the ratified routing replaces their declining 20%; minimum validators and maintenance receive nothing from the protocol at any horizon.")
a("So whether TV-04 can pass turns on four things this model cannot supply: the panel's role costs and viable-or-collapse declarations, the tip level, a named payer for validators and maintenance, and the provers' fee route. Those are the BLOCKED rows below.")
a("")
@ -487,7 +487,7 @@ def readme(inp, model, files, root):
a("")
a("## Registry")
a("")
a("The TV-04 row is recorded by the CI steward from the batch `tools/ci/batches/tv-04-20261009-01.json` with the verdict NOT RUN and this directory's files as its evidence.")
a("The registry batch for TV-04 is `registry-batch-tv-04.json` beside this file: one cell, the case TV-04, the verdict NOT RUN, method model, this directory's files and the build-9 run logs as its evidence. The CI steward places it under `tools/ci/batches/` with its map cell and records it through `tools/ci/test-record.mjs --record`; this landing writes no registry row.")
a("")
return "\n".join(L)