Magic Vault 5×3 Draft Math Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Create an executable, measured draft-v0.1 math pack for magic-vault-5x3 with a 5×3 base game, 10 paylines, a 6+ COIN Hold & Win trigger near 1 in 80, approximately 96% total RTP and a 500× round cap.
Architecture: The canonical executable config and all calculations live in /Users/admin/kiro/backend; the documentation workspace records the GDD, Math Spec, hashes and summarized evidence without duplicating the canonical config. Reuse hold_and_win/v1 state/RNG/economic behavior, adapting only its configured layout to 5 columns × 3 rows and using base-grid COIN positions as the initial locked cells. Stop after measured Draft evidence; do not add live routing, deploy, enable flags or create a Final.
Tech Stack: Go 1.22, libs/mathengine, deterministic libs/rng, YAML math packs, Go tests, Markdown evidence.
Global Constraints
- Game ID is exactly
magic-vault-5x3; Go package/directory name ismagic_vault_5x3. - Lifecycle is
draft-v0.1,DEV ONLY,NOT FOR PRODUCTION,NOT FOR CERTIFICATION. - Base and Hold & Win grids are 5 columns × 3 rows; canonical cell index is
column*3 + row. - Base evaluation is 10 fixed paylines, left-to-right from reel 1.
- Symbols are
WILD,COIN,H1–H4,L1–L4; COIN has no line payout and WILD does not substitute for COIN. - Six or more visible COIN symbols trigger Hold & Win; those same cells become initially locked feature cells.
hold_and_win/v1economics stay fixed: 3 respins, 43,000 PPM, regular values/weights1:30,2:25,3:18,5:15,10:10,20:2, prize weightsregular:1000,mini:20@10x,minor:5@25x,major:1@100x, Grand 500×.- Target trigger is approximately 1 in 80 with acceptance band 1 in 75–85.
- Target whole-game RTP is 96.0% ±0.3 percentage points; expected feature contribution is approximately 40.56%, leaving approximately 55.44% for the base game.
- Round award must never exceed 500× and 500× must be reachable.
- Exact results, simulated estimates and design targets must be labelled separately.
- Do not modify
hold_and_win_reference, frozen vectors,libs/rng, runtime routing, API contracts, deployment files or feature flags. - Backend commits and math-workspace commits are separate; stage exact task files only.
File Map
Backend repository: /Users/admin/kiro/backend
- Create
libs/mathengine/games/magic_vault_5x3/magic-vault-5x3.yaml— canonical Draft config. - Create
libs/mathengine/games/magic_vault_5x3/pack.go— embedded config access and stable identifiers. - Create
libs/mathengine/games/magic_vault_5x3/pack_test.go— locked contract, runnable pack and COIN semantics. - Create
libs/mathengine/games/magic_vault_5x3/exact_test.go— exact base/trigger enumeration and decomposition. - Create
libs/mathengine/games/magic_vault_5x3/golden_test.go— deterministic vectors, simulation report and max-win evidence. - Create
apps/math-studio/internal/domain/packs/magic_vault_5x3.go— studio preset matching the canonical pack. - Create
apps/math-studio/internal/domain/packs/magic_vault_5x3_test.go— registration and anti-drift proof. - Modify
apps/math-studio/internal/domain/packs/pack.go— register the new game preset. - Modify
libs/mathengine/games/README.md— list Magic Vault as a Draft complete game.
Math workspace: /Users/admin/Documents/ChatGPT/math slot
- Create
games/magic-vault-5x3/README.md— game index and backend identity. - Create
games/magic-vault-5x3/gdd/magic-vault-5x3-gdd.md— player-visible rules and art mapping. - Create
games/magic-vault-5x3/math/magic-vault-5x3-math-spec.md— formal math contract and measured decomposition. - Create
games/magic-vault-5x3/changelog.md— Draft revision and tuning history. - Create
games/magic-vault-5x3/evidence/exact/draft-v0.1.md— exact base/trigger results. - Create
games/magic-vault-5x3/evidence/simulation/draft-v0.1.md— seeded statistical evidence. - Create
games/magic-vault-5x3/evidence/max-win/draft-v0.1.md— reachability and cap proof. - Create
games/magic-vault-5x3/evidence/manifest-draft-v0.1.md— hashes, commands and evidence binding. - Modify
games/README.mdand rootREADME.mdonly if they are tracked at execution time; otherwise leave them untouched and report the missing index link.
Task 1: Create the executable backend Draft pack
Files:
- Create:
/Users/admin/kiro/backend/libs/mathengine/games/magic_vault_5x3/pack.go - Create:
/Users/admin/kiro/backend/libs/mathengine/games/magic_vault_5x3/pack_test.go - Create:
/Users/admin/kiro/backend/libs/mathengine/games/magic_vault_5x3/magic-vault-5x3.yaml
Interfaces:
-
Consumes:
mathengine.MathVersionConfig, YAML schema, existinghold_and_win/v1executor. -
Produces:
magic_vault_5x3.ID,magic_vault_5x3.MechanicVersion,Config(),RawYAML(). -
Step 1: Write the failing package contract test
- Step 2: Run the test and observe RED
Run: cd /Users/admin/kiro/backend && go test ./libs/mathengine/games/magic_vault_5x3 -run TestDraftContract -count=1
Expected: FAIL because the package does not exist.
- Step 3: Add the minimal embedded-pack API
- Step 4: Add the initial canonical YAML
Use exactly these fixed sections, with reel weights and payout values clearly marked as Draft tuning inputs in comments:
Replace Strips: [] immediately in the same step with five deterministic weighted-entry strips containing only the declared symbols. This zero-payout scaffold is permitted only until Task 3 and must never be called measured Draft math.
- Step 5: Assert COIN and WILD semantics
Extend pack_test.go to verify COIN has no payout map, WILD is the only wild symbol, all H/L symbols have 3/4/5 entries, no BONUS symbol exists, and mathengine.RunRound(*cfg, "magic-vault-pack-smoke", 1) succeeds.
- Step 6: Run package tests and commit
Run: cd /Users/admin/kiro/backend && go test ./libs/mathengine/games/magic_vault_5x3 -count=1
Expected: PASS.
Commit exact files:
Task 2: Register an anti-drift Math Studio preset
Files:
- Create:
/Users/admin/kiro/backend/apps/math-studio/internal/domain/packs/magic_vault_5x3.go - Create:
/Users/admin/kiro/backend/apps/math-studio/internal/domain/packs/magic_vault_5x3_test.go - Modify:
/Users/admin/kiro/backend/apps/math-studio/internal/domain/packs/pack.go
Interfaces:
-
Consumes:
magic_vault_5x3.Config(),packs.Pack,domain.FeatureDefinition. -
Produces: registered preset name
magic_vault_5x3that builds a config canonically equal to the embedded YAML. -
Step 1: Write registration and equality tests
This compares the complete executable structs and does not introduce a second encoder or hash.
- Step 2: Run the tests and observe RED
Run: cd /Users/admin/kiro/backend && go test ./apps/math-studio/internal/domain/packs -run MagicVault -count=1
Expected: FAIL because the preset is absent.
- Step 3: Implement the preset by transcribing the canonical YAML field-for-field
Name() must return magic_vault_5x3; Description() must say DRAFT / DEV ONLY; Generate() must include the identical symbols, strips, paylines, cap and Hold & Win values. Do not read the YAML at runtime from the preset—independent construction is what makes the equality test useful.
- Step 4: Register the preset and verify
Add &MagicVault5x3Pack{} to the existing registry literal in pack.go.
Run: cd /Users/admin/kiro/backend && go test ./apps/math-studio/internal/domain/packs -run MagicVault -count=1
Expected: PASS.
- Step 5: Commit exact files
Task 3: Tune the exact base game and trigger distribution
Files:
- Create:
/Users/admin/kiro/backend/libs/mathengine/games/magic_vault_5x3/exact_test.go - Modify:
/Users/admin/kiro/backend/libs/mathengine/games/magic_vault_5x3/magic-vault-5x3.yaml - Modify:
/Users/admin/kiro/backend/apps/math-studio/internal/domain/packs/magic_vault_5x3.go
Interfaces:
-
Consumes: canonical pack,
mathengine.ExactCalculate, exact stop weights. -
Produces: exact trigger probability, exact base RTP and a measured base/feature/total decomposition.
-
Step 1: Write target-bound exact tests
Implement exactCoinTriggerProbability as an exact weighted convolution: for each reel entry,
count COIN in its three-symbol wrapped window, accumulate that count by the entry's integer weight,
then convolve the five per-reel count distributions. Divide the summed weight of totals >= 6 by
the product of all five reel-weight totals. Assert the final probability mass is 1 within 1e-12.
- Step 2: Run the exact test and observe RED
Run: cd /Users/admin/kiro/backend && go test ./libs/mathengine/games/magic_vault_5x3 -run TestExactDraftTargets -count=1 -v
Expected: FAIL because scaffold reels/payouts are untuned. ExactCalculate receives the base-only
copy because hold_and_win is stochastic and the engine correctly rejects it as non-enumerable;
the trigger is still exact through the independent integer-weight convolution above. Do not
substitute Monte Carlo and call it exact.
- Step 3: Tune only base-owned parameters
Iterate only:
- the number/placement/weight of COIN entries on each of five strips;
- weights/placement of H1–H4, L1–L4 and WILD entries;
- H/L/WILD 3/4/5 line payouts.
Do not change paylines, COIN trigger count, HAW values/weights, PPM, respins, jackpots or cap. Prefer symmetric reel weight totals and document any asymmetric COIN layout needed to reach the trigger band.
- Step 4: Re-run exact tests after every tuning candidate
Run: cd /Users/admin/kiro/backend && go test ./libs/mathengine/games/magic_vault_5x3 -run 'TestExactDraftTargets|TestDraftContract' -count=1 -v
Expected: PASS only when trigger is 1 in 75–85 and base RTP is 55.44% ±0.30pp.
- Step 5: Reconcile the studio preset
Copy the accepted reels/paytable into MagicVault5x3Pack.Generate() and run:
cd /Users/admin/kiro/backend && go test ./apps/math-studio/internal/domain/packs -run MagicVault -count=1
Expected: PASS, proving no canonical/preset drift.
- Step 6: Commit the accepted exact Draft candidate
If no candidate meets both bands, do not commit a false success. Record the closest candidates and stop at AWAITING_USER_APPROVAL — DRAFT MATH.
Task 4: Prove COIN carry-over and 5×3 mechanic parity
Files:
- Modify:
/Users/admin/kiro/backend/libs/mathengine/games/magic_vault_5x3/pack_test.go - Create:
/Users/admin/kiro/backend/libs/mathengine/games/magic_vault_5x3/golden_test.go
Interfaces:
-
Consumes:
mathengine.StartHoldAndWin,RunToCompletion, configured COIN grid. -
Produces: deterministic evidence that triggering COIN positions are the initial locked cells and that 5×3 ordering is stable.
-
Step 1: Add a deterministic six-COIN carry-over test
Build a 5×3 grid with COIN at canonical indices 0, 2, 4, 7, 11, 14, start the feature with a deterministic seed, and assert:
Also assert each initially locked cell receives exactly one prize and no empty cell receives one.
- Step 2: Add deterministic lifecycle vectors
Record at least these seeds and expected results in table-driven tests:
- exactly six trigger coins followed by ordinary zero-respin settlement;
- a step with at least one landing and respin reset;
- full-grid settlement awarding exactly 500×;
- identical seed/config producing byte-identical state and award on two executions.
Expected structs must be literals in the test, not regenerated snapshots.
- Step 3: Mutation-check orientation sensitivity
Temporarily change Columns: 5, Rows: 3 to Columns: 3, Rows: 5 in the test copy and verify at least one recorded cell-order vector fails. Revert the mutation before commit. Record this observation in a test comment.
- Step 4: Run and commit
Run: cd /Users/admin/kiro/backend && go test ./libs/mathengine/games/magic_vault_5x3 -run 'Carry|Golden|Determin' -count=1 -v
Expected: PASS after reverting the mutation.
Task 5: Produce seeded Draft simulation and max-win evidence
Files:
- Modify:
/Users/admin/kiro/backend/libs/mathengine/games/magic_vault_5x3/golden_test.go
Interfaces:
-
Consumes:
mathengine.RunBatch, accepted config and exact result from Task 3. -
Produces: reproducible aggregate statistics with uncertainty and a reachable 500× witness.
-
Step 1: Add a deterministic sharded simulation test/runner
Use a fixed master seed such as magic-vault-draft-v0.1-confirmation, 2,000,000 paid rounds and eight non-overlapping [start,end) shards. Merge with mathengine.MergeBatches; verify a single unsharded control slice matches the same index range.
The report output must include:
- Step 2: Add acceptance assertions
Assert measured total RTP lies in [0.957, 0.963], max observed does not exceed 500×, and simulated trigger/base figures are statistically compatible with the exact values. Do not require the simulation point estimate itself to equal exact base RTP.
- Step 3: Add direct feature-conditioned confirmation
Run at least 1,000,000 triggered features through canonical RunToCompletion with independent
seed magic-vault-draft-v0.1-feature-confirmation. Initial locked states must be sampled from Magic
Vault's own exact trigger distribution rather than copied from the reference harness. Report
conditional mean, SE/CI, full-grid rate and max.
Compare the result with 32.4461×, but do not force equality: that reference mean includes the
reference harness's distribution of initial locked-cell counts. If Magic Vault's measured mean
differs materially, keep all mechanic parameters fixed, recompute the required base target as
0.96 - P(trigger) × measured conditional mean, retune only the base paytable, rerun Task 3 exact
tests with the new documented target, and repeat the whole-game simulation. Record this as base
balancing, not mechanic tuning.
- Step 4: Prove max-win reachability separately
Use a deterministic full-grid state and SettleHoldAndWin to assert AwardMultiplier == 500, SettlementReason == full_grid, and every ordinary/base-plus-feature path remains capped at 500×. Label this a reachable-value proof, not an exhaustive proof unless the engine's exact max-win calculator covers the full stateful feature.
- Step 5: Run the evidence suite
Run:
Expected: PASS with emitted aggregates saved for Task 6. A Monte Carlo result is always labelled estimated.
- Step 6: Commit deterministic tests, not bulky raw dumps
Task 6: Author the two Draft documents and evidence bundle
Files:
- Create all
games/magic-vault-5x3/**files listed in the File Map.
Interfaces:
-
Consumes: exact/simulation outputs, backend Git SHA, config SHA-256, approved art mapping.
-
Produces: linked GDD, Math Spec, evidence and manifest for Draft review.
-
Step 1: Capture immutable identities
Run:
Record both full values and rng.AlgorithmID() in the manifest. Do not copy the YAML into this workspace.
- Step 2: Write the GDD
The GDD must state the 5×3/10-line rules, exact line definitions, all symbol roles, 6+ COIN trigger, carry-over positions, 3-respin loop, jackpot values, Grand replacement rule, 500× cap, art filenames and explicit exclusions. Label RTP figures as math results rather than player-facing promises.
- Step 3: Write the Math Spec
The Math Spec must separate:
-
locked rules;
-
tuned base reel weights and paytable;
-
exact base RTP and exact trigger probability;
-
estimated conditional feature mean and whole-game RTP with uncertainty;
-
formula
Total RTP = Base RTP + P(trigger) × E[HAW award | trigger]; -
payout units (line-paytable units versus total-bet feature multipliers);
-
RNG seed/draw-order contract and 5×3 canonical index;
-
cap and max-win reasoning;
-
known limitations and Draft-only status.
-
Step 4: Write evidence reports from captured output
Each report must include command, date, rounds/state-space, seeds, backend SHA, config hash, result, method boundary and unresolved drift. Never write exact beside a simulated statistic.
- Step 5: Write changelog and manifest
Changelog entry draft-v0.1 lists every tuned parameter and states that hold_and_win/v1 economic parameters did not change. Manifest links GDD, Math Spec and all three evidence reports and marks the pack NOT FOR CERTIFICATION.
- Step 6: Verify links and commit only the game folder
Run:
Resolve every relative Markdown link manually or with the repository's link checker if present.
Task 7: Register the game taxonomy without broad cleanup
Files:
- Modify:
/Users/admin/kiro/backend/libs/mathengine/games/README.md - Conditionally modify:
/Users/admin/Documents/ChatGPT/math slot/games/README.md - Conditionally modify:
/Users/admin/Documents/ChatGPT/math slot/README.md
Interfaces:
-
Consumes: completed Draft paths.
-
Produces: discoverable game entry without reclassifying the frozen reference pack.
-
Step 1: Add the backend game listing
Add one entry stating that magic_vault_5x3/ is a complete Draft game pack, owns its base math and trigger distribution, reuses hold_and_win/v1, and is not production-enabled.
- Step 2: Add workspace links only when files are tracked
Run git ls-files --error-unmatch README.md and the same for games/README.md. Modify and stage only files for which the command succeeds. If either is untracked user content, preserve it and mention the missing link in the report.
- Step 3: Commit independently in each repository
Backend:
Workspace, only if tracked index files changed:
Task 8: Run the Draft gate and hand back measured results
Files:
- Modify only evidence/manifest documents if verification discovers stale commands, SHAs or hashes.
Interfaces:
-
Consumes: all backend and workspace artifacts.
-
Produces: a clean Draft checkpoint or a factual blockers report.
-
Step 1: Verify focused backend behavior
- Step 2: Verify repository-wide invariants
Expected: all green. Confirm byte-level non-change for libs/rng, libs/mathengine/parity/vectors.go, libs/mathengine/parsheet/testdata, libs/mathengine/games/classic_fruits_3x3 and libs/mathengine/games/hold_and_win_reference across the implementation range.
- Step 3: Verify workspace integrity
Recompute backend SHA and config SHA-256 and compare them with every document.
- Step 4: Reconcile numerical results
Confirm:
-
exact trigger is within 1 in 75–85;
-
exact base RTP plus exact trigger probability times simulated conditional mean equals reported total RTP;
-
total estimate is 96.0% ±0.3pp with CI shown;
-
max is reachable at 500× and never observed/executable above 500×;
-
all changed/open parameters are recorded in the changelog;
-
no runtime/deployment/frontend file changed.
-
Step 5: Stop at the Draft approval gate
Return a compact table of target versus measured values, backend Git SHA, config SHA-256, simulation seeds/rounds/CI, changed files, verification commands and unresolved blockers. End exactly with:
Do not create Final, freeze the version, push, deploy, enable flags or claim developer-ready/certified status.