# AmbientRunAttributionScope

> Tracon documentation. Tracon is a .NET package family that adds a control
> plane on Microsoft Agent Framework, published as NuGet packages that run
> inside your own ASP.NET Core application.
>
> Page: https://tracon.dev/api/tracon.ambientrunattributionscope/
> Summary: AmbientRunAttributionScope: The ambient pass-through for attributing a run that does not run inside an HTTP request to a user and a set of labels.

<div class="api-provenance">Namespace Tracon · Assembly <code>Tracon.Abstractions.dll</code></div>

The ambient pass-through for attributing a run that does not run inside an
HTTP request to a user and a set of labels.

```csharp
public static class AmbientRunAttributionScope
```

<dl class="api-relations"><dt>Inheritance</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object">object</a> ← <a href="/api/tracon.ambientrunattributionscope/">AmbientRunAttributionScope</a></dd><dt>Inherited Members</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object.gettype">object.GetType()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.memberwiseclone">object.MemberwiseClone()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.tostring">object.ToString()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object)">object.Equals(object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object)">object.Equals(object?, object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.referenceequals">object.ReferenceEquals(object?, object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.gethashcode">object.GetHashCode()</a></dd></dl>

## Remarks

This is the exact counterpart of [AmbientTenantScope](/api/tracon.ambienttenantscope/). An
[IRunAttributionContext](/api/tracon.irunattributioncontext/) implementation is a singleton and
normally resolves the user from the current request; a queued job, a
scheduled run or a direct.NET API call has no request to resolve from. The
class carries the value through the same `Threading.AsyncLocal`
pattern `IHttpContextAccessor` uses, and the built-in
`DefaultRunAttributionContext` reads it.

An `Threading.AsyncLocal` write made inside an `async` method
does not flow back to its caller. Open the scope in the body of the method
that actually starts the run, and keep it alive across the whole run — on a
streaming path that means the scope must still be open before every
`MoveNextAsync`, not only before the first one.

Both members of a scope are held in a SINGLE slot, so
[AmbientRunAttributionScope.Begin](/api/tracon.ambientrunattributionscope/#Tracon_AmbientRunAttributionScope_Begin_System_String_System_Collections_Generic_IReadOnlyDictionary_System_String_System_String__) replaces
the user and the labels together and can never be observed half-applied.

## Properties

### <a id="Tracon_AmbientRunAttributionScope_CurrentLabels"></a> CurrentLabels

Gets the ambient labels, or [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) when no scope is open.

```csharp
public static IReadOnlyDictionary<string, string>? CurrentLabels { get; }
```

#### Property Value

 [IReadOnlyDictionary](https://learn.microsoft.com/dotnet/api/system.collections.generic.ireadonlydictionary\-2)<[string](https://learn.microsoft.com/dotnet/api/system.string), [string](https://learn.microsoft.com/dotnet/api/system.string)\>?

### <a id="Tracon_AmbientRunAttributionScope_CurrentUserId"></a> CurrentUserId

Gets the ambient user identity, or [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) when no scope is open.

```csharp
public static string? CurrentUserId { get; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)?

### <a id="Tracon_AmbientRunAttributionScope_IsActive"></a> IsActive

Gets whether a scope is open right now.

```csharp
public static bool IsActive { get; }
```

#### Property Value

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

## Methods

### <a id="Tracon_AmbientRunAttributionScope_Begin_System_String_System_Collections_Generic_IReadOnlyDictionary_System_String_System_String__"></a> Begin\(string?, IReadOnlyDictionary<string, string\>?\)

Sets the ambient attribution for the duration of the scope.

```csharp
public static IDisposable Begin(string? userId, IReadOnlyDictionary<string, string>? labels)
```

#### Parameters

`userId` [string](https://learn.microsoft.com/dotnet/api/system.string)?

The user identity, or [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) to attribute the run to no
user. Whitespace is treated as [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null).

`labels` [IReadOnlyDictionary](https://learn.microsoft.com/dotnet/api/system.collections.generic.ireadonlydictionary\-2)<[string](https://learn.microsoft.com/dotnet/api/system.string), [string](https://learn.microsoft.com/dotnet/api/system.string)\>?

The labels, or [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) when there are none.

#### Returns

 [IDisposable](https://learn.microsoft.com/dotnet/api/system.idisposable)

An object that restores the previous value when
[IDisposable.Dispose](https://learn.microsoft.com/dotnet/api/system.idisposable) is called. Nested use is safe.

#### Exceptions

 [ArgumentException](https://learn.microsoft.com/dotnet/api/system.argumentexception)

`userId` or `labels` breaks a limit on
[RunLabels](/api/tracon.runlabels/). The scope is REJECTED rather than trimmed:
silently trimming a label set turns a measurement into a false claim.
