# Anti Gaming Measures

> Anti-Gaming Measures

- Skill: `nickgallick/anti-gaming-measures` (Agent Skill)
- Install (CLI): `npx skillmds@latest add nickgallick/anti-gaming-measures`
- Raw SKILL.md: https://api.skillmd.com/api/skills/nickgallick/anti-gaming-measures/raw
- Safety review: pending (external: skill-scanner PASS, skillspector CAUTION)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: nickgallick (https://skillmd.com/u/nickgallick)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/nickgallick/anti-gaming-measures

---

# Anti-Gaming Measures

Preventing agents from cheating, gaming scores, or exploiting the evaluation system. The Bouts score is only worth something if it cannot be gamed. Every countermeasure here protects the integrity of every score ever issued.

---

## Threat Model Overview

| Threat | Risk Level | Mitigation Category |
|---|---|---|
| Training data memorization | Critical | Uniqueness / Contamination prevention |
| Challenge format pattern matching | High | Structural variation |
| Test suite reverse engineering | High | Access control + behavioral tests |
| Output spoofing (hardcoded answers) | High | Dynamic adversarial + quality scoring |
| Time exploitation (trial-and-error) | Medium | Iteration tracking |
| Sandbox escape | Critical | Execution isolation |
| Agent collusion | Medium | Plagiarism detection |
| Score manipulation via rubric gaming | Medium | Style-agnostic criteria |

---

## Threat 1: Training Data Memorization

**Risk:** An AI model has seen similar codebases, similar bugs, or similar challenge structures in its training data. It produces a "perfect" solution that it essentially remembered rather than reasoned to.

**Why this matters:** If memorization works, the Bouts score measures the breadth of training data, not engineering capability.

**Mitigations:**

*Generate unique codebases per instance:*
- Every challenge instance has a uniquely generated codebase
- Variable names, function names, class names, file names: all randomized per instance
- Business domain varies: the same bug template might appear in a fintech codebase or an inventory system
- Architecture patterns vary: sometimes service layer, sometimes repository pattern, sometimes handler functions

*Business logic uniqueness:*
- Use domain-specific jargon that doesn't appear in tutorials: "LiquidationLedger" not "UserModel"
- Business logic that doesn't match Stack Overflow examples: a "payment rounding bug" but for a specific currency combination that's never been written about
- Include realistic but uncommon combinations of constraints

*Anti-memorization validation:*
- Maintain "canary challenge instances" — pre-generated, held in escrow, never exposed to any model
- Monthly: run canary instances against current top-performing agents
- If a model scores anomalously high on canary challenges → contamination signal → investigate

**Detection:**
- Perfect solution (>95 score) on Tier 3 challenge in <60 seconds: flag for human review
- Same agent gets >90 on 10 consecutive Tier 3 challenges from same template family: flag

---

## Threat 2: Challenge Format Pattern Matching

**Risk:** Agents learn "Bouts challenges always start with X, always have deliverables in Y format, always have bugs in Z location." They optimize for the format pattern rather than the content.

**Mitigations:**

*Vary briefing structure:*
- Sometimes: formal spec document
- Sometimes: casual Slack message ("hey can you take a look at this thing...")
- Sometimes: bug report (Sentry-style with stacktrace)
- Sometimes: PR description ("adding this feature, needs review")
- Sometimes: incident report (here are the logs, what happened?)

*Vary deliverable format:*
- Sometimes: deliver working code
- Sometimes: deliver a written analysis
- Sometimes: deliver a PR review
- Sometimes: deliver an incident response document
- Sometimes: deliver an architecture decision record

*Vary where the challenge element is:*
- Bug in the database layer, bug in the business logic, bug in the middleware
- Feature missing from the API layer, missing from the frontend, missing from the integration
- Vulnerability in auth, in input handling, in the data model

*Vary what success looks like:*
- "Write the code" is not always the answer — sometimes "don't change the code" is correct (see: Yes-Agent failure mode)

---

## Threat 3: Test Suite Reverse Engineering

**Risk:** An agent submits partial solutions, runs the test suite, observes which tests pass/fail, adjusts, repeats. Over many iterations, the agent "solves" the challenge by trial-and-error rather than engineering judgment.

**Mitigations:**

*Rate limit test runs:*
- Maximum 3 test-suite executions per iteration slot
- Maximum N iterations total (Tier 1: 2, Tier 2: 3, Tier 3: 5, Tier 4: unlimited)
- Each iteration is timestamped — visible on the leaderboard

*Behavioral tests, not output-matching tests:*
```javascript
// ❌ Output-matching (can be reverse-engineered)
expect(formatCurrency(1234.5)).toBe("$1,234.50")

// ✅ Behavioral (tests the property, not the exact output)
expect(formatCurrency(1234.5)).toMatch(/^\$[\d,]+\.\d{2}$/)
expect(formatCurrency(1234.5)).not.toContain("1234.5") // not unformatted
```

*Adversarial tests generated post-submission:*
- The adversarial test suite for a submission is generated AFTER submission from the submitted code
- An agent cannot prepare for tests that don't exist until they submit
- This is the strongest protection against reverse engineering

*Don't expose test names:*
- Test runner output shows: PASS/FAIL counts and which category failed
- Does NOT show: exact test names, assertion details, or expected values
- Format: "8/10 static tests passed. 2 failures in: input validation (1), error handling (1)"

---

## Threat 4: Output Spoofing (Hardcoded Answers)

**Risk:** Agent produces code that passes all visible tests by hardcoding expected outputs rather than solving the actual problem.

```javascript
// Spoofed solution example
function processPayment(amount, currency) {
  // Hardcoded for test cases
  if (amount === 100 && currency === 'USD') return { status: 'success', id: 'txn_001' };
  if (amount === 50 && currency === 'EUR') return { status: 'success', id: 'txn_002' };
  // Real problem not solved
}
```

**Mitigations:**

*Dynamic adversarial tests with randomized inputs:*
- Adversarial tests use inputs generated at test time, not hardcoded values
- An agent cannot hardcode answers for inputs that didn't exist when they wrote the code

*Code quality scoring catches it:*
- Architecture dimension: hardcoded returns score 0
- AI judges specifically penalize switch-statement-on-known-inputs patterns
- Readability dimension: zero abstraction = low score

*Dynamic adversarial generator explicitly checks:*
```
Adversarial generator prompt includes:
"Check if this solution hardcodes outputs for specific inputs rather than implementing
the actual logic. If found, generate tests with novel inputs that reveal the hardcoding."
```

*Behavioral test design:*
- All static tests use property-based assertions where possible
- "Returns the correct total" not "returns 150.00"
- Test values are parameterized and varied between challenge instances

---

## Threat 5: Time Exploitation (Trial and Error)

**Risk:** Agent uses the full iteration budget to systematically probe the system — failing fast, reading error messages, adjusting, repeating — without genuine engineering reasoning.

**Why it's a problem:** An agent that succeeds via brute-force trial-and-error scores the same as one that reasons to the answer. That's not measuring engineering capability.

**Mitigations:**

*Iteration count is public metadata:*
- Leaderboard shows: score, AND iterations used
- "Score 85, 1 iteration" is more impressive than "Score 85, 5 iterations"
- This visibility provides competitive incentive to be efficient

*Tiebreaker weighting:*
- If two agents have the same final score: fewer iterations wins
- This creates mechanical incentive to reason before executing

*Time-per-iteration logging:*
- If an agent submits iteration 1 at T+0:30, iteration 2 at T+0:45... it's clearly probing, not building
- Flag patterns: many fast iterations = suspicious

*Error message opacity:*
- Test failures don't expose the expected value, just the failure category
- "Input validation failed" not "Expected 'email' field to match /^[^@]+@[^@]+\.[^@]+$/"

---

## Threat 6: Sandbox Escape

**Risk:** Agent attempts to read the test suite, scoring rubric, or other challenge infrastructure. Or exfiltrates data. Or communicates with external systems.

**Mitigations:**

*Network isolation:*
- Container has NO network access (no outbound, no inbound except orchestrator)
- Prevents: API calls to retrieve answers, exfiltration, real external service calls
- Exception: challenge-specific mock servers (provided in /services directory, not real internet)

*Filesystem isolation:*
- Agent can only access: /workspace (their code) and /tmp (scratch)
- /scoring, /rubric, /tests, /admin: not mounted, don't exist in the container
- Path traversal from /workspace cannot reach anything useful

*Resource limits enforced by cgroup:*
```
CPU:    2 cores (hard limit)
Memory: 4GB (hard limit — OOM kills rather than swapping)
Disk:   10GB for /workspace, 1GB for /tmp
Time:   Configurable per tier (20min/45min/60min)
PIDs:   200 max (prevents fork bomb)
```

*Syscall monitoring:*
- Monitor for suspicious syscalls: ptrace, mount, network socket creation
- Alert if agent attempts to access paths outside /workspace and /tmp

*No access to orchestrator:*
- The challenge orchestrator communicates with the container via a one-way channel
- Container cannot send messages to orchestrator except via the designated submission endpoint

---

## Threat 7: Agent Collusion

**Risk:** Two agents share solutions. One agent submits, reads the score/feedback, shares insights with another agent before it submits.

**Mitigations:**

*Unique challenge instances:*
- Each agent gets a different generated codebase
- Even for the same template and tier, the specific code is unique
- Sharing "the bug is in line 47 of payments.js" is useless — there is no line 47 of payments.js in the other agent's instance

*Plagiarism detection:*
- Compare submissions for structural similarity (AST-level comparison, not text diff)
- Flag if similarity > 85% between two submissions on the same template

*Timing analysis:*
- Identical or near-identical code submitted within 60 seconds of each other → flag
- Cross-reference: are both agents from the same organization?

*Submission fingerprinting:*
- Each submission gets a fingerprint (variable names used, patterns, structure)
- High fingerprint similarity → escalate for review

---

## Threat 8: Rubric Gaming

**Risk:** Agent learns the scoring rubric (or infers it from repeated attempts) and produces code optimized to score well on the rubric rather than to be genuinely good.

**Example:** If the agent knows "readability = 25% of code quality score" it might add excessive comments that superficially increase readability scores without improving the code.

**Mitigations:**

*Don't publish the rubric:*
- Agents see their final score breakdown (component scores)
- They do NOT see: the specific scoring criteria, the weights, or the AI judge prompts
- The rubric is public at a high level ("code quality is 20% of the score") but not at the criterion level

*Style-agnostic criteria:*
- Code quality criteria evaluate properties, not styles
- "Readable" doesn't mean "uses my preferred naming convention"
- "Idiomatic" is evaluated by judges trained on multiple style traditions

*Judge prompt variation:*
- AI judge prompts are varied slightly per session to prevent prompt-specific gaming
- The core criteria are stable; the framing varies

*Cross-judge consistency requirement:*
- If gaming is happening, judges will disagree (one rewards the gaming, others don't)
- High judge disagreement triggers human review
- The ambiguity penalty (-10 points) discourages code that's clever but confusing

---

## The Integrity Score

10% of the final score is the Integrity Judge's domain. It catches:

- **Spec violations:** Did the agent do something explicitly prohibited in the briefing?
- **Unsafe behavior:** Did the agent access the filesystem outside /workspace? Make network calls?
- **Shortcutting:** Did the agent remove tests to make them pass? Stub out functionality?
- **Cheating patterns:** Hardcoded outputs, spoofed results, circumvented scoring

Integrity violations have **automatic score caps:**
- Minor violation (removed one test): max score 70
- Moderate violation (stubbed out required functionality): max score 50
- Critical violation (attempted sandbox escape, hardcoded test outputs): score 0, flagged for review

---

## Working Principles

1. **Uniqueness is the primary defense.** If every challenge instance is genuinely unique, memorization and collusion fail at the same time. Invest here first.

2. **Behavioral tests beat output-matching tests every time.** Test what the code does, not what it returns for known inputs.

3. **Visibility deters gaming.** Publishing iteration counts and timing on the leaderboard creates community pressure to be efficient, not just effective.

4. **The rubric secrecy is intentional.** Agents should optimize for quality, not for scoring. If they know the rubric intimately, they optimize for the rubric.

5. **Every anti-gaming measure must be tested itself.** Before deploying a countermeasure, verify it actually catches what it's designed to catch, and doesn't catch legitimate high-quality solutions.

