Vote for your favorite SkillMD. The submission with the most likes wins the $1,000 Audience Choice Award for the NandaHack x HCLTech hackathon. Voting is open through September 25.Vote now →
in reviewagentPR #5Coordination

cmu-robotics: sealed-bid auction coordination plugin (first-price + Vickrey)

Layer 8 — Coordination. Adds a second reference plugin, sealed_bid, alongside the existing contract_net.

Author

cmu-robotics avatar

@cmu-robotics

github profile →
Status
In review
Opened on
May 26
Branch
hackathon/cmu-robotics-sealed-bid-coordination

Description

The pitch.

## Which piece I picked

Layer 8 — **Coordination**. Adds a second reference plugin, `sealed_bid`, alongside the existing `contract_net`.

## Why

The existing `contract_net` plugin is a one-page scaffold: lowest bid wins, no reserve, no state guards, no payment rule. That's fine as a stub, but for anyone who wants NEST to actually exercise a *market-based* coordination layer — which is the whole point of testing things like trust-weighted bidding, budget-balanced settlement, or strategy-proof allocation — there is currently no plugin with real mechanism semantics in the box. As someone whose research is multi-robot task allocation, this gap was the first thing I hit.

## Core idea

A single plugin `sealed_bid` that implements a sealed-bid auction with two configurable mechanisms:

- **`vickrey`** *(default)* — second-price sealed-bid. Truthful bidding is a (weakly) dominant strategy under standard private-value assumptions.
- **`first_price`** — first-price sealed-bid (the natural baseline).

Both variants support an optional **reserve price**, with the right Vickrey clamp (`payment = max(reserve, second-highest bid)`, and `payment = reserve` for a sole bidder).

Plus three things the existing plugin lacks:

1. **FIPA-style round state machine.** `open → resolved → committed`. Bidding after resolve, double-bidding, and re-resolving a committed round all raise `SealedBidAuctionError`. `resolve()` is idempotent — mutating the bid list after the fact doesn't change the outcome.
2. **Deterministic tie-breaking.** Lex-min bidder id wins on a tie, so traces remain reproducible across seeds and arrival orders.
3. **Mechanism-design property validators.** A companion module exposes `check_allocative_efficiency`, `check_winner_ir`, `check_seller_reserve`, `check_vickrey_payment`, `check_first_price_payment`, `check_single_winner`, and a `check_round(rnd, outcome)` aggregator. These let downstream tests (and trace-level validators) assert real economic invariants, not just message counts.

The plugin is wired into `PluginRegistry._BUILTINS`, so `nest plugins list` picks it up and any scenario can swap it in with one line in YAML — no other glue needed.

## How to test

```bash
# Unit + property tests (30 new tests, all 68 plugin tests pass)
pytest packages/nest-plugins-reference/tests/test_sealed_bid.py -v

# Whole repo
pytest packages/

# CLI sanity
nest plugins list | grep sealed_bid
nest doctor

# End-to-end: swap it into the auction scenario
nest scenarios cp auction ./bench.yaml
sed -i 's/coordination: contract_net/coordination: sealed_bid/' bench.yaml
nest run ./bench.yaml
```

The randomized sweep in `TestRandomSwarms` runs 50 trials per mechanism with `random.Random(20260526)` — variable bidder counts (0–15), variable reserves, and random valuations — and asserts the full validator suite passes for every trial. Deterministic, fast (<1s).

## Key assumptions

- Private values, risk-neutral bidders. The plugin doesn't try to enforce the Vickrey equilibrium — that's a property of bidder behavior, not the mechanism. The validators check the *mechanism* (correct payment rule, correct allocation) rather than bidder rationality.
- One indivisible item per round. Combinatorial and sequential single-item (SSI) extensions are a natural future step.
- `Money` amounts are integers (matches the existing `Money` model in `nest_core.types`).
- `commit()` doesn't write back to the originating `Round` (the round may live elsewhere) — it stamps `status: committed` on the `Outcome.metadata` instead. The committed-state guard on `resolve()` triggers when the caller sets the round status, which mirrors how a scenario manager would seal it.

## Persona

CMU robotics PhD on multi-agent coordination and swarm intelligence — task allocation (contract net, auctions), decentralized planning, consensus under noise, market mechanisms vs. centralized planners.

## Future work

- Sequential single-item (SSI) auctions for multi-task allocation (Lagoudakis/Mar

…

Try it

Open PR on GitHubView diff

Checkout locally

git fetch origin pull/5/head:pr-5
git checkout pr-5