| Skipping the "go" gate and just running | State the contract first; one confirmation, then full speed. |
| Calling a red test a "harness limitation" | Suspect a bad EXPECT first โ defeated non-token upgrades go to discard; a player's OWN defeated units go to THEIR discard; double-pip aspect cards cost +4 off-aspect. Verify before blaming the harness. |
| Running a retro after every phase | Only two retros: at the autonomousโpair-programmed handoff and at the very end. Don't retro per-phase. |
| Updating the plan but not the set tracker (or vice-versa) | Both: plan checkbox and SWUSim/docs/{set}-implement.md. |
| Spawning subagents to "go faster" | Run batches inline โ the loop is sequential by design (each batch's green regression gates the next). |
| Committing at the end | Never. The user commits manually. |
| Marking a batch done while regression is red | Green-gate every batch; 0 failed or it's not done. |
| Halting the whole run on a Hard / ambiguous card | Defer it to the backlog and keep going (Step 5). Only halt for a blocker the rest of the scope depends on, or being stuck. Surface the backlog at the checkpoints. |
| Calling a set "card-complete" with a non-empty backlog | It isn't. Report the backlog; run swusim-set-validation before any complete claim. |
| Marking a card Done on happy-path coverage | The bar is 98%, and it is a COVERAGE matrix, not a vibe. The most-missed cell is the negative โ the case proving a condition is load-bearing (the clause must NOT fire when its gate is false). Second-most-missed: the same ability reached by a DIFFERENT dispatch path (as an upgrade, as a token, relocated, deployed-vs-front) and persistence across an arena move / control change / request boundary. Run the adversarial audit before Done: re-read the printed text cold, list what an independent auditor would test, diff against your sections. See the swusim-implement-card "coverage matrix". |
| Marking a leader Done on its front side alone | A leader has two ability sets (front + deployed deployTextData); each must independently clear 98%. Verify the deployed On Attack / When Deployed / passive / deployed Action has a real handler, not just the front Action. See SWUSim/docs/leader-gaps.md. |
| Implementing a clause but getting its TARGET SET / OPTIONALITY wrong | "another X unit" (no "friendly") is enemy-legal too; "up to N" / "you may" needs a decline + heal-less (MAY-choose, not mandatory-choose); a zero-effect target must be unselectable; "can't attack/ready" must apply at SELECTION time. See the swusim-implement-card "Recurring bug shapes" block. |
| Shipping a "do-nothing / stacking / stale" bug | Name-a-card vs an EMPTY opponent hand must skip the prompt; "opponent may pay N" the opponent can't afford must auto-resolve; a self-hand discard must exclude the in-flight event (still in ZoneSearch as removed); a When-Defeated target-choose reading $self by positional mzID is STALE after cleanup; a repeatable "+X/+Y this phase" buff DE-DUPES unless each application gets a unique token; an upgrade printed "attach to a unit" is enemy-attachable. See the swusim-implement-card "More recurring bug shapes (SEC โฆ)" block. |
| Shipping an "attacker-death / token-event / cost-flag-scope" bug | A "when a friendly unit's attack ends / on-defeat / deal-excess" whose effect targets OTHER units must fire when the SOURCE unit trades/dies (move the trigger above the attacker-survival gate + capture the marker in combatCtx before expiry); a TOKEN create/attach/consume/return must fire the same observers as a real card AND a token CEASES on leaving play (never to hand); a "first/next X this phase" cost-flag must be set on ANY qualifying play (not only while controlling the card); a prevention/cap must skip UNPREVENTABLE (indirect + _SWUDamageUnpreventable) damage; a "only friendly non-leader unit" grant must re-check the subject isn't itself a leader unit; Support lends WhenAttackEnds abilities too. See the swusim-implement-card "More recurring bug shapes (ASH โฆ)" block. |
| Shipping a "request-boundary / bespoke-path" bug โ a green suite cannot see either | Any value written before an AddDecision and read by the handler behind it MUST be serialized (ride the CUSTOM Param or an SWUVar) โ an in-memory global is EMPTY in the next request, and the handler usually returns silently, so the card just disappears (JTL_094 Luke was neither rebuilt nor discarded in real games). Guard every such flow with a SimulateRequestBoundary section, and add any new transient global to simulateRequestBoundary() or it becomes untestable. Likewise, a bespoke move/attach/create path must re-do the whole ceremony: fire host reactions, CollectOnAttachedTriggers, and FlushEntryTriggerBag โ AddTrigger only BAGS a trigger; without the flush it never surfaces. See the swusim-implement-card "More recurring bug shapes (JTL re-validation โฆ)" block. |
| Shipping a "payment capacity / generated-field / single-flush-point" bug | Gate a "you may pay N" on SWUTotalPaymentCapacity() (ready resources + Credits + SEC_122 Droids), never a bare SWUResourceCount โ otherwise a player who can pay is never offered the ability. A generated Add<Zone> accessor silently stringifies any field type the generator lacks a branch for (array[string] โ the literal "Array", wiping every TurnEffect on an arena move) โ fix the GENERATOR and regenerate, and treat any Array to string conversion warning as data loss, not noise. A parked/deferred bag drained from only ONE call site strands work on every other path. |
| Shipping a "leave-play observer / control-transfer / leader-unit-status / reduced-deploy" bug | EVERY leave-play path that defeats upgrades (combat, ability-defeat, bounce, AND capture/base-capture) must fire _SWUOnUpgradeDefeated โ capture was the miss (Zeb ASH_161); taking control of a unit transfers its NON-PILOT upgrades' control (pilots keep theirs) so "friendly upgrade" logic fires for the new controller after an NGOR take-control-then-defeat; a base-prevention (Close the Shield Gate) must skip UNPREVENTABLE damage like the unit path; a card keyed off "a leader unit" must read the LIVE object via IsLeaderUnit(GetZoneObject($d['mzID'])) not printed CardType (Darksaber/pilot-made leaders โ Pellaeon ASH_093); a leader with a reduced deploy threshold (Bo-Katan ASH_010 = resources + Mandalorian units) needs its own SWUDeployLeader branch. See the swusim-implement-card "More recurring bug shapes (ASH validate-tests re-run โฆ)" block. |