Nebius Global AI Hackathon · Coding and Agentic Engineering

The bisect that refuses
to blame the innocent.

git bisect run in one reused environment convicted the wrong commit 10 times out of 10. Faultline gives every commit it tests its own fresh Nebius container that installs that commit's own dependencies — and named the real culprit in 3 rounds, 19 jobs, for $0.0948.

Seismogram · every mark is a Nebius job T+15:57 · settled
Seismogram of hunt 827dfe7e Three rows, one per round, across commits 0 to 255. Round 1 probed 8 commits from 0 to 255; round 2 probed 8 commits from 150 to 178; round 3 probed 171, 172 and 173. Commit 173, 4e133d6c, failed and is the fault. The dependency pin moves at commit 150. commit 0 32 64 96 128 150 173 192 224 255 150 · pytz pin moves ROUND 18 jobs · 318.5 s ROUND 28 jobs · 374.3 s ROUND 33 jobs · 268.6 s 173 · 4e133d6c · THE FAULT Seismogram of hunt 827dfe7e Three rows, one per round, across commits 0 to 255. Round 1 probed 8 commits from 0 to 255; round 2 probed 8 commits from 150 to 178; round 3 probed 171, 172 and 173. Commit 173, 4e133d6c, failed and is the fault. The dependency pin moves at commit 150. 0 64 128 173 255 150 · pin moves R18 jobs R28 jobs R33 jobs 173 · 4e133d6c

Each burst is one probe: a fresh container that fetched the repo at that commit, installed that commit's dependencies and ran one test. The quiet before each burst is real — 4 min 21 s of VM start-up (p50) for 5.3 s of fetching, installing and testing — replayed at ×100 from the recorded timestamps. Round times overlap by about 4 s where two ticks raced at the end of round 1.

Instrument readings

One reused environment got it wrong
ten times out of ten.

With the environment built at the known-good ref, five trials named the pin bump, e46e5342. Built at the failing ref, five named a changelog edit, acebfbfa. Neither touched the bug.

10 / 10

times git bisect run in one reused environment named the wrong commit

evidence/bench/hero-local.json

255 → 1

commits narrowed to one, in 3 rounds

data/recorded-hunt.json

19

Nebius Serverless AI Jobs across 4 regions, 8 at a time

data/recorded-hunt.json · jobId × 19

20 / 20

concurrent-write races on the real bucket, exactly one winner each

evidence/g5-conditional-writes.json

513 unit and integration tests at 100 % coverage of the engine · 7 probe contract tests · 50 end-to-end checks — npm test needs no credentials.

Trace 01 · the same 255 commits, bisected twice

One environment named the bump. A clean room named the bug.

On the left, the standard tool in one environment — excerpted from the benchmark's recorded output (trial 1), with Faultline's verdicts on the same two commits below it. On the right, the live app's report for the same history — round 2 tested the pin bump in its own container, and it passed.

faultbench-tzdata-pipeline · one reused env
# one venv, built once at v0.1.0, reused for every step
$ git bisect start 43f3528c 0260b672  # main, v0.1.0
$ git bisect run python -m pytest -q -p no:cacheprovider tests/test_normalize.py::test_naive_local_midnight_is_interpreted_in_zone
…
FAILED tests/test_normalize.py::test_naive_local_midnight_is_interpreted_in_zone
e46e534219b7d051e003508c88b5bfe621536349 is the first bad commit
    build(deps): bump pytz to 2023.3 — Mexico abolished DST, update golden values
bisect found first bad commit
# 8 steps · 1.45 s · the same wrong answer in 5 of 5 trials

# faultline · hunt 827dfe7e · a fresh container per probe
✓ 150 e46e5342 pass  the pin bump, in its own container — innocent
✗ 173 4e133d6c fail  normalize: attach the zone directly instead of localize()

Benchmark output, evidence/bench/hero-local.json — the env built at the failing ref names acebfbfa instead, 5 of 5.

faultline.edycu.dev · Fault Report
Fault Report header from the live app: normalize: attach the zone directly instead of localize(); commit 4e133d6c856c2e756fce5a328896f20fecfc62eb, verified by executed testsThe diff lines from the same report: moment = zone_for(zone).localize(moment) replaced by moment = moment.replace(tzinfo=zone_for(zone))
The live app's Fault Report for the recorded hunt — the diff is the bug: localize() became replace(tzinfo=…).
The Fault Report's 'Why it breaks' paragraph, explained by nemotron-3-super-120b-a12b on Nebius Token Factory, labelled as generated text: the culprit was proven by running the test, the paragraph was not

Why it breaks — one Token Factory call to NVIDIA Nemotron 3 Super, labelled generated in the app. It gets the mechanism and 06:37 vs 06:00 right, but calls UTC−6 “DST-adjusted” — Mexico City has had no DST since 2022. The culprit came from the test, not this paragraph.

git bisect run, one env built at v0.1.0reused for every step
e46e5342build(deps): bump pytz to 2023.3 — Mexico abolished DST, update golden values
0 / 5 right
1.43 sp50 · N = 5
git bisect run, one env built at mainreused for every step
acebfbfadocs(changelog): spell out the units on the public helpers (#104)
0 / 5 right
1.49 sp50 · N = 5
git bisect run, a fresh venv at every stepthe harness you would have to write
4e133d6cnormalize: attach the zone directly instead of localize()
5 / 5 right
57.4 sp50 · N = 5
Faultlinea fresh Nebius container per probe, 8 at a time
4e133d6cnamed by executed tests
1 / 1 run
957 s19 jobs · $0.0948 · 16.7× the fresh-venv time

Read the time column honestly: Faultline is the slowest way to the right answer here. The fresh-venv harness is right too — Faultline is that harness, already written, run 8 at a time in clean Nebius containers, with both ends proven and refusals when the evidence contradicts itself.

Under the needle

Six decisions. Each one tested.

Six decisions that keep a wrong commit from being named — each one covered by tests.

Both ends, proven first

Round 1 runs your known-good ref and your failing ref in clean containers beside the first suspects. If the failing ref passes there, the break is your environment, not a commit — and Faultline says so instead of naming one.

round 1 · v0.1.0 + main

A probe holds nothing

Any public repo's conftest.py is arbitrary code. A probe gets one presigned URL for its own verdict and a tick URL it can only ping with an empty POST — no key, no bucket mount.

presigned PUT

No daemon, no database

Every dispatch is claimed before it happens; the hunt record is only replaced if nobody changed it first. On the real bucket: 20 races of 2–8 writers, one winner each time.

claim   PUT hunts/<id>/claims/<probe>.json  If-None-Match: "*"
412     another tick already won
hunt    PUT hunts/<id>.json  If-Match: <etag>

Infrastructure is never evidence

A probe that dies without reporting is retried, then the hunt pauses and says why. A throttled create (429) waits out its backoff. Neither becomes a verdict — a probe that never got to run the test is a skip, never a fail.

429 → backoff

It finishes with nobody watching

Each probe pings the hunt when its verdict lands, so the next round goes out by itself. Close the tab.

POST …/tick

The model explains; it never decides

After the tests name the culprit, one Nebius Token Factory call asks NVIDIA Nemotron 3 Super why it breaks, with the diff and the failing output. The paragraph is labelled generated, and the hunt record keeps its Token Factory request ID.

nvidia/nemotron-3-super-120b-a12b

The live instrument

What a judge sees at /

The app's home replays this recording with its real job IDs; “Run a live hunt” dispatches real Nebius jobs. These are screenshots of the deployed app, not mock-ups.

The app's status strip during round 1 of hunt 827dfe7e: eight probes across the 255-commit range
Round 1 — eight probes across 255 commits, both ends includedlive app · recorded hunt
The app's status strip at the end: settled in 3 rounds, 19 probes complete, 1 commit named, $0.0948 total; commit 173 named
Settled — 3 rounds · 19 probes · commit 173 named · $0.0948live app · recorded hunt
The app's integration panel listing the latest probe jobs read live from the Nebius Jobs API: four completed jobs in eu-west1 from hunt 94efded1
Latest jobs, read live from the Nebius Jobs API — here, four jobs of hunt 94efded1/api/integrations/verify

Honest by design · calibration notes

What the instrument does not claim.

one probe, p50 of 194:21 waiting for the VM · 5.3 s fetching, installing and testing

Drawn to scale. Almost all of a probe is waiting for its machine — the reason Faultline is slower than a local fresh-venv bisect, and why we want to try Sandboxes next (unmeasured: its beta access is pending).

“Read the wall-clock column honestly: Faultline is slower on both.”

— README · Engineering Rigor

“That fixture was built to drift, so the reused-environment failures are by construction; what it shows is the mechanism.”

— README · Engineering Rigor

“The root-cause paragraph is generated and can be wrong; the culprit is not.”

— README · Honest limits

Questions a judge would ask

Before you click Run.

Is it faster than git bisect?

No. Fresh-venv git bisect run finished the drift fixture in 57.4 s (p50, N = 5) and attrs in 43.8 s (p50, N = 3); Faultline took 957 s and 919 s. A probe's VM took 4 min 21 s to start (p50) for about 5 s of fetching, installing and testing, and Nebius throttles job creation. What it saves is knowing about the drift, writing the fresh-environment harness, and running it on your own machine.

README · Engineering Rigor · DEMO.md §5

Wasn't the fixture built to make git bisect fail?

Yes — faultbench-tzdata-pipeline moves its pytz pin at commit 150 on purpose, so the reused-environment failures are by construction. On a real regression — attrs 22.1.0 → 22.2.0, 135 commits, where a reused environment gets it right too — every method, Faultline included, named 89a890a3, the commit the fix (#1085) cites.

README · Engineering Rigor · evidence/bench/attrs-*.json

What is recorded, and what is live?

The replay on this page and on the app's home is hunt 827dfe7e, recorded 2026-10-13, labelled as a recording, with its real job IDs. “Run a live hunt” in the app dispatches real Nebius jobs — one hunt at a time, with a daily cap so traffic cannot drain the credit.

DEMO.md §6 · README · Honest limits

What does NVIDIA Nemotron do — and what if it is wrong?

One Nebius Token Factory call per hunt (a second only if the first is abandoned mid-call), after the tests have named the culprit, with the diff and the failing output. It was partly wrong on both benchmark hunts; the culprit was not, because it came from running the test. The hunt record keeps the request ID.

DEMO.md §5 · README · NVIDIA Nemotron on Token Factory

What can a malicious repository do?

Its conftest.py runs inside a probe, which holds one presigned URL for its own verdict object and a tick URL it can only ping with an empty POST — no key and no bucket mount. It can lie about its own commit's verdict; it cannot write another hunt's records — at worst it can ping a tick, or, like any visitor, start a hunt that counts against the visible daily cap.

README · Architecture · tests/hunt.integration.test.ts

Why Serverless AI Jobs and not Sandboxes?

Sandboxes would fit better, but its beta access is still pending: GET /sandboxes/v1/whoami reports every permission false. The engine talks to a four-verb ProbeBackend (dispatch, status, find, cancel); a Sandboxes backend would implement the same four. We have not been able to try one.

evidence/sandboxes-whoami.json · src/lib/backend/types.ts

Let the tests name it.
Not the environment.