# PLO same-nut-straight freeroll casebook

This evidence bundle supports the GTO Gecko article **“PLO Freeroll: When the Same Nut Straight Is Not a Chop.”** It publishes the fixed physical cards, rules profile, exhaustive completion-level outcomes, primary JavaScript generator, separate Python reimplementation, chart source, and file hashes behind every displayed result.

## Question and strict definition

When two players hold the same current nut straight in heads-up four-card Pot-Limit Omaha high, does Hero have a **true final-board freeroll**, merely a redraw, or no live way to scoop?

This casebook uses a falsifiable three-part definition. A true final-board freeroll requires:

1. both players' best legal hands to tie with the current nut straight;
2. at least one legal final-board completion on which Hero wins outright; and
3. zero legal final-board completions on which Hero loses.

A locked chop fails the second condition. A dominated redraw or a redraw facing a full-house counter-redraw fails the third. The definition describes the declared fixed-card showdown model; poker writing can use “freeroll” more loosely.

## Rules profile

- Heads-up four-card PLO high.
- Standard 52-card deck with ranks 2 through ace.
- Each player receives four private cards.
- Every final hand uses **exactly two hole cards and exactly three board cards**.
- Standard high-poker category order is used, with a straight flush highest, then four of a kind, full house, flush, straight, three of a kind, two pair, one pair, and high card.
- A-2-3-4-5 is the lowest straight. Straights otherwise compare by their highest card.
- Identical best five-card scores split the pot equally.
- All fixed cards are known and collision-free. No jokers or wild cards are present.
- Future betting is excluded. Every legal physical-card completion is treated as equally likely.

The primary rules source is the current [PokerStars Omaha rules page](https://www.pokerstars.com/poker/games/omaha/), accessed 2026-09-04. It states the four-card Omaha deal, exactly-two-plus-exactly-three construction, standard 52-card deck, and split of identical hands.

## Exact inputs and results

Card tokens use rank followed by suit: `T` is ten, and `c`, `d`, `h`, and `s` are clubs, diamonds, hearts, and spades.

| Case ID | Starting board | Hero | Villain | Completions | Hero W / T / L | Hero equity | Strict result |
| --- | --- | --- | --- | ---: | ---: | ---: | --- |
| `locked-chop` | `9s 8s 7d 2c` | `Jh Th Ac Kd` | `Jd Td 3c 4c` | 40 rivers | 0 / 40 / 0 | 50% | false |
| `nut-flush-freeroll` | `9s 8s 7d 2c` | `Jh Th As Ks` | `Jd Td 3c 4c` | 40 rivers | 9 / 31 / 0 | 61.25% | true |
| `higher-straight-freeroll` | `Ts 8s 7d 2c` | `Qh 9h Jc 3d` | `Jd 9d 4c 5c` | 40 rivers | 4 / 36 / 0 | 55% | true |
| `dominated-flush-redraw` | `9s 8s 7d 2c` | `Jh Th 5s 3s` | `Jd Td As Ks` | 40 rivers | 0 / 33 / 7 | 41.25% | false |
| `pair-counter-redraw` | `9s 8s 7d 2c` | `Jh Th As Ks` | `Jd Td 2d 2h` | 40 rivers | 7 / 23 / 10 | 46.25% | false |
| `pokerstars-flop-example` | `9h 8d 7d` | `Ac As Jd Tc` | `Kd Qd Jh Th` | 820 final boards | 28 / 377 / 415 | 26.402439024390244% | false |

Every starting state is a tie with a jack-high straight, and the board-level nut-straight ceiling is `11` in every row. Each starting board is unpaired and contains at most two cards of one suit, so no full house, quads, flush, or straight flush is available; the nut straight is also the current overall nuts in these six states. The strict flag is `true` only for the nut-flush and higher-straight redraw cases.

The last row reproduces the fixed cards in PokerStars Learn's current [“Six Common PLO Mistakes”](https://www.pokerstars.com/poker/learn/strategies/plo-six-common-mistakes/) article, published 2026-06-24 and accessed 2026-09-04. PokerStars reports 34 Hero wins, 460 ties, and 506 Villain wins per 1,000 trials. Scaling this exact 28/377/415 partition from 820 boards to 1,000 gives 34.146/459.756/506.098, which rounds to the displayed 34/460/506. That agreement is an external check; the source's use of “freeroll situation” is broader than this bundle's zero-loss definition.

## Exhaustive method

For each case, the JavaScript generator performs these steps:

1. Parse the declared physical cards and reject invalid tokens or collisions.
2. Evaluate the starting state by trying all `C(4,2) = 6` hole-card pairs and every three-card subset of the current board.
3. Require the two best scores to tie, require their category to be straight, and require the straight high card to equal the board-level nut-straight ceiling.
4. Remove every known card from the 52-card deck.
5. Enumerate every legal final-board completion from the remaining physical cards.
6. Evaluate both final hands with the exact-two-plus-exactly-three rule and classify Hero's result as win, tie, or loss.
7. Compute `equityPct = (wins + ties / 2) / legalCompletions × 100`.
8. Set `trueFreeroll = wins > 0 && losses === 0`.

For each turn case, four board cards plus eight hole cards are known, so 40 river cards remain. The five turn cases therefore contribute `5 × 40 = 200` completion rows.

For the flop case, three board cards plus eight hole cards are known, leaving 41 cards. With no betting or decisions between the turn and river, only the final five-card board matters. Each unordered pair has the same probability, so the sample space is `C(41,2) = 820`, not 1,640. Adding both street orders would duplicate every final-board result once. The complete public CSV therefore contains **1,020 data rows**.

This is exact enumeration, not Monte Carlo sampling. It has no random seed, sampling interval, solver range, population model, or convergence claim.

## Independent verification

`plo-freeroll-verifier.py` is a separate Python standard-library reimplementation. It does not import the JavaScript evaluator. It separately parses cards, ranks five-card hands, searches every legal Omaha construction, recomputes the board-level nut straight, enumerates all completions, and reconciles the result fields in the CSV and summary. Because its checks use Python assertions, it fails closed and refuses optimized (`-O`) execution, where Python would remove them.

The frozen full run in `verification-report.json` has status `pass` and records:

- 6 cases;
- 1,020 reconciled completion rows; and
- 8,263 checks.
- Python optimization flag `0` (assertion checks enabled).

Those checks comprise nine five-card evaluator fixtures, three bundle-shape checks, fourteen case-level checks per case, seven checks for every completion, and one final one-to-one CSV reconciliation. Agreement between two implementations supports the declared model. It is not peer review, a proof that every poker evaluator is correct, or certification of arbitrary product software.

## Data dictionary

### `cases.json`

| Field | Meaning |
| --- | --- |
| `schemaVersion` | Public input schema version. |
| `game`, `street`, `deck`, `board` | Bundle-wide defaults. A case can override `street` or `board`. |
| `definition` | Operational strict-freeroll test. |
| `cases[].id` | Stable machine identifier used in every artifact. |
| `cases[].label` | Human-readable profile name. |
| `cases[].hero`, `cases[].villain` | Four fixed hole-card tokens for each player. |
| `cases[].question` | Diagnostic question the case isolates. |
| `cases[].expected` | Frozen win, tie, loss, equity, and strict-result assertions. Generation fails on drift. |

### `summary.json`

| Field | Meaning |
| --- | --- |
| `question`, `method`, `assumptions` | Public model definition and exclusions. |
| `cases[].currentCategory` | Best starting-hand category for both tied players. |
| `cases[].currentScore` | Comparable starting score; `[4, 11]` is a jack-high straight. |
| `cases[].nutStraightHigh` | Highest straight rank possible from the starting board under the Omaha construction rule. |
| `cases[].startingStreet`, `cardsToCome` | Whether one river or an unordered turn-river pair is enumerated. |
| `cases[].legalCompletions` | Complete size of the case's final-board sample space. |
| `cases[].wins`, `ties`, `losses` | Mutually exclusive Hero outcome counts that partition the sample space. |
| `cases[].equityPct` | Hero's split-pot showdown equity percentage. |
| `cases[].trueFreeroll` | `true` exactly when Hero has at least one win and zero losses. |

### `final-board-outcomes.csv`

| Column | Meaning |
| --- | --- |
| `case_id` | Stable case identifier. |
| `starting_street` | `turn` or `flop`. |
| `completion` | One or two machine card tokens, in canonical deck/combination order. |
| `completion_display` | The same cards with rank and suit glyphs for audit convenience. |
| `hero_outcome` | `win`, `tie`, or `loss`. |
| `hero_category`, `villain_category` | Final best-hand category names. |
| `hero_best_five`, `villain_best_five` | One maximizing legal two-hole/three-board construction selected by the evaluator. Another equally scoring five-card construction can exist. |

### Other files

- `plo-freeroll-generator.mjs` — primary exhaustive generator and JavaScript evaluator.
- `plo-freeroll-verifier.py` — separate Python evaluator and full verifier.
- `verification-report.json` — environment and result of the frozen independent run.
- `MANIFEST.sha256` — SHA-256 identities for this README, the frozen inputs and outputs, both implementations, the SVG, and its deterministic chart generator.
- `scripts/generate-plo-freeroll-chart.mjs` — repository-local SVG generator that reads only `summary.json`.
- `public/images/blog_images/plo-freeroll-completion-outcomes.svg` — accessible visual summary; the article's HTML table and figure caption provide the text equivalent.

## Reproduce

Run these commands from the repository root, in this order:

```bash
node public/data/plo-freeroll/plo-freeroll-generator.mjs
node scripts/generate-plo-freeroll-chart.mjs
python public/data/plo-freeroll/plo-freeroll-verifier.py --report public/data/plo-freeroll/verification-report.json
node scripts/generate-plo-freeroll-manifest.mjs
node --test tests/plo-freeroll-data.test.mjs tests/plo-freeroll-article.test.mjs
```

The generator and chart script use Node.js built-ins. The verifier uses only the Python standard library. The frozen report was produced with Python 3.11.9 on Windows; elapsed time is hardware-dependent. Generate the manifest last because it hashes the other public evidence files and chart source. The repository attributes and generators fix the evidence text to LF line endings so byte-level hashes remain stable across supported checkouts.

## Interpretation boundaries and limitations

- These are six fixed-card diagnostic examples, not a representative sample of played PLO hands and not an estimate of how often freerolls occur.
- The results are showdown equities, not action expected values. They do not select check, bet, call, raise, or fold.
- No ranges, position, action history, pot size, stack-to-pot ratio, future betting, fold equity, rake, or opponent behavior is modeled.
- The five turn cases expose one-card completion mechanisms. The flop case collapses street order only because no intermediate decision or path-dependent quantity is modeled.
- The model is heads-up. Additional players change blockers, pot shares, and available completions.
- The model is four-card PLO high. It does not cover PLO5, PLO6, Omaha Hi/Lo, Short Deck Omaha, wild cards, or nonstandard ranking rules.
- The board-level nut-straight test asks for the highest straight possible from that board. It does not claim that a straight is the overall nuts when a flush, full house, or stronger category is already possible.
- A best-five field records one maximizing construction. Tied alternative constructions are not exhaustively listed.
- Exact enumeration removes sampling error inside the declared model; it does not remove input, implementation, terminology, or real-world strategy uncertainty.

## Current product context and sources

GTO Solutions AS publishes GTO Gecko and PLO Gecko. The [PLO Gecko US App Store listing](https://apps.apple.com/us/app/plo-gecko-omaha-poker-trainer/id6756220388) and [Google Play listing](https://play.google.com/store/apps/details?id=com.ploedge.pokertrainer), both accessed 2026-09-04, describe PLO4 and PLO5 study and training. This bundle did not install or test either app binary, is not generated from product output, and does not establish that either app contains these six exact states. Product behavior, availability, access, and listing language can change; recheck the official store surface before reusing a product claim.

Topic and rules sources, all accessed 2026-09-04:

- PokerStars, [How to Play Omaha Poker](https://www.pokerstars.com/poker/games/omaha/) — rules profile used here.
- PokerStars Learn, [Six Common PLO Mistakes](https://www.pokerstars.com/poker/learn/strategies/plo-six-common-mistakes/) — fixed-card external comparison.
- PLO Gecko, [US App Store](https://apps.apple.com/us/app/plo-gecko-omaha-poker-trainer/id6756220388) and [Google Play](https://play.google.com/store/apps/details?id=com.ploedge.pokertrainer) — narrow, dated product context only.
