`SetMapToCurrentZone()` answers out of the `(continent, zone)` pair
`feed_world_map` pushes into the VM, because the VM cannot query the
world — the reference's resolver `0x4a6650` reads the player's area
live. That makes the schedule part of the verb's contract, and only
half of it was declared: the feed ordered `.after(UiInput)` and
nothing else, so it ran before `terrain_stream::update_current_area`
wrote the area under the player and published the previous frame's
zone.
At a crossing the feed therefore named the zone just left, `area`'s
`feed_zone_events` fired `ZONE_CHANGED_NEW_AREA` on the new one, and
both addons that answer it while the map is closed reselected where
the map already was. From grom's 03:57 log at the Ironforge gate:
`ZONE_CHANGED_NEW_AREA 10/10 handler(s) · MINIMAP_ZONE_CHANGED 8/8
handler(s) · the UI asked to follow the player 3× · WorldMapFrame
shown=Some(false)` — every handler reached, the verb called three
times, the selection unmoved. Every map-derived overlay then sits a
zone behind, `GetPlayerMapPosition` and so pfQuest's minimap pins
included, until the player opens the world map by hand (pfQuest
reselects on close), which is the workaround he reported.
Ordered after `AreaAuthoritySet`, whose own doc already required it of
every consumer of the area, and pinned by a schedule test over the
declared graph: remove the edge and it fails naming both systems.
The watchdog's zero-ask arm said "nothing has called
`SetMapToCurrentZone()` since the player crossed" through all of this.
The count was right and the window was not: it starts where this feed
first publishes the new zone, which the stale feed made *later* than
the addons' answer, so three real calls read as none. That one wrong
fork cost two sessions; the wording now names the window it measures.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SgstFWtn1RxEJ5kVrpgYwn