← all tickets

41 — Replace the remaining no-window choice approximations (Spin Doctor, Sprint)

Status: fixed

What to fix: Ticket 39 built the decision plumbing for "which card(s) does the player pick" (five kinds: carnivore_trash, longevity_trash, longevity_recur, hansei_trash, anoetic_trash — see rust/netrunner-core/src/legal.rs::hq_trash_options and the resolvers in engine.rs). Two System Gateway cards were left out of scope there and still auto-resolve a corp choice:

1. Spin Doctor (30053) — "Remove this asset from the game: Shuffle up to 2 cards from Archives into R&D." spin_doctor_use (rust/netrunner-core/src/cards/sg.rs, ~sg.rs:1488) drains the first 2 faceup Archives cards. Which cards (and how many, "up to 2") is the corp's choice. DecisionData::LongevityRecur is the same shape — a shared "recur up to N from Archives" decision may fall out naturally, and would let both cards drop their bespoke handling.

2. Sprint (30041) — "Draw 3 cards, then shuffle 1 card from HQ into R&D." sprint (~sg.rs:1258) takes hq.remove(0) *and puts it in Archives facedown instead of R&D* — so this is two bugs: the missing choice, and the wrong destination zone. The card returns a card to R&D (and shuffles); it does not trash it.

Definition of done:

Comments

2026-08-01: Filed from ticket 39, which fixed the same shape of approximation for Carnivore, Longevity Serum, Hansei Review and Anoetic Void and left these two as the follow-up. Sprint's wrong destination zone was noticed while writing this ticket — it is not a ticket-39 regression.

2026-08-02: Done. The shared decision did fall out: ticket 39's longevity_recur is now archives_recur, carrying a RecurSource (Longevity Serum / Spin Doctor) that names the log lines, picks the R&D shuffle's rng stream, and drives the client prompt's "up to N" — Spin Doctor's bespoke drain is gone and both cards go through engine::archives_recur. Spin Doctor now pays its cost first (removed from the game up front), offers facedown Archives cards too, honours "up to 2" via done_archives_recur, and shuffles R&D once and only if something moved; the click-ability-window approximation note stays. Sprint gets a new sprint_return decision over HQ (legal.rs::hq_card_options, renamed from hq_trash_options since Sprint is not a trash) and the chosen card is now shuffled into R&D instead of binned facedown in Archives. Corp AI takes every archives_recur card as before, and falls through to the first HQ card for sprint_return (the old auto-behavior). Client prompts for sprint_return / archives_recur in static/game.js off a new pending_archives_recur view field, and server/serialize.py hides the named HQ card in Sprint's new log line from the runner. Tests: Sprint returns a chosen freshly-drawn card and asks nothing with an empty HQ; Spin Doctor recurs a chosen faceup + facedown pair, and separately stops early after one card / asks nothing with an empty Archives.