Pabloler21 Claude Sonnet 4.6 commited on
Commit
b8e5756
·
1 Parent(s): cadf187

feat(pacing): shorten the tester run (end_affinity 35, recall_cooldown 1, bad_min_turn 3)

Browse files
Files changed (2) hide show
  1. memory.py +2 -2
  2. tests/test_memory.py +35 -22
memory.py CHANGED
@@ -3,8 +3,8 @@ import re
3
  from schemas import TurnUpdate
4
 
5
  PACING = {
6
- "tester": {"recall_min_memories": 1, "recall_cooldown": 2,
7
- "end_affinity": 50, "end_claimed": 2, "bad_min_turn": 4},
8
  "full": {"recall_min_memories": 2, "recall_cooldown": 3,
9
  "end_affinity": 68, "end_claimed": 3, "bad_min_turn": 6},
10
  }
 
3
  from schemas import TurnUpdate
4
 
5
  PACING = {
6
+ "tester": {"recall_min_memories": 1, "recall_cooldown": 1,
7
+ "end_affinity": 35, "end_claimed": 2, "bad_min_turn": 3},
8
  "full": {"recall_min_memories": 2, "recall_cooldown": 3,
9
  "end_affinity": 68, "end_claimed": 3, "bad_min_turn": 6},
10
  }
tests/test_memory.py CHANGED
@@ -197,15 +197,15 @@ class TestShouldRecall:
197
  assert fired is True
198
  assert mem == "memory B"
199
 
200
- def test_no_recall_within_2_turns_of_last(self):
201
- state = self._state(affinity=60, turn=6, last_recall_turn=5)
202
  fired, mem = should_recall(state)
203
- assert fired is False # 6 - 5 = 1 < 2
204
 
205
- def test_recall_exactly_at_2_turns_after_last(self):
206
- state = self._state(affinity=60, turn=7, last_recall_turn=5)
207
  fired, mem = should_recall(state)
208
- assert fired is True # 7 - 5 = 2 >= 2
209
  assert mem == "has a dog named Nala"
210
 
211
  def test_no_recall_if_no_unclaimed_after_some_claimed(self):
@@ -250,6 +250,19 @@ class TestDecideEnding:
250
  def test_loop_when_tone_mildly_negative(self):
251
  assert decide_ending(_end_state(tone=-10)) == "loop"
252
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
  # --- dev seed forces a deterministic ending (HOLLOW_FAST_FINALE) ---
254
  def test_force_ending_overrides_the_tone_branch(self):
255
  # a flat-tone state would normally be "loop"; the dev force wins
@@ -264,9 +277,9 @@ class TestDecideEnding:
264
  assert decide_ending(s) == "bad"
265
 
266
  def test_bad_needs_minimum_turns(self):
267
- s = _end_state(affinity=12, claimed_count=0, tone=-60, turn=3,
268
  wounds=["w1", "w2"])
269
- assert decide_ending(s) is None
270
 
271
  def test_bad_needs_two_wounds(self):
272
  s = _end_state(affinity=12, claimed_count=0, tone=-60, turn=8,
@@ -280,8 +293,8 @@ class TestDecideEnding:
280
  assert decide_ending(s) == "bad"
281
 
282
  # --- none ---
283
- def test_none_below_50(self):
284
- assert decide_ending(_end_state(affinity=49, claimed_count=5)) is None
285
 
286
  def test_none_with_fewer_than_2_claimed(self):
287
  assert decide_ending(_end_state(affinity=95, claimed_count=1)) is None
@@ -371,14 +384,14 @@ class TestApplyUpdatePlusSignTolerance:
371
 
372
 
373
  class TestSingleGateBranchesByTone:
374
- def test_nothing_fires_below_50(self):
375
- # one gate at 50; no lower threshold can race a warm run
376
- assert decide_ending(_end_state(affinity=49, tone=5)) is None
377
- assert decide_ending(_end_state(affinity=49, tone=30)) is None
378
 
379
- def test_gate_at_50_branches_only_by_tone(self):
380
- assert decide_ending(_end_state(affinity=50, tone=20)) == "good"
381
- assert decide_ending(_end_state(affinity=50, tone=19)) == "loop"
382
 
383
 
384
  class TestHollowWordsFiltered:
@@ -441,13 +454,13 @@ def test_first_recall_fires_without_high_affinity():
441
  assert do is True and mem == "grew up near the sea" # wow by turn ~2, low bond
442
 
443
 
444
- def test_recall_still_waits_two_turns_between():
445
  from memory import should_recall
446
  state = {"affinity": 60, "treasure": ["a", "bb", "ccc"], "claimed": ["a"],
447
- "turn": 4, "last_recall_turn": 3}
448
- assert should_recall(state)[0] is False # only 1 turn since last
449
- state["turn"] = 5
450
- assert should_recall(state)[0] is True # 2 turns since last
451
 
452
 
453
  def test_good_ending_reachable_at_lower_affinity():
 
197
  assert fired is True
198
  assert mem == "memory B"
199
 
200
+ def test_no_recall_on_the_same_turn_as_last(self):
201
+ state = self._state(affinity=60, turn=5, last_recall_turn=5)
202
  fired, mem = should_recall(state)
203
+ assert fired is False # 5 - 5 = 0 < 1 (tester cooldown)
204
 
205
+ def test_recall_one_turn_after_last(self):
206
+ state = self._state(affinity=60, turn=6, last_recall_turn=5)
207
  fired, mem = should_recall(state)
208
+ assert fired is True # 6 - 5 = 1 >= 1 (tester cooldown)
209
  assert mem == "has a dog named Nala"
210
 
211
  def test_no_recall_if_no_unclaimed_after_some_claimed(self):
 
250
  def test_loop_when_tone_mildly_negative(self):
251
  assert decide_ending(_end_state(tone=-10)) == "loop"
252
 
253
+ # --- tester thresholds lowered for a short, judge-friendly run ---
254
+ def test_tester_good_fires_at_lowered_affinity_35(self):
255
+ assert decide_ending(_end_state(affinity=35, claimed_count=2,
256
+ tone=30, turn=5)) == "good"
257
+
258
+ def test_tester_good_just_below_35_does_not_fire(self):
259
+ assert decide_ending(_end_state(affinity=34, claimed_count=2,
260
+ tone=30, turn=5)) is None
261
+
262
+ def test_tester_bad_fires_at_turn_3(self):
263
+ assert decide_ending(_end_state(affinity=12, claimed_count=0, tone=-45,
264
+ turn=3, wounds=["w1", "w2"])) == "bad"
265
+
266
  # --- dev seed forces a deterministic ending (HOLLOW_FAST_FINALE) ---
267
  def test_force_ending_overrides_the_tone_branch(self):
268
  # a flat-tone state would normally be "loop"; the dev force wins
 
277
  assert decide_ending(s) == "bad"
278
 
279
  def test_bad_needs_minimum_turns(self):
280
+ s = _end_state(affinity=12, claimed_count=0, tone=-60, turn=2,
281
  wounds=["w1", "w2"])
282
+ assert decide_ending(s) is None # 2 < bad_min_turn (3)
283
 
284
  def test_bad_needs_two_wounds(self):
285
  s = _end_state(affinity=12, claimed_count=0, tone=-60, turn=8,
 
293
  assert decide_ending(s) == "bad"
294
 
295
  # --- none ---
296
+ def test_none_below_35(self):
297
+ assert decide_ending(_end_state(affinity=34, claimed_count=5)) is None
298
 
299
  def test_none_with_fewer_than_2_claimed(self):
300
  assert decide_ending(_end_state(affinity=95, claimed_count=1)) is None
 
384
 
385
 
386
  class TestSingleGateBranchesByTone:
387
+ def test_nothing_fires_below_35(self):
388
+ # one gate at 35; no lower threshold can race a warm run
389
+ assert decide_ending(_end_state(affinity=34, tone=5)) is None
390
+ assert decide_ending(_end_state(affinity=34, tone=30)) is None
391
 
392
+ def test_gate_at_35_branches_only_by_tone(self):
393
+ assert decide_ending(_end_state(affinity=35, tone=20)) == "good"
394
+ assert decide_ending(_end_state(affinity=35, tone=19)) == "loop"
395
 
396
 
397
  class TestHollowWordsFiltered:
 
454
  assert do is True and mem == "grew up near the sea" # wow by turn ~2, low bond
455
 
456
 
457
+ def test_recall_still_waits_one_turn_between():
458
  from memory import should_recall
459
  state = {"affinity": 60, "treasure": ["a", "bb", "ccc"], "claimed": ["a"],
460
+ "turn": 3, "last_recall_turn": 3}
461
+ assert should_recall(state)[0] is False # same turn as last recall
462
+ state["turn"] = 4
463
+ assert should_recall(state)[0] is True # 1 turn gap >= tester cooldown
464
 
465
 
466
  def test_good_ending_reachable_at_lower_affinity():