test(game): pin RECRUIT_CHANCE_BASE === CREW_CHANCE so the no-trait recruit path can't silently diverge (#43)
CI / build + unit + e2e (pull_request) Successful in 3m3s

This commit is contained in:
2026-10-04 21:20:27 +00:00
parent 9af7d21d93
commit 352ef31625
+5 -1
View File
@@ -5,7 +5,7 @@ import { afterAll, describe, expect, it } from 'vitest'
import { and, eq } from 'drizzle-orm'
import { openGameDb, type GameDb } from '@/lib/db/client'
import * as schema from '@/lib/db/schema'
import { ROLES, generateStartingCrew, rollCrewMember, startingCrewRng } from './crew'
import { CREW_CHANCE, ROLES, generateStartingCrew, rollCrewMember, startingCrewRng } from './crew'
import { RECRUIT_CHANCE_BASE, RECRUIT_CHANCE_TALKER, STARTING_LEVELS, XP_THRESHOLDS, type SkillName } from './crew-costs'
import { MIN_AVAILABLE } from './missions'
import { BASE_CAPACITY, BASE_LEVEL, SHIP_TYPES } from './ship-costs'
@@ -577,6 +577,10 @@ describe('resolveExploreTask (A/B against explorePlanet)', () => {
// 1. Pin the constants.
expect(RECRUIT_CHANCE_BASE).toBe(0.18)
expect(RECRUIT_CHANCE_TALKER).toBe(0.30)
// Guard the two separately-declared 0.18 constants: the no-trait recruit path passes
// RECRUIT_CHANCE_BASE explicitly while rollCrewMember's default uses CREW_CHANCE — if
// they ever diverge the no-trait outcome would silently drift from its bit-identity pin.
expect(RECRUIT_CHANCE_BASE).toBe(CREW_CHANCE)
// 2. Prove the constant is consumed by rollCrewMember: a fixed rng in [0.18, 0.30)
// (a member is found iff rng() < chance).