···604604 const violations = commanderUncommonRule.validate(ctx);
605605 expect(violations).toHaveLength(0);
606606 });
607607+608608+ it("rejects DFC saga that transforms into creature (front face check)", async () => {
609609+ // Behold the Unspeakable has an uncommon printing and transforms into
610610+ // a legendary creature, but the FRONT face is a Saga - not legal for PDH
611611+ const behold = await cards.get("Behold the Unspeakable");
612612+ const deck = makeDeck([makeCard(behold, "commander")], "paupercommander");
613613+ const printingsMap = new Map<OracleId, Card[]>();
614614+ printingsMap.set(behold.oracle_id, [
615615+ mockPrinting(behold, "uncommon", ["paper"]),
616616+ ]);
617617+ const ctx = await makeContextWithCards(
618618+ deck,
619619+ [behold],
620620+ undefined,
621621+ printingsMap,
622622+ );
623623+ const violations = commanderUncommonRule.validate(ctx);
624624+ expect(violations).toHaveLength(1);
625625+ expect(violations[0].message).toContain("not a creature");
626626+ });
607627 });
608628609629 describe("signatureSpellRule color identity", () => {
+7-4
src/lib/deck-validation/rules/commander.ts
···77 type Violation,
88 violation,
99} from "../types";
1010-import { getOracleText, getTypeLine } from "../utils";
1010+import { getFrontFaceTypeLine, getOracleText, getTypeLine } from "../utils";
11111212/**
1313 * Commander required - at least one commander
···7474/**
7575 * Check if card has a creature type valid for commander (creature, vehicle, spacecraft with P/T).
7676 * Shared between regular Commander and PDH validation.
7777+ *
7878+ * For DFCs/MDFCs, checks the FRONT FACE only - a Saga that transforms into
7979+ * a creature (e.g., Behold the Unspeakable) is NOT a legal commander.
7780 */
7881export function hasCommanderCreatureType(card: Card): boolean {
7979- const typeLine = getTypeLine(card).toLowerCase();
8282+ const typeLine = getFrontFaceTypeLine(card).toLowerCase();
80838184 if (typeLine.includes("creature")) return true;
8285 if (typeLine.includes("vehicle")) return true;
···9093}
91949295export function isValidCommanderType(card: Card): boolean {
9393- const typeLine = getTypeLine(card).toLowerCase();
9696+ const frontTypeLine = getFrontFaceTypeLine(card).toLowerCase();
9497 const oracleText = getOracleText(card).toLowerCase();
95989696- const isLegendary = typeLine.includes("legendary");
9999+ const isLegendary = frontTypeLine.includes("legendary");
97100 const canBeCommander = oracleText.includes("can be your commander");
9810199102 // Grist-style cards: creatures in all zones except battlefield
+13
src/lib/deck-validation/utils.ts
···34343535 return "";
3636}
3737+3838+/**
3939+ * Get the front face type line only.
4040+ * For DFCs/MDFCs, commander legality is determined by the front face.
4141+ * A Saga that transforms into a creature (e.g., Behold the Unspeakable)
4242+ * is NOT a legal commander because the front face is a Saga.
4343+ */
4444+export function getFrontFaceTypeLine(card: Card): string {
4545+ if (card.card_faces && card.card_faces.length > 0) {
4646+ return card.card_faces[0].type_line ?? "";
4747+ }
4848+ return card.type_line ?? "";
4949+}