Evidence

What we tested, and what it showed

Graftyard ran on Cloudflare in test installs across North America, Europe and Asia-Pacific. Real clients hit it, a chaos driver attacked it, and checkers read back every site's log. These are the results through 5 November 2026, failures included.

  • 348 of 348git client checks on three git versions, a site failing in half
  • 0 of 3,588,424acknowledged writes lost in audited chaos runs
  • 104.6 hof chaos on Cloudflare, 12,304,207 operations checked
  • 172 to 370 msmedian commit across two continents
  • 84 of 85planted bugs caught by the test suites
  • 259Rust tests in the workspace, 0 failing

GHES 3.22 compatibility

Unmodified clients, checked against the GHES schemas

No client was patched and no request went to github.com. The host answers /api/v3/meta with installed_version 3.22.0, so gh, git-lfs, VS Code and JetBrains all take their GHES path.

Clients

Client and commandsWhereResult
gh 2.102.1: issue list / create / view / commentHosted edge on Cloudflare, 2026-11-05Pass, 5 of 5 exit 0
gh 2.102.1: pr list / create --draft / viewHosted edgePass, 3 of 3 exit 0
gh 2.102.1: release create / upload / view / download, --archive=tar.gzHosted edgePass, the asset round-trips byte for byte
git-lfs 3.8.0: push, clone, pull, lock, locks, unlockHosted edgePass, pulled bytes equal pushed bytes
clients.sh, 29 checks per clientgit 2.39.5, 2.51.0, 2.56.0; 12 runs348 of 348 rows, with and without a site failing
git's own smart-HTTP tests, t/t55xx to t/t58xxgit 2.51.0 and 2.56.0, site 0 failing0 baseline passes lost on 2.51.0; 1 on 2.56.0 (t5549 #2, a server-side receive.hiderefs)

Schemas

CheckScopeResult
Live replies on Cloudflare26 GraphQL, 12 REST, 5 LFS0 failures
Replayed client requests65 requests from git 2.56.0, git-lfs 3.8.0 and gh 2.102.1; 93 replies0 failures
Agent layer off by default93 replies × 13 Accept values, compared byte for byte with and without the layer0 of 1,209 differ

The GraphQL schema is generated from the GHES 3.22 SDL (1,626 types). gh pr checks exits 1 on a pull request with no checks, which is gh's own answer for that case; every request in it returned 200. VS Code, JetBrains, Terraform, Jenkins and Argo CD are covered by reading their source for the GHES paths they call, not yet by a live run.

Chaos and linearizability

Seven runs with faults on, 104.6 hours

Every 8 to 16 s the driver reset a member or moved leadership. 5% of calls between sites failed and 5% of replication replies were dropped. Clients in Atlanta, London and Singapore kept writing.

  • Porcupine checked each history for linearizability, key by key.
  • Lost-write audit: after a run, all three sites' stored logs are read back and every acknowledged write is looked up.

The runs on Cloudflare

RunLengthOperationsFaults injectedResult
cf-48h48 h5,742,7365,729 resets, 3,607 transfersPass. 0 of 1,814,873 acked writes lost
lin24b24 h2,850,5234,176 resets, 2,752 transfersPass. 0 of 904,294 acked writes lost; ack check 0 violations
lin2424 h2,739,6915,547 resets, 3,743 transfersNot passed. 0 of 869,257 lost, but an early ack was not ruled out; rerun as lin24b
cf-long-24 h475,301138 resets, 77 transfersIllegal. A real bug: a reused ticket after a leader reset. Fixed, then cf-48h
cf-long-12 h270,040243 resets, 186 transfersOk
wp4-cf-52 h 5 min184,349343 resets, 253 transfersOk
wp4-cf-131 min41,56782 resets, 62 transfersOk

Recorded-clock checks flag some cross-site reads as Illegal; with 100 ms of clock allowance, or with the measured bound, every passing run is Ok on all keys. lin24b's 20 flagged segments trace to 15 lost client log chunks and 2 ties needing 1 and 4 ms of skew, against 63 to 92 ms measured that minute.

Targeted fault gates

FaultRunsResult
Leader killed after quorum, before the reply (BF-12)12,000 kills landed12,000 of 12,000 kept their original outcome; 0 applied twice
Receipts that miss their deadline (BF-14)2,400 commands2,400 of 2,400 decided once; 0 forwarded
One site's member class failing (B0-03)26 runs plus 6 reruns11.0 to 12.9 s to recover; 0 failed operations
22% of member calls and storage writes failing (B0-25)9 runs, 300 pushes each92.3% to 98.7% of pushes land within three attempts
Every member of 4 or 8 groups reset inside 60 s (B0-26)4 runs at 100 writes/sPass. Every group commits within 1.2 s of its last reset
Simulator, HARSH and GRAY faults40,191,804 steps, 2,000 seeds1,000,856 acked writes, every one with valid ack evidence

Latency

What two continents cost a write

A write waits for one round to the nearest site in another region. That is the price of losing nothing when a region goes down. Reads from the leader's region pay no such round.

MeasureMedianTailGate
One cross-region round, enam to weur, under 100 commands/sp50 107 to 189 msp99 283 to 473 msB0-01, Milestone 0
Idle ping, leader to the weur memberp50 135 msp99 151 to 216 msB0-01, Milestone 0
Commit, one entry in flight, 15 runsp50 172 to 370 msp99 399 to 690 msB0-01, Milestone 0
Learner reads, 16 learners at 1,000 reads/s each16,000 reads/s, 0 failedp99 683 to 743 msB0-18
CI clones from the R2 clone cache, 33 a second100% from R2 with the push hooktime to first byte p99 406 msB0-23
Clients during the 24-hour chaos run lin24bp50 314 msp99 952 msBM-1

The commit figures are from Milestone 0's prototype. The production Rust host measured p99 414 to 807 ms in its second pass: 2 of 6 runs under the 600 ms line, none over 1 s. Closing that gap is open work.

Still open

  • SSH git sessions held at 99.59% to 99.89% through container kills, between the 99% and 99.9% lines. SSH is opt-in, and its gate is carried to Milestone 6.
  • One planted bug of 85 went uncaught: a resumed leader sending entries before they were durable.
  • Milestone 2 (pull requests, merge queues, folds) is under way; its gate has not run yet.

Sources: tests/RESULTS.md and the results files it cites, in the Graftyard repository.