# UI Target Migration Guide — Object Repository targets from the export

Execution of an extracted genome whose build has UI activities gives every UI activity an Object Repository target derived from the target catalog the migration preflight wrote ([source-migration-guide.md § Migration preflight](source-migration-guide.md)). The UiPath side of each selector: [selector-translation-guide.md](selector-translation-guide.md); where each check goes: [ui-verification-guide.md](ui-verification-guide.md).

## Rules

1. **Migrate targets from the catalog before anything else.** In a migration, every UI activity of the built project receives an Object Repository (OR) target derived from the catalog. The placeholder-selector stub pattern is the fallback only when no export was resolved AND no live application is reachable; a live application is captured with the owning skill's target-capture procedure instead.
2. **Every migrated target is inferred and says so.** Its OR element description is written for the developer who heals it:
   - It starts with `INFERRED (<confidence>)` and the element's flags (fragile, parametrised, derived, `offline-unverified`), then says what the element is.
   - It names the source control with its object's name, id and line, and quotes the locator the source recorded; only enabled source steps count.
   - For every variable in the element's own selector it gives four things: the source's expression verbatim (`1|…|1|$vRowIndex.Number:toString$`), the source variable's name, how the source computes it (a loop counter from 1, a base plus the row number, each with the line that sets it), and what binds it in the rebuild (the variable or argument and the step that sets it). A rebuild variable that stands for several values the source recorded (captions, titles) lists those values, each with its line.
   - A variable of the application's scope is described once, on the screen that carries the scope ([selector-translation-guide.md](selector-translation-guide.md) rule 9), not on every element.
   - It cites no record of the run — a brief ruling, a finding or deviation number — because those mean nothing once the working folder is gone.

   The run-time semantic fallback is a separate field ([selector-translation-guide.md](selector-translation-guide.md) rules 11 and 12) and carries none of this. The first run against the real application is a healing pass; accepted fixes go into the OR element in place so every consumer inherits them. Until the live driver has confirmed a target (§ Verifying targets) it is unverified; without an application every element is labelled `offline-unverified`.
3. **Build through the owning skill.** Contract (mandatory reads, discovery commands, per-activity docs, file-tool authoring, validate per file and build per project as the skill prescribes): [execution-guide.md § 2.2](execution-guide.md). Create, link and update OR elements through the owning skill's Object Repository CLI, target-configuration and target-attachment guidance; never hand-type selectors into XAML or definition files — the documented exceptions, the no-application case and a number attribute bound to a selector variable, are in [offline-definition-workarounds-guide.md](offline-definition-workarounds-guide.md).

## Target spec

**Write the target spec per component, once**, after the migration preflight has derived the catalogs ([source-migration-guide.md § Migration preflight](source-migration-guide.md)). One agent takes the catalog entries of the component's steps (selected by the step table's source objects), collapses them to distinct identities by the framework pack's identity and normalisation rules and § Object Repository identity, derives each identity's selector by [selector-translation-guide.md](selector-translation-guide.md) and the pack's selectors guide, and adds the derived elements the component's composite patterns need (§ Composite interactions). It writes one data file, `migration/source/targets-<component>.json`, the input of registration:
- per application, its scope selector, authored once;
- per screen, its key, name, window selector and description;
- per element, its key, screen, name, acting activity type, selector (strict, with the `<nav>` path from the control's caption where there is one, or semantic only), each selector variable with the source expression it comes from, the source variable, its start value and step with their lines (or the recorded values it stands for), and what binds it in the rebuild (an argument or a workflow variable, completed by the group that authors the binding), semantic description ([selector-translation-guide.md](selector-translation-guide.md) rule 11), description (§ Rules, rule 2), flags (fragile, parametrised, derived, live-pass note) and the source controls it collapses.

UI groups take their screens' entries from the spec instead of deriving selectors. They add an entry only for a node it lacks, such as a verification target or a derived entry found while building a pattern, under the same rules and into the same file.

## UI targets — pipeline

| Step | Output |
|---|---|
| 1. Load the target spec and the built workflows | UI activities per workflow (activity id, type, display name, arguments, variables) and the spec's entries for their screens. The catalog the spec is derived from has two channels and both are targets: the controls the source recorded, and the identities it passed as arguments to a scripting wrapper (a SAP GUI scripting id, a selector fragment) — each such identity is an element of the calling step, exactly like a recorded control |
| 2. Map every UI activity to a target spec entry (or *none*) | the link table: one row per target slot — workflow file, activity id, target property (the card's screen, `Target`, `VerifyOptions.Target`), spec key |
| 3. Derive targets and collapse them to nodes | done once per component in the target spec (§ Target spec): per element the selector (source guide's selectors companion for the left side, [selector-translation-guide.md](selector-translation-guide.md) for the UiPath side), with the `<nav>` path from a caption the source recorded beside the control, semantic description, confidence; per application one scope selector (rule 9 there); one entry per identity key (§ Object Repository identity). A group derives and collapses only the entries it adds |
| 4. Find or create OR screens and elements through the owning skill's Object Repository CLI | lookup by identity key first; create only when new; one element per node, reused across workflows; the registry maps each spec key to its `referenceId` |
| 5. Link screens then elements into each workflow per the owning skill's target-attachment guidance | linked XAML, placeholder prefixes removed from linked activities |
| 6. Validate every workflow; build; pack | per-workflow report: linked count, created vs reused vs parametrised, confidence, remaining errors |

Mapping rules: every UI activity mapped once, activity ids file-unique; the step table and the target spec identify each workflow step's source processes and controls; shared widgets (search box, OK, Submit, comment box, menus) map to one control (§ Object Repository identity); literals the workflow receives as arguments (a person name, a placeholder the source rewrote at run time) become selector variables (`{{Argument}}`) bound to the workflow argument; steps the built workflow has but the source had not (optional pop-up checks, verifications) get no source control, a precise semantic description and low confidence. A **composite source step** (§ Composite interactions) maps to one invocation of the pattern's helper workflow, whose elements — the catalog's anchor control plus the derived elements the source never learned — exist once.

**One tool per run registers and links, from three files.** Steps 4 and 5 are mechanical once the target spec and the link table exist. The part that authors a workflow writes that file's link-table rows as it authors it, and completes in the spec entry the rebuild binding of each selector variable it binds. The **Object Repository registry**, one per project because each project holds its own store, maps each spec key to its `referenceId` and a fingerprint of the definition last pushed (selector, anchor, scope, activity type, name, description); only the tool writes it.
- **Who writes the tool:** the first part that registers targets writes it once, in the working folder and outside every project, taking the project as a parameter, and the brief names it. Every later part, in any project, appends spec entries and link rows and runs that tool, never a copy of its own.
- **What it does for the files it is given:** builds the definitions of their spec entries, each with its semantic description as the semantic step beside the strict one and its description composed from the spec entry's fields (§ Rules, rule 2), looks each entry up in the registry and in the store before creating it (§ Object Repository identity rule 4), creates each screen's new elements in one batch, replaces every entry whose fingerprint changed, links screens and then elements, re-applies number-attribute selector variables ([offline-definition-workarounds-guide.md § Selector variables in number attributes](offline-definition-workarounds-guide.md) step 5), and counts the references in each file against the link table.

Command order, output shapes and the CLI defects the tool works around: [offline-definition-workarounds-guide.md § Order of commands, offline](offline-definition-workarounds-guide.md).

**Linking is the last thing done to a workflow file, and it is not self-verifying.** Four mechanics decide whether step 5 of the pipeline survives; each one fails quietly:

1. **Link a part's files in one pass, once their content is final; later changes are in-place edits.** Validate the files together first: the load proves the host serves the new content (item 3). The link rows are one per target slot of every UI activity in the file, not one per "target not set" error: validate reports no missing target on an activity that runs without one (the owning skill's validate guidance). Then link every row in one run of the tool — one element-link call takes entries for several files — and validate the files together again; linking file by file costs three calls per file for the same result. Linking rewrites the workflow in place. An `Edit` keeps the links; rewriting the whole file after linking silently loses them while the run's bookkeeping still says "linked".
2. **Verify each link by re-reading the file, never by the command's result.** Batched link calls go through a command line, and a batch past the shell's length limit is truncated while the call still reports success for the part that arrived. Count the references in the file after each batch and compare with what the batch contained; size the batches by payload length rather than entry count.
3. **The authoring host caches workflow files.** A file changed on disk after the host has read it is still served from the cache, and the link then fails against the stale copy. Its signature: the link reports that the workflow cannot be loaded, while a validate of the same file reports only the ordinary "target not set" errors — and copying the file to a new path and linking that succeeds, which is the test that confirms it. Before linking a changed file, validate it: the unlinked targets' "target not set" errors prove the host is serving the new content, where a cached, already-linked copy would report none. When the host must be reset, stop only the headless Studio process that holds this project — confirm the process's name and that its command line names the project before stopping it; a process id taken from an instance listing can be stale and reused by an unrelated process.
4. **Re-registering does not update a definition.** Find-before-create reuses the element and leaves the stored selector as it was, so a regenerated definition never reaches the store unless it is pushed with the replace command (§ Object Repository identity rule 4). To know which ones moved, compare each definition with the fingerprint the registry holds and replace exactly the ones that differ.

## Object Repository identity — one element per node

Duplicate elements (same screen, same selector, different name or suffix) come from choosing the wrong unit, not from a registration accident. The failure mode is an element count an order of magnitude above the number of distinct nodes, and it has three causes that compound: keying elements by source window, source control *and* activity type; making one screen per source window; minting one element per field value. Rules that prevent it:

1. **An element is a node on a screen.** Its identity key is the tuple (screen, strict selector, fuzzy selector, anchors, selector variables), normalised (attribute order, quoting, whitespace). The same control clicked in one step and typed into in another is **one** element: the metadata `ActivityType` only tunes the generated selector, it does not fork the element — give it the acting type (Type Into over Click over None) and let every activity use it. Two definitions with one key and different names are one duplicate; reuse the first.
2. **Screens are the application's states, not the source's windows.** The scope selector is the application's, authored once ([selector-translation-guide.md](selector-translation-guide.md) rule 9). A source window is provenance: several source windows that share the scope and the controls collapse into one screen, and controls shared by every page (chrome, search, command bar, dialogs) live on one shared screen so they exist once. Screen names are unique within the application. Name screens after what the user sees (page or dialog), never after source window ids. An Object Repository application is one executable or one browser host: a runtime's own prompts (a security warning, an update prompt) are screens of the application that owns their process, not of the business application they interrupt, and a launcher and a desktop client that are different executables are two applications. The application card follows the same unit, one per application instance as the UIA package's authoring guide sets it: a `ByInstance` card attaches every window of the instance, and each target's own window selector picks the window it is searched in, so a dialog or a second window of the process is reached inside that card and a source window is never a reason for a card. A card per window of the same process also runs, and is no defect.
3. **Recurring widget roles are one parametrised element.** A prompt's acting leaf, its popup entry and its value display recur for every field with a different label and value; they are **one element each** with selector variables (`{{FieldLabel}}`, `{{Value}}`), not one element per field. Selector variables bind by name to variables or arguments in scope, so the pattern is built **once as a helper workflow** (`PickPromptValue(FieldLabel, Value)`, `ChooseListOption(FieldLabel, Value)`, `EnterSegmentedDate(FieldLabel, Date)`) that owns the variable names, the retry branch and the verify; every step invokes the helper. A source that used the pattern 150 times yields 150 invocations and three elements, not 450 elements and 150 copies of the sequence. A single activity on such an element is no pattern: it stays at its step, with a variable of the selector variable's name in that workflow, assigned where its value changes. Picks on different lists, each its own element, are built at each call site too, never in one helper that picks the list by a key: the key hides which list a step uses, and a wrong key fails only at run time.
4. **Find before create.** The owning skill's capture flow looks a screen up by its window selector and an element up by name and description before registering; a migration does the same mechanically: read the existing store (the OR CLI's screen and element listings, or the `.objects` tree) into a map keyed by identity, reuse the `referenceId` of every hit in the link, and create only new keys. A name collision with a different key gets a qualifier from the screen or role (`OK` / `OK (dialog)`); a key collision with a different name is the duplicate and is not created. One registration process at a time — two concurrent runs each create the same keys. After registration, count distinct keys against elements and delete every element whose `referenceId` no workflow references. Write back to an existing element with the OR CLI's **replace** command (keeps the `referenceId`, so workflow links survive); its **create** command on an existing element adds a duplicate and orphans the link. Command syntax: the owning skill's Object Repository guidance, routed from the UIA package guide.
5. **Report the collapse.** The migration report states elements created, reused and parametrised, and lists the helpers with the steps that invoke them; a screen count near the source's window count, or an element count near its control count, signals that steps 1–3 were skipped.

## Composite interactions — one source step, several UiPath activities

Test frameworks package multi-step interactions into one parameterised step: type-ahead pick, menu path, option list, find-row-then-act, keystrokes to the focused element. The genome substep carries the interaction contract ([genome-format-guide.md § Workflow](genome-format-guide.md)); the source guide's composite-actions table names the source actions and dictates wording; this section fixes how execution builds them. **Rule: build the pattern, never the nearest single activity.** Each naive mapping below validates, runs, and does the wrong thing: type-ahead as "type, then click the first popup entry", a custom list as a native select, a two-level menu as one click. This is the most expensive class of migration defect, because none of it shows up as an error — the project builds, the run completes, and the automation exercised nothing.

**Derived elements.** The catalog holds only the anchor control (input, menu root, table); the popup entries, menu items, option rows and matched cells the source clicked were never learned and must be derived. A derived element's selector is tag plus matched text plus semantic description — never an identifier the source did not record for it ([selector-translation-guide.md](selector-translation-guide.md) rule 13). Which attribute carries the matched text is the three-case test of [selector-translation-web-guide.md § Rule 5](selector-translation-web-guide.md) (form-ish tag → synthesised `aaname`; text leaf → `aaname` + `isleaf='1'`; container → `visibleinnertext` matched exactly); the tag is the one the node's role in the pattern implies, never a guessed `DIV` — a derived element has no recorded tag to draw on, so it is the one case where the role's implied tag is the best evidence there is (rule 14). Where the catalog does not say which node is which, the target is tag-only with the semantic description and owes a live pass (rule 13).

Before building any UI group of an extracted genome, read the per-control `actions` in the derived target catalog and the substep wording, classify every UI step against this table, and read the owning skill's control-interaction guidance for the classified controls (option lists, date inputs, tables) as it mandates. Each pattern of several activities occurring more than once is built as one helper workflow parametrised by field label and value (§ Object Repository identity rule 3); the steps invoke it. A row that builds a single activity — keystrokes, a coordinate click, set state, set versus type — is that activity at each call site, with its keys or state chosen at build time. Node roles named below (wrapper, label, form item, acting leaf, value display, popup list, popup entry) and their concrete shapes: [selector-translation-guide.md](selector-translation-guide.md) rule 16 and, on the web, [selector-translation-web-guide.md § Rule 16](selector-translation-web-guide.md).

| Pattern | Naive mapping that fails | Build | Derived elements |
|---|---|---|---|
| **Type-ahead pick** — type text, suggestion list appears, pick the entry matching a caption rule, optional confirm key | type + click "first item" (positional container element); type + Enter without checking what was accepted; **verifying on the option's text leaf**, which also exists in the still-open list and passes before anything was accepted | 1. Type the value into the field's *acting leaf* — the labelled input, never the widget wrapper — with key-event input (never set-value: the list opens only on key events). 2. Confirm as the source did (Enter) or pick: the entry is the popup's text leaf, scoped to the *popup labelled with the field*, caption as a selector variable under the source's criteria (contains / equals / nth). 3. Verify on the acting activity's `VerifyOptions` (`Appears`) against the field's **value display scoped to the field** ([ui-verification-guide.md](ui-verification-guide.md)) — the source's own verification becomes this acceptance check. The typed text is gone once the prompt accepts, so Type Into's target-less Auto/Expected-text verify does not apply to a prompt. 4. When the source itself had a fallback (Enter failed → click the entry), keep it as a Check with the click in the not-found branch; the verify still belongs on the acting activities | popup entry (scoped to the labelled popup) and value display (scoped to the field) — one pair per widget type, parametrised by field label and value, or one pair per field; low confidence until seen live, `derived from <anchor control>` |
| **Option list** — choose an item by caption rule from a list, dropdown or combo | `SelectItem` on a custom (div/li/span) widget; positional `idx` on the item; verifying on the option text | Probe the control live as the owning skill's select-item guidance prescribes (the package's element-interaction commands): read its `items`, and try a select where `items` is empty. If the control takes Select Item, use `SelectItem` with the source's caption under the source's criterion: the caption for Is Equal To, `*value*` for Contains, `value*` for Starts With, where that guidance says the control takes a pattern. If the source ignores case, read `items` and select the entry that matches; where `items` stays empty, select the caption as the application spells it and record the deviation. If the control does not take Select Item (custom lists expose `selecteditem` but not `items`), click the combobox open (the acting leaf, inside the form item pinned by its label), click the option under the *list labelled with the field*, and verify the field's displayed selection, scoped to the field. With no application to probe, a source step that selects from a combo or list box is `SelectItem` at its call site under the same rules, and a source that clicked the list open and then an entry keeps those two clicks; the first live run probes each list, and a list that does not take Select Item gets the click-to-open form, noted per list. A numeric index in the source is positional: keep it as an index on the option element and flag it | option entry (scoped to the labelled list), displayed selection; medium when the source caption is literal, low when variable-bound |
| **Segmented date entry** — source clicked a date field off-centre (its first segment) and typed the whole date | Type Into on the widget wrapper with the source's click offset; a bare-tag Check afterwards | Target the first segment by the field's label (only the first segment carries it), or scope on the form item (§ Element Scope) and type into each segment with the segment's expected text as the verify. Follow the owning skill's date-input guidance for the rendered format, `EmptyFieldMode` None and auto-advance. Verify against the widget's rendered value (a hidden "current value is …" leaf, or the segments) — never a bare `tag='DIV'` | month/day/year segments under the field's form item; medium |
| **Menu / tree path** — `A\|B\|C` from a menu root, levels revealed by hover or click | one click on the root, or on the leaf caption anywhere on the page | One click (or hover, per the live probe) per level, each re-resolving its target after the previous level rendered; levels are separate activities, never one target with the leaf text. Each revealed level is usually a *new popup of the same type*, and a label can repeat across groups of one level, so a level entry is scoped to its own popup (the newest one) or to its group header, never matched page-wide by text. The last level gets a verify (the page or dialog the leaf opens). A desktop tree or tab control that takes `SelectItem` (probed as for an option list) selects a node by its caption, not by its path: a level whose caption is unique in the control is that select, any other stays a click. Menu roots that appear in several source windows reuse one element | one element per level (text leaf under its own popup); medium for the root (mapped), low for levels |
| **Table row by content** — find the row whose cell(s) match, then click, read, type or verify in that row | store a row number and index into the table with it; assume the grid's markup without looking | Never carry a row integer. Choose the cell shape per [selector-translation-guide.md](selector-translation-guide.md) rule 8 (read one cell live: table attributes → row-anchored `TD` by `rowName`/`colName`; absent → row container pinned by exact text, cell as its descendant; key text repeated in its column → pin the row by the discriminating value). Alternatively extract the table, filter in code, then act through the pinned row. `Last` = last matching row. Multi-criteria finds and-combine the cell matches. Source "popup rendered as table" (suggestion popups) is an option pick, not a table op | matched cell (anchor), target cell in the same row; medium |
| **Table cell** — act on the cell at (row rule, column caption or number) | absolute `tableRow`/`tableCol` | Column by header caption (`colName='{caption}*'` when exposed, else decided by the live pass, which can anchor the cell to its header), row by content rule from the preceding find; a literal row number in the source is positional and stays flagged; double-click and follow-up keystroke preserved. A prompt inside a cell (typed value + Enter) is a type-ahead pick inside the cell | header cell, target cell; medium |
| **Read cell / row count / control text** | Get Text on the table element | Get Text or Get Attribute on the row-anchored cell after previewing what it extracts (owning skill's get-text guidance); row count via table extraction or a rows attribute, verified live | as table cell |
| **Keystrokes** — keys sent to the window or the focused element | Keyboard Shortcuts to the browser window / page body; a Delay | Determine the target from the preceding step: the keys go to that element (Type Into text with special-key tokens when they follow typing; Keyboard Shortcuts targeted at the element otherwise). One Keyboard Shortcuts activity per chord the source sent (two chords are two activities, not one); a source bring-to-front before the keys is `ActivateBefore` on the keystroke activity, not a separate window activity; a click on the same element is the fallback when the source had one. Page scrolling keys are dropped (UiPath scrolls the target into view). A browser refresh becomes the browser navigation activity. Invented shortcuts are forbidden; only keys the source actually sent | none; the target is the preceding step's element |
| **Coordinate click** — click at pointer position or screen x/y | Click with an offset on the page | Identify the intended element from surrounding steps (dismiss a popup, focus the page, an unmapped button) and target it; semantic description; flag `*[Inferred]*` in the report | derived element; low |
| **Set state** — ensure checkbox/radio state | Click | Check/Uncheck with the state (idempotent); radio click plus verify selected | none |
| **Input-method hint** — source switched to key-event input for the fields that follow | ignored | Carry into the affected activities' input mode (key events / hardware, per the owning skill's input-methods guidance); the type-ahead pattern needs it | none |
| **Set versus type** — the source either set a field's value (its previous content replaced, no key events) or typed key by key after the current content (optionally with a delay between keys) | one Type Into default for both | Setting → the field is emptied first and the value entered; key events only where the page reacts to keys (a type-ahead, an input mask). Typing → key events, the field **not** emptied, the source's delay between keys kept. The source guide's step vocabulary says which source call is which | none |

Every derived element is named `derived from <anchor control> — <pattern>` in its description, labelled `INFERRED (low)` unless the table says medium, and listed in the report under the healing-pass note as the first targets to verify live. The description names which attributes came from the source control; if it has to say an attribute was "taken from" another control, that attribute does not belong in the selector. Source match criteria carry over unchanged ([selector-translation-guide.md](selector-translation-guide.md) rule 2); confidence tiers and targeting method (strict selectors, a caption reached by a `<nav>` path, anchors only from a live capture, the semantic fallback always added) are rule 12 there, the semantic description rule 11 — a derived element with no control of its own stays **low**. The first live run must exercise every type-ahead and menu-path step; a step that "passes" by clicking the wrong entry is the failure mode this section prevents, so the verify sub-step of each pattern is mandatory, not optional.

**Actions without a control** map to target-less activities, not to invented elements: opening a browser at a URL or starting an executable is a Start Process (with the executable, its arguments and working directory) followed by an application card that *attaches* to the resulting window through the Object Repository screen for the reads and closes that follow — offline, a card's launch URL or file path cannot be written into a definition ([offline-definition-workarounds-guide.md](offline-definition-workarounds-guide.md)), and the live pass may move the open into the card; a forced close of a process is Kill Process; maximise, activate or close of a window is a Window Operations activity inside a card attached to a window-level screen (a screen with no elements); a desktop screenshot on error is Take Screenshot with no target; "the dialog appears within N seconds" is the first activity that targets the dialog, with N as its timeout, and a Check App State on the dialog's captured button or on the window-level screen only where the source branched on the dialog or no later step acts on it ([ui-verification-guide.md](ui-verification-guide.md)). Every one of these still carries its window-level scope from the catalog.

With no reachable application the owning skill's CLI cannot produce a first definition; shapes and the seed-and-mutate procedure for that case: [offline-definition-workarounds-guide.md](offline-definition-workarounds-guide.md).

## Element Scope — attach once, keep the children local

Element Scope (`NElementScope`, Version V5, body an `ActivityAction<Object>` named `ContextTarget`; shape from the owning skill's `activities get-default-xaml`) attaches to one element; every activity inside resolves its target relative to it. Its target is a `TargetAnchorable` like any other; children's targets carry **no** scope selector of their own. This is the activity-level form of [selector-translation-guide.md](selector-translation-guide.md) rule 14 step 2, and the right shape exactly when the acting leaves have no name of their own:

| Situation | Scope target | Children |
|---|---|---|
| Segmented input — a date's month/day/year, a phone's parts — only the first segment carries the field label | form item pinned by the label (`<webctrl tag='LI' visibleinnertext='{Label}*' />`) or widget wrapper *with a per-instance id* | segment inputs by their own segment identifier (e.g. `<webctrl tag='INPUT' data-automation-id='dateSectionDay-input' />` and siblings) |
| Div-based combobox or custom control labelled only by `aria-labelledby` | labelled form item | `<webctrl aria-role='combobox' />`, then the value display for the verify |
| Several actions on one row of a repeated structure (table row, card, inbox item) | row pinned by its key text (`<webctrl tag='TR' visibleinnertext='*{key}*' />`, or `rowName`) | cell, button or link by its column or caption |
| Dialog or panel repeating the page's controls (an OK button in a popup over a page that has one) | dialog container | local `OK` |

Do not reach for a scope when the leaf is already named by its label — `<webctrl tag='INPUT' aaname='Location' />` is unique on its own and a scope around it adds one more thing to heal. Never scope on the component-type wrapper shared by every instance, and never on a wrapper pinned by its inner text (that text is the field's current value). The scope element is one Object Repository element like any other; its children are elements of the same screen with local selectors.

## Verifying targets — one element per family against the live driver

A migration's targets are generated from rules, so a wrong rule is wrong hundreds of times. Verify the *rule*, on one live instance per interaction family, before the family is written back.

**Which of three situations the run is in decides what a verdict can say.** The application the automation will drive is usually *not* reachable from the machine doing the migration — that is the normal case, not a failure, and the run completes without it:

| Situation | What a verdict settles | Label |
|---|---|---|
| The target application itself is reachable | everything: shape, the instance's captions, uniqueness on the real screens | `verified` |
| A **comparable instance** is reachable — another tenant, environment or version of the same product | the *shape* only: which node the driver acts on, which attribute carries the label and which the value, the role identifiers a component framework emits, whether a grid is real table markup, whether a control exposes `items`. These are properties of the product, so they transfer; the target instance's own captions, data, page layout and version drift do not | `shape-verified`, and the report says which instance settled it |
| Nothing is reachable | shape only as far as a definition can be read back on its own (§ below) | `offline-unverified` |

A comparable instance is a **windfall, not a step**: take it when the user has one, and never make the run depend on it. To use it, copy the definition to a scratch file, substitute the selector variables with values present on that screen and the scope with that instance's, and run the validator against the copy — the project's own definitions and scope are never pointed at the other instance. A shape confirmed this way is still owed the healing pass on the real application; what it buys is that the *translation* is no longer the suspect when a target fails there.

Capabilities used below (driver default, attribute listing, selector evaluator, snapshot reload) and what each settles: [selector-translation-guide.md](selector-translation-guide.md) rule 15; their syntax is the UIA package's, routed from its guide. Procedure, for whichever instance is reachable:

1. **Capture the screen** that holds the family (a snapshot of the window), with the widget in the state the step needs (list open, value accepted).
2. **Ask the driver for its own shape**: the driver default for the acting node with the family's activity type. Compare tag and attributes with the derived selector, and the driver's anchor, when it has one, with the caption a derived `<nav>` path starts from; a derivation that disagrees with the driver on which node is acted on is wrong, not "different".
3. **Read the acting node's attribute listing** and strike every attribute the derived selector names that the node does not carry. Read the label's, the value display's and the popup entry's listings the same way (rule 16).
4. **Evaluate uniqueness** (the selector evaluator, one ref per tag) for the derived selector and for the fixed one — with the popup open for a pick, after the pick for the value display, so the shared-text trap shows. A selector with a `<nav>` path goes to target validation instead, and its screenshot shows the node the path landed on.
5. **Probe capability where the pattern depends on it**: the control's `items` for a list (Select Item or open-and-click), one grid cell's attribute listing for `tableRow`/`colName`/`rowName` (table attributes or text-pinned rows).
6. **Fix the rule, regenerate the family, write back** with the OR CLI's replace command (keeps the `referenceId`, so the workflow links survive), then re-run steps 2–4 on a second instance of the family.
7. **Record per family**: the driver's default, the shipped shape, the collisions found, and which of the three labels above the family carries and why. A UI migration is not reported done before a verdict exists per family — `offline-unverified` is a verdict, an unstated one is not.

Families to walk for a typical form-driven application: window scope; labelled text input; prompt / type-ahead (leaf, popup entry, value display); custom list (combobox, option, displayed selection); checkbox / radio; segmented date; command button and icon button; menu root and revealed level; grid header and cell; search box and result link; dialog close and error banner. Expect to reach only some of them: a family needs a page that shows it in the state the step needs, and reaching such a page read-only is the binding constraint, not the probing. A family left unexercised is recorded as such, and a *partly* exercised one says which part — an editable grid cell whose row and column matched but whose input was never reached is not the same as a cell that was never seen. Drive read-only: open pages, open menus and lists, type into a field to make a popup appear, and cancel out; never submit, save or confirm.

Stale refs are normal — every capture re-mints them, a driver-default call can invalidate the refs of the capture it read from, and a click that re-renders a widget (a search box or prompt moving into a popup) invalidates its refs too; re-capture rather than retry.

Application not reachable: read the definitions back against [selector-translation-guide.md § Checking a definition](selector-translation-guide.md) and the offline guide's own checks, fix what fails, and label every element `offline-unverified`. A structural pass proves shape, not that anything matches the screen.

## Anti-patterns

1. Shipping placeholder targets when the Source Map names a reachable export (rule 1).
2. Hand-typing selectors into XAML or definition files; the OR CLI and the derivation rules are the only path (rule 3).
3. Declaring a target "done" without confidence label and healing-pass note (rule 2), or reporting migrated definitions done without a per-family verdict (§ Verifying targets).
4. Mapping a composite source step to the nearest single activity — type-ahead as type + click-first-entry, a list that offers no `items` (a div, li or span popup) as `SelectItem`, menu path as one click, found row as a stored row number — or building a type-ahead or option pick without the verify sub-step; a wrong entry accepted silently is the costliest migration failure (§ Composite interactions).
5. Sending keystrokes to the window instead of the focused element, or keeping the source's page-scrolling keys (§ Composite interactions, keystrokes row).
6. Typing a whole date into a segmented widget's wrapper with the source's click offset, or scoping around a leaf its label already names (§ Element Scope).
7. Registering one element per source step, source window or activity type, one screen per source window, or one element per field value — and copying a composite pattern's activities into every step instead of one helper workflow (§ Object Repository identity).
8. Rewriting a linked workflow wholesale instead of editing it in place, or treating a link command's success as proof that the links landed (§ UI targets); re-registering a changed definition with the create command and assuming the store now holds it (§ Object Repository identity rule 4).
9. Treating a reachable application as a precondition — a run finishes with `offline-unverified` verdicts — or reporting a shape confirmed on a comparable instance as if the target application had confirmed it (§ Verifying targets).
10. Selector-shape mistakes — borrowed identifier on a derived element, fuzzy selector with no anchor, an anchor authored without a live capture, a positional caption written onto the control, inherited inner text matched on a broad tag, tightened or loosened source criteria, widget wrapper and leaf flattened into one tag, scope derived per screen, grid markup assumed from the application's name — are prohibited where the rule lives: [selector-translation-guide.md](selector-translation-guide.md) rules 2, 5, 6, 8, 9, 12, 13, 14. Copying passwords or dropping account identity: [genome-format-guide.md § Platform Dependencies](genome-format-guide.md). Letting a seed definition's fields survive into offline-built elements: [offline-definition-workarounds-guide.md](offline-definition-workarounds-guide.md).
11. Registering and linking from what each part retypes and scripts for itself: a spec of its own targets, a definition generator, a link script, ids resolved from other parts' scratch folders. Linking file by file with a validate before and after each one. The run has one target spec per component, one registry per project, one link table and one target tool (§ Target spec, § UI targets).
