Skip to content

parser: under their control binding unparsed — permanents enter under the wrong controller (CR 110.2a) #6691

Description

@mike-theDude

Summary

crates/engine/src/parser/oracle_effect/lower.rs handles " under your control", " under their owners' control", and " under its owner's control", but " under their control" falls through a catch-all to enters_under: None.

Per CR 110.2a — "If an effect instructs a player to put an object onto the battlefield, that object enters the battlefield under that player's control unless the effect states otherwise" — the permanent should enter under the named player's control. Instead it enters under the owner's/controller's, silently inverting the card.

Affected cards (~10)

Jailbreak · Endless Whispers · Dubious Challenge · Plague Reaver · Gerrymandering · Immortal Obligation · Turtle Tracks · Occupation of Kulrath · Occupation of Llanowar · The Beamtown Bullies

Two distinct parse paths — a fix must cover BOTH

1. Player-subject path (The Beamtown Bullies)
Reaches lower_subject_predicate_ast. As of #6689 this carries an Effect::unimplemented("enters_under_their_control", …) marker, so coverage correctly reports supported: false, gap_count: 1.

2. Pure-imperative path (Jailbreak, Turtle Tracks, Endless Whispers) — still silently wrong
Reaches try_parse_put_zone_change_parts directly, where the new guard cannot see it. These still export supported: true, gap_count: 0 while inverting the controller.

Jailbreak: "Return target permanent card in an opponent's graveyard to the battlefield under their control."
Cast it on an opponent's creature card and the creature enters under your control — the opposite of what the card says, reported as fully supported.

This second path is a live wrong-game-result bug, not merely a coverage gap.

The runtime is already capable

resolve_enters_under_player routes through controller_ref_player, and crates/engine/src/game/effects/change_zone.rs has a passing test covering ControllerRef::TargetPlayer. The work is parser-side, plus wiring a target-slot carrier so the binding has a player reference to resolve against.

Implementation warning

try_parse_put_zone_change_parts is not a safe place to emit a gap effect. Its caller in crates/engine/src/parser/oracle_effect/imperative.rs matches only Effect::ChangeZone/ChangeZoneAll and returns None for anything else, so returning a gap effect there collapses the entire clause to Unimplemented { name: "put" }, destroying the surrounding parse. This was hit and backed out during #6689.

Ordering

For The Beamtown Bullies specifically, land this together with the activation blocker (companion issue) — see the warning there. Fixing that one alone inverts the card.

Pointers

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions