"Wrong game" re-searches on the spot; resolve explains what it won't do

Eric pressed wrong-game on both rows, ran resolve, and resolve
truthfully found "nothing to match" — unmatched is a human-owned state
it refuses to touch, but the button's name promised a re-match and the
pipeline was the natural place to seek one. reopen_match now clears
the match AND re-searches immediately (merged depunct search, sibling
editions included, stats attached), returning the row as an ambiguous
ballot on the very card the button lives on; if BGG is unreachable it
reopens bare with a visible warning, and re-search/manual-id remain.
run_resolve's summary now says out loud that unmatched rows wait for
the human — it never overrides a decision, including "this is wrong."

Data: the two stranded WIZ-WAR rows re-searched into ballots — both
cards now offer all three lineages, awaiting Eric's picks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqpWSz9g
This commit is contained in:
Eric Wagoner
2026-08-05 21:53:22 -04:00
co-authored by Claude Fable 5
parent 1dd72d2688
commit 481fa63488
5 changed files with 84 additions and 7 deletions
+42
View File
@@ -605,3 +605,45 @@ def test_local_decision_keeps_a_real_game_off_bgg(tmp_path):
(row,) = read_matches(cfg.matches_path)
assert row["match_status"] == "local"
assert row["bgg_id"] == "" # a local citizen carries no BGG identity
def test_reopen_match_returns_a_fresh_ballot(tmp_path):
""" "Wrong game" must not strand the row: it re-searches immediately
and comes back ambiguous with the candidates on the card — resolve
(which never touches unmatched rows) is not part of this loop."""
cfg = _setup(
tmp_path,
[
_row(
title_raw="WIZ-WAR",
match_status="auto",
bgg_id="589",
bgg_name="Wiz-War",
)
],
)
session = ReviewSession(
cfg, console=quiet_console(), input_fn=scripted(), client=fixture_client()
)
row = session.rows[0]
session.reopen_match(row)
assert row["match_status"] == "ambiguous"
names = {c["name"] for c in json.loads(row["candidates_json"])}
assert "Wiz-War" in names
assert any("Eighth Edition" in n for n in names) # the lineages surface
# BGG unreachable: the row still reopens, bare but actionable
dead = ReviewSession(
cfg,
console=quiet_console(),
input_fn=scripted(),
client=BGGClient(
cache_dir=tmp_path / "empty",
transport=httpx.MockTransport(
lambda req: httpx.Response(401, text="Unauthorized")
),
),
)
row2 = dead.rows[0]
dead.reopen_match(row2)
assert row2["match_status"] == "unmatched"
assert dead.warnings # the degradation is visible