Skip to content

fix(mcp): report real tier/ELO/G on idempotent arena_submit re-submit - #68

Open
colinisme wants to merge 1 commit into
mainfrom
fix/arena-submit-noop-snapshot
Open

fix(mcp): report real tier/ELO/G on idempotent arena_submit re-submit#68
colinisme wants to merge 1 commit into
mainfrom
fix/arena-submit-noop-snapshot

Conversation

@colinisme

Copy link
Copy Markdown
Contributor

Problem

arena_submit reports a misleading Tier: Bronze, ELO 0, G at submit: 0 when an agent that is already in the matchmaking pool re-submits — even though the ghost is correctly sitting in its real tier (e.g. Gold) and matchmaking pairs it there.

Reproduced live on mainnet while running Arena battles for three agents: Colin111 (#32) was already pooled from a prior session, so its re-submit printed Bronze / 0 / 0 — yet it was matched in Gold and won. The on-chain submission was always correct; only the MCP's return message was wrong.

Root cause

ArenaEngine.submit() is intentionally idempotent:

// ArenaEngine.sol:408
if (!isSubmitted[agentId]) {
    ...
    emit GhostSubmitted(agentId, t, g.elo, gNow);
}

A re-submit of an already-pooled ghost is a no-op that emits no GhostSubmitted event. arenaSubmit() parsed only that event, so when it was absent the function fell through to its tier = 0, elo = 0, gAtSubmit = 0 defaults → Bronze / 0 / 0. (settleMatch clears isSubmitted, which is why agents that had just fought re-submitted with correct values and never showed the bug.)

Fix

When no GhostSubmitted event is found, fall back to live on-chain reads instead of the zero defaults:

  • arena.tierStates([agentId]) → real tier + G balance
  • arena.getGhost(agentId) → real ELO

The tool message now leads with "Already in the pool" for the no-op case so it's honest about what happened, and adds an alreadyPooled flag to the return shape.

Verification (live, Gravity mainnet)

Scenario Before After
Fresh submit (event emitted) Ghost submitted! Tier: Gold, ELO 1017, G 2175 unchanged ✅
Re-submit, already pooled (no event) Ghost submitted! Tier: Bronze, ELO 0, G 0 Already in the pool Tier: Gold, ELO 1017, G 2175

tier_info confirms ground truth = Gold / 2175. tsc --noEmit passes; the tracked bin/gravity-town-mcp.mjs bundle was rebuilt from the patched source.

🤖 Generated with Claude Code

ArenaEngine.submit() is idempotent — re-submitting an already-pooled
ghost is a no-op guarded by `if (!isSubmitted[agentId])` and emits no
GhostSubmitted event. arena_submit parsed only that event, so a re-submit
fell through to the 0/0/Bronze defaults and reported a misleading
"Ghost submitted! Tier: Bronze, ELO 0, G 0" even though the ghost was
correctly sitting in (e.g.) the Gold pool and matchmaking accordingly.

Fall back to live on-chain reads (tierStates + getGhost) when no event is
present, and lead the message with "Already in the pool" so the no-op
case is honest. Verified live on mainnet: a pooled agent now reports its
true Gold/ELO/G on re-submit instead of Bronze/0/0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
gravity-town Ready Ready Preview, Comment Jun 5, 2026 4:57am

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant