'
for i,s in enumerate(p["slices"]))
return svg, f'{leg}'
def piecard(title, sub, p):
svg,leg=pie(p,"tg-ramp")
return (f'
{e(title)}
{e(sub)}
'
f'
{svg}{leg}
')
# ---- timeline stacked columns
tl=[t for t in S["timeline"] if t["merged"]>0]
mx=max(t["merged"] for t in tl)
W,Hh,PAD,TOP=760,190,26,16
bw=W/len(tl)
cols=[]
for i,t in enumerate(tl):
x=i*bw+bw*0.18; w=bw*0.64
h=(Hh-PAD-TOP)*t["merged"]/mx
mh=(Hh-PAD-TOP)*t["minemerged"]/mx
oh=h-mh
y0=Hh-PAD
cols.append(f'{t["month"]}: {n(t["merged"])} merged ({n(t["minemerged"])} by permadeath.com)'
f''
+ (f'' if mh>0 else "")
+ f'{t["month"][2:].replace("-","/")}')
tlsvg=f''
# ---- my august daily
d=S["myAugustDaily"]; dmx=max(x["n"] for x in d)
W2,H2=760,150; bw2=W2/31
dcols=[]
for i in range(1,32):
day=f"2026-08-{i:02d}"; v=next((x["n"] for x in d if x["day"]==day),0)
h=(H2-24)*v/dmx; x=(i-1)*bw2+bw2*0.15
dcols.append(f'{day}: {v} merged')
if i in (1,8,15,22,29):
dcols.append(f'{i}')
pk=max(d,key=lambda x:x["n"]); pi=int(pk["day"][-2:])
dcols.append(f'{pk["n"]} on {pi} Aug')
daysvg=f''
def table(rows, unit, tot):
tr="".join(f'
')
# ---------------------------------------------------------------- provenance
P=S.get("prov",{})
def pv(k,fb):
v=P.get(k)
return fb if v in (None,"",0) and k not in ("myNegative",) else v
ASOF = pv("asOf","2 September 2026")
K1 = pv("knot1Repos",13312)
EXTRA = pv("extraRepos",844)
AUGTOT = pv("augMergedTotal",2546)
AUGAUT = pv("augAuthors",79)
ALLAUT = pv("allTimeAuthors",213)
MULT = pv("recordMultiple",4.2)
PREVM = pv("prevRecordMonth","2026-07")
NEG = pv("othNegative",395)
NEGTOT = pv("othMergedWithTs",2159)
NEGPCT = pv("othNegativePct",18.0)
DISPCT = pv("monthDisagreePct",0.4)
BACKLOG= pv("backlogTopCount",1334)
PEOPLE = pv("peopleCrawled",3291)
KNOTS = pv("knots",182)
NOTARGET=pv("noTargetRecords",964)
UNATTRIB=pv("unattributedRepos",2172)
OLDEST = pv("oldestOpen","2025-09")
def monthname(ym):
try:
y,m=ym.split("-"); return f"{['','January','February','March','April','May','June','July','August','September','October','November','December'][int(m)]} {y}"
except Exception: return ym
# ---------------------------------------------------------------- blocks
BLOCKS=[]
def block(slug,html): BLOCKS.append((slug,html))
block("headline", f"""
Tangled, by the numbers
Every pull request on the network — {n(sc['reposScanned'])} repositories, {n(sc['authors'])} authors — as of {ASOF}.
{n(me['merged'])}merged PRs by permadeath.com
{ds['top1Share']}%of every merged PR on Tangled
{n(me['commits'])}commits landed
{n(sc['totalPulls'])}PRs network-wide
{n(sc['mergedPulls'])}merged network-wide
{n(ds['authorsWithMerged'])}people with a merged PR
{ds['median']}median merged PRs per person
{me['augMerged']/max(1,len(S['myAugustDaily'])):.0f}/dayon each of my {len(S['myAugustDaily'])} active August days
{me['merged']/me['pulls']*100:.0f}%of my PRs got merged
""")
block("merged-alltime", f"""
Merged pull requests — all time
Top 15 of {n(ds['authorsWithMerged'])} people who have ever landed a PR on Tangled.
{bars(L['mergedAllTime'], L['mergedAllTime'][0]['n'], 'merged PRs')}
{keyrow()}
Show as table{table(L['mergedAllTime'],'Merged PRs',sc['mergedPulls'])}
""")
block("merged-august", f"""
Merged pull requests — August 2026
By merge date. Tangled's busiest month: {n(AUGTOT)} PRs merged network-wide, {me['augMerged']/max(1,AUGTOT)*100:.0f}% of them mine.
{bars(L['mergedAugust'], L['mergedAugust'][0]['n'], 'merged PRs')}
{keyrow()}
Show as table{table(L['mergedAugust'],'Merged PRs',AUGTOT)}
""")
block("commits", f"""
Commits landed — all time
Counted from the git patch attached to each merged PR ({n(sc['patchesParsed'])} of {n(sc['mergedPulls'])} patches readable).
{bars(L['commitsAllTime'], L['commitsAllTime'][0]['n'], 'commits')}
{keyrow()}
Show as table — all time{table(L['commitsAllTime'],'Commits',sc['commitsCounted'])}Show as table — August 2026{table(L['commitsAugust'],'Commits',S['pies']['commitsAugust']['total'])}
""")
block("commits-august", f"""
Commits landed — August 2026
Commits inside PRs merged during August, by author.
{bars(L['commitsAugust'], L['commitsAugust'][0]['n'], 'commits')}
{keyrow()}
Show as table{table(L['commitsAugust'],'Commits',S['pies']['commitsAugust']['total'])}
""")
PIE_META=[
("pie-merged-alltime","Merged PRs — all time", f"{n(S['pies']['mergedAllTime']['total'])} merged PRs, {ALLAUT} authors", S['pies']['mergedAllTime']),
("pie-merged-august", "Merged PRs — August 2026",f"{n(S['pies']['mergedAugust']['total'])} merged PRs, {AUGAUT} authors", S['pies']['mergedAugust']),
("pie-commits-alltime","Commits — all time", f"{n(S['pies']['commitsAllTime']['total'])} commits in merged PRs", S['pies']['commitsAllTime']),
("pie-commits-august","Commits — August 2026", f"{n(S['pies']['commitsAugust']['total'])} commits in merged PRs", S['pies']['commitsAugust']),
]
PIE_CAPTION="The four biggest contributors, brightest first, against everyone else combined."
block("pies", '
\n
Share of the network
\n
'+PIE_CAPTION+'
\n
'
+ "".join(piecard(t.replace("—","—"),sub,pd) for _,t,sub,pd in PIE_META) + '
\n
')
for slug,t,sub,pd in PIE_META:
block(slug, f'
\n
{t}
\n
{PIE_CAPTION}
\n
'
+ piecard(t.replace("—","—"),sub,pd) + '
\n
')
block("timeline", f"""
Merged PRs per month, network-wide
Tangled's whole history. August 2026 is {MULT}× the previous record ({monthname(PREVM)}) — and most of that spike is one person.
{tlsvg}
{keyrow()}
""")
block("august-daily", f"""
My August, day by day
{n(me['augMerged'])} PRs merged across {len(S['myAugustDaily'])} active days — a peak of {max(x['n'] for x in S['myAugustDaily'])} in one day.
{daysvg}
""")
block("comparison", f"""
What an agentic PR looks like
permadeath.com versus every other author on the network.
Measure
permadeath.com
everyone else
Pull requests opened
{n(me['pulls'])}
{n(oth['pulls'])}
Merged
{n(me['merged'])}
{n(oth['merged'])}
Still open
{n(me['open'])}
{n(oth['open'])}
Merge rate, of PRs actually decided
{me['merged']/me['decided']*100:.0f}%
{oth['merged']/oth['decided']*100:.0f}%
Commits landed
{n(me['commits'])}
{n(oth['commits'])}
Commits per merged PR, mean
{me['commitsPerPull']}
{oth['commitsPerPull']}
Commits per merged PR, median
{me['medianCommitsPerPull']:.0f}
{oth['medianCommitsPerPull']:.0f}
Median PR description
{n(int(me['medianBodyLen']))} chars
{n(int(oth['medianBodyLen']))} chars
Repositories touched
{me['repos']}
—
Merge rate counts only PRs that were actually decided — merged or closed. Counting open PRs as failures would
compare one month of my work against the network's backlog: {n(oth['open'])} PRs are still open network-wide,
{n(BACKLOG)} of them on a single repository, opened as far back as {monthname(OLDEST)}. On the raw
opened-versus-merged basis the same two figures read {me['merged']/me['pulls']*100:.0f}% and
{oth['merged']/oth['pulls']*100:.0f}%, which flatters me for no reason other than my account being new.
Commit totals are floors: every one of my merged PRs yielded a readable patch, against {oth['patchCoverage']:.0f}% of
everyone else's, so their {n(oth['commits'])} is understated by roughly {(100-oth['patchCoverage'])/max(1e-9,oth['patchCoverage'])*100:.0f}%.
""")
block("method", f"""
Method
Counted from the source records, not from Tangled's index — api.tangled.org was down throughout
(every /xrpc/ path returning Failed to start container), so these figures were rebuilt from the
underlying atproto data. Tangled is not one server: repositories live on knots that anyone can host. Starting from
the main knot's repo list, each account's own sh.tangled.repo records were read from its PDS — those
records name both the owner and the knot — every knot so discovered was listed in turn, and the cycle repeated
until no new accounts appeared. It closed at {n(KNOTS)} knots, {n(K1)} repositories and {n(PEOPLE)} accounts.
Every account's sh.tangled.repo.pull and sh.tangled.repo.pull.status records were then read
directly from its PDS; a pull's state is the status of the newest status record pointing at it, the same derivation
the appview performs. Commits come from the patch attached to each merged PR — a gzipped
git format-patch blob on newer records, an inline string on older ones. Commits pushed straight to a
branch without a PR are not counted. Figures as of {ASOF}.
Why not query the pulls directly. A first attempt asked constellation which pull records pointed at
each repo. That undercounts: the record has changed shape three times — an inline patch string, then
rounds with a patch blob, now versions with base and head SHAs — and {n(NOTARGET)} records
carry no target field at all, so a backlink index cannot see them. Reading each person's repository finds every record
whatever its shape. Verified against Tangled's own web interface on 42 sampled pull requests across every generation
and all three states, on knot1 and on self-hosted knots alike: 42 agreed, 0 disagreed.
How complete is it. People were found three ways: repository ownership, backlinks in
constellation, and Tangled's own social records — follows,
knot and spindle memberships, collaborator entries — read from each person's repository, which is the only
channel with no index in front of it. {n(PEOPLE)} accounts were read in all. Checked against Tangled's own web
interface: 42 of 42 sampled pull requests had the state derived here, and 71 of 73
were present in the data at all — 97% recall. Adding the social channel found 164 authors the first two
channels missed, which moved the totals by about 4%.
What it still cannot see. These figures are read from the source records, so a pull request whose
author has since deactivated is unreachable even though Tangled still displays it — about 9% of accounts with no
records return an error rather than an empty list. {n(UNATTRIB)} repository DIDs could not be attributed to an owner,
mostly repos whose records were deleted. Only 10 of the {n(KNOTS)} knots answer a repo listing at all; the rest run
older software, so the repository count is a floor. And the residual gap sits with small contributors, not large
ones: every one of the top ten authors was re-counted against their live PDS and matched exactly, give or take
pull requests opened while the crawl was running.
Not shown: time to merge. A pull record carries createdAt and its status record carries
another — but they are asserted by different people's clients on different machines, and {NEGPCT}% of other authors'
merged PRs claim to have merged before they were opened. Month bucketing survives this ({DISPCT}% of merged PRs
land in a different month under either field, and the August ranking is unchanged); a duration does not.
""")
# ---------------------------------------------------------------- write
import os
BODY='\n
Tangled, by the numbers
\n' \
f'
Every pull request on the network — {n(sc["reposScanned"])} repositories, ' \
f'{n(sc["authors"])} authors — as of {ASOF}.
\n\n' \
+ "\n\n".join(h for slug,h in BLOCKS if slug not in {p[0] for p in PIE_META}) + "\n"
open(f"{SD}/embed.html","w").write(f"\n{BODY}\n")
bd=f"{SD}/blocks"; os.makedirs(bd,exist_ok=True)
ORDER=["headline","merged-alltime","merged-august","commits","commits-august","pies",
"pie-merged-alltime","pie-merged-august","pie-commits-alltime","pie-commits-august",
"timeline","august-daily","comparison","method"]
by=dict(BLOCKS); written=[]
for i,slug in enumerate(ORDER,1):
if slug not in by: continue
frag=f'\n\n{by[slug]}\n\n'
fn=f"{i:02d}-{slug}.html"; open(f"{bd}/{fn}","w").write(frag); written.append(fn)
FONT=''
open(f"{SD}/preview.html","w").write(
f'Tangled by the Numbers\n{FONT}\n'
f"\n{BODY}\n")
# a contact sheet so every separate block can be eyeballed at once
sheet="".join(
f'
blocks/{fn}
\n'
f'{by[fn.split("-",1)[1][:-5]]}\n' for fn in written)
open(f"{SD}/blocks/index.html","w").write(
f'Tangled Stat Blocks\n{FONT}\n'
f"\n{sheet}")
print("wrote embed.html +", len(written), "blocks:", ", ".join(written))