QwenCloud Hackathon · Track 3 · Agent Society

Five agents. Nine seats. The right people fly.

Tarmac is an airline irregular-ops agent society where conflict is the architecture: five agents with opposed objectives negotiate sealed-bid claims on a row-locked seat ledger, and a mediator resolves mechanically detected deadlocks with Ed25519-signed, regulation-cited rulings. An ablation bench proves the society beats a single planner — measurably.

SCENARIO storm_dfw PAX 180 / SEATS 139 OFFLINE zero keys REPLAY byte-identical

00

Protected passengers stranded — single planner vs the society

docs/BENCH.md · 10 seeds

0%0%

Special-needs SLA met — minors, medical, wheelchair

docs/BENCH.md · 10 seeds

0

Tests, all green, in ~5 seconds

pytest · CI on every push

0%

Coverage across ledger, bids, deadlock, mediator, invariants

pytest --cov=tarmac_society

The one number

Strip the mediator and it's 96.

Same storm, three conditions, ten seeds, fully deterministic. The society doesn't just beat a single planner — remove its mediator and the society becomes worse than one planner, because contested claims get quarantined with no one to rule. The mediator is load-bearing, not decorative.

Ablation — storm_dfw

180 pax · 139 legal seats · medians of 10 seeds · tarmac bench

Protected passengers stranded (medical courier · minor · wheelchair · tight connections — lower is better)

SINGLE PLANNER
17
SOCIETY − MEDIATOR
14
FULL SOCIETY
3

Stranded overnight — no seat at all (lower is better)

SINGLE PLANNER
52
SOCIETY − MEDIATOR
96
FULL SOCIETY
50

Seat supply is physically fixed — 139 seats for 180 passengers — so raw strandings barely move. The society's win is in who flies: the single planner seats a flexible high-fare passenger on the last compliant nonstop while stranding the medical courier; the society doesn't.

Full ablation benchmark table
MetricSingle plannerSociety − mediatorFull society
Protected pax stranded (SLA-failed) ↓17143
Stranded overnight (no seat) ↓52 [50–53]96 [81–109]50 [49–52]
Tight connections saved ↑039
Special-needs SLA met (%) ↑0.00.0100.0
Crew duty violations (invariant I2) ↓100
Rounds to quiescence ↓165
Contest stake (credibility) ↓06040

Medians across 10 seeds; [q1–q3] IQR. Offline deterministic policy agents; identical scenario per seed across all three conditions. Reproduce: tarmac bench.

Tarmac hero panel — five agents negotiating seats on an amber departure board

The protocol

Claims are function calls, not sentences.

Contention has physics: a claim is a typed mutation against a real ledger. Two threads racing the last seat — exactly one wins. Tested.

Sealed-bid commit → reveal

In contested rounds every agent posts SHA256(claim ‖ nonce) before anyone reveals — rivals can't adapt a bid after seeing another's. The ledger rejects any reveal that doesn't re-derive its digest (invariant I4). Negotiation that's provably leak-free.

Mechanical deadlock detection

A wait-for cycle or a resource contested ≥2 rounds triggers mediation. Never vibes-based — always reproducible.

Ed25519-signed rulings

Every mediator ruling is signed and cites a regulation — a portable artifact you can verify with the public key, without trusting the database.

Row-locked seat ledger

SQLite row locks enforce capacity and exclusivity (I1). Double-claims are rejected at the storage layer, and every event extends a hash-chained log — replay re-derives the identical manifest (I5).

Domain-agnostic core

The protocol ships as tarmac-societyClaimLedger, DeadlockDetector, Mediator. examples/meeting_rooms.py reuses it for room booking in 20 lines. Not airline-shaped.

Honest by design

What's real, exactly.

Every claim on this page is committed to the repo and checked in CI. Here's the fine print, up front.

Offline default

Deterministic policy agents

The default run uses deterministic policy agents — no network, no key, byte-identical every time. They genuinely negotiate, deadlock, and resolve on the fixture. Add --live + DASHSCOPE_API_KEY to swap in the real Qwen agents (qwen3.7-plus roles, qwen3.7-max mediator).

Wire-tested, not vaporware

19 tests drive the live path

The LiveQwen DashScope transport is exercised by 19 deterministic tests against a stub client — model routing, structured output, one-retry, the mediator's thinking flag, embeddings. --live executes an already-verified path; it adds tokens, not code.

A simulator, stated plainly

Rehearsal, not a live GDS

Synthetic reservation data, one curated storm plus a seeded generator. Decision-support and rehearsal — not a live booking integration. ECS deployment is documented in infra/ecs/, not claimed as deployed.

Flight information

Questions judges ask.

Why is the mediator "load-bearing"?

The ablation's middle column is the proof: run the identical society without adjudication and contested claims are quarantined at the round cap — 96 passengers stranded overnight versus 52 for a lone planner and 50 for the full society. Deleting one component makes the system worse than the baseline; that's an existence proof the component does the work.

Can I verify the results without an API key?

Yes — that's the designed judge path. python scripts/verify_offline.py disables all sockets, runs the full society on the committed fixture, replays the manifest from the hash-chained log, and re-checks invariants I1–I5. Exit 0 means the run reproduced itself byte-for-byte with zero network.

What stops agents from arguing forever?

A credibility currency: contesting a claim costs points, winning refunds them plus a premium, losing burns them. Argument is economically bounded — the bench reports the stake spent (40 for the full society vs 60 without a mediator), and rounds to quiescence stay finite.

Why does this need Qwen Cloud specifically?

The society must be measured, not just demoed. qwen3.7-plus keeps five role personas affordable across ~60 turns per run; qwen3.7-max with thinking adjudicates five conflicting position papers; structured output makes claims mechanically executable; context cache reuses the 4k-token storm prefix every turn; the Batch API prices a 60-run ablation. Remove that stack and the benchmark becomes economically impossible.

Is this only for airlines?

No. The negotiation core — ClaimLedger, DeadlockDetector, Commitment, Mediator — is domain-agnostic. examples/meeting_rooms.py rebuilds meeting-room booking on the same protocol in about 20 lines. Anywhere agents contend for scarce, exclusive resources, the physics transfer.

How solid is the code, really?

327 tests, 99% coverage, green in ~5 seconds — covering ledger locking and double-claim rejection, commit→reveal mismatch rejection, the deadlock detector on synthetic wait-for graphs, credibility math, the ruling flow, invariants I1–I5, and a fixture guarantee that storm_dfw always produces at least one genuine deadlock. CI runs ruff, mypy, pytest, CodeQL, pip-audit, TruffleHog, and a wheel-install smoke test on every push.

Cleared for departure

Run the storm yourself.
Zero keys. Five seconds.

One command verifies the whole society offline — sockets disabled, invariants replayed, exit 0.