A saved procedure may need a new button identity when an old name stops matching. Making the success condition easier at the same time would change the work rather than repair it. The historical semantic-target repair contract permits a failed step's target to move while retaining its input, action and expected result.

Only the target slot may change

AssertTargetRepair restores the original target into the candidate and compares the rest exactly with the original step. Changes to action kind, input, parameter or expectation are refused. PatchTarget overlays a target onto the original step rather than constructing unrelated work. A small function expresses the change boundary.

A known role must remain fixed and a recorded inViewport requirement cannot be removed. An old definition without a role may learn one from a fresh real target. Filling an unknown field differs from weakening a known constraint. The contract therefore states which parts must survive even when the control identity itself needs relocation.

Use a fresh real reference rather than an invented selector

A model-written selector is not directly stored as the repair. ProgramTarget finds an element matching every reference field in the current observation and validates it through the driver, checking scope, sensitivity and agreement of observed and validated names. An expired reference cannot simply be accepted as an equivalent control.

The repair's stepIndex and tabId must match the failed step too. This prevents borrowing a convenient button from another step. It does not prove every business meaning automatically. Observable properties narrow an equivalent target, while the unchanged expectation still verifies the final result of the original work.

Do not hide ambiguity by increasing a wait

A later appearance of the same target can justify bounded lookupWaitMs metadata. But an ambiguous duplicate or truncated result with unchanged target properties cannot pass through a wait-only repair. The counterexample ends with PROGRAM_REPAIR_TARGET_UNCHANGED.

Two candidate meanings do not become one merely by waiting longer. The source test checks that this case stops after one model-substitute request. Timing and disambiguation solve different problems. A site change requiring a fundamentally different procedure remains outside this narrow repair contract instead of being disguised as a longer wait for the old target.

Check the same restriction at execution and persistence

The engine applies assertTargetRepair again to a callback-provided step and refuses a replacement after dispatch. A test returning a weaker expected string must fail scope validation. The execution boundary therefore checks the contract instead of relying on one repair function's good intentions.

Role-change refusal also appears at program persistence. Versioning after full original-condition verification and retaining the old definition are separate historical plugin contracts. They do not establish one transaction surviving every disk failure. Approval to execute a changed target and success of its long-term storage require their own evidence.

Distinguish retained code from current automatic integration

This design and CLI integration records belong to earlier versions including 0.1.58. The current internal gateway remains removed. Retained helpers and tests do not establish automatic repair of every current external execution. I reviewed functions, tests and history without repairing a fresh live-site control.

The linked synthetic target module experiments with resolving one current target; it is not an automatic repair model. The reusable idea is to define the replaceable slot and preserved promise before editing. I prefer a change that continues the same work precisely over a green result obtained by lowering what success requires.