You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
RFC: one label set for request attribution (project, client, host, …) instead of one axis per dimension
#4676
Hi — I run Headroom as a shared LAN gateway for a handful of Macs, and I've built
something I'd like to contribute if it fits your plans. Before opening PRs I want to
check it doesn't step on Headroom Enterprise's "deep attribution".
The problem
Every number the proxy reports is a sum over requests, but OSS can split that sum only
by model and (since 0.41) by agent, plus a separate projects map. A proxy serving
several machines reports them as one. Each new axis today means another context var,
another RequestOutcome field, another record_request kwarg, another tracker map.
And OutcomeSnapshot carries no project/client at all, so a pipeline extension can't
attribute anything without patching core.
The proposal: OSS collects labels; it does not authenticate
A dimension is a name plus a resolver that reads it from the request. Middleware
resolves all enabled dimensions once into a context var; the outcome funnel puts the {dimension: label} map on RequestOutcome, OutcomeSnapshot.attribution, the savings
tracker (by_dimension, capped 16 dims × 50 labels) and the ledger (dims).
Built-ins wrap what OSS already reads: project, client (classify_client), tenant (X-Headroom-Tenant-ID), plus host (X-Headroom-Host sent by wrap,
peer address fallback with the local machine's addresses coalesced) and traffic_class (interactive vs headless SDK, from the UA).
Operators add dimensions with HEADROOM_ATTRIBUTION_DIMENSIONS=default,team; clients
send X-Headroom-<name> or X-Headroom-Labels: team=infra; cost-center=42.
headroom savings --by host --where project=web, /statssavings.by_dimension
(dashboard callers only — labels name machines and people), a dashboard table,
opt-in OTel attributes via the existing register_otel_metric_attribute_provider.
Optional --require-dimension host refuses unlabelled model traffic (400 / WS 1008);
operational routes are always exempt, checked by a test that walks the route table.
Deliberately not in it: authenticated identity. Labels are self-reported and
documented as such. identity.set_identity_resolver stays the place for real
per-tenant identity; an Enterprise build can publish its authenticated user as a
dimension with register_dimension("user", …) and every OSS surface picks it up. So
OSS gets the plumbing, and Enterprise gets a richer data source to sell on top — if
that's not the split you want, I'd rather know now.
Also built (as an opt-in proxy extension on the public seams, could stay out of tree):
per-label cache economics including "busts" (a conversation that was reading its prefix
re-writes it), top conversations by cost, and repo/branch dimensions read from the
wrap-registered workspace.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Hi — I run Headroom as a shared LAN gateway for a handful of Macs, and I've built
something I'd like to contribute if it fits your plans. Before opening PRs I want to
check it doesn't step on Headroom Enterprise's "deep attribution".
The problem
Every number the proxy reports is a sum over requests, but OSS can split that sum only
by model and (since 0.41) by agent, plus a separate
projectsmap. A proxy servingseveral machines reports them as one. Each new axis today means another context var,
another
RequestOutcomefield, anotherrecord_requestkwarg, another tracker map.And
OutcomeSnapshotcarries no project/client at all, so a pipeline extension can'tattribute anything without patching core.
The proposal: OSS collects labels; it does not authenticate
A dimension is a name plus a resolver that reads it from the request. Middleware
resolves all enabled dimensions once into a context var; the outcome funnel puts the
{dimension: label}map onRequestOutcome,OutcomeSnapshot.attribution, the savingstracker (
by_dimension, capped 16 dims × 50 labels) and the ledger (dims).project,client(classify_client),tenant(X-Headroom-Tenant-ID), plushost(X-Headroom-Hostsent bywrap,peer address fallback with the local machine's addresses coalesced) and
traffic_class(interactive vs headless SDK, from the UA).HEADROOM_ATTRIBUTION_DIMENSIONS=default,team; clientssend
X-Headroom-<name>orX-Headroom-Labels: team=infra; cost-center=42.headroom savings --by host --where project=web,/statssavings.by_dimension(dashboard callers only — labels name machines and people), a dashboard table,
opt-in OTel attributes via the existing
register_otel_metric_attribute_provider.--require-dimension hostrefuses unlabelled model traffic (400 / WS 1008);operational routes are always exempt, checked by a test that walks the route table.
Deliberately not in it: authenticated identity. Labels are self-reported and
documented as such.
identity.set_identity_resolverstays the place for realper-tenant identity; an Enterprise build can publish its authenticated user as a
dimension with
register_dimension("user", …)and every OSS surface picks it up. SoOSS gets the plumbing, and Enterprise gets a richer data source to sell on top — if
that's not the split you want, I'd rather know now.
Also built (as an opt-in proxy extension on the public seams, could stay out of tree):
per-label cache economics including "busts" (a conversation that was reading its prefix
re-writes it), top conversations by cost, and
repo/branchdimensions read from thewrap-registered workspace.
Proposed PR split
OutcomeSnapshotgainsattribution,conversation_key,original_tokens,output_tokens_saved(+PipelineExtensionManager.add). Small, unblocks extensions.headroom.proxy.attribution+ built-ins + tracker/ledger/savings --by.host+traffic_class+wrapheaders.--require-dimension.Running in production here on 0.43.1 since 2026-11-06. Happy to adjust naming, caps or
the split. Would you take this?
All reactions