# Workflow.Retarget (re-base the SLA clocks)

> Re-evaluates every SLA clock's budget on the current run against the now-updated entity, so a mid-run change to the SLA terms (e.g. re-grading a ticket's severity) takes effect from the change, not from the origin. Call it after writing the new terms in a handler body.

<!-- id: workflow-retarget · area: workflow · stability: stable · html: https://osysharp.com/reference/workflow/retarget/ -->

## Summary        {#summary}
**`Workflow.Retarget()`** re-evaluates every live SLA clock on the current run — the whole-instance `Deadline`, the
current state's `Expire`, and each milestone's `Within` — against the entity as it stands *now*. Use it when a handler
body has just changed the values those budgets are computed from (a severity re-grade, a new contract), so the new,
possibly tighter, terms apply immediately. The time already accrued is kept; only the remaining budget is re-based from
the change point. It is a no-argument, fire-and-forget effect and returns nothing.

## Signature      {#signature}
```osy syntax
Workflow.Retarget();
```

## Description    {#description}
A workflow's SLA budgets are expressions over `this.Item` (`Expire = this.Item.SlaResolveWithin`, a milestone
`Within = this.Item.Foo`). They are evaluated once, when the clock is armed. If a handler later rewrites those inputs,
the armed clocks still hold the OLD budget — `Workflow.Retarget()` is how you make them reflect the new one.

For each live clock it: re-evaluates the clock's budget expression against the current `this.Item`; re-resolves the
run's [ServiceHours (SLA-accrual windows)](https://osysharp.com/reference/workflow/service-hours/) schedule (which the same handler may also have changed); keeps the SLA time accrued so
far; and re-bases the **remaining** budget from now (`remaining = newBudget − accrued`, walked through the new
schedule). If the new budget is already exhausted the clock is due immediately. A **paused** clock (the run is in a
non-accruing state) keeps its new budget and re-bases when it resumes.

`Workflow.Retarget()` is only valid inside a workflow handler body (it acts on the enclosing run). It runs on the same
transaction as the body, so the new terms and the re-based clocks commit together.

## Examples       {#examples}
Re-grade a ticket and re-base its clocks in one route body:

```osy title="escalate then retarget" test app=workflow-retarget
enum Severity { Low, High }
enum TicketState { Open, Done }

entity SlaTarget {
  [Required] Severity Severity;
  TimeSpan RespondWithin;
  security { allow read, create when IsAuthenticated; }
}

entity Ticket {
  [Required, MaxLength(120)] string Title;
  Severity Severity = Severity.Low;
  TimeSpan SlaRespondWithin;
  TicketState State = TicketState.Open;
  security { allow read, create, update when IsAuthenticated; }
}

workflow TicketFlow {
  Tracks  = Ticket.State;
  Initial = Open;
  event Bump(Severity severity);
  state Open {
    subscribe Bump(Severity severity);
    on Bump(Severity severity) {
      this.Item.Severity         = severity;
      var target = SlaTarget.Single(t => t.Severity == severity);
      this.Item.SlaRespondWithin = target.RespondWithin;
            Workflow.Retarget();                                // the new terms take effect from here, not from the origin
    }
  }
  terminal success Done { }
}
```

## See also       {#see-also}
- [ServiceHours (SLA-accrual windows)](https://osysharp.com/reference/workflow/service-hours/) — the schedule the re-based clocks walk (re-resolved on retarget)
- [Assigned / Finished (milestones)](https://osysharp.com/reference/workflow/milestone/) — the `Within` budgets that are re-evaluated
- <span class="planned" title="this page is planned and not written yet">workflow-state</span> — the state `Expire` that is re-evaluated
