# Refund Rush — Change Management Policy

**Game:** Refund Rush
**Version:** 1.0
**Effective date:** 2026-04-20
**Owner:** Oki Studios
**Audience:** GLI / iTech / BMM test labs, aggregator integration teams, jurisdictional regulators

---

## 1. Purpose & scope

This document defines how Refund Rush separates **math changes** (which require re-certification) from **platform changes** (which do not), how each class of change is reviewed and shipped, and what evidence is preserved for audit.

The policy applies to **every byte of code, configuration, and content shipped to production** for Refund Rush. There are no informal channels, no emergency exceptions to the math-change re-cert requirement, and no off-process production access.

The policy was designed to satisfy GLI-19 §4 (Change Control), GLI-33 §6 (Software Maintenance), MGA Player Protection Directive Annex 3, UKGC RTS Annex A §A.7, and AGCO Standards 1-2 §1.41. It is shared with the test lab and reconfirmed at every annual re-validation.

---

## 2. Change classification

Every change is classified at PR creation time by the developer and reconfirmed by a second reviewer. The classification determines the workflow.

### 2.1 Math change

**Definition:** any change to source files under `game_server/app/core/`. This is the certification-scoped math layer that a future lab certificate will be keyed to. Verified mechanically by the `/_meta/math-hash` endpoint and the `tests/cert/` regression suite.

**Examples:**

- Paytable values, reel-strip ordering, RTP scale table
- Feature math (Direct Deposit weights, Bonus Season ladder, Refund Meter prizes)
- Progressive multipliers, seeds, contribution rates, trigger weights
- Random-event probabilities or payout values
- RNG wrapper logic
- Anything that could change theoretical or empirical RTP, hit frequency, max-win reachability, or feature trigger frequency

**Workflow:**

1. Open re-certification ticket with the active test lab. Pay the re-cert fee. Obtain ticket reference.
2. Develop the change on a feature branch. CI's `tests/cert/` suite will fail on every commit until the golden values in the suite are updated.
3. Update `tests/cert/` golden constants to match the new math.
4. Submit the changed source + new constants + new math-hash to the test lab.
5. Lab re-computes theoretical RTP and theoretical RTP per RTP variant; signs the new certificate.
6. Lab issues new certificate with new math-hash recorded.
7. Operator/aggregator notification (see §5).
8. Merge to `main`. Tag the release. Build the production image. Capture the new math-hash from `/_meta/math-hash` after deploy and confirm equality with the certificate.

**SLA:** dictated by the test lab (typical: 4–8 weeks for an incremental math change, 8–16 weeks for a new feature).

**No exceptions after certification.** A math change cannot be shipped under the platform-change workflow even for "obvious bug fixes." Once a certificate exists, if the math hash on production differs from the certificate hash, the operator must disable the game pending lab re-issuance.

### 2.2 Platform change

**Definition:** any change to source files NOT under `game_server/app/core/` — including dependencies, the runtime image, OS packages, the database schema, network configuration, frontend code, and assets.

**Examples:**

- Security patches to FastAPI, SQLAlchemy, asyncpg, uvicorn, Postgres, Redis, the OS kernel
- New API endpoints (e.g. `/_meta/math-hash` itself)
- Frontend UI updates (animations, mascot art, sound effects, layout)
- Localization strings, currency formatting changes
- Performance tuning of non-math code paths
- Compliance-mode toggle additions (jurisdiction profiles in `app/policy/`)
- Telemetry / observability changes
- Documentation

**Workflow:**

1. Open PR. CI runs the full test suite including `tests/cert/`. Math-hash gate confirms `app/core/` is unchanged.
2. Code review by a second engineer. Both sign off via PR approval (audit-logged in source control).
3. Merge to `main`. Tag the release. Build the production image. Deploy.
4. Post-deploy: capture new platform-hash from `/_meta/platform-hash`. Log in the change register (§4).
5. No regulator/lab notification required for routine platform changes.

**SLA depends on severity:**

| Severity | Trigger | SLA from disclosure to prod |
|---|---|---|
| **Emergency** | CVSS ≥ 9.0 in any runtime dep, or active exploitation | 24–48 hours |
| **High** | CVSS 7.0–8.9 | 7 days |
| **Medium** | CVSS 4.0–6.9 | 30 days |
| **Routine** | Maintenance updates, minor features, dep refresh | Monthly maintenance window |
| **Major version bumps** | Python minor (3.12→3.13), Postgres major, FastAPI major | Plan + regression-test pass + lab attestation, then deploy |

### 2.3 Major-version dependency upgrade

**Definition:** any upgrade to a runtime dependency whose new major version could change behaviour beyond bug fixes (e.g. Python 3.x.y → 3.(x+1).0, Postgres 15 → 16).

**Workflow:**

1. Open PR. CI must pass including `tests/cert/`.
2. Run the full simulator regression suite at all 3 RTP variants for ≥ 5M spins each. RTP must hold within the certified ±0.30% tolerance.
3. Send a "no-change attestation" to the test lab: cover letter + diff summary + simulator regression results + math-hash unchanged + platform-hash before/after. Lab signs off (typical 1–2 business days).
4. Deploy.
5. Log in change register with attestation reference.

This is *not* re-certification. The certificate doesn't change. But the lab needs to know we crossed a major-version line and that we proved the math is unaffected.

---

## 3. Authorisation matrix

Refund Rush Studios is currently a single-developer operation. The matrix below documents the governance model, including the controls that apply when the team grows past one person. Even today, every action is logged so a future audit can reconstruct who did what and why.

| Action | Approver(s) today (solo) | Approver(s) post-team |
|---|---|---|
| Math change → re-cert | Owner | Owner + Math Lead |
| Platform change → prod | Owner | Engineer + reviewer |
| Emergency CVE patch | Owner (logged within 24h) | On-call + Eng Manager |
| Major version upgrade | Owner | Engineer + reviewer + lab attestation |
| Production database access | Owner (break-glass logged) | Two-person rule (engineer + manager) |
| Secret rotation | Owner | Owner + designated deputy |
| Lab/regulator correspondence | Owner | Compliance Officer |

Solo-developer state is acceptable to most regulators *if and only if* every operational action is logged in a tamper-evident trail (§4). The two-person rule kicks in automatically when team size ≥ 2.

---

## 4. Audit trail

Every change to production state — code, config, secret, database schema, RNG seed source, certificate — is recorded in an append-only register that the regulator can pull on demand.

### 4.1 Source-control register

- Git history is the canonical source-of-truth for code changes. Branch protection on `main`: signed commits required, linear history (no force-pushes after merge), CI must pass.
- All commits to `main` are GPG-signed with a key registered with the test lab. Unsigned commits are rejected at the server.
- Every release is tagged `vMAJOR.MINOR.PATCH`, signed, with the production image SHA-256 included in the tag annotation.

### 4.2 Deploy register

The production deploy register records every production deploy:

```
timestamp | git_tag | math_hash | platform_hash | deployer | rollback_target | notes
```

The math_hash and platform_hash columns are pulled from `/_meta/build-info` immediately after the deploy completes. Mismatch triggers an automatic rollback.

### 4.3 Operational register

Out-of-band production actions (manual database queries, secret reads, break-glass SSH) are logged to the operational register with timestamp, actor, justification, and reviewer (or post-hoc review for emergencies). Solo-developer state: every entry self-reviewed within 7 days and counter-signed by an external compliance counsel on a quarterly cadence.

### 4.4 Per-round audit log

Every game round is recorded to `game_rounds` with: `round_id`, `session_id`, `player_id` (opaque), `bet_amount`, `result_grid`, `total_win`, `rng_data` (full draw history), `audit_hash` (SHA-256 hash-chained to previous round). The chain is read-only to the application role; only the migration role can `UPDATE`/`DELETE`. Tampering with any past row invalidates every subsequent hash on read.

---

## 5. Regulator and aggregator notification

| Event | Notify | Timing |
|---|---|---|
| Math change → new certificate | Lab, all aggregators with deals, jurisdictional regulators per their rules | Before deploy |
| Major version dep upgrade | Lab (no-change attestation), aggregators (FYI) | Before deploy |
| Routine security patch | None | Logged only |
| Emergency CVE patch | Aggregators (FYI within 24h) | After deploy |
| Production incident affecting fairness | Lab + all jurisdictional regulators | Within disclosure window per jurisdiction (UKGC: 24h, MGA: 48h, AGCO: 24h) |
| Math-hash mismatch detected | Self-disable + notify lab + aggregators | Immediately |

---

## 6. Rollback procedure

Every production deploy is reversible. Rollback target is recorded in the deploy register at the moment of deploy.

**Routine rollback (last-known-good):**

1. Identify last green deploy from register.
2. `kubectl rollout undo` (or equivalent) to that image SHA.
3. Verify `/_meta/build-info` matches expected hashes.
4. Log the rollback as a separate register entry.

**Math-change rollback:**

A math-change rollback is in effect a math change in reverse — it ships a different math hash. Therefore: same workflow as §2.1 (re-certification required for the rolled-back math), unless the rolled-back math was previously certified and the certificate is still valid. In emergencies the operator can disable the game entirely (returns 503) while the rollback path is sorted.

**Emergency disable:**

`POST /api/v1/_meta/emergency-disable` requires `X-Emergency-Token` and puts the
game in a 503 state for spin, feature, and buy-bonus routes. `/health` and
`/_meta/*` continue serving so operators and regulators can verify the disable
and pull build/audit evidence. Re-enable with
`POST /api/v1/_meta/emergency-enable` after rollback or incident clearance.
Emergency disable is always preferable to keeping a potentially uncertified
game online.

---

## 7. Annual re-validation

Even with no changes, every certified jurisdiction requires a periodic re-attestation:

| Body | Cadence | Scope |
|---|---|---|
| MGA | Annual | Compliance attestation, sample audit log review |
| UKGC | Annual | RTS Annex A self-assessment + technical sample |
| AGCO | Annual | Standards 1–2 self-assessment + RG checks |
| GLI | At-renewal (typically biennial) | Full re-test of theoretical RTP per variant |

Refund Rush Studios maintains a calendar of upcoming re-validation deadlines and submits the required evidence packs at least 30 days before each.

---

## 8. Policy review

This policy is reviewed and updated at minimum annually, plus immediately after any material change to:

- The certification-scoped math layer (new feature, new RTP variant)
- The aggregator/operator integration surface
- The team structure (transition from solo to team)
- The set of jurisdictional certifications held
- Any incident that exposed a process gap

Reviews are versioned in source control. The current version supersedes all earlier drafts.

---

## 9. Contact

Operational issues, math-defense requests, certificate verification:

- Studio: Oki Studios
- Operational contact: supplied per aggregator agreement
- Public attestation endpoints: `https://<game-host>/api/v1/_meta/math-hash`, `/_meta/platform-hash`, `/_meta/build-info`

---

*This policy supersedes all earlier change-management drafts.*
