System study · Released
GitFace
A GitHub account read as a set of documents: a year of work opened as a retrospective, and a position measured against a population that was enumerated in full rather than sampled.
- verifiedREADME.gitface — the project's own account of what it does not claim
- verifiedGitFace census — 15,411 accounts matched, 14,450 enumerated
- Role
- Sole author — all 80 commits
- Period
- 2025-12 — 2026-08
- Interactive
- Runs on this site
- TypeScript
- Next.js
- React
- GraphQL
- Tailwind CSS
The artifact
Fig. 1

What a GitHub profile will not tell you
A GitHub profile answers one question well — what exists — and very little about how it came to. The contribution graph is a year of colour with no reading order, the repository list is sorted by recency, and work done inside private or organization repositories appears only as a count with no shape. README.gitface, the document GitFace ships inside itself, states the intent plainly: an editor that reads a GitHub account honestly, and says plainly what it cannot know.So GitFace is a reading layer over that history rather than a replacement for it. It treats one account as a set of documents — an explorer, tabs, a year opened as a retrospective — and attaches a second question to the same data: not only what happened, but where it sits among other accounts. Both halves project from one activity model, so a figure shown in one view is the same figure in another.
- verifiedREADME.gitface — the project's own account of what it does not claim
- verifiedGitFace source — engine, data layer and census script read
Who built it
- Engineering role
- Sole author
- verifiedGitFace lineage — 80 commits on its paths, 9 of them the focused build
- Measured contribution
- 80 of 80 commits (100%)every commit touching a GitFace path in this repository — the editor, the data layer, the benchmark engine and the census script. Of these, the nine prefixed ‘gitface:’ are the focused build; the rest are the editor the work grew out of.
- verifiedGitFace lineage — 80 commits on its paths, 9 of them the focused build
- Team
- Sole author. No other committer appears on any GitFace path.
- verifiedGitFace lineage — 80 commits on its paths, 9 of them the focused build
What the API would not give
- infrastructureGitHub’s search API returns at most 1,000 results for any query, and the query defining this population matches 15,411 accounts. No single request can list the population, which is why it is cut into 23 created-date strata — the largest reporting 978 — rather than queried whole.
- verifiedGitFace source — engine, data layer and census script read
- verifiedGitFace census — 15,411 accounts matched, 14,450 enumerated
- infrastructureBuilt against a public-scope personal access token with no private repository or organization visibility, so private language coverage is legitimately empty rather than suppressed.
- provisionalCensus, privacy and engine audits — run once, not reproducible from a clone
How the number is made
Everything GitFace shows comes from one activity model. The data layer resolves an account into per-year records once, and every other view — the retrospective, the benchmark, the export — is a projection of those records rather than a second trip to GitHub. Three GitHub measurements are carried side by side and never added together: the contribution calendar, the typed contributionsCollection totals, and search-indexed commits on public default branches. README.gitface records why they stay apart — they disagree by design, and in 2023 the search index reported more commits than the calendar reported contributions.The population had to be enumerated offline, because of the ceiling above. The census script, 883 lines, cuts the population into created-date strata each sized under that ceiling and sweeps every one as a resumable job: checkpointed to disk, three workers, GraphQL blocks of five accounts by five years, degrading to four, two and finally one account per query when a block fails. The sweep cost 3,092 page operations and absorbed 209 throttle retries. It published only after an integrity gate passed — 23 of 23 strata complete, the population reconciling against the count the search itself reported, and no account appearing in two strata.What ships is a 502 KB file of distributions and nothing else — a count of zeros and a sorted array of values, per metric per year, and no account behind either. The engine reads that one file from disk and makes no GitHub request of its own, and it never returns a position bare — value, rank, denominator and percentile travel together, against two populations, everyone matched and only those active that year. Where too little sits behind a comparison it returns insufficient-data rather than a number.
- verifiedGitFace source — engine, data layer and census script read
- verifiedGitFace census — 15,411 accounts matched, 14,450 enumerated
- verifiedREADME.gitface — the project's own account of what it does not claim
- verifiedPublished snapshot re-derived and scanned — 36 checks
Anonymous benchmark snapshot
- verifiedGitFace census — 15,411 accounts matched, 14,450 enumerated
- verifiedPublished snapshot re-derived and scanned — 36 checks
Resumable census builder
Checkpointed, atomic writes, integrity gate that refuses partial publication.
- verifiedGitFace source — engine, data layer and census script read
Snapshot audit
npm run audit:benchmark — 36 offline checks over the published file.
- verifiedPublished snapshot re-derived and scanned — 36 checks
README.gitface
Shipped as a document inside the editor, and the place the limits are stated first.
- verifiedREADME.gitface — the project's own account of what it does not claim
Enumerate, or estimate
Enumerate the population, or estimate it
Stratify by account creation date and enumerate exhaustively. Twenty-three strata, found by recursive bisection, each under the ceiling, disjoint by construction and together covering the whole population.How this was decided
- Context
- A rank is meaningless without a denominator, and this denominator could not be had for the asking — the search ceiling above puts the whole population beyond the reach of any single query.
- verifiedGitFace source — engine, data layer and census script read
- verifiedGitFace census — 15,411 accounts matched, 14,450 enumerated
- Options considered
- Sample a subset and extrapolate the distribution
- Compare against the first 1,000 results the search will return
- Cut the population into strata that each fit under the ceiling, and enumerate every one
- verifiedGitFace census — 15,411 accounts matched, 14,450 enumerated
- Trade-off
- Cost and staleness. The sweep took 3,092 page operations and absorbed 209 throttle retries, and the result is a snapshot dated 2026-08-17 that only moves when the census is run again. A sample would have taken minutes and would have moved whenever anyone asked.What exhaustive enumeration buys is that the denominator is a real count of real accounts rather than an estimate with a confidence interval attached, and that a reader can check the arithmetic instead of trusting the method. The snapshot carries its strata, its page cost and its integrity checks so that checking is possible at all.
- verifiedGitFace census — 15,411 accounts matched, 14,450 enumerated
- verifiedPublished snapshot re-derived and scanned — 36 checks
- Outcome
- The published snapshot reconciles: 14,450 enumerated accounts plus 961 excluded organizations plus zero permanent failures against the 15,411 the search reported, across 23 of 23 completed strata. Re-derived from the raw arrays, offline, on 2026-08-19.
- verifiedPublished snapshot re-derived and scanned — 36 checks
- verifiedGitFace census — 15,411 accounts matched, 14,450 enumerated
- verifiedGitFace census — 15,411 accounts matched, 14,450 enumerated
- verifiedGitFace source — engine, data layer and census script read
- verifiedPublished snapshot re-derived and scanned — 36 checks
Three measurements, kept apart
Carry all three. Every metric in the snapshot maps to one of exactly two families, and no view adds across a family boundary or derives a composite score from them.How this was decided
- Context
- GitHub reports activity in three ways — the contribution calendar, the typed contributionsCollection totals, and search-indexed commits on public default branches — and the three disagree with each other by design.
- verifiedREADME.gitface — the project's own account of what it does not claim
- verifiedGitFace source — engine, data layer and census script read
- Options considered
- Add them into one activity number
- Choose one measurement and discard the other two
- Carry all three in separate families that are never merged
- verifiedREADME.gitface — the project's own account of what it does not claim
- Trade-off
- One number is easier to show and far easier to rank. Three families mean the reader has to be told which question each answers, and the page never gets a headline figure to lead with.The disagreement is not noise to be averaged away. README.gitface records that in 2023 the search index reported more commits than the calendar reported contributions, because the two count different things over different repositories. A sum of the three would be a number with nothing it refers to.
- verifiedREADME.gitface — the project's own account of what it does not claim
- verifiedPublished snapshot re-derived and scanned — 36 checks
- Outcome
- Checked against the published file on 2026-08-19: ten metrics resolve to exactly two families, and no score, rating, composite or overall key appears anywhere in the snapshot.
- verifiedPublished snapshot re-derived and scanned — 36 checks
- verifiedREADME.gitface — the project's own account of what it does not claim
- verifiedPublished snapshot re-derived and scanned — 36 checks
- verifiedGitFace source — engine, data layer and census script read
Correcting the package rather than working around it
Implement the corrected query inside GitFace, and record the fault against wrap-git rather than quietly patching over it.How this was decided
- Context
- GitFace reads GitHub through wrap-git, a package published for this purpose. Building the language view surfaced a defect in it: the language-by-year function filtered commits by login where the API required an email, and could only see public owned repositories.
- verifiedREADME.gitface — the project's own account of what it does not claim
- verifiedwrap-git — 16 documented gaps and opportunities
- Options considered
- Ship the language view with the defect in place
- Drop the language view until the package is fixed
- Implement the corrected query inside GitFace and record the defect against the package
- verifiedREADME.gitface — the project's own account of what it does not claim
- Trade-off
- Two implementations of one idea, and a published package that still carries the fault until it is fixed at source. The view could ship correct without waiting on a release; the cost is a divergence somebody has to close later, and it is recorded as such rather than forgotten.
- verifiedREADME.gitface — the project's own account of what it does not claim
- verifiedwrap-git — 16 documented gaps and opportunities
- Outcome
- GitFace resolves languages by year through its own implementation in the data layer. The defect stands recorded against wrap-git as a known gap.
- verifiedGitFace source — engine, data layer and census script read
- verifiedwrap-git — 16 documented gaps and opportunities
- verifiedREADME.gitface — the project's own account of what it does not claim
- verifiedGitFace source — engine, data layer and census script read
- verifiedwrap-git — 16 documented gaps and opportunities
The pipeline, drawn
- Fig. 2

Four stages, and the one place a GitHub request happens. Every figure on it is one the evidence below already carries.source · GitFace — the census pipeline, drawndiagram — drawn from a source audit, not a capture
The editor
Step through the sequence — every step is also readable in order without doing so.
- 01 — A YEAR READ AS RETROSPECTIVEproduct screen.RECAP — A YEAR READ AS RETROSPECTIVEreserved · 16/10
- 02 — POSITION AGAINST POPULATIONproduct screenBENCHMARK — POSITION AGAINST POPULATIONreserved · 16/10
- 03 — WHAT THIS CANNOT TELL USproduct screenBENCHMARK — WHAT THIS CANNOT TELL USreserved · 16/10
- 04 — NARROW PANEFig. 3

The same editor at 520 pixels wide.source · GitFace — two captures of the editor as it runs on this site
Open it
GitFace is the editor on the home page of this site — the same build this case study describes, reading live GitHub data.
Open GitFace on the home pageWhat was measured
- Accounts enumerated
- 14,450 of 15,411 accounts
- verifiedGitFace census — 15,411 accounts matched, 14,450 enumerated
- Strata swept
- 23 of 23
- verifiedGitFace census — 15,411 accounts matched, 14,450 enumerated
- Published snapshot
- 502 KB
- verifiedGitFace census — 15,411 accounts matched, 14,450 enumerated
- Snapshot audit
- 36 of 36 checks
- verifiedPublished snapshot re-derived and scanned — 36 checks
Evidence
10 sources · how each was obtained
- verifiedGitFace v1 — completion commit e411094repository · attests existence · captured 2026-08-18git show --stat e411094 — 22 files, 3,835 insertions, 182 deletionsAn earlier label read '33 files', which is the file count of src/components/mini_vscode, not this commit. Two measurements printed as one fact; the label now carries only the commit.
- verifiedGitFace lineage — 80 commits on its paths, 9 of them the focused buildcommit-history · attests existence · captured 2026-08-19git log over src/components/mini_vscode, src/lib/{github-activity,benchmark,gitface-export}.ts, src/types/{Recap,Benchmark}Types.ts, scripts/build-benchmark.mjs and src/data/benchmark — 80 commits, sole author; of these the 9 prefixed 'gitface:' span 2026-08-16 to 2026-08-17 and total 91 file-changes, 7,912 insertions, 1,136 deletionsTwo different measurements, deliberately kept apart. The editor these paths began as was first committed on 2025-12-10; the work that made it GitFace is the nine prefixed commits. Neither number is 'how long GitFace took'.
- verifiedGitFace source — engine, data layer and census script readrepository · attests structure · captured 2026-08-19read and counted: 2,528 lines across six core files, 33 files under src/components/mini_vscode; BENCHMARK_METRICS declares 10 metrics across 2 families; PAGINATION_CEILING = 1000 at build-benchmark.mjs:81Proves how the code is written, not what it does when run. Anything behavioural must rest on a node that exercised it.
- verifiedREADME.gitface — the project's own account of what it does not claimdocument · attests existence · captured 2026-08-19243 lines of committed prose, shipped as a document inside the editor; read in fullProject documentation written by the author. It establishes what GitFace intends and what it refuses to assert; it is not an independent check that the code does either.
- verifiedGitFace census — 15,411 accounts matched, 14,450 enumeratedbenchmark-census · attests measurement · captured 2026-08-17stratified exhaustive enumeration over 23 created-date strata, 3,092 page operations, 209 throttle retries, 0 degradations, 0 permanent failuresThe query matched 15,411 accounts; 961 organizations were excluded by design, leaving 14,450 enumerated. The population is accounts whose self-declared location matches Ethiopia or Addis Ababa, and the snapshot says in its own disclaimer that this is neither a list of Ethiopian developers nor a complete one.
- verifiedPublished snapshot re-derived and scanned — 36 checksgenerated-audit · attests structure · captured 2026-08-19npm run audit:benchmark — 36 checks over artifact, anonymity, arithmetic, structure, privacy boundary and self-declared limits; 36/36 passing, offline, no tokenReads the committed snapshot and recomputes its arithmetic from the raw arrays rather than trusting its own integrity block. Structure rather than behaviour: it proves what the published file contains, not that the running engine behaves correctly.
- provisionalCensus, privacy and engine audits — run once, not reproducible from a clonegenerated-audit · attests behaviour · captured 2026-08-18re-run 2026-08-18 against a compiled engine and the raw checkpoint cache: census audit ALL PASSED, privacy/provenance 52/52, methodology 20/20, engine 32/32Provisional on purpose. Re-deriving every distribution from raw checkpoints needs .benchmark-cache, which is git-ignored precisely because it holds per-account records, and exercising the engine needs it compiled first. Neither survives a clone, so the figures are recorded rather than guaranteed. What can be reproduced was moved into scripts/audit-benchmark.mjs.
- provisionalsgc93/next-line-front — public repositorypublic-url · attests existence · captured 2026-08-19confirmed public by the author on 2026-08-19; not re-checked against github.com from this machineSays the source can be read. It says nothing about stars, forks, traffic or use, and nothing here should be read as any of those.
- verifiedGitFace — two captures of the editor as it runs on this siteFig. 1 · Fig. 3screenshot-set · attests existence · captured 2026-08-21captured from the production build served on localhost, headless Chrome; each frame clipped to the editor window at the slot's declared ratio, one at 1440x1000 and one at a 520-wide phone viewportBoth frames show the README document, which renders from the page itself. The documents that assemble from live GitHub data are not captured here, because this machine has no outbound network and a screenshot of that failure would show a fault in the environment rather than in the product.
- provisionalGitFace — the census pipeline, drawnFig. 2diagram · attests structure · drawn 2026-08-21drawn from ev.gitface.source-audit, ev.gitface.census and ev.gitface.snapshot-audit; every figure on it — 23 strata, 3,092 page operations, 209 retries, 502 KB, 10 metrics across 2 families — is one those nodes already carryAn illustration, not a capture. It depicts the shape the source audit established, and it is provisional because a person drew it and nobody can re-run drawing. It is not evidence that the system behaves as drawn. The one relationship it draws to GitHub is the census run, which happened once and offline; the engine is shown reading the committed file and nothing else.
Links
Still open
What this case study does not yet cover, and what would close it.
Never measured
- No outcome was measured while this project was active.
Awaiting first-person reflection
- What this project taught has not been written up yet.
- A first-hand account of this work has not been written yet.