IRunAttributionContext
AgentPrism.Abstractions.dllResolves who a run belongs to and what work it was made for.
public interface IRunAttributionContextRemarks
Section titled “Remarks”This is the sibling of ITenantContext. The tenant answers “whose data is this”; this interface answers “which user spent this” and “which job was it spent on”. Both questions are needed to break a cost report down further than the tenant.
The user identity is never read from the request body.
A userId field on POST /api/agents/{name}/run would let any
client write spend against another user’s name, which forges the cost
record outright. The consumer binds this interface to its own identity
pipeline — a claim, an API key, a resolved principal.
The interface is registered with TryAdd and the built-in
implementation returns null for both members unless
AmbientRunAttributionScope is active, so an application that
registers nothing keeps its current behaviour exactly: the columns stay
NULL and nothing else changes.
The implementation must be a singleton, for the same
reason as ITenantContext: singleton services take a
dependency on it, and a scoped registration would be a captive dependency.
Resolve per-request state through IHttpContextAccessor.
Properties
Section titled “Properties”Labels
Section titled “ Labels”Gets the labels of the current run, or null when there are none.
IReadOnlyDictionary<string, string>? Labels { get; }Property Value
Section titled “Property Value”IReadOnlyDictionary<string, string>?
Remarks
Section titled “Remarks”Labels are a query dimension, not a metric dimension.
They live in the runs table and are never added to
agentprism.tokens or agentprism.run.cost: turning a free
label set into a metric dimension blows up time-series cardinality. The
same rule applies to IRunAttributionContext.UserId.
The limits are on RunLabels.
UserId
Section titled “ UserId”Gets the user the current run belongs to, or null when it is unknown.
string? UserId { get; }Property Value
Section titled “Property Value”Remarks
Section titled “Remarks”The value is an opaque string. AgentPrism neither
resolves nor validates its meaning, and stores no personal detail of
its own; the consumer decides what the identifier means. This is the
same stance IDataSubjectResolver takes, and the data
subject erasure flow covers this column too.