diff --git a/index.bs b/index.bs
index 1489f0ef7..a4417ac79 100644
--- a/index.bs
+++ b/index.bs
@@ -1548,6 +1548,7 @@ data, rather than [=structured header|structured values=],
because of limitations on nesting in the latter. The recursive
nature of JSON makes it more amenable to future extensions.
+
"value"
+
To parse aggregatable debug reporting data given a |dataList|, a
positive integer |maxValue|, and a [=set=] of [=debug data types=]
|supportedTypes|:
@@ -1756,6 +1790,9 @@ positive integer |maxValue|, and a [=set=] of [=debug data types=]
|debugDataMap|[|type|] to |unspecifiedContribution|.
1. Return |debugDataMap|.
+
+
+
To
parse an aggregatable debug reporting config given a [=map=] |map|, a
positive integer |maxValue|, a [=set=] of [=debug data types=] |supportedTypes|,
and an [=aggregatable debug reporting config=] |default|:
@@ -1791,8 +1828,11 @@ and an [=aggregatable debug reporting config=] |default|:
The parsing errors are intentionally ignored in this algorithm with |default|
returned to avoid data loss from the debug reporting feature.
+
+
Getting registration info
+
To get registration info from a header list given a
[=header list=] |headers|:
@@ -1821,8 +1861,11 @@ To get registration info from a header list given a
Issue: Require |preferredPlatformValue| to be a [=structured header/token=].
+
+
Cookie-based debugging
+
To check if cookie-based debugging is allowed given a
[=suitable origin=] |reportingOrigin| and a [=site=] |contextSite|:
@@ -1839,13 +1882,19 @@ To check if cookie-based debugging is allowed given a
return blocked.
1. Return allowed.
+
+
Obtaining context origin
+
To obtain the context origin of a [=node=] |node|, return |node|'s [=node navigable=]'s
[=navigable/top-level traversable=]'s [=navigable/active document=]'s [=origin=].
+
+
Obtaining a randomized response
+
To obtain a randomized response given |trueValue|, a [=set=] |possibleValues|, and a
double |randomPickRate|:
@@ -1855,8 +1904,11 @@ double |randomPickRate|:
probability.
1. Otherwise, return |trueValue|.
+
+
Parsing aggregation key piece
+
To parse an aggregation key piece given a [=string=] |input|, perform the following steps.
This algorithm will return either a non-negative 128-bit integer or an error.
@@ -1868,9 +1920,13 @@ This algorithm will return either a non-negative 128-bit integer or an error.
1. If the characters within |value| are not all [=ASCII hex digits=], return an error.
1. Interpret |value| as a hexadecimal number and return as a non-negative 128-bit integer.
-
Should processing be blocked by reporting-origin limit
+
-Given an [=attribution rate-limit record=] |newRecord|:
+Should processing be blocked by reporting-origin limit
+
+
+To check if processing should be blocked by reporting-origin limit
+given an [=attribution rate-limit record=] |newRecord|:
1. Let |max| be [=max source reporting origins per rate-limit window=].
1. Let |scopeSet| be « "[=rate-limit scope/source=]" ».
@@ -1888,17 +1944,25 @@ Given an [=attribution rate-limit record=] |newRecord|:
1. If |distinctReportingOrigins|'s [=set/size=] is greater than |max|, return blocked.
1. Return allowed.
-
Can attribution rate-limit record be removed
+
+
+Can attribution rate-limit record be removed
+
+
+To check if an attribution rate-limit record can be removed
+given an [=attribution rate-limit record=] |record| and a [=moment=] |now|:
-Given an [=attribution rate-limit record=] |record| and a [=moment=] |now|:
1. If the [=duration from=] |record|'s [=attribution rate-limit record|time=] and |now| is <= [=attribution rate-limit window=] , return false.
1. If |record|'s [=attribution rate-limit record/scope=] is "[=rate-limit scope/event-attribution=]"
or "[=rate-limit scope/aggregatable-attribution=]", return true.
1. If |record|'s [=attribution rate-limit record/expiry time=] is after |now|, return false.
1. Return true.
+
+
Obtaining and delivering a verbose debug report
+
To obtain and deliver a verbose debug report given a [=list=] of [=verbose debug data=] |data|,
a [=suitable origin=] |reportingOrigin|, and a [=boolean=] |fenced|:
@@ -1910,6 +1974,8 @@ a [=suitable origin=] |reportingOrigin|, and a [=boolean=] |fenced|:
:: |reportingOrigin|
1. [=Queue a task=] to [=attempt to deliver a verbose debug report=] with |debugReport|.
+
+
Making a background attributionsrc request
An eligibility is one of the following:
@@ -1933,6 +1999,7 @@ An eligibility is one of the following:
+
To validate a background attributionsrc eligibility given an
[=eligibility=] |eligibility|:
@@ -1940,6 +2007,9 @@ To validate a background attributionsrc eligibility given an
"[=eligibility/navigation-source=]" or
"[=eligibility/event-source-or-trigger=]".
+
+
+
To make a background attributionsrc request given a [=URL=] |url|, an
[=origin=] |contextOrigin|, an [=eligibility=] |eligibility|, a [=boolean=] |fenced|,
a {{Document}} |document|, and a [=referrer policy=] |referrerPolicy|:
@@ -1975,6 +2045,9 @@ we cannot process registrations through integration with [=fetch=].
Issue: Check for transient activation with "[=eligibility/navigation-source=]".
+
+
+
To make background attributionsrc requests given an
{{HTMLAttributionSrcElementUtils}} |element|, an [=eligibility=] |eligibility|,
and a [=referrer policy=] |referrerPolicy|:
@@ -1996,6 +2069,9 @@ and a [=referrer policy=] |referrerPolicy|:
Issue: Consider allowing the user agent to limit the size of |tokens|.
+
+
+
To process an attributionsrc response given a [=suitable origin=] |contextOrigin|,
an [=eligibility=] |eligibility|, a [=boolean=] |fenced|, and a [=response=] |response|:
@@ -2003,6 +2079,9 @@ an [=eligibility=] |eligibility|, a [=boolean=] |fenced|, and a [=response=] |re
1. Run [=process an attribution eligible response=] with |contextOrigin|,
|eligibility|, |fenced|, and |response|.
+
+
+
To get the registration platform given a [=header value=] or null |webHeader|,
a [=header value=] or null |osHeader|, and a [=registrar=] or null |preferredPlatform|:
@@ -2034,6 +2113,9 @@ a [=header value=] or null |osHeader|, and a [=registrar=] or null |preferredPla
+
+
+
To process an attribution source response given a [=suitable origin=]
|contextOrigin|, a [=suitable origin=] |reportingOrigin|, a [=source type=]
|sourceType|, a [=header value=] or null |webSourceHeader|, a [=header value=]
@@ -2076,8 +2158,11 @@ or null |osSourceHeader|, a [=registration info=] |registrationInfo|, and a
+
+
+
To process an attribution trigger response given a [=suitable origin=]
-|contextOrigin|, a [=suitable origin=] |reportingOrigin|, a [=response=] |response|,
+|contextOrigin|, a [=suitable origin=] |reportingOrigin|,
a [=header value=] or null |webTriggerHeader|, a [=header value=] or null
|osTriggerHeader|, a [=registration info=] |registrationInfo|, and a [=boolean=]
|fenced|:
@@ -2118,6 +2203,9 @@ a [=header value=] or null |webTriggerHeader|, a [=header value=] or null
+
+
+
To process an attribution eligible response given a [=suitable origin=]
|contextOrigin|, an [=eligibility=] |eligibility|, a [=boolean=] |fenced|,
and a [=response=] |response|:
@@ -2182,11 +2270,14 @@ and a [=response=] |response|:
|sourceHeader|, |osSourceHeader|, |registrationInfo|, and |fenced|.
1. If |hasTriggerRegistration| is true:
1. Run [=process an attribution trigger response=]
- with |contextOrigin|, |reportingOrigin|, |response|, |triggerHeader|,
+ with |contextOrigin|, |reportingOrigin|, |triggerHeader|,
|osTriggerHeader|, |registrationInfo|, and |fenced|.
+
+
+
To obtain and deliver debug reports on registration header errors
given a [=header name=] |headerName|, a [=header value=] |headerValue|, a
[=suitable origin=] |reportingOrigin|, a [=suitable origin=] |contextOrigin|,
@@ -2208,8 +2299,11 @@ and a [=boolean=] |fenced|:
:: |body|
1. Run [=obtain and deliver a verbose debug report=] with « |data| », |reportingOrigin|, and |fenced|.
+
+
Attribution debugging
+
To check if attribution debugging can be enabled given an [=attribution debug info=] |debugInfo|:
1. If |debugInfo|'s [=attribution debug info/source debug key=] is null,
@@ -2218,6 +2312,9 @@ To check if attribution debugging can be enabled given an [=attributi
return false.
1. Return true.
+
+
+
To
serialize an attribution debug info given a [=map=] |data| and an
[=attribution debug info=] |debugInfo|:
@@ -2230,8 +2327,11 @@ To
serialize an attribution debug info given a [=map=] |data| and an
We require both source and trigger debug keys to be present to avoid
a privacy leak from one-sided third-party cookie access.
+
+
Obtaining and delivering an aggregatable debug report
+
To check if aggregatable debug reporting should be blocked by rate-limit
given an [=aggregatable debug rate-limit record=] |newRecord|:
@@ -2253,6 +2353,9 @@ given an [=aggregatable debug rate-limit record=] |newRecord|:
return blocked.
1. Return allowed.
+
+
+
To obtain and deliver an aggregatable debug report given a [=list=]
of [=aggregatable contributions=] |contributions|,
a [=suitable origin=] |reportingOrigin|, a [=site=] |effectiveDestination|,
@@ -2277,6 +2380,9 @@ an [=aggregation coordinator=] |aggregationCoordinator|, and a [=moment=] |now|:
1. [=Queue a task=] to [=attempt to deliver an aggregatable debug report=] with |report|.
+
+
+
To obtain and deliver an aggregatable debug report on registration given a [=list=] |contributions|,
a [=site=] |contextSite|, an [=origin=] |reportingOrigin|, a possibly null
[=attribution source=] |source|, a [=site=] |effectiveDestination|,
@@ -2327,10 +2433,13 @@ an [=aggregation coordinator=] |aggregationCoordinator|, and a [=moment=] |now|:
[=aggregatable debug rate-limit cache=] if the [=duration from=] |entry|'s
[=aggregatable debug rate-limit record/time=] and |now| is > [=aggregatable debug rate-limit window=].
+
+
# Source Algorithms # {#source-algorithms}
Obtaining a randomized source response
+
To obtain a set of possible trigger states given a [=randomized response output configuration=] |config|:
1. Let |possibleTriggerStates| be a new [=set=].
1. [=set/iterate|For each=] |triggerData| of |config|'s [=randomized response output configuration/trigger data=]:
@@ -2348,16 +2457,25 @@ To obtain a set of possible trigger states given a [=randomized respo
with repetition.
1. Return |possibleValues|.
+
+
+
To obtain a randomized source response pick rate given a positive integer |states| and a double |epsilon|:
1. Return |states| / (|states| − 1 + e|epsilon|).
+
+
+
To obtain a randomized source response given a [=set=] of possible trigger states |possibleValues| and a double |epsilon|:
1. Let |pickRate| be the result of [=obtaining a randomized source response pick rate=] with |possibleValues|'s [=set/size=] and |epsilon|.
1. Return the result of [=obtaining a randomized response=] with null, |possibleValues|, and
|pickRate|.
+
+
Computing channel capacity
+
To
compute the channel capacity of a source given a positive integer |states| and a double |epsilon|:
1. If |states| is 1, return 0.
1. If |states| is greater than the user agent's [=max trigger-state cardinality=], return an error.
@@ -2367,10 +2485,15 @@ To
compute the channel capacity of a source given a positive integer
This algorithm computes the channel capacity [[CHAN]] of a q-ary symmetric channel [[Q-SC]].
+
+
+
To compute the scopes channel capacity of a source given a positive integer |numTriggerStates|, a positive integer |attributionScopeLimit|, and a positive integer |maxEventStates|:
1. Let |totalStates| be |numTriggerStates| + |maxEventStates| × (|attributionScopeLimit| − 1).
1. Return log2(|totalStates|).
+
+
Parsing source-registration JSON
A source-registration JSON key is one of the following:
@@ -2403,6 +2526,7 @@ A source-registration JSON key is one of the following:
"values"
+
To parse an attribution destination from a [=string=] |str|:
1. Let |url| be the result of running the [=URL parser=] on the value of
the |str|.
@@ -2412,6 +2536,9 @@ To parse an attribution destination from a [=string=] |str|:
1. Return the result of [=obtain a site|obtaining a site=] from |url|'s
[=url/origin=].
+
+
+
To parse attribution destinations from a [=map=] |map|:
1. If |map|["[=source-registration JSON key/destination=]"] does not [=map/exists|exist=], return an error.
1. Let |val| be |map|["[=source-registration JSON key/destination=]"].
@@ -2434,6 +2561,9 @@ To parse attribution destinations from a [=map=] |map|:
destinations are equivalent, regardless of the order of sites in the
registration JSON.
+
+
+
To parse a duration given a [=map=] |map|, a [=string=] |key|, and a
tuple of [=durations=] (|clampStart|, |clampEnd|):
@@ -2451,6 +2581,9 @@ tuple of [=durations=] (|clampStart|, |clampEnd|):
Issue: Consider rejecting out-of-bounds values instead of silently clamping.
+
+
+
To parse aggregation keys given a [=map=] |map|:
1. Let |aggregationKeys| be a new [=map=].
@@ -2468,6 +2601,9 @@ To parse aggregation keys given a [=map=] |map|:
1. [=map/Set=] |aggregationKeys|[|key|] to |keyPiece|.
1. Return |aggregationKeys|.
+
+
+
To parse named budgets for source given a [=map=] |map|:
1. Let |namedBudgets| be a new [=map=].
@@ -2484,6 +2620,9 @@ To parse named budgets for source given a [=map=] |map|:
1. [=map/Set=] |namedBudgets|[|key|] to |value|.
1. Return |namedBudgets|.
+
+
+
To obtain default effective windows given a [=source type=] |sourceType|,
a [=moment=] |sourceTime|, and a [=duration=] |eventReportWindow|:
@@ -2504,6 +2643,9 @@ a [=moment=] |sourceTime|, and a [=duration=] |eventReportWindow|:
1. Set |lastEnd| to |lastEnd| + |deadline|.
1. Return |windows|.
+
+
+
To parse top-level report windows given a [=map=] |map|, a [=moment=] |sourceTime|,
a [=source type=] |sourceType|, and a [=duration=] |expiry|:
@@ -2520,6 +2662,9 @@ a [=source type=] |sourceType|, and a [=duration=] |expiry|:
1. Return the result of [=parsing report windows=] with
|map|["[=source-registration JSON key/event_report_windows=]"], |sourceTime|, and |expiry|.
+
+
+
To parse report windows given a |value|, a
[=moment=] |sourceTime|, and a [=duration=] |expiry|:
@@ -2552,8 +2697,11 @@ To parse report windows given a |value|, a
1. Set |startDuration| to |endDuration|.
1. Return |windows|.
-To parse trigger data into a trigger data set given a [=map=] |map|
-and a [=trigger-data matching mode=] |matchingMode|:
+
+
+
+To parse trigger data into a trigger data set given a [=map=] |map|,
+a [=trigger-data matching mode=] |matchingMode|, and a [=source type=] |sourceType|:
1. Let |set| be a new [=trigger data set=].
1. If |map|["[=source-registration JSON key/trigger_data=]"] [=map/exists=]:
@@ -2572,7 +2720,7 @@ and a [=trigger-data matching mode=] |matchingMode|:
1. [=set/iterate|For each=] integer |triggerData| of
[=the exclusive range|the range=] 0 to
[=default trigger data cardinality=][|sourceType|], exclusive:
- 1. [=set/Append=] |triggerData| to |triggerDataSet|.
+ 1. [=set/Append=] |triggerData| to |set|.
1. If |matchingMode| is "[=trigger-data matching mode/modulus=]":
1. Let |i| be 0.
1. [=set/iterate|For each=] |triggerData| of |set|:
@@ -2580,6 +2728,9 @@ and a [=trigger-data matching mode=] |matchingMode|:
1. Set |i| to |i| + 1.
1. Return |set|.
+
+
+
To parse a source aggregatable debug reporting config given |value|, a
non-negative integer |defaultBudget|, and an [=aggregatable debug reporting config=]
|defaultConfig|:
@@ -2595,6 +2746,9 @@ non-negative integer |defaultBudget|, and an [=aggregatable debug reporting conf
with |value|, |budget|, |supportedTypes|, and |defaultConfig|.
1. Return the [=tuple=] (|budget|, |config|).
+
+
+
To parse attribution scopes from a [=map=] |map|:
1. If |map|["[=source-registration JSON key/attribution_scopes=]"] does not [=map/exists|exist=], return null.
1. Let |value| be |map|["[=source-registration JSON key/attribution_scopes=]"].
@@ -2615,6 +2769,9 @@ To parse attribution scopes from a [=map=] |map|:
:: |maxEventStates|
1. Return |attributionScopes|.
+
+
+
To parse max event states from a [=map=] |map|:
1. If |map|["[=source-registration JSON key/max_event_states=]"] does not [=map/exist=], return [=default max event states=].
1. Let |maxEventStates| be |map|["[=source-registration JSON key/max_event_states=]"].
@@ -2622,6 +2779,9 @@ To parse max event states from a [=map=] |map|:
1. If |maxEventStates| is greater than the user agent's [=max trigger-state cardinality=], return an error.
1. Return |maxEventStates|.
+
+
+
To parse attribution scope values for source from a [=map=] |map| and a 32-bit positive integer |limit|:
1. If |map|["[=source-registration JSON key/values=]"] does not [=map/exist=], return an error.
1. Let |result| be a new [=set=].
@@ -2639,6 +2799,9 @@ To parse attribution scope values for source from a [=map=] |map| and
to prevent the selection of both sources with and without scopes, which would effectively
result in |limit| + 1 scopes.
+
+
+
To parse source-registration JSON given a [=byte sequence=]
|json|, a [=suitable origin=] |sourceOrigin|, a [=suitable origin=] |reportingOrigin|, a
[=source type=] |sourceType|, a [=moment=] |sourceTime|, and a [=boolean=] |fenced|:
@@ -2709,8 +2872,8 @@ To parse source-registration JSON given a [=byte sequence=]
[=parsing top-level report windows=] with |value|, |sourceTime|, |sourceType|,
and |expiry|.
1. If |eventReportWindows| is an error, return it.
-1. Let |triggerDataSet| be the result of [=parsing trigger data into a trigger data set=] with |value|
- and |triggerDataMatchingMode|.
+1. Let |triggerDataSet| be the result of [=parsing trigger data into a trigger data set=] with |value|,
+ |triggerDataMatchingMode|, and |sourceType|.
1. If |triggerDataSet| is an error, return it.
1. Let |attributionScopes| be the result of running [=parse attribution scopes=] with |value|.
1. If |attributionScopes| is an error, return it.
@@ -2792,8 +2955,11 @@ To parse source-registration JSON given a [=byte sequence=]
Issue: Determine proper charset-handling for the JSON header value.
+
+
Processing an attribution source
+
To
check if an [=attribution source=] exceeds the time-based destination limits given an
[=attribution source=] |source|, run the following steps:
@@ -2828,6 +2994,9 @@ To
check if an [=attribution source=] exceeds the time-based destination li
When both limits are hit, we interpret it as "[=destination rate-limit result/hit reporting limit=]"
for debug reporting.
+
+
+
To check if an [=attribution source=] exceeds the per day destination limits
given an [=attribution source=] |source|, run the following steps:
@@ -2843,6 +3012,9 @@ given an [=attribution source=] |source|, run the following steps:
[=set/union|unioned=] with |source|'s [=attribution source/attribution destinations=].
1. Return whether |destinations|'s [=set/size=] is greater than [=max destinations per source reporting site per day=].
+
+
+
To delete sources for unexpired destination limit given a [=set=] of
[=attribution source/internal IDs=] |sourcesToDelete| and a [=moment=] |now|:
@@ -2884,6 +3056,8 @@ To delete sources for unexpired destination limit given a [=set=] of
+
+
A destination limit record is a [=struct=] with the following items:
@@ -2898,6 +3072,7 @@ A destination limit record is a [=struct=] with the following items:
+
To get sources to delete for the unexpired destination limit given an
[=attribution source=] |source|, run the following steps:
1. Let |destinationRecords| be a new [=list=].
@@ -2954,6 +3129,9 @@ To get sources to delete for the unexpired destination limit given an
1. [=set/Append=] |record|'s [=destination limit record/source ID=] to |sourcesToDelete|.
1. Return |sourcesToDelete|.
+
+
+
To check if an [=attribution source=] should be blocked by reporting-origin per site limit given an [=attribution source=] |source|:
1. Let |matchingRateLimitRecords| be all [=attribution rate-limit records=] |record| in the [=attribution rate-limit cache=] where all of the following are true:
@@ -2965,6 +3143,9 @@ To check if an [=attribution source=] should be blocked by reporting-origin
1. If |distinctReportingOrigins|'s [=list/size=] is greater than [=max source reporting origins per source reporting site=], return blocked.
1. Return allowed.
+
+
+
To obtain a fake report given an [=attribution source=] |source| and
a [=trigger state=] |triggerState|:
@@ -2977,8 +3158,11 @@ a [=trigger state=] |triggerState|:
|triggerState|'s [=trigger state/report window=]'s [=report window/end=].
1. Return |fakeReport|.
+
+
+
To obtain and deliver a verbose debug report on source registration given a
-[=source debug data types=] |dataType|, an [=attribution source=] |source|,
+[=source debug data type=] |dataType|, an [=attribution source=] |source|,
a [=boolean=] |isNoised|, and a [=boolean=] |destinationLimitReplaced|:
1. If |source|'s [=attribution source/debug reporting enabled=] is false, return.
@@ -3054,6 +3238,9 @@ leakage of cross-origin data.
1. Run [=obtain and deliver a verbose debug report=] with « |data| », |source|'s [=attribution source/reporting origin=],
and |source|'s [=attribution source/fenced=].
+
+
+
To obtain and deliver an aggregatable debug report on source registration
given a [=source debug data type=] |dataType|, an [=attribution source=] |source|,
a [=boolean=] |isNoised|, and a [=boolean=] |destinationLimitReplaced|:
@@ -3087,22 +3274,31 @@ a [=boolean=] |isNoised|, and a [=boolean=] |destinationLimitReplaced|:
|config|'s [=aggregatable debug reporting config/aggregation coordinator=],
and |source|'s [=attribution source/source time=].
+
+
+
To obtain and deliver debug reports on source registration
given a [=source debug data type=] |dataType|, an [=attribution source=] |source|,
an optional [=boolean=] |isNoised| (default false), and an optional
[=boolean=] |destinationLimitReplaced| (default false):
1. Run [=obtain and deliver a verbose debug report on source registration=]
- with |dataTypes|, |source|, |isNoised|, and |destinationLimitReplaced|.
+ with |dataType|, |source|, |isNoised|, and |destinationLimitReplaced|.
1. Run [=obtain and deliver an aggregatable debug report on source registration=]
- with |dataTypes|, |source|, |isNoised|, and |destinationLimitReplaced|.
+ with |dataType|, |source|, |isNoised|, and |destinationLimitReplaced|.
+
+
+
To delete expired sources given a [=moment=] |now|:
1. [=set/iterate|For each=] |source| of the [=attribution source cache=]:
1. If |source|'s [=attribution source/expiry time=] is less than |now|,
[=set/remove=] |source| from the [=attribution source cache=].
+
+
+
To find sources with common destinations and reporting origin given an [=attribution source=] |pendingSource|:
1. Let |matchingSources| be a new [=list=].
1. [=set/iterate|For each=] |source| of the user agent's [=attribution source cache=]:
@@ -3112,6 +3308,9 @@ To find sources with common destinations and reporting origin given a
1. [=list/Append=] |source| to |matchingSources|.
1. Return |matchingSources|.
+
+
+
To remove associated event-level reports and rate-limit records given an [=attribution source/internal ID=] |sourceId| and a [=moment=] |minTriggerTime|:
1. [=set/iterate|For each=] [=event-level report=] |report| of the [=event-level report cache=]:
1. If |report|'s [=event-level report/source ID=] is not equal to |sourceId|, [=iteration/continue=].
@@ -3119,6 +3318,9 @@ To remove associated event-level reports and rate-limit records given
1. [=set/Remove=] |report| from the [=event-level report cache=].
1. [=list/Remove=] all [=attribution rate-limit records=] |entry| from the [=attribution rate-limit cache=] where |entry|'s [=attribution rate-limit record/entity ID=] is equal to |report|'s [=event-level report/internal ID=].
+
+
+
To remove sources with unselected attribution scopes for destination given a [=site=] |destination| and an [=attribution source=] |pendingSource|:
1. Let |scopeRecords| be a new [=list=].
1. Let |scopes| be |pendingSource|'s [=attribution source/attribution scopes=]'s [=attribution scopes/values=].
@@ -3140,6 +3342,9 @@ To remove sources with unselected attribution scopes for destination
1. [=Remove associated event-level reports and rate-limit records=] with |source|'s [=attribution source/internal ID=] and |pendingSource|'s [=attribution source/source time=].
1. [=set/Remove=] |source| from the [=attribution source cache=].
+
+
+
To remove sources with unselected attribution scopes given an [=attribution source=] |pendingSource|:
1. If |pendingSource|'s [=attribution source/attribution scopes=] is null, return.
1. [=Assert=]: |pendingSource|'s [=attribution source/attribution destinations=] is [=list/sort in ascending order|sorted=] in
@@ -3149,6 +3354,9 @@ To remove sources with unselected attribution scopes given an [=attri
1. [=set/iterate|For each=] |destination| in |pendingSource|'s [=attribution source/attribution destinations=]:
1. [=Remove sources with unselected attribution scopes for destination=] with |destination| and |pendingSource|.
+
+
+
To remove or update sources for attribution scopes given an [=attribution source=] |pendingSource|:
1. Let |pendingScopes| be |pendingSource|'s [=attribution source/attribution scopes=].
1. Let |matchingSources| be the result of running [=find sources with common destinations and reporting origin=] with |pendingSource|.
@@ -3165,6 +3373,9 @@ To remove or update sources for attribution scopes given an [=attribu
1. [=set/Remove=] |source| from the [=attribution source cache=].
1. [=Remove sources with unselected attribution scopes=] with |pendingSource|.
+
+
+
To process an attribution source given an [=attribution source=] |source|:
1. [=Delete expired sources=] with |source|'s [=attribution source/source time=].
@@ -3267,7 +3478,7 @@ To process an attribution source given an [=attribution source=] |sou
:: |source|'s [=attribution source/internal ID=]
: [=attribution rate-limit record/destination limit priority=]
:: |source|'s [=attribution source/destination limit priority=]
- 1. If the result of running [=should processing be blocked by reporting-origin limit=] with
+ 1. If the result of running [=check if processing should be blocked by reporting-origin limit=] with
|rateLimitRecord| is blocked:
1. Run [=obtain and deliver debug reports on source registration=]
with "[=source debug data type/source-reporting-origin-limit=]",
@@ -3277,7 +3488,7 @@ To process an attribution source given an [=attribution source=] |sou
1. [=set/iterate|For each=] |record| of |newRateLimitRecords|, [=set/append=] |record| to
the [=attribution rate-limit cache=].
1. [=list/Remove=] all [=attribution rate-limit records=] |entry| from the [=attribution rate-limit cache=] if the result of running
- [=can attribution rate-limit record be removed=] with |entry| and |source|'s [=attribution source/source time=] is true.
+ [=check if an attribution rate-limit record can be removed=] with |entry| and |source|'s [=attribution source/source time=] is true.
1. If |source|'s [=attribution source/randomized response=] is not null and is a [=list=]:
1. [=list/iterate|For each=] [=trigger state=] |triggerState| of |source|'s
[=attribution source/randomized response=]:
@@ -3318,6 +3529,8 @@ in [=verbose debug reports=] have to be checked before any limits that are repor
prevent side-channel leakage of cross-origin data. Furthermore, the [=verbose debug data=]
have to be fully determined regardless of the result of checks on implicitly reported limits.
+
+
# Triggering Algorithms # {#trigger-algorithms}
A trigger-registration JSON key is one of the following:
@@ -3351,6 +3564,7 @@ A trigger-registration JSON key is one of the following:
Creating an attribution trigger
+
To parse event triggers given a [=map=] |map|:
1. Let |eventTriggers| be a new [=set=].
@@ -3390,6 +3604,9 @@ To parse event triggers given a [=map=] |map|:
1. [=set/Append=] |eventTrigger| to |eventTriggers|.
1. Return |eventTriggers|.
+
+
+
To parse aggregatable trigger data given a [=map=] |map|:
1. Let |aggregatableTriggerData| be a new [=list=].
@@ -3422,6 +3639,9 @@ To parse aggregatable trigger data given a [=map=] |map|:
1. [=list/Append=] |aggregatableTrigger| to |aggregatableTriggerData|.
1. Return |aggregatableTriggerData|.
+
+
+
To parse aggregatable filtering ID max bytes given a [=map=] |map|:
1. Let |maxBytes| be [=default filtering ID max bytes=].
@@ -3432,12 +3652,18 @@ To parse aggregatable filtering ID max bytes given a [=map=] |map|:
1. Otherwise, return an error.
1. Return |maxBytes|.
+
+
+
To validate aggregatable key-values value given a |value|:
1. If |value| is not an integer, return false.
1. If |value| is less than or equal to 0, return false.
1. If |value| is greater than [=allowed aggregatable budget per source=], return false.
1. Return true.
+
+
+
To parse aggregatable key-values given a [=map=] |map| and a positive integer |maxBytes|:
1. Let |out| be a new [=map=].
@@ -3468,6 +3694,9 @@ To parse aggregatable key-values given a [=map=] |map| and a positive
:: |filteringId|
1. Return |out|.
+
+
+
To parse aggregatable values given a [=map=] |map| and a positive integer |maxBytes|:
1. If |map|["[=trigger-registration JSON key/aggregatable_values=]"] does not [=map/exist=], return a new [=list=].
@@ -3505,6 +3734,9 @@ To parse aggregatable values given a [=map=] |map| and a positive int
1. [=list/Append=] |aggregatableValuesConfiguration| to |aggregatableValuesConfigurations|.
1. Return |aggregatableValuesConfigurations|.
+
+
+
To parse aggregatable dedup keys given a [=map=] |map|:
1. Let |aggregatableDedupKeys| be a new [=list=].
@@ -3530,6 +3762,9 @@ To parse aggregatable dedup keys given a [=map=] |map|:
1. [=set/Append=] |aggregatableDedupKey| to |aggregatableDedupKeys|.
1. Return |aggregatableDedupKeys|.
+
+
+
To parse named budgets for trigger given a [=map=] |map|:
1. Let |namedBudgets| be a new [=list=].
@@ -3555,6 +3790,9 @@ To parse named budgets for trigger given a [=map=] |map|:
1. [=list/Append=] |namedBudget| to |namedBudgets|.
1. Return |namedBudgets|.
+
+
+
To parse attribution scopes for trigger from a [=map=] |map|:
1. Let |result| be a new [=set=].
1. If |map|["[=trigger-registration JSON key/attribution_scopes=]"] does not [=map/exist=], return |result|.
@@ -3565,6 +3803,9 @@ To parse attribution scopes for trigger from a [=map=] |map|:
1. [=set/Append=] |value| to |result|.
1. Return |result|.
+
+
+
To create an attribution trigger given a [=byte sequence=]
|json|, a [=site=] |destination|, a [=suitable origin=] |reportingOrigin|,
a [=moment=] |triggerTime|, and a [=boolean=] |fenced|:
@@ -3668,8 +3909,11 @@ a [=moment=] |triggerTime|, and a [=boolean=] |fenced|:
Issue: Determine proper charset-handling for the JSON header value.
+
+
Does filter data match
+
To match [=filter values=] given a [=filter value=] |a| and a [=filter value=] |b|:
1. If |b| [=set/is empty=], then:
1. If |a| [=set/is empty=], then return true.
@@ -3678,6 +3922,9 @@ To match [=filter values=] given a [=filter value=] |a| and a [=filte
1. If |i| [=set/is empty=], then return false.
1. Return true.
+
+
+
To match [=filter values=] with negation given a [=filter value=] |a| and a [=filter value=] |b|:
1. If |b| [=set/is empty=], then:
1. If |a| is not [=set/is empty|empty=], then return true.
@@ -3686,6 +3933,9 @@ To match [=filter values=] with negation given a [=filter value=] |a|
1. If |i| is not [=set/is empty|empty=], then return false.
1. Return true.
+
+
+
To match an attribution source against a filter config given an
[=attribution source=] |source|, a [=filter config=] |filter|, a [=moment=] |moment|, and a [=boolean=]
|isNegated|:
@@ -3716,6 +3966,9 @@ To match an attribution source against a filter config given an
1. Return true.
+
+
+
To match an attribution source against filters given an
[=attribution source=] |source|, a [=list=] of [=filter configs=] |filters|, a [=moment=] |moment|, and a [=boolean=]
isNegated:
@@ -3725,6 +3978,9 @@ To match an attribution source against filters given an
1. If the result of running [=match an attribution source against a filter config=] with |source|, |filter|, |moment|, and |isNegated| is true, return true.
1. Return false.
+
+
+
To match an attribution source against filters and negated filters given an
[=attribution source=] |source|, a [=list=] of [=filter configs=] |filters|, a [=list=] of [=filter configs=] |notFilters|, and a [=moment=] |moment|:
@@ -3734,8 +3990,11 @@ To match an attribution source against filters and negated filters gi
|source|, |notFilters|, |moment|, and [=match an attribution source against filters/isNegated=] set to true is false, return false.
1. Return true.
+
+
Should send a report unconditionally
+
To check if an aggregatable attribution report should be unconditionally sent given an [=attribution trigger=] |trigger|:
1. If |trigger|'s [=attribution trigger/trigger context ID=] is not null, return true.
@@ -3743,8 +4002,11 @@ To check if an aggregatable attribution report should be unconditionally se
is not equal to [=default filtering ID max bytes=], return true.
1. Return false.
+
+
Should attribution be blocked by rate limits
+
To check if attribution should be blocked by attribution rate limit given an [=attribution rate-limit record=] |newRecord|:
1. Let |matchingRateLimitRecords| be all [=attribution rate-limit records=] |record| of [=attribution rate-limit cache=] where all of the following are true:
@@ -3756,6 +4018,9 @@ To check if attribution should be blocked by attribution rate limit g
1. If |matchingRateLimitRecords|'s [=list/size=] is greater than or equal to [=max attributions per rate-limit window=], return blocked.
1. Return allowed.
+
+
+
To check if attribution should be blocked by rate limits given an [=attribution rate-limit record=] |newRecord|:
1. If the result of running [=check if attribution should be blocked by attribution rate limit=] with |newRecord| is blocked:
@@ -3763,18 +4028,21 @@ To check if attribution should be blocked by rate limits given an [=a
1. If |newRecord|'s [=attribution rate-limit record/scope=] is "[=rate-limit scope/aggregatable-attribution=]",
set |debugDataType| to "[=trigger debug data type/trigger-aggregate-attributions-per-source-destination-limit=]".
1. Return the [=triggering result=] ("[=triggering status/dropped=]", (|debugDataType|, null)).
-1. If the result of running [=should processing be blocked by reporting-origin limit=] with
+1. If the result of running [=check if processing should be blocked by reporting-origin limit=] with
|newRecord| is blocked:
1. Return the [=triggering result=] ("[=triggering status/dropped=]",
("[=trigger debug data type/trigger-reporting-origin-limit=]", null)).
1. Return null.
-Issue(1287): Consider performing [=should processing be blocked by reporting-origin limit=] from
+Issue(1287): Consider performing [=check if processing should be blocked by reporting-origin limit=] from
[=triggering attribution=] to avoid duplicate invocation from
[=triggering event-level attribution=] and [=triggering aggregatable attribution=].
+
+
Creating aggregatable contributions
+
To create [=aggregatable contributions=] from [=attribution source/aggregation keys=] and aggregatable [=aggregatable values configuration/values=]
given a [=map=] |aggregationKeys| and a [=map=] |aggregatableValues|,
run the following steps:
@@ -3792,6 +4060,9 @@ To create [=aggregatable contributions=] from [=attribution source/aggregat
1. [=list/Append=] |contribution| to |contributions|.
1. Return |contributions|.
+
+
+
To create [=aggregatable contributions=] given an [=attribution source=] |source| and an
[=attribution trigger=] |trigger|, run the following steps:
@@ -3816,8 +4087,11 @@ To create [=aggregatable contributions=] given an [=attribution sourc
|aggregationKeys| and |aggregatableValuesConfiguration|'s [=aggregatable values configuration/values=].
1. Return a new [=list=].
+
+
Can source create aggregatable contributions
+
To check if an [=attribution source=] can create [=aggregatable contributions=] given an
[=aggregatable attribution report=] |report| and an [=attribution source=] |sourceToAttribute|, run the following steps:
@@ -3827,6 +4101,9 @@ To check if an [=attribution source=] can create [=aggregatable contributio
|remainingAggregatableBudget|, return false.
1. Return true.
+
+
+
To find matching budget name given an [=attribution trigger=] |trigger| and an [=attribution source=] |sourceToAttribute|:
1. [=list/iterate|For each=] [=named budget=] |namedBudget| of |trigger|'s [=attribution trigger/named budgets=]:
1. If the result of running [=match an attribution source against filters and negated filters=]
@@ -3836,6 +4113,9 @@ To find matching budget name given an [=attribution trigger=] |trigge
1. Return |namedBudget|'s [=named budget/name=].
1. Return null.
+
+
+
To check if an [=attribution source=] can create [=aggregatable contributions=] for matched budget name
given an [=aggregatable attribution report=] |report|, an [=attribution source=] |sourceToAttribute|,
and a [=string=] |matchedBudgetName|, run the following steps:
@@ -3845,8 +4125,11 @@ and a [=string=] |matchedBudgetName|, run the following steps:
|sourceToAttribute|'s [=attribution source/remaining named budgets=][|matchedBudgetName|], return false.
1. Return true.
+
+
Obtaining verbose debug data on trigger registration
+
To obtain verbose debug data body on trigger registration given a
[=trigger debug data type=] |dataType|, an [=attribution trigger=] |trigger|,
a possibly null [=attribution source=] |sourceToAttribute|, and a possibly null
@@ -3901,6 +4184,9 @@ a possibly null [=attribution source=] |sourceToAttribute|, and a possibly null
[=serialize an integer|serialized=].
1. Return |body|.
+
+
+
To obtain verbose debug data on trigger registration given a [=trigger debug data type=] |dataType|,
an [=attribution trigger=] |trigger|, a possibly null [=attribution source=]
|sourceToAttribute|, and a possibly null [=attribution report=] |report|:
@@ -3917,8 +4203,11 @@ an [=attribution trigger=] |trigger|, a possibly null [=attribution source=]
:: The result of running [=obtain verbose debug data body on trigger registration=] with |dataType|, |trigger|, |sourceToAttribute|, and |report|.
1. Return |data|.
+
+
Triggering event-level attribution
+
An [=event-level report=] |a| is lower-priority than
an [=event-level report=] |b| if any of the following are true:
@@ -3926,6 +4215,8 @@ an [=event-level report=] |b| if any of the following are true:
* |a|'s [=event-level report/trigger priority=] is equal to |b|'s [=event-level report/trigger priority=]
and |a|'s [=event-level report/trigger time=] is greater than |b|'s [=event-level report/trigger time=].
+
+
An event-level-report-replacement result is one of the following:
@@ -3943,6 +4234,7 @@ An event-level-report-replacement result is one of the follo
+
To maybe replace event-level report given an [=attribution source=]
|sourceToAttribute| and an [=event-level report=] |report|:
@@ -3973,6 +4265,9 @@ To maybe replace event-level report given an [=attribution source=]
1. [=set/Remove=] |rateLimitRecord| from the [=attribution rate-limit cache=].
1. Return "[=event-level-report-replacement result/add-new-report=]".
+
+
+
To trigger event-level attribution given an [=attribution trigger=] |trigger| and an
[=attribution source=] |sourceToAttribute|, run the following steps:
@@ -4084,8 +4379,11 @@ To trigger event-level attribution given an [=attribution trigger=] |
[=attempt to deliver a debug report=] with |report|.
1. Return the [=triggering result=] (|triggeringStatus|, |debugData|).
+
+
Triggering aggregatable attribution
+
To trigger aggregatable attribution given an [=attribution trigger=] |trigger| and an
[=attribution source=] |sourceToAttribute|, run the following steps:
@@ -4164,8 +4462,11 @@ To trigger aggregatable attribution given an [=attribution trigger=]
[=queue a task=] to [=attempt to deliver a debug report=] with |report|.
1. Return the [=triggering result=] ("[=triggering status/attributed=]", null).
+
+
Triggering attribution
+
To obtain and deliver a verbose debug report on trigger registration
given a [=set=] of [=trigger debug data=] |dataSet|, an [=attribution trigger=] |trigger|,
and a possibly null [=attribution source=] |sourceToAttribute|:
@@ -4180,6 +4481,9 @@ and a possibly null [=attribution source=] |sourceToAttribute|:
1. Run [=obtain and deliver a verbose debug report=] with |debugDataList|, |trigger|'s [=attribution trigger/reporting origin=],
and |trigger|'s [=attribution trigger/fenced=].
+
+
+
To obtain and deliver an aggregatable debug report on trigger registration
given a [=set=] of [=trigger debug data=] |dataSet|, an [=attribution trigger=] |trigger|,
and a possibly null [=attribution source=] |sourceToAttribute|:
@@ -4214,6 +4518,9 @@ and a possibly null [=attribution source=] |sourceToAttribute|:
|config|'s [=aggregatable debug reporting config/aggregation coordinator=],
and |trigger|'s [=attribution trigger/trigger time=].
+
+
+
To obtain and deliver debug reports on trigger registration
given a [=set=] of [=trigger debug data=] |dataSet|, an [=attribution trigger=] |trigger|,
and a possibly null [=attribution source=]
@@ -4224,11 +4531,17 @@ and a possibly null [=attribution source=]
1. Run [=obtain and deliver an aggregatable debug report on trigger registration=]
with |dataSet|, |trigger|, and |sourceToAttribute|.
+
+
+
To check if an [=attribution source=] and [=attribution trigger=] have matching attribution scopes given an [=attribution source=] |source| and an [=attribution trigger=] |trigger|:
1. If |trigger|'s [=attribution trigger/attribution scopes=] [=set/is empty=], return true.
1. Return whether the [=set/intersection=] of |source|'s [=attribution source/attribution scopes=]'s [=attribution scopes/values=] and |trigger|'s [=attribution trigger/attribution scopes=] is not [=set/is empty|empty=].
+
+
+
An [=attribution source=] |a| is higher-priority than an [=attribution source=] |b|
if the following steps return true:
@@ -4237,6 +4550,9 @@ if the following steps return true:
1. If |a|'s [=attribution source/source time=] is greater than |b|'s [=attribution source/source time=], return true.
1. Return false.
+
+
+
To find matching sources given an [=attribution trigger=] |trigger|:
1. Let |matchingSources| be a new [=list=].
@@ -4259,6 +4575,9 @@ To find matching sources given an [=attribution trigger=] |trigger|:
[=check if an attribution source and attribution trigger have matching attribution scopes|matching attribution scopes with the attribution trigger=]
to avoid creating multiple [=attribution reports=] from a single cross-site user interaction.
+
+
+
To check if an [=attribution trigger=] contains aggregatable data given an [=attribution trigger=] |trigger|,
run the following steps:
@@ -4266,6 +4585,9 @@ run the following steps:
1. If any of |trigger|'s [=attribution trigger/aggregatable values configurations=]'s [=aggregatable values configuration/values=] is not [=list/is empty|empty=], return true.
1. Return false.
+
+
+
To trigger attribution given an [=attribution trigger=] |trigger|, run the following steps:
1. Let |hasAggregatableData| be the result of [=checking if an attribution trigger contains aggregatable data=]
@@ -4308,12 +4630,15 @@ To trigger attribution given an [=attribution trigger=] |tri
run [=generate null attribution reports=] with |trigger| and
[=generate null attribution reports/report=] set to null.
1. [=list/Remove=] all [=attribution rate-limit records=] |entry| from the [=attribution rate-limit cache=] if the result of running
- [=can attribution rate-limit record be removed=] with |entry| and |trigger|'s [=attribution trigger/trigger time=] is true.
+ [=check if an attribution rate-limit record can be removed=] with |entry| and |trigger|'s [=attribution trigger/trigger time=] is true.
Issue(1287): Consider replacing |debugDataSet| with a [=list=].
+
+
Establishing report delivery time
+
To check whether a moment falls within a window given a [=moment=] |moment| and
a [=report window=] |window|:
@@ -4323,6 +4648,9 @@ a [=report window=] |window|:
return falls after.
1. Return falls within.
+
+
+
To obtain an event-level report delivery time given a
[=report window list=] |windows| and a [=moment=] |triggerTime|:
@@ -4333,6 +4661,9 @@ To obtain an event-level report delivery time given a
|window|'s [=report window/end=].
1. [=Assert=]: not reached.
+
+
+
To obtain an aggregatable attribution report delivery time given an [=attribution trigger=]
|trigger|, perform the following steps. They return a [=moment=].
@@ -4342,8 +4673,11 @@ To obtain an aggregatable attribution report delivery time given an [
1. Let |r| be a random double between 0 (inclusive) and 1 (exclusive) with uniform probability.
1. Return |triggerTime| + |r| × [=randomized aggregatable attribution report delay=].
+
+
Obtaining an event-level report
+
To obtain an event-level report given an [=attribution source=] |source|,
a [=moment=] |triggerTime|, a possibly null non-negative 64-bit integer
triggerDebugKey,
@@ -4381,14 +4715,20 @@ a 64-bit integer priority |priority|, and a non-negative 64-bit integer |trigger
:: (|source|'s [=attribution source/debug key=], |triggerDebugKey|).
1. Return |report|.
+
+
Obtaining an aggregatable report's required budget
+
An [=aggregatable report=] |report|'s
required aggregatable budget is the total [=aggregatable contribution/value=] of |report|'s
[=aggregatable report/contributions=].
+
+
Obtaining an aggregatable attribution report
+
To obtain an aggregatable attribution report given an [=attribution source=] |source| and
an [=attribution trigger=] |trigger|:
@@ -4423,8 +4763,11 @@ an [=attribution trigger=] |trigger|:
:: |source|'s [=attribution source/internal ID=].
1. Return |report|.
+
+
Generating randomized null attribution reports
+
To obtain a null attribution report given an [=attribution trigger=] |trigger| and a [=moment=] |sourceTime|:
1. Let |reportTime| be the result of running [=obtain an aggregatable attribution report delivery time=] with |trigger|.
@@ -4460,9 +4803,15 @@ To obtain a null attribution report given an [=attribution trigger=]
:: Null
1. Return |report|.
+
+
+
To obtain rounded source time given a [=moment=] |sourceTime|, return |sourceTime| in seconds
since the UNIX epoch, rounded down to a multiple of a whole day (86400 seconds).
+
+
+
To determine if a randomized null attribution report is generated given a double |randomPickRate|:
1. [=Assert=]: |randomPickRate| is between 0 and 1 (both inclusive).
@@ -4470,6 +4819,9 @@ To determine if a randomized null attribution report is generated giv
1. If |r| is less than |randomPickRate|, return true.
1. Otherwise, return false.
+
+
+
To generate null attribution reports given an [=attribution trigger=] |trigger| and a possibly null [=aggregatable attribution report=]
report:
@@ -4501,11 +4853,17 @@ To generate null attribution reports given an [=attribution trigger=]
1. [=list/Append=] |nullReport| to |nullReports|.
1. Return |nullReports|.
+
+
+
To shuffle a [=list=] |list|, reorder |list|'s elements such that each possible permutation has equal
probability of appearance.
+
+
Deferring trigger attribution
+
To
maybe defer and then complete trigger attribution given an [=attribution trigger=] |trigger|,
run the following steps [=in parallel=]:
@@ -4518,6 +4876,8 @@ run the following steps [=in parallel=]:
Issue: Specify this in terms of
Navigation
+
+
# Report delivery # {#report-delivery}
The user agent must periodically run [=queue reports for delivery=] on the
@@ -4531,6 +4891,7 @@ For example, this can be used to limit the maximum age of
any report that is sent.
+
To
queue reports for delivery given a [=set=] of
[=attribution reports=] |cache|, run the following steps:
@@ -4560,15 +4921,21 @@ To
queue reports for delivery given a [=set=] of
This is intended to allow user agents to optimize device resource usage.
1. Run [=attempt to deliver a report=] with |report|.
+
+
Encode an unsigned k-bit integer
+
To encode an unsigned k-byte integer given an integer |integerToEncode|
and an integer |byteLength|, return the representation of |integerToEncode| as a
big-endian [=byte sequence=] of length |byteLength|, left padding with zeroes as
necessary.
+
+
Obtaining an aggregatable report's debug mode
+
An [=aggregatable report=] |report|'s debug mode is the result
of running the following steps:
@@ -4585,8 +4952,11 @@ of running the following steps:
+
+
Obtaining an aggregatable report's shared info
+
An [=aggregatable report=] |report|'s shared info is the result
of running the following steps:
@@ -4630,8 +5000,11 @@ of running the following steps:
1. Return the [=string=] resulting from executing [=serialize an infra value to a json string=] on |sharedInfo|.
+
+
Obtaining an aggregatable report's aggregation service payloads
+
To obtain the public key for encryption given an [=aggregation coordinator=] |aggregationCoordinator|:
1. Let |url| be a new [=URL record=].
@@ -4648,6 +5021,9 @@ Issue: Specify this in terms of [=fetch=].
might independently pick a key uniformly at random for every encryption operation.
The key has to be uniquely identifiable.
+
+
+
An [=aggregatable report=] |report|'s plaintext payload
is the result of running the following steps:
@@ -4699,6 +5075,9 @@ is the result of running the following steps:
1. Return the [=byte sequence=] resulting from [[!RFC8949|CBOR encoding]] |payload|.
+
+
+
To obtain the encrypted payload given an [=aggregatable report=] |report| and
a public key |pkR|, run the following steps:
@@ -4710,6 +5089,9 @@ a public key |pkR|, run the following steps:
1. Return the [=byte sequence=] or an error resulting from [[RFC9180#name-encryption-and-decryption|encrypting]]
|plaintext| with the [[RFC9180#name-encryption-to-a-public-key|sender's context]].
+
+
+
To obtain the aggregation service payloads given an [=aggregatable report=] |report|,
run the following steps:
@@ -4732,8 +5114,11 @@ run the following steps:
1. [=list/Append=] |aggregationServicePayload| to |aggregationServicePayloads|.
1. Return |aggregationServicePayloads|.
+
+
Serialize attribution report body
+
To obtain an event-level report body given an [=attribution report=] |report|, run the following steps:
1. Let |data| be a [=map=] of the following key/value pairs:
@@ -4762,11 +5147,17 @@ To obtain an event-level report body given an [=attribution report=]
[=event-level report/attribution debug info=].
1. Return |data|.
+
+
+
To serialize an [=event-level report=] |report|, run the following steps:
1. Let |data| be the result of running [=obtain an event-level report body=] with |report|.
1. Return the [=byte sequence=] resulting from executing [=serialize an infra value to JSON bytes=] on |data|.
+
+
+
To obtain an [=aggregatable report=] body given an [=aggregatable report=] |report|, run the following steps:
1. [=Assert=]: |report|'s [=aggregatable report/effective attribution destination=] is not an [=opaque origin=].
@@ -4783,6 +5174,9 @@ To obtain an [=aggregatable report=] body given an [=aggregatable rep
1. Return |data|.
+
+
+
To serialize an [=aggregatable attribution report=] |report|, run the following steps:
1. Let |data| be the result of running [=obtain an aggregatable report body=] with |report|.
@@ -4792,11 +5186,17 @@ To serialize an [=aggregatable attribution report=] |report|, run th
|data|["`trigger_context_id`"] to |report|'s [=aggregatable attribution report/trigger context ID=].
1. Return the [=byte sequence=] resulting from executing [=serialize an infra value to JSON bytes=] on |data|.
+
+
+
To serialize an [=aggregatable debug report=] |report|, run the following steps:
1. Let |data| be the result of running [=obtain an aggregatable report body=] with |report|.
1. Return the [=byte sequence=] resulting from executing [=serialize an infra value to JSON bytes=] on |data|.
+
+
+
To serialize an [=attribution report=] |report|, run the following steps:
1. [=Assert=]: |report| is an [=event-level report=] or an [=aggregatable attribution report=].
@@ -4809,8 +5209,11 @@ To serialize an [=attribution report=] |report|, run the following st
+
+
Serialize verbose debug report body
+
To serialize a [=verbose debug report=] |report|, run the following steps:
1. Let |collection| be a new [=list=].
@@ -4823,8 +5226,11 @@ To serialize a [=verbose debug report=] |report|, run the following s
1. [=list/Append=] |data| to |collection|.
1. Return the [=byte sequence=] resulting from executing [=serialize an Infra value to JSON bytes=] on |collection|.
+
+
Get report request URL
+
To generate a report URL given a [=suitable origin=] |reportingOrigin| and a [=list=] of [=strings=] |path|:
1. Let |reportUrl| be a new [=URL=] record.
@@ -4836,6 +5242,9 @@ To generate a report URL given a [=suitable origin=] |reportingOrigin
1. Set |reportUrl|'s [=url/path=] to |fullPath|.
1. Return |reportUrl|.
+
+
+
To generate an attribution report URL given an [=attribution report=] |report| and an optional
[=boolean=] isDebugReport (default false):
@@ -4853,20 +5262,29 @@ To generate an attribution report URL given an [=attribution report=]
1. Return the result of running [=generate a report URL=] with |report|'s
[=attribution report/reporting origin=] and |path|.
+
+
+
To generate a verbose debug report URL given a [=verbose debug report=] |report|:
1. Let |path| be «"`debug`", "`verbose`"».
1. Return the result of running [=generate a report URL=] with |report|'s
[=verbose debug report/reporting origin=] and |path|.
+
+
+
To generate an aggregatable debug report URL given an [=aggregatable debug report=] |report|:
1. Let |path| be «"`debug`", "`report-aggregate-debug`"».
1. Return the result of running [=generate a report URL=] with |report|'s
[=aggregatable debug report/reporting origin=] and |path|.
+
+
Creating a report request
+
To create a report request given a [=URL=] |url| and a [=byte sequence=] |body|:
1. Let |headers| be a new [=header list=] containing a [=header=] named
@@ -4900,10 +5318,13 @@ To create a report request given a [=URL=] |url| and a [=byte sequenc
:: "`no-store`"
1. Return |request|.
+
+
Issuing a report request
This algorithm constructs a [=request=] and attempts to deliver it to a [=suitable origin=].
+
To attempt to deliver a report given an [=attribution report=] |report|, run the following steps:
1. [=Assert=]: Neither the [=event-level report cache=] nor the
@@ -4921,8 +5342,11 @@ A user agent may retry this algorithm in the event that there was an error.
To prevent the report recipient from learning additional information about
whether a user is online, retries might be limited in number and subject to random delays.
+
+
Issuing a debug report request
+
To attempt to deliver a debug report given an [=attribution report=] |report|:
1. The user-agent may ignore the report; if so, return.
@@ -4933,8 +5357,11 @@ To attempt to deliver a debug report given an [=attribution report=]
1. Let |request| be the result of executing [=create a report request=] on |url| and |data|.
1. [=Fetch=] |request|.
+
+
Issuing a verbose debug request
+
To attempt to deliver a verbose debug report given a [=verbose debug report=] |report|:
1. The user-agent may ignore the report; if so, return.
@@ -4943,8 +5370,11 @@ To attempt to deliver a verbose debug report given a [=verbose debug
1. Let |request| be the result of executing [=create a report request=] on |url| and |data|.
1. [=Fetch=] |request|.
+
+
Issuing an aggregatable debug request
+
To attempt to deliver an aggregatable debug report given an [=aggregatable debug report=] |report|:
1. The user-agent may ignore the report; if so, return.
@@ -4957,6 +5387,8 @@ Issue(220): This fetch should use a network partition key for an opaque origin.
A user agent may retry this algorithm in the event that there was an error.
+
+
# Cross App and Web Algorithms # {#cross-app-and-web}
Get OS registrations
@@ -4971,6 +5403,7 @@ An OS registration is a [=struct=] with the following items:
+
To get [=OS registrations=] from a header value given a
[=header value=] |header|:
@@ -4996,6 +5429,8 @@ To get [=OS registrations=] from a header value given a
1. If |registrations| [=list/is empty=], return an error.
1. Return |registrations|.
+
+
A registrar is one of the following:
@@ -5008,6 +5443,7 @@ A registrar is one of the following:
+
To get supported registrars:
1. Let |supportedRegistrars| be a new [=list=].
@@ -5017,8 +5453,11 @@ To get supported registrars:
to |supportedRegistrars|.
1. Return |supportedRegistrars|.
+
+
Deliver OS registration debug reports
+
To obtain and deliver debug reports on OS registrations given an
[=OS debug data type=] |dataType|, a [=list=] of [=OS registrations=] |registrations|,
an [=origin=] |contextOrigin|, and a [=boolean=] |fenced|:
@@ -5042,6 +5481,8 @@ an [=origin=] |contextOrigin|, and a [=boolean=] |fenced|:
:: |body|
1. Run [=obtain and deliver a verbose debug report=] with « |data| », |origin|, and |fenced|.
+
+
# User-Agent Automation # {#automation}
The user-agent has an associated boolean automation local testing mode (default false).