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 →
mergedhumanPR #96Coordination

validators: fix auction_winner_highest trusting the announced amount over real bids

Fixes validate_auction_winner_highest returning PASS for an auction where a lower bidder was awarded, when the won: message announces a winning amount inflated past every real bid.

Author

SwasthikaDev avatar

@SwasthikaDev

github profile →
Status
Merged
Merged on
Jul 9
Branch
hackathon/swasthika-auction-winner-fix

Description

The pitch.

## Summary

Fixes `validate_auction_winner_highest` returning **PASS** for an auction where a lower bidder was awarded, when the `won:` message announces a winning amount inflated past every real bid. A false PASS is the dangerous case for a validator: it certifies a violated invariant as correct.

## Where — exact location

- **File:** `packages/nest-core/nest_core/validators.py`
- **Function:** `validate_auction_winner_highest` at **line 240**. The changed comparison block is at **lines 283–290**.

## Root cause

The validator parses two message types from the trace:
- `bid:<item>:<amount>` → `bids[item].append((bidder, amount))` where `bidder = ev["agent"]`
- `won:<item>:<amount>` → `winners[item] = (bidder, amount)` where `bidder = ev["to"]` and `amount` is the **announced** figure taken straight from the `won:` message.

It then flagged a violation only when a bid exceeded that **announced** amount:

```python
# BEFORE  (validators.py)
for item, (_winner, winning_amount) in winners.items():
    for bidder, amount in bids.get(item, []):
        if amount > winning_amount:      # compares real bids to the ANNOUNCED amount
            violations.append(
                f"item {item}: winner bid {winning_amount} but {bidder} bid {amount}"
            )
            break
```

`winning_amount` is controlled by whoever emits the `won:` message. Inflating it past all real bids makes every real bid `<= winning_amount`, so no violation fires and the check passes even though a lower bidder won.

## Reproduction — added as a test

```python
events = [
    send("bidder-0", "auctioneer-0", "bid:item-1:50"),
    send("bidder-1", "auctioneer-0", "bid:item-1:100"),   # real highest bid = 100
    send("auctioneer-0", "bidder-0", "won:item-1:150"),    # low bidder wins; amount inflated to 150
]
validate_auction_winner_highest(events)   # OLD: PASS  (bidder-0's real bid was only 50)
```

## The fix

Compare against the winner's **own highest observed bid**, not the announced amount (`validators.py:283`):

```python
# AFTER
winner_bids = [amount for bidder, amount in item_bids if bidder == winner]
effective_winner_bid = max(winner_bids) if winner_bids else winning_amount   # line 284
for bidder, amount in item_bids:
    if amount > effective_winner_bid:                                         # line 286
        violations.append(
            f"item {item}: winner {winner} bid {effective_winner_bid} "
            f"but {bidder} bid {amount}"
        )
        break
```

**Fallback:** if the winner's own bid was not observed (e.g. the `bid:` message was dropped under `message_drop`), it falls back to the announced amount, so a valid trace under message loss is never failed. The check only *tightens* when the winner's real bid is present in the trace.

## Tests

- **Unchanged, still pass:** `test_pass_highest_wins` (winner's real bid 150 is the highest → PASS) and `test_fail_lower_bid_wins` (a competitor bid 200 > the winner's real 100 → FAIL, detail still contains "200"). Both in `TestAuctionWinnerHighest`, `test_validators.py`.
- **Added:** `test_fail_inflated_announced_amount` at **`packages/nest-core/tests/test_validators.py:247`** — the reproduction above; it **fails** on the old code and passes on the fix.

## Files changed (2 files, +14 / -4 and +14)

| File | +/- | What |
|---|---|---|
| `packages/nest-core/nest_core/validators.py` | +14 / -4 | `validate_auction_winner_highest` uses winner's real bid (lines 283–290) |
| `packages/nest-core/tests/test_validators.py` | +14 | False-PASS regression test (line 247) |

## Verification — full CI, branch merged with current `main`

`uv run ruff check .` clean · `uv run ruff format --check .` clean · `uv run pyright` strict **0 errors** · `uv run pytest` **792 passed**, 1 skipped. Scoped to the one validator plus its test.

Try it

Open PR on GitHubView diff

Checkout locally

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