in reviewhumanPR #62Negotiation
cloud-post-code-pareto-negotiation: multi-attribute bargaining, Pareto frontier, agents trading off price vs deadline
The default alternating_offers plugin bargains over price only. This PR adds a second plugin, pareto, where agents bargain simultaneously over price, deadline, and quality and converge toward Pareto-optimal agreements: deals where neither…
Author
@cloud-post-code
github profile →- Status
- In review
- Opened on
- Jul 3
- Branch
- hackathon/cloud-post-code-pareto-negotiation
Description
The pitch.
## What this PR does
The default `alternating_offers` plugin bargains over **price only**. This PR adds a second plugin, `pareto`, where agents bargain simultaneously over **price, deadline, and quality** and converge toward Pareto-optimal agreements: deals where neither side could be made better off without making the other worse.
All changes are scoped strictly to the negotiation layer, the `multi_attribute_market` scenario, validator additions, and leaderboard/docs. No shared infrastructure files (`sim/`, `metrics.py`, `marketplace.py`, `alternating_offers.py`) were modified.
---
## Spec deliverables (§07 — Multi-attribute negotiation with Pareto-frontier search)
| Criterion | Where |
|-----------|-------|
| Plugin registered as `("negotiation", "pareto")` | `plugins.py` +1 line |
| Bargains over ≥ 2 attributes from `Terms` | price + deadline (n) + quality tier |
| Each agent has a private utility function | `ParetoParams` per agent, never shared |
| Utility weights passed via constructor only | `ParetoNegotiator(agent_id, params)` |
| `respond()` evaluates full `Terms` | checks p, n, q feasibility + utility |
| Converges toward Pareto-optimal agreements | fewer dominated agreements than `alternating_offers` baseline |
| Adversarial validator FAILs `alternating_offers` | 10/10 sessions quantity-dominated (upstream `alternating_offers` unchanged) |
| Adversarial validator PASSes `pareto` | fewer violations than baseline in every run |
| Scenario with 50 client-consultant pairs | `scenarios/multi_attribute_market.yaml` |
| Deterministic params from seeded RNG | `hash(agent_id) ^ seed` via `_agent_rng()` |
| Does not break `alternating_offers` | plugin extended, not replaced; `alternating_offers.py` untouched |
| Breakdown sessions labeled and excluded | pairs 7 & 8 emit `close:breakdown:` |
| Leaderboard entry | rank #2: 80% deal rate, 69.6 msg/tick throughput, 100% delivery |
---
## Attribute model
```
price.amount → p (int 0–100) distributive axis — buyer wants low, seller wants high
conditions["deadline"] → n (int ticks) integrative axis — sweet-spots differ, joint optimum reachable
conditions["quality"] → q (float 0–1) static per session; gates feasibility only
```
---
## Six strategies (spec equations 10–12)
| Strategy | Concession rule |
|----------|----------------|
| `ttt_directional` | Mirror a bounded fraction of the opponent's per-issue movement on each axis |
| `zeuthen_concede` | Concede when own Zeuthen risk ratio ≤ opponent's; decrement `tau` by `tau_step` |
| `rubinstein_discount` | Accept when `u_i(x_j) ≥ delta^t · V_i`; discount continuation value each round |
| `logrolling_tradeoff` | Stay on own iso-utility contour; maximise estimated opponent utility |
| `nash_bargaining` | Asymmetric Nash product `(u_i − d_i)^β · û_j^(1−β)` over own feasible grid |
| `ks_bargaining` | Kalai-Smorodinsky: minimise `|λ_i − λ_j|` where `λ = (u − d) / (m − d)` |
Strategies assigned deterministically: buyer for pair `i` gets `STRATEGY_IDS[(i*2) % 6]`, seller gets `STRATEGY_IDS[(i*2+1) % 6]`. Buyer and seller always get different strategies.
---
## Files changed
### New / substantially expanded
| File | Net lines | What it does |
|------|-----------|-------------|
| `packages/nest-plugins-reference/nest_plugins_reference/negotiation/pareto.py` | +1,463 | `ParetoParams`, utility model, `build_feasible_grid`, `pareto_nondominated`, 6 strategy classes, `ParetoNegotiator` |
| `packages/nest-core/nest_core/scenarios_builtin/multi_attribute_market.py` | +741/−576 | 50 client-consultant pairs; joint-zone opening; clamped counters; breakdown pairs 7 & 8 |
| `packages/nest-core/nest_core/validators.py` | +374 | `_parse_pnq()`, `_pair_key()`, Pareto-dominance checker, adversarial validator |
| `packages/nest-plugins-reference/tests/test_pareto_negotiation.py` | +615 | 8 integration tests: determinism, frontier, acceptance, bre
…Try it
Open PR on GitHubView diffCheckout locally
git fetch origin pull/62/head:pr-62
git checkout pr-62