diff --git a/index.bs b/index.bs
index d91bbb8b3a..c06129d6b7 100644
--- a/index.bs
+++ b/index.bs
@@ -566,12 +566,12 @@ To clear site data given an [=origin=] |origin|:
1. [=set/iterate|For each=] [=event-level report=] |report| of the [=event-level report cache=]:
1. If |report|'s [=event-level report/reporting origin=] and |origin| are [=same origin=],
[=set/remove=] |report| from the [=event-level report cache=].
-1. [=set/iterate|For each=] [=aggregatable report=] |report| of the [=aggregatable report cache=]:
- 1. If |report|'s [=aggregatable report/reporting origin=] and |origin| are [=same origin=],
- [=set/remove=] |report| from the [=aggregatable report cache=].
+1. [=set/iterate|For each=] [=aggregatable attribution report=] |report| of the [=aggregatable attribution report cache=]:
+ 1. If |report|'s [=aggregatable attribution report/reporting origin=] and |origin| are [=same origin=],
+ [=set/remove=] |report| from the [=aggregatable attribution report cache=].
Note: We deliberately do *not* remove matching entries from the
-[=attribution rate-limit cache=], as doing so would allow a site to reset and
+[=attribution rate-limit cache=] and [=aggregatable debug rate-limit cache=], as doing so would allow a site to reset and
therefore exceed the intended rate limits at will.
# Structures # {#structures}
@@ -829,8 +829,8 @@ An attribution source is a [=struct=] with the following items:
:: A [=set=] of [=aggregatable dedup key/dedup key|aggregatable dedup key values=] associated with this [=attribution source=].
: debug reporting enabled
:: A [=boolean=].
-: number of aggregatable reports
-:: Number of [=aggregatable reports=] created for this [=attribution source=].
+: number of aggregatable attribution reports
+:: Number of [=aggregatable attribution reports=] created for this [=attribution source=].
: trigger-data matching mode
:: A [=trigger-data matching mode=].
: debug cookie set (default false)
@@ -839,6 +839,8 @@ An attribution source is a [=struct=] with the following items:
:: A [=boolean=].
: remaining aggregatable debug budget
:: A non-negative integer.
+: number of aggregatable debug reports
+:: Number of [=aggregatable debug reports=] created for this [=attribution source=].
: aggregatable debug reporting config
:: An [=aggregatable debug reporting config=].
@@ -924,9 +926,9 @@ An aggregatable source registration time configuration is one of the
: "exclude"
-:: "`source_registration_time`" is excluded from an [=aggregatable report=]'s [=aggregatable report/shared info=].
+:: "`source_registration_time`" is excluded from an [=aggregatable attribution report=]'s [=aggregatable attribution report/shared info=].
: "include"
-:: "`source_registration_time`" is included in an [=aggregatable report=]'s [=aggregatable report/shared info=].
+:: "`source_registration_time`" is included in an [=aggregatable attribution report=]'s [=aggregatable attribution report/shared info=].
@@ -977,17 +979,23 @@ An attribution trigger is a [=struct=] with the following items:
An attribution report is a [=struct=] with the following items:
-
+
: reporting origin
:: A [=suitable origin=].
: report time
:: A [=moment=].
: report ID
:: A [=string=].
+
+
+
+An attribution debug info is a [=tuple=] with the following items:
+
+
: source debug key
-:: Null or a non-negative 64-bit integer.
+:: Null or a [=string=].
: trigger debug key
-:: Null or a non-negative 64-bit integer.
+:: Null or a [=string=].
@@ -1012,12 +1020,14 @@ An event-level report is an [=attribution report=] with the following additional
:: A string.
: attribution destinations
:: A [=set=] of [=sites=].
+: attribution debug info
+:: An [=attribution debug info=].
-Aggregatable contribution
+
-An aggregatable contribution is a [=struct=] with the following items:
+An aggregatable contribution is a [=struct=] with the following items:
: key
@@ -1027,30 +1037,38 @@ An aggregatable contribution is a [=struct=] with the following items:
-Aggregatable report
+An aggregatable report is an [=attribution report=] with the following additional items:
-An aggregatable report is an [=attribution report=] with the following additional items:
-
-
-: source time
-:: A [=moment=].
+
: contributions
:: A [=list=] of [=aggregatable contributions=].
: effective attribution destination
:: A [=site=].
-: serialized private state token
-:: A [=serialized private state token=].
: aggregation coordinator
:: An [=aggregation coordinator=].
+
+
+
+An aggregatable attribution report is an [=aggregatable report=] with the following additional items:
+
+
+: source time
+:: A [=moment=].
+: serialized private state token
+:: A [=serialized private state token=].
: source registration time configuration
:: An [=aggregatable source registration time configuration=].
: is null report (default false)
:: A [=boolean=].
: trigger context ID
:: Null or a [=string=].
+: attribution debug info
+:: An [=attribution debug info=].
+An aggregatable debug report is an [=aggregatable report=].
+
Attribution rate-limits
A rate-limit scope is one of the following:
@@ -1081,10 +1099,26 @@ An attribution rate-limit record is a [=struct=] with the following i
-Attribution debug data
+Aggregatable debug rate-limits
+
+An aggregatable debug rate-limit record is a [=struct=] with the following items:
+
+
+: context site
+:: A [=site=].
+: reporting site
+:: A [=site=].
+: time
+:: A [=moment=].
+: consumed budget
+:: A positive integer.
+
+
+
+
A debug data type is a non-empty string that specifies the set of data that is
-contained in a [=verbose debug report=] or in an aggregatable debug report.
+contained in a [=verbose debug report=] or in an [=aggregatable debug report=].
A source debug data type is a [=debug data type=] for source registrations.
Possible values are:
@@ -1245,10 +1279,12 @@ A user agent holds an attribution source cache, which is a [=set=] of
A user agent holds an event-level report cache, which is a [=set=] of [=event-level reports=].
-A user agent holds an aggregatable report cache, which is a [=set=] of [=aggregatable reports=].
+A user agent holds an aggregatable attribution report cache, which is a [=set=] of [=aggregatable attribution reports=].
A user agent holds an attribution rate-limit cache, which is a [=set=] of [=attribution rate-limit records=].
+A user agent holds an aggregatable debug rate-limit cache, which is a [=set=] of [=aggregatable debug rate-limit records=].
+
The above caches are collectively known as the attribution caches. The [=attribution caches=] are
shared among all [=environment settings objects=].
@@ -1301,7 +1337,7 @@ Its value is «[ [=source type/navigation=] → 3, [=source type/event=] → 1 ]
Allowed aggregatable budget per source is a positive integer that controls the total
[=aggregatable report/required aggregatable budget=] of all [=aggregatable reports=]
-and aggregatable debug reports created for an [=attribution source=]. Its value is 65536.
+created for an [=attribution source=]. Its value is 65536.
Max aggregation keys per source registration is a positive integer that
controls the maximum [=map/size=] of an [=attribution source=]'s
@@ -1325,6 +1361,22 @@ controls the maximum [=map/size=] of a [=trigger spec map=] for an
the maximum [=string/length=] of an [=attribution trigger=]'s [=attribution trigger/trigger context ID=].
Its value is 64.
+Max contributions per aggregatable debug report is a positive
+integer that controls the maximum [=list/size=] of an [=aggregatable debug report=]'s
+[=aggregatable debug report/contributions=]. Its value is 2.
+
+Aggregatable debug rate-limit window is a positive [=duration=] that
+controls the rate-limiting window for aggregatable debug reporting. Its value is
+1 day.
+
+Max aggregatable debug budget per rate-limit window is a [=tuple=]
+consisting of two positive integers. The first controls the total [=aggregatable debug report/required aggregatable budget=]
+of all [=aggregatable debug reports=] with a given [=aggregatable debug rate-limit record/context site=]
+per [=aggregatable debug rate-limit window=]. The second controls the total
+[=aggregatable debug report/required aggregatable budget=] of all [=aggregatable debug reports=]
+with a given ([=aggregatable debug rate-limit record/context site=], [=aggregatable debug rate-limit record/reporting site=])
+per [=aggregatable debug rate-limit window=]. Its value is (220, 65536).
+
# Vendor-Specific Values # {#vendor-specific-values}
Max pending sources per source origin is a positive integer that
@@ -1338,14 +1390,14 @@ and [=obtain a randomized source response=].
Max trigger-state cardinality is a positive integer that controls the maximum [=set/size=] of [=obtain a set of possible trigger states|the set of possible trigger states=] for any one [=attribution source=].
-Randomized null report rate excluding source registration time is a
-double between 0 and 1 (both inclusive) that controls the randomized number of null reports
+Randomized null attribution report rate excluding source registration time is a
+double between 0 and 1 (both inclusive) that controls the randomized number of null attribution reports
generated for an [=attribution trigger=] whose [=attribution trigger/aggregatable source registration time configuration=]
is "[=aggregatable source registration time configuration/exclude=]". If [=automation local testing mode=] is true,
this is 0.
-Randomized null report rate including source registration time is a
-double between 0 and 1 (both inclusive) that controls the randomized number of null reports
+Randomized null attribution report rate including source registration time is a
+double between 0 and 1 (both inclusive) that controls the randomized number of null attribution reports
generated for an [=attribution trigger=] whose [=attribution trigger/aggregatable source registration time configuration=]
is "[=aggregatable source registration time configuration/include=]". If [=automation local testing mode=] is true,
this is 0.
@@ -1355,16 +1407,18 @@ controls how many [=event-level reports=] can be in the
[=event-level report cache=] per [=site=] in
[=event-level report/attribution destinations=].
-Max aggregatable reports per attribution destination is a positive integer that controls how
-many [=aggregatable reports=] can be in the [=aggregatable report cache=] per
-[=aggregatable report/effective attribution destination=].
+Max aggregatable attribution reports per attribution destination is a positive integer that controls how
+many [=aggregatable attribution reports=] can be in the [=aggregatable attribution report cache=] per
+[=aggregatable attribution report/effective attribution destination=].
Max event-level channel capacity per source is a [=map=] that
controls how many bits of information can be exposed associated with a single [=attribution source=].
The keys are «[=source type/navigation=], [=source type/event=]». The values are non-negative doubles.
-Max aggregatable reports per source is a positive integer that controls how many [=aggregatable reports=]
+Max aggregatable reports per source is a [=tuple=] consisting of two
+positive integers. The first controls how many [=aggregatable attribution reports=]
can be created by [=attribution triggers=] attributed to a single [=attribution source=].
+The second controls how many [=aggregatable debug reports=] can be created for an [=attribution source=].
Max destinations covered by unexpired sources is a positive
integer that controls the maximum number of distinct [=sites=] across all [=attribution source/attribution destinations=]
@@ -1412,8 +1466,8 @@ controls the maximum number of attributions for a
[=attribution rate-limit record/reporting origin=] [=site=]) per
[=attribution rate-limit window=]. This attribution limit is separate for event-level and aggregate reporting.
-Randomized aggregatable report delay is a positive [=duration=] that controls the
-random delay to deliver an [=aggregatable report=]. If [=automation local testing mode=] is true,
+Randomized aggregatable attribution report delay is a positive [=duration=] that controls the
+random delay to deliver an [=aggregatable attribution report=]. If [=automation local testing mode=] is true,
this is 0.
Default aggregation coordinator is the [=aggregation coordinator=] that controls how to
@@ -2133,6 +2187,120 @@ and a [=boolean=] |fenced|:
Note: The user agent may optionally include error details of any type in |body|["`error`"].
+Attribution debug mode
+
+To check if attribution debug mode can be enabled given an [=attribution debug info=] |debugInfo|:
+
+1. If |debugInfo|'s [=attribution debug info/source debug key=] is null,
+ return false.
+1. If |debugInfo|'s [=attribution debug info/trigger debug key=] is null,
+ return false.
+1. Return true.
+
+To serialize an attribution debug info given a [=map=] |data| and an
+[=attribution debug info=] |debugInfo|:
+
+1. If |debugInfo|'s [=attribution debug info/source debug key=] is not null, [=map/set=]
+ |data|["`source_debug_key`"] to |debugInfo|'s [=attribution debug info/source debug key=],
+ [=serialize an integer|serialized=].
+1. If |debugInfo|'s [=attribution debug info/trigger debug key=] is not null, [=map/set=]
+ |data|["`trigger_debug_key`"] to |report|'s [=attribution debug info/trigger debug key=],
+ [=serialize an integer|serialized=].
+
+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|:
+
+1. Let |matchingRecords| be all [=aggregatable debug rate-limit records=]
+ |record| of [=aggregatable debug rate-limit cache=] where all of the following
+ are true:
+ * |record|'s [=aggregatable debug rate-limit record/context site=] and |newRecord|'s [=aggregatable debug rate-limit record/context site=] are equal
+ * The [=duration from=] |record|'s [=aggregatable debug rate-limit record/time=] and |newRecord|'s [=aggregatable debug rate-limit record/time=] is <= [=aggregatable debug rate-limit window=]
+1. Let |totalBudget| be |newRecord|'s [=aggregatable debug rate-limit record/consumed budget=].
+1. Let |totalSameReportingBudget| be |totalBudget|.
+1. [=set/iterate|For each=] |record| of |matchingRecords|:
+ 1. Increment |totalBudget| value by |record|'s [=aggregatable debug rate-limit record/consumed budget=].
+ 1. If |record|'s [=aggregatable debug rate-limit record/reporting site=] and
+ |newRecord|'s [=aggregatable debug rate-limit record/reporting site=] are equal,
+ increment |totalSameReportingBudget| by |record|'s [=aggregatable debug rate-limit record/consumed budget=].
+1. If |totalBudget| is greater than [=max aggregatable debug budget per rate-limit window=][0],
+ return blocked.
+1. If |totalSameReportingBudget| is greater than [=max aggregatable debug budget per rate-limit window=][1],
+ return blocked.
+1. Return allowed.
+
+To obtain and deliver an aggregatable debug report given a [=list=]
+of [=aggregatable contributions=] |contributions|,
+an [=origin=] |reportingOrigin|, a [=site=] |effectiveDestination|,
+an [=aggregation coordinator=] |aggregationCoordinator|, and a [=moment=] |now|:
+
+1. Let |report| be a new [=aggregatable debug report=] with the items:
+ : [=aggregatable debug report/reporting origin=]
+ :: |reportingOrigin|
+ : [=aggregatable debug report/effective attribution destination=]
+ :: |effectiveDestination|
+ : [=aggregatable debug report/report time=]
+ :: |now|
+ : [=aggregatable debug report/report ID=]
+ :: The result of [=generating a random UUID=]
+ : [=aggregatable debug report/contributions=]
+ :: |contributions|
+ : [=aggregatable debug report/aggregation coordinator=]
+ :: |aggregationCoordinator|
+
+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|,
+an [=aggregation coordinator=] |aggregationCoordinator|, and a [=moment=] |now|:
+
+1. If |contributions| [=list/is empty=]:
+ 1. Run [=obtain and deliver an aggregatable debug report=]
+ with «», |contextSite|, |reportingOrigin|, |effectiveDestination|,
+ |aggregationCoordinator|, and |now|.
+ 1. Return.
+1. Let |remainingBudget| be [=allowed aggregatable budget per source=].
+1. Let |numReports| be 0.
+1. If |source| is not null:
+ 1. Set |remainingBudget| to |source|'s [=attribution source/remaining aggregatable debug budget=].
+ 1. Set |numReports| to |source|'s [=attribution source/number of aggregatable debug reports=].
+1. Let |requiredBudget| be the total [=aggregatable contribution/value=] of |contributions|.
+1. If |requiredBudget| is greater than |remainingBudget|:
+ 1. Run [=obtain and deliver an aggregatable debug report=] with «»,
+ |reportingOrigin|, |effectiveDestination|, |aggregationCoordinator|, and |now|.
+ 1. Return.
+1. If |numReports| is equal to [=max aggregatable reports per source=][1]:
+ 1. Run [=obtain and deliver an aggregatable debug report=] with «»,
+ |reportingOrigin|, |effectiveDestination|, |aggregationCoordinator|, and |now|.
+ 1. Return.
+1. Let |rateLimitRecord| be a new [=aggregatable debug rate-limit record=] with the items:
+ : [=aggregatable debug rate-limit record/context site=]
+ :: |contextSite|
+ : [=aggregatable debug rate-limit record/reporting site=]
+ :: The result of [=obtaining a site=] from |reportingOrigin|
+ : [=aggregatable debug rate-limit record/time=]
+ :: |now|
+ : [=aggregatable debug rate-limit record/consumed budget=]
+ :: |requiredBudget|
+1. If the result of running [=check if aggregatable debug reporting should be blocked by rate-limit=]
+ with |rateLimitRecord| is blocked:
+ 1. Run [=obtain and deliver an aggregatable debug report=] with «»,
+ |reportingOrigin|, |effectiveDestination|, |aggregationCoordinator|, and |now|.
+ 1. Return.
+1. Run [=obtain and deliver an aggregatable debug report=] with |contributions|,
+ |reportingOrigin|, |effectiveDestination|, |aggregationCoordinator|, and |now|.
+1. If |source| is not null:
+ 1. Decrement |source|'s [=attribution source/remaining aggregatable debug budget=]
+ value by |requiredBudget|.
+ 1. Increment |source|'s [=attribution source/number of aggregatable debug reports=]
+ value by 1.
+1. [=set/Append=] |rateLimitRecord| to the [=aggregatable debug rate-limit cache=].
+1. [=list/Remove=] all [=aggregatable debug rate-limit records=] |entry| from the
+ [=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
@@ -2685,7 +2853,7 @@ a [=trigger state=] |triggerState|:
To obtain and deliver a verbose debug report on source registration given a
[=source debug data type=] |dataType|, an [=attribution source=] |source|, and
-an optional [=boolean=] |isNoised| (default false):
+a [=boolean=] |isNoised|:
1. If |source|'s [=attribution source/debug reporting enabled=] is false, return.
1. If |source|'s [=attribution source/debug cookie set=] is false, return.
@@ -2739,6 +2907,41 @@ an optional [=boolean=] |isNoised| (default false):
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|,
+and a [=boolean=] |isNoised|:
+
+1. If |source|'s [=attribution source/fenced=] is true, return.
+1. Let |config| be |source|'s [=attribution source/aggregatable debug reporting config=].
+1. Let |debugDataMap| be |config|'s [=aggregatable debug reporting config/debug data=].
+1. If |debugDataMap| [=map/is empty=], return.
+1. Let |contributions| be a new [=list=].
+1. Let |dataTypeToReport| be |dataType|.
+1. If |dataTypeToReport| is "[=source debug data type/source-success=]"
+ and |isNoised| is true, set |dataTypeToReport| to "[=source debug data type/source-noised=]".
+1. If |debugDataMap|[|dataTypeToReport|] [=map/exists=]:
+ 1. Let |contribution| be a new [=aggregatable contribution=] with items:
+ : [=aggregatable contribution/key=]
+ :: |debugDataMap|[|dataTypeToReport|]'s [=aggregatable contribution/key=] bitwise-OR
+ |config|'s [=aggregatable debug reporting config/key piece=]
+ : [=aggregatable contribution/value=]
+ :: |debugDataMap|[|dataTypeToReport|]'s [=aggregatable contribution/value=]
+ 1. [=list/Append=] |contribution| to |contributions|.
+1. Run [=obtain and deliver an aggregatable debug report on registration=] with |contributions|,
+ |source|'s [=attribution source/source site=], |source|'s [=attribution source/reporting origin=],
+ |source|, |source|'s [=attribution source/attribution destinations=][0],
+ |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|,
+and an optional [=boolean=] |isNoised| (default false):
+
+1. Run [=obtain and deliver a verbose debug report on source registration=]
+ with |dataType|, |source|, and |isNoised|.
+1. Run [=obtain and deliver an aggregatable debug report on source registration=]
+ with |dataType|, |source|, and |isNoised|.
+
To process an attribution source given an [=attribution source=] |source|:
1. Let |cache| be the user agent's [=attribution source cache=].
@@ -2753,11 +2956,11 @@ To process an attribution source given an [=attribution source=] |sou
1. Let |epsilon| be |source|'s [=attribution source/event-level epsilon=].
1. Let |channelCapacity| be the result of [=computing the channel capacity of a source=] with |randomizedResponseConfig| and |epsilon|.
1. If |channelCapacity| is an error:
- 1. Run [=obtain and deliver a verbose debug report on source registration=] with "[=source debug data type/source-trigger-state-cardinality-limit=]" and |source|.
+ 1. Run [=obtain and deliver debug reports on source registration=] with "[=source debug data type/source-trigger-state-cardinality-limit=]" and |source|.
1. Return.
1. Let |sourceType| be |source|'s [=attribution source/source type=].
1. If |channelCapacity| is greater than [=max event-level channel capacity per source=][|sourceType|]:
- 1. Run [=obtain and deliver a verbose debug report on source registration=] with "[=source debug data type/source-channel-capacity-limit=]" and |source|.
+ 1. Run [=obtain and deliver debug reports on source registration=] with "[=source debug data type/source-channel-capacity-limit=]" and |source|.
1. Return.
1. Set |source|'s [=attribution source/randomized response=] to the result of
[=obtaining a randomized source response=] with |randomizedResponseConfig| and |epsilon|.
@@ -2772,25 +2975,24 @@ To process an attribution source given an [=attribution source=] |sou
[=attribution source/source origin=] are [=same origin=].
1. If |pendingSourcesForSourceOrigin|'s [=list/size=] is greater than or equal
to the user agent's [=max pending sources per source origin=]:
- 1. Run [=obtain and deliver a verbose debug report on source registration=] with "[=source debug data type/source-storage-limit=]" and |source|.
+ 1. Run [=obtain and deliver debug reports on source registration=] with "[=source debug data type/source-storage-limit=]" and |source|.
1. Return.
1. If the result of running [=check if an attribution source exceeds the unexpired destination limit=]
with |source| is true:
- 1. Run [=obtain and deliver a verbose debug report on source registration=] with "[=source debug data type/source-destination-limit=]" and |source|.
+ 1. Run [=obtain and deliver debug reports on source registration=] with "[=source debug data type/source-destination-limit=]" and |source|.
1. Return.
1. If the result of running [=check if an attribution source should be blocked by reporting-origin per site limit=]
with |source| is blocked:
- 1. Run [=obtain and deliver a verbose debug report on source registration=] with "[=source debug data type/source-reporting-origin-per-site-limit=]" and |source|.
+ 1. Run [=obtain and deliver debug reports on source registration=] with "[=source debug data type/source-reporting-origin-per-site-limit=]" and |source|.
1. Return.
1. Let |destinationRateLimitResult| be the result of running [=check if an attribution source exceeds the time-based destination limit=] with |source|.
1. If |destinationRateLimitResult| is "[=destination rate-limit result/hit reporting limit=]":
- 1. Run [=obtain and deliver a verbose debug report on source registration=] with "[=source debug data type/source-destination-rate-limit=]" and |source|.
+ 1. Run [=obtain and deliver debug reports on source registration=] with "[=source debug data type/source-destination-rate-limit=]" and |source|.
1. Return.
-1. Let |debugDataType| be "[=source debug data type/source-success=]".
1. Let |isNoised| be true if |source|'s [=attribution source/randomized response=]
is not null, otherwise false.
1. If |destinationRateLimitResult| is "[=destination rate-limit result/hit global limit=]":
- 1. Run [=obtain and deliver a verbose debug report on source registration=] with "[=source debug data type/source-destination-global-rate-limit=]", |source|, and |isNoised|.
+ 1. Run [=obtain and deliver debug reports on source registration=] with "[=source debug data type/source-destination-global-rate-limit=]", |source|, and |isNoised|.
1. Return.
1. Let |newRateLimitRecords| be a new [=set=].
1. [=set/iterate|For each=] |destination| in |source|'s [=attribution source/attribution destinations=]:
@@ -2811,7 +3013,7 @@ To process an attribution source given an [=attribution source=] |sou
:: null
1. If the result of running [=should processing be blocked by reporting-origin limit=] with
|rateLimitRecord| is blocked:
- 1. Run [=obtain and deliver a verbose debug report on source registration=] with
+ 1. Run [=obtain and deliver debug reports on source registration=] with
"[=source debug data type/source-reporting-origin-limit=]", |source|,
and |isNoised|.
1. Return.
@@ -2845,7 +3047,8 @@ To process an attribution source given an [=attribution source=] |sou
: [=attribution rate-limit record/event-level report ID=]
:: null
1. [=set/Append=] |rateLimitRecord| to the [=attribution rate-limit cache=].
-1. Run [=obtain and deliver a verbose debug report on source registration=] with |debugDataType|, |source|,
+1. Run [=obtain and deliver debug reports on source registration=] with
+ "[=source debug data type/source-success=]", |source|,
and |isNoised|.
1. [=set/Append=] |source| to |cache|.
@@ -3277,21 +3480,21 @@ To create [=aggregatable contributions=] given an [=attribution sourc
Can source create aggregatable contributions
To check if an [=attribution source=] can create [=aggregatable contributions=] given an
-[=aggregatable report=] |report| and an [=attribution source=] |sourceToAttribute|, run the following steps:
+[=aggregatable attribution report=] |report| and an [=attribution source=] |sourceToAttribute|, run the following steps:
1. Let |remainingAggregatableBudget| be |sourceToAttribute|'s [=attribution source/remaining aggregatable attribution budget=].
1. [=Assert=]: |remainingAggregatableBudget| is greater than or equal to 0.
-1. If |report|'s [=aggregatable report/required aggregatable budget=] is greater than
+1. If |report|'s [=aggregatable attribution report/required aggregatable budget=] is greater than
|remainingAggregatableBudget|, return false.
1. Return true.
-Obtaining debug data on trigger registration
+Obtaining verbose debug data on trigger registration
-To obtain debug data body on trigger registration given a
+To obtain verbose debug data body on trigger registration given a
[=trigger debug data type=] |dataType|, an [=attribution trigger=] |trigger|,
-an optional [=attribution source=]
+an optional [=attribution source=]
sourceToAttribute, and an optional [=attribution report=]
-report:
+report:
1. Let |body| be a new [=map=].
1. If |dataType| is:
@@ -3307,13 +3510,13 @@ an optional [=attribution source=] [=trigger debug data type/trigger-aggregate-storage-limit=]"
- :: [=map/Set=] |body|["`limit`"] to [=max aggregatable reports per attribution destination=],
+ :: [=map/Set=] |body|["`limit`"] to [=max aggregatable attribution reports per attribution destination=],
[=serialize an integer|serialized=].
: "[=trigger debug data type/trigger-aggregate-insufficient-budget=]"
:: [=map/Set=] |body|["`limit`"] to [=allowed aggregatable budget per source=],
[=serialize an integer|serialized=].
: "[=trigger debug data type/trigger-aggregate-excessive-reports=]"
- :: [=map/Set=] |body|["`limit`"] to [=max aggregatable reports per source=],
+ :: [=map/Set=] |body|["`limit`"] to [=max aggregatable reports per source=][0],
: "[=trigger debug data type/trigger-event-low-priority=]"
: "[=trigger debug data type/trigger-event-excessive-reports=]"
::
@@ -3334,10 +3537,10 @@ an optional [=attribution source=] sourceToAttribute,
-and an optional [=attribution report=] report:
+sourceToAttribute,
+and an optional [=attribution report=] report:
1. If |trigger|'s [=attribution trigger/debug reporting enabled=] is false, return null.
1. If the result of running [=check if cookie-based debugging is allowed=] with |trigger|'s
@@ -3348,7 +3551,7 @@ and an optional [=attribution report=] Triggering event-level attribution
@@ -3516,8 +3719,8 @@ To trigger event-level attribution given an [=attribution trigger=] |
1. If |matchedConfig|'s [=event-level trigger configuration/dedup key=] is not null,
[=list/append=] it to |sourceToAttribute|'s [=attribution source/dedup keys=].
1. If |triggeringStatus| is "[=triggering status/attributed=]" and
- |report|'s [=event-level report/source debug key=] is not null and |report|'s
- [=event-level report/trigger debug key=] is not null, [=queue a task=] to
+ the result of [=checking if attribution debug mode can be enabled=]
+ with |report|'s [=event-level report/attribution debug info=] is true, [=queue a task=] to
[=attempt to deliver a debug report=] with |report|.
1. Return the [=triggering result=] (|triggeringStatus|, |debugData|).
@@ -3546,15 +3749,15 @@ To trigger aggregatable attribution given an [=attribution trigger=]
[=list/contains=] it:
1. Return the [=triggering result=] ("[=triggering status/dropped=]",
("[=trigger debug data type/trigger-aggregate-deduplicated=]", null)).
-1. Let |report| be the result of running [=obtain an aggregatable report=] with |sourceToAttribute| and |trigger|.
-1. If |report|'s [=aggregatable report/contributions=] [=list/is empty=]:
+1. Let |report| be the result of running [=obtain an aggregatable attribution report=] with |sourceToAttribute| and |trigger|.
+1. If |report|'s [=aggregatable attribution report/contributions=] [=list/is empty=]:
1. Return the [=triggering result=] ("[=triggering status/dropped=]",
("[=trigger debug data type/trigger-aggregate-no-contributions=]", null)).
-1. Let |numMatchingReports| be the number of entries in the [=aggregatable report cache=] whose
- [=aggregatable report/effective attribution destination=] equals |trigger|'s [=attribution trigger/attribution destination=]
- and [=aggregatable report/is null report=] is false.
+1. Let |numMatchingReports| be the number of entries in the [=aggregatable attribution report cache=] whose
+ [=aggregatable attribution report/effective attribution destination=] equals |trigger|'s [=attribution trigger/attribution destination=]
+ and [=aggregatable attribution report/is null report=] is false.
1. If |numMatchingReports| is greater than or equal to the user agent's
- [=max aggregatable reports per attribution destination=]:
+ [=max aggregatable attribution reports per attribution destination=]:
1. Return the [=triggering result=] ("[=triggering status/dropped=]",
("[=trigger debug data type/trigger-aggregate-storage-limit=]", null)).
1. Let |rateLimitRecord| be a new [=attribution rate-limit record=] with the items:
@@ -3575,35 +3778,34 @@ To trigger aggregatable attribution given an [=attribution trigger=]
1. If the result of running [=check if attribution should be blocked by rate limits=]
with |trigger|, |sourceToAttribute|, and |rateLimitRecord| is not null,
return it.
-1. If |sourceToAttribute|'s [=attribution source/number of aggregatable reports=] value is equal to [=max aggregatable reports per source=], then:
+1. If |sourceToAttribute|'s [=attribution source/number of aggregatable attribution reports=] value is equal to [=max aggregatable reports per source=][0], then:
1. Return the [=triggering result=] ("[=triggering status/dropped=]",
("[=trigger debug data type/trigger-aggregate-excessive-reports=]", null)).
1. If the result of running [=check if an attribution source can create aggregatable contributions=]
with |report| and |sourceToAttribute| is false:
1. Return the [=triggering result=] ("[=triggering status/dropped=]",
("[=trigger debug data type/trigger-aggregate-insufficient-budget=]", null)).
-1. Add |report| to the [=aggregatable report cache=].
-1. Increment |sourceToAttribute|'s [=attribution source/number of aggregatable reports=] value by 1.
+1. [=set/Append=] |report| to the [=aggregatable attribution report cache=].
+1. Increment |sourceToAttribute|'s [=attribution source/number of aggregatable attribution reports=] value by 1.
1. Decrement |sourceToAttribute|'s [=attribution source/remaining aggregatable attribution budget=] value by
- |report|'s [=aggregatable report/required aggregatable budget=].
+ |report|'s [=aggregatable attribution report/required aggregatable budget=].
1. If |matchedDedupKey| is not null, [=list/append=] it to |sourceToAttribute|'s [=attribution source/aggregatable dedup keys=].
1. [=set/Append=] |rateLimitRecord| to the [=attribution rate-limit cache=].
-1. Run [=generate null reports and assign private state tokens=] with |trigger| and |report|.
-1. If |report|'s [=aggregatable report/source debug key=] is not null and |report|'s
- [=aggregatable report/trigger debug key=] is not null, [=queue a task=] to
- [=attempt to deliver a debug report=] with |report|.
+1. Run [=generate null attribution reports and assign private state tokens=] with |trigger| and |report|.
+1. If the result of [=checking if attribution debug mode can be enabled=]
+ with |report|'s [=aggregatable attribution report/attribution debug info=] is true,
+ [=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 an optional [=attribution source=]
-sourceToAttribute:
+and an optional [=attribution source=] |sourceToAttribute|:
1. Let |debugDataList| be a new [=list=].
1. [=set/iterate|For each=] |data| of |dataSet|:
- 1. Let |debugData| be the result of running [=obtain debug data on trigger registration=] with
+ 1. Let |debugData| be the result of running [=obtain verbose debug data on trigger registration=] with
|data|'s [=trigger debug data/data type=], |trigger|, |sourceToAttribute|,
and |data|'s [=trigger debug data/report=].
1. If |debugData| is not null, [=list/append=] |debugData| to |debugDataList|.
@@ -3611,6 +3813,48 @@ and an optional [=attribution source=]
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 an optional [=attribution source=] |sourceToAttribute|:
+
+1. If |trigger|'s [=attribution trigger/fenced=] is true, return.
+1. Let |config| be |trigger|'s [attribution trigger/aggregatable debug reporting config=].
+1. Let |debugDataMap| be |config|'s [=aggregatable debug reporting config/debug data=].
+1. If |debugDataMap| [=map/is empty=], return.
+1. Let |sourceKeyPiece| be 0.
+1. If |sourceToAttribute| is not null, then set |sourceKeyPiece| to
+ |sourceToAttribute|'s [=attribution source/aggregatable debug reporting config=]'s
+ [=aggregatable debug reporting config/key piece=].
+1. Let |contributions| be a new [=list=].
+1. Let |contextKeyPiece| be |sourceKeyPiece| bitwise-OR |config|'s
+ [=aggregatable debug reporting config/key piece=].
+1. [=set/iterate|For each=] |data| of |dataSet|:
+ 1. Let |type| be |data|'s [=trigger debug data/data type=].
+ 1. If |debugDataMap|[|type|] [=map/exists=]:
+ 1. Let |keyPiece| be |contextKeyPiece| bitwise-OR |debugDataMap|[|type|]'s
+ [=aggregatable contribution/key=].
+ 1. Let |contribution| be a new [=aggregatable contribution=] with the items:
+ : [=aggregatable contribution/key=]
+ :: |keyPiece|
+ : [=aggregatable contribution/value=]
+ :: |debugDataMap|[|type|]'s [=aggregatable contribution/value=]
+ 1. [=list/Append=] |contribution| to |contributions|.
+1. Run [=obtain and deliver an aggregatable debug report on registration=] with |contributions|,
+ |trigger|'s [=attribution trigger/attribution destination=], |trigger|'s [=attribution trigger/reporting origin=],
+ |sourceToAttribute|, |trigger|'s [=attribution trigger/attribution destination=],
+ |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 an optional [=attribution source=]
+sourceToAttribute:
+
+1. Run [=obtain and deliver a verbose debug report on trigger registration=]
+ with |dataSet|, |trigger|, and |sourceToAttribute|.
+1. Run [=obtain and deliver an aggregatable debug report on trigger registration=]
+ with |dataSet|, |trigger|, and |sourceToAttribute|.
+
To find matching sources given an [=attribution trigger=] |trigger|:
1. Let |matchingSources| be a new [=list=].
@@ -3641,11 +3885,11 @@ To trigger attribution given an [=attribution trigger=] |tri
[=set/is empty=] and |hasAggregatableData| is false, return.
1. Let |matchingSources| be the result of running [=find matching sources=] with |trigger|.
1. If |matchingSources| [=list/is empty=]:
- 1. Run [=obtain and deliver a verbose debug report on trigger registration=] with
+ 1. Run [=obtain and deliver debug reports on trigger registration=] with
« ("[=trigger debug data type/trigger-no-matching-source=]", null) »,
- |trigger|, and [=obtain and deliver a verbose debug report on trigger registration/sourceToAttribute=] set to null.
- 1. If |hasAggregatableData| is true, then run [=generate null reports and assign private state tokens=]
- with |trigger| and [=generate null reports and assign private state tokens/report=] set to null.
+ |trigger|, and [=obtain and deliver debug reports on trigger registration/sourceToAttribute=] set to null.
+ 1. If |hasAggregatableData| is true, then run [=generate null attribution reports and assign private state tokens=]
+ with |trigger| and [=generate null attribution reports and assign private state tokens/report=] set to null.
1. Return.
1. Let |sourceToAttribute| be |matchingSources|[0].
1. If the result of running
@@ -3653,11 +3897,11 @@ To trigger attribution given an [=attribution trigger=] |tri
|sourceToAttribute|, |trigger|'s [=attribution trigger/filters=],
|trigger|'s [=attribution trigger/negated filters=], and
|trigger|'s [=attribution trigger/trigger time=] is false:
- 1. Run [=obtain and deliver a verbose debug report on trigger registration=] with
+ 1. Run [=obtain and deliver debug reports on trigger registration=] with
« ("[=trigger debug data type/trigger-no-matching-filter-data=]", null) »,
|trigger|, and |sourceToAttribute|.
- 1. If |hasAggregatableData| is true, then run [=generate null reports and assign private state tokens=]
- with |trigger| and [=generate null reports and assign private state tokens/report=] set to null.
+ 1. If |hasAggregatableData| is true, then run [=generate null attribution reports and assign private state tokens=]
+ with |trigger| and [=generate null attribution reports and assign private state tokens/report=] set to null.
1. Return.
1. [=list/Remove=] |sourceToAttribute| from |matchingSources|.
1. [=list/iterate|For each=] |item| of |matchingSources|:
@@ -3671,11 +3915,11 @@ To trigger attribution given an [=attribution trigger=] |tri
then [=set/append=] |eventLevelResult|'s [=triggering result/debug data=] to |debugDataSet|.
1. If |aggregatableResult|'s [=triggering result/debug data=] is not null,
then [=set/append=] |aggregatableResult|'s [=triggering result/debug data=] to |debugDataSet|.
-1. Run [=obtain and deliver a verbose debug report on trigger registration=] with |debugDataSet|,
+1. Run [=obtain and deliver debug reports on trigger registration=] with |debugDataSet|,
|trigger|, and |sourceToAttribute|.
1. If |hasAggregatableData| and |aggregatableResult|'s [=triggering result/status=] is "[=triggering status/dropped=]",
- run [=generate null reports and assign private state tokens=] with |trigger| and
- [=generate null reports and assign private state tokens/report=] set to null.
+ run [=generate null attribution reports and assign private state tokens=] with |trigger| and
+ [=generate null attribution reports and assign private state tokens/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.
@@ -3702,13 +3946,13 @@ To obtain an event-level report delivery time given a
|window|'s [=report window/end=].
1. [=Assert=]: not reached.
-To obtain an aggregatable report delivery time given an [=attribution trigger=]
+To obtain an aggregatable attribution report delivery time given an [=attribution trigger=]
|trigger|, perform the following steps. They return a [=moment=].
1. Let |triggerTime| be |trigger|'s [=attribution trigger/trigger time=].
1. If |trigger|'s [=attribution trigger/trigger context ID=] is not null, return |triggerTime|.
1. Let |r| be a random double between 0 (inclusive) and 1 (exclusive) with uniform probability.
-1. Return |triggerTime| + |r| * [=randomized aggregatable report delay=].
+1. Return |triggerTime| + |r| * [=randomized aggregatable attribution report delay=].
Obtaining an event-level report
@@ -3744,109 +3988,103 @@ a 64-bit integer priority |priority|, and a [=trigger spec map=] [=map/entry=]
:: |source|'s [=attribution source/source identifier=].
: [=event-level report/report ID=]
:: The result of [=generating a random UUID=].
- : [=event-level report/source debug key=]
- :: |source|'s [=attribution source/debug key=].
- : [=event-level report/trigger debug key=]
- :: |triggerDebugKey|.
+ : [=event-level report/attribution debug info=]
+ :: (|source|'s [=attribution source/debug key=], |triggerDebugKey|).
1. Return |report|.
Obtaining an aggregatable report's required budget
-An [=aggregatable report=] |report|'s
+An [=aggregatable report=] |report|'s
required aggregatable budget is the total [=aggregatable contribution/value=] of |report|'s
[=aggregatable report/contributions=].
-Obtaining an aggregatable report
+Obtaining an aggregatable attribution report
-To obtain an aggregatable report given an [=attribution source=] |source| and
+To obtain an aggregatable attribution report given an [=attribution source=] |source| and
an [=attribution trigger=] |trigger|:
-1. Let |reportTime| be the result of running [=obtain an aggregatable report delivery time=] with |trigger|.
-1. Let |report| be a new [=aggregatable report=] struct whose items are:
+1. Let |reportTime| be the result of running [=obtain an aggregatable attribution report delivery time=] with |trigger|.
+1. Let |report| be a new [=aggregatable attribution report=] struct whose items are:
- : [=aggregatable report/reporting origin=]
+ : [=aggregatable attribution report/reporting origin=]
:: |source|'s [=attribution source/reporting origin=].
- : [=aggregatable report/effective attribution destination=]
+ : [=aggregatable attribution report/effective attribution destination=]
:: |trigger|'s [=attribution trigger/attribution destination=].
- : [=aggregatable report/source time=]
+ : [=aggregatable attribution report/source time=]
:: |source|'s [=attribution source/source time=].
- : [=aggregatable report/report time=]
+ : [=aggregatable attribution report/report time=]
:: |reportTime|.
- : [=aggregatable report/report ID=]
+ : [=aggregatable attribution report/report ID=]
:: The result of [=generating a random UUID=].
- : [=aggregatable report/source debug key=]
- :: |source|'s [=attribution source/debug key=].
- : [=aggregatable report/trigger debug key=]
- :: |trigger|'s [=attribution trigger/debug key=].
- : [=aggregatable report/contributions=]
+ : [=aggregatable attribution report/attribution debug info=]
+ :: (|source|'s [=attribution source/debug key=], |trigger|'s [=attribution trigger/debug key=]).
+ : [=aggregatable attribution report/contributions=]
:: The result of running [=create aggregatable contributions=] with |source| and |trigger|.
- : [=aggregatable report/serialized private state token=]
+ : [=aggregatable attribution report/serialized private state token=]
:: null.
- : [=aggregatable report/aggregation coordinator=]
+ : [=aggregatable attribution report/aggregation coordinator=]
:: |trigger|'s [=attribution trigger/aggregation coordinator=].
- : [=aggregatable report/source registration time configuration=]
+ : [=aggregatable attribution report/source registration time configuration=]
:: |trigger|'s [=attribution trigger/aggregatable source registration time configuration=].
- : [=aggregatable report/trigger context ID=]
+ : [=aggregatable attribution report/trigger context ID=]
:: |trigger|'s [=attribution trigger/trigger context ID=]
1. Return |report|.
-Generating randomized null reports
+Generating randomized null attribution reports
-To obtain a null report given an [=attribution trigger=] |trigger| and a [=moment=] |sourceTime|:
+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 report delivery time=] with |trigger|.
-1. Let |report| be a new [=aggregatable report=] struct whose items are:
+1. Let |reportTime| be the result of running [=obtain an aggregatable attribution report delivery time=] with |trigger|.
+1. Let |report| be a new [=aggregatable attribution report=] struct whose items are:
- : [=aggregatable report/reporting origin=]
+ : [=aggregatable attribution report/reporting origin=]
:: |trigger|'s [=attribution trigger/reporting origin=]
- : [=aggregatable report/effective attribution destination=]
+ : [=aggregatable attribution report/effective attribution destination=]
:: |trigger|'s [=attribution trigger/attribution destination=]
- : [=aggregatable report/source time=]
+ : [=aggregatable attribution report/source time=]
:: |sourceTime|
- : [=aggregatable report/report time=]
+ : [=aggregatable attribution report/report time=]
:: |reportTime|
- : [=aggregatable report/report ID=]
+ : [=aggregatable attribution report/report ID=]
:: The result of [=generating a random UUID=]
- : [=aggregatable report/source debug key=]
- :: null
- : [=aggregatable report/trigger debug key=]
- :: |trigger|'s [=attribution trigger/debug key=]
- : [=aggregatable report/contributions=]
+ : [=aggregatable attribution report/attribution debug info=]
+ :: (null, |trigger|'s [=attribution trigger/debug key=])
+ : [=aggregatable attribution report/contributions=]
:: «»
- : [=aggregatable report/serialized private state token=]
+ : [=aggregatable attribution report/serialized private state token=]
:: null
- : [=aggregatable report/aggregation coordinator=]
+ : [=aggregatable attribution report/aggregation coordinator=]
:: |trigger|'s [=attribution trigger/aggregation coordinator=]
- : [=aggregatable report/source registration time configuration=]
+ : [=aggregatable attribution report/source registration time configuration=]
:: |trigger|'s [=attribution trigger/aggregatable source registration time configuration=]
- : [=aggregatable report/is null report=]
+ : [=aggregatable attribution report/is null report=]
:: true
- : [=aggregatable report/trigger context ID=]
+ : [=aggregatable attribution report/trigger context ID=]
:: |trigger|'s [=attribution trigger/trigger context ID=]
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 report is generated given a double |randomPickRate|:
+To determine if a randomized null attribution report is generated given a double |randomPickRate|:
1. [=Assert=]: |randomPickRate| is between 0 and 1 (both inclusive).
1. Let |r| be a random double between 0 (inclusive) and 1 (exclusive) with uniform probability.
1. If |r| is less than |randomPickRate|, return true.
1. Otherwise, return false.
-To generate null reports given an [=attribution trigger=] |trigger| and an optional [=aggregatable report=] |report| defaulting to null:
+To generate null attribution reports given an [=attribution trigger=] |trigger| and an optional [=aggregatable attribution report=] |report| defaulting to null:
1. Let |nullReports| be a new [=list=].
1. If |trigger|'s [=attribution trigger/aggregatable source registration time configuration=] is "[=aggregatable source registration time configuration/exclude=]":
- 1. Let |randomizedNullReportRate| be [=randomized null report rate excluding source registration time=].
+ 1. Let |randomizedNullReportRate| be [=randomized null attribution report rate excluding source registration time=].
1. If |trigger|'s [=attribution trigger/trigger context ID=] is not null, set
|randomizedNullReportRate| to 1.
- 1. If |report| is null and the result of [=determining if a randomized null report is generated=] with
+ 1. If |report| is null and the result of [=determining if a randomized null attribution report is generated=] with
|randomizedNullReportRate| is true:
- 1. Let |nullReport| be the result of [=obtaining a null report=] with |trigger| and |trigger|'s
+ 1. Let |nullReport| be the result of [=obtaining a null attribution report=] with |trigger| and |trigger|'s
[=attribution trigger/trigger time=].
- 1. [=set/Append=] |nullReport| to the [=aggregatable report cache=].
+ 1. [=set/Append=] |nullReport| to the [=aggregatable attribution report cache=].
1. [=list/Append=] |nullReport| to |nullReports|.
1. Otherwise:
1. [=Assert=]: |trigger|'s [=attribution trigger/trigger context ID=] is null.
@@ -3854,21 +4092,21 @@ To generate null reports given an [=attribution trigger=] |trigger| a
1. Round |maxSourceExpiry| away from zero to the nearest day (86400 seconds).
1. Let |roundedAttributedSourceTime| be null.
1. If |report| is not null, set |roundedAttributedSourceTime| to the result of [=obtaining rounded source time=] with |report|'s
- [=aggregatable report/source time=].
+ [=aggregatable attribution report/source time=].
1. [=set/iterate|For each=] integer |day| of [=the range=] 0 to the number of days in |maxSourceExpiry|, inclusive:
1. Let |fakeSourceTime| be |trigger|'s [=attribution trigger/trigger time=] - |day| days.
1. If |roundedAttributedSourceTime| is not null and equals the result of [=obtaining rounded source time=] with |fakeSourceTime|:
1. [=iteration/Continue=].
- 1. If the result of [=determining if a randomized null report is generated=] with [=randomized null report rate including source registration time=] is true:
- 1. Let |nullReport| be the result of [=obtaining a null report=] with |trigger| and |fakeSourceTime|.
- 1. [=set/Append=] |nullReport| to the [=aggregatable report cache=].
+ 1. If the result of [=determining if a randomized null attribution report is generated=] with [=randomized null attribution report rate including source registration time=] is true:
+ 1. Let |nullReport| be the result of [=obtaining a null attribution report=] with |trigger| and |fakeSourceTime|.
+ 1. [=set/Append=] |nullReport| to the [=aggregatable attribution report cache=].
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.
-To assign private state tokens given a [=list=] of [=aggregatable reports=] |reports| and
+To assign private state tokens given a [=list=] of [=aggregatable attribution reports=] |reports| and
an [=attribution trigger=] |trigger|:
1. If |reports| [=list/is empty=], return.
@@ -3879,14 +4117,14 @@ an [=attribution trigger=] |trigger|:
1. [=shuffle a list|Shuffle=] |verifications|.
1. Let |n| be the minimum of |reports|'s [=list/size=] and |verifications|'s [=list/size=].
1. [=set/iterate|For each=] integer |i| of [=the exclusive range|the range=] 0 to |n|, exclusive:
- 1. Set |reports|[i]'s [=aggregatable report/report ID=] to |verifications|[i]'s [=trigger verification/id=].
- 1. Set |reports|[i]'s [=aggregatable report/serialized private state token=] to |verifications|[i]'s [=trigger verification/token=].
+ 1. Set |reports|[i]'s [=aggregatable attribution report/report ID=] to |verifications|[i]'s [=trigger verification/id=].
+ 1. Set |reports|[i]'s [=aggregatable attribution report/serialized private state token=] to |verifications|[i]'s [=trigger verification/token=].
-To generate null reports and assign private state tokens given an [=attribution trigger=] |trigger|
-and an optional [=aggregatable report=] report defaulting to null:
+To generate null attribution reports and assign private state tokens given an [=attribution trigger=] |trigger|
+and an optional [=aggregatable attribution report=] report defaulting to null:
-1. Let |reports| be the result of [=generating null reports=] with |trigger| and |report|.
+1. Let |reports| be the result of [=generating null attribution reports=] with |trigger| and |report|.
1. If |report| is not null:
1. [=list/Append=] |report| to |reports|.
1. Run [=assign private state tokens=] with |reports| and |trigger|.
@@ -3908,7 +4146,7 @@ Issue: Specify this in terms of debug mode is the result
of running the following steps:
-1. If |report|'s [=aggregatable report/source debug key=] is null, return disabled.
-1. If |report|'s [=aggregatable report/trigger debug key=] is null, return disabled.
-1. Return enabled.
+1. If |report| is an:
+
+ : [=aggregatable attribution report=]
+ ::
+ 1. If the result of [=checking if attribution debug mode can be enabled=] with
+ |report|'s [=aggregatable attribution report/attribution debug info=] is true,
+ return enabled.
+ 1. Return disabled.
+ : [=aggregatable debug report=]
+ :: Return disabled.
+
+
Obtaining an aggregatable report's shared info
-An [=aggregatable report=] |report|'s shared info is the result
+An [=aggregatable report=] |report|'s shared info is the result
of running the following steps:
1. Let |reportingOrigin| be |report|'s [=aggregatable report/reporting origin=].
+1. Let |api| be null.
+1. If |report| is an:
+
+ : [=aggregatable attribution report=]
+ :: Set |api| to "`attribution-reporting`".
+ : [=aggregatable debug report=]
+ :: Set |api| to "`attribution-reporting-debug`".
+
+
1. Let |sharedInfo| be a [=map=] of the following key/value pairs:
: "`api`"
- :: "`attribution-reporting`"
+ :: |api|
: "`attribution_destination`"
:: |report|'s [=aggregatable report/effective attribution destination=], serialized
: "`report_id`"
@@ -3976,15 +4232,16 @@ of running the following steps:
1. If |report|'s [=aggregatable report/debug mode=] is enabled,
[=map/set=] |sharedInfo|["`debug_mode`"] to "`enabled`".
-1. If |report|'s [=aggregatable report/source registration time configuration=] is:
-
- : "[=aggregatable source registration time configuration/include=]"
- :: [=map/Set=] |sharedInfo|["`source_registration_time`"] to the result of [=obtaining rounded source time=]
- with |report|'s [=aggregatable report/source time=], [=serialize an integer|serialized=].
- : "[=aggregatable source registration time configuration/exclude=]"
- :: [=map/Set=] |sharedInfo|["`source_registration_time`"] to "`0`".
+1. If |report| is an [=aggregatable attribution report=]:
+ 1. If |report|'s [=aggregatable attribution report/source registration time configuration=] is:
+
+ : "[=aggregatable source registration time configuration/include=]"
+ :: [=map/Set=] |sharedInfo|["`source_registration_time`"] to the result of [=obtaining rounded source time=]
+ with |report|'s [=aggregatable attribution report/source time=], [=serialize an integer|serialized=].
+ : "[=aggregatable source registration time configuration/exclude=]"
+ :: [=map/Set=] |sharedInfo|["`source_registration_time`"] to "`0`".
-
+
1. Return the [=string=] resulting from executing [=serialize an infra value to a json string=] on |sharedInfo|.
@@ -4010,9 +4267,18 @@ An [=aggregatable report=] |report|'s plaintext p
is the result of running the following steps:
1. Let |payloadData| be a new [=list=].
+1. Let |maxContributions| be null.
+1. If |report| is an:
+
+ : [=aggregatable attribution report=]
+ :: Set |maxContributions| to [=max aggregation keys per source registration=].
+ : [=aggregatable debug report=]
+ :: Set |maxContributions| to [=max contributions per aggregatable debug report=].
+
+
1. Let |contributions| be |report|'s [=aggregatable report/contributions=].
-1. [=iteration/While=] |contributions|' [=list/size=] is less than [=max
- aggregation keys per source registration=]:
+1. [=Assert=]: |contributions|'s [=list/size=] is less than or equal to |maxContributions|.
+1. [=iteration/While=] |contributions|' [=list/size=] is less than |maxContributions|:
1. Let |nullContribution| be a new [=aggregatable contribution=] with the
items:
@@ -4099,12 +4365,8 @@ To obtain an event-level report body given an [=attribution report=]
: "`scheduled_report_time`"
:: |report|'s [=event-level report/report time=] in seconds since the UNIX epoch, [=serialize an integer|serialized=]
-1. If |report|'s [=event-level report/source debug key=] is not null, [=map/set=]
- |data|["`source_debug_key`"] to |report|'s [=event-level report/source debug key=],
- [=serialize an integer|serialized=].
-1. If |report|'s [=event-level report/trigger debug key=] is not null, [=map/set=]
- |data|["`trigger_debug_key`"] to |report|'s [=event-level report/trigger debug key=],
- [=serialize an integer|serialized=].
+1. Run [=serialize an attribution debug info=] with |data| and |report|'s
+ [=event-level report/attribution debug info=].
1. Return |data|.
To serialize an [=event-level report=] |report|, run the following steps:
@@ -4112,7 +4374,7 @@ To serialize an [=event-level report=] |report|, run the following st
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 serialize an [=aggregatable report=] |report|, run the following steps:
+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 the [=opaque origin=].
1. Let |aggregationServicePayloads| be the result of running [=obtain the aggregation service payloads=].
@@ -4126,25 +4388,32 @@ To serialize an [=aggregatable report=] |report|, run the following
: "`aggregation_coordinator_origin`"
:: |report|'s [=aggregatable report/aggregation coordinator=], [=serialization of an origin|serialized=]
-1. If |report|'s [=aggregatable report/source debug key=] is not null, [=map/set=]
- |data|["`source_debug_key`"] to |report|'s [=aggregatable report/source debug key=],
- [=serialize an integer|serialized=].
-1. If |report|'s [=aggregatable report/trigger debug key=] is not null, [=map/set=]
- |data|["`trigger_debug_key`"] to |report|'s [=aggregatable report/trigger debug key=],
- [=serialize an integer|serialized=].
-1. If |report|'s [=aggregatable report/trigger context ID=] is not null, [=map/set=]
- |data|["`trigger_context_id`"] to |report|'s [=aggregatable report/trigger context ID=].
+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|.
+1. Run [=serialize an attribution debug info=] with |data| and |report|'s
+ [=aggregatable attribution report/attribution debug info=].
+1. If |report|'s [=aggregatable attribution report/trigger context ID=] is not null, [=map/set=]
+ |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=].
1. If |report| is an:
- - [=event-level report=]
- - Return the result of running [=serialize an event-level report=] with |report|.
+ : [=event-level report=]
+ :: Return the result of running [=serialize an event-level report=] with |report|.
+ : [=aggregatable attribution report=]
+ :: Return the result of running [=serialize an aggregatable attribution report=] with |report|.
- - [=aggregatable report=]
- - Return the result of running [=serialize an aggregatable report=] with |report|.
Serialize verbose debug report body
@@ -4177,15 +4446,16 @@ To generate a report URL given a [=suitable origin=] |reportingOrigin
To generate an attribution report URL given an [=attribution report=] |report| and an optional
[=boolean=] isDebugReport (default false):
+1. [=Assert=]: |report| is an [=event-level report=] or an [=aggregatable report=].
1. Let |path| be a new [=list=].
1. If |isDebugReport| is true, [=list/append=] "`debug`" to |path|.
1. If |report| is an:
- - [=event-level report=]
- - [=list/Append=] "`report-event-attribution`" to |path|.
+ : [=event-level report=]
+ :: [=list/Append=] "`report-event-attribution`" to |path|.
+ : [=aggregatable attribution report=]
+ :: [=list/Append=] "`report-aggregate-attribution`" to |path|.
- - [=aggregatable report=]
- - [=list/Append=] "`report-aggregate-attribution`" to |path|.
1. Return the result of running [=generate a report URL=] with |report|'s
[=attribution report/reporting origin=] and |path|.
@@ -4196,6 +4466,12 @@ To generate a verbose debug report URL given a [=verbose debug report
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|, a [=byte sequence=] |body|,
@@ -4241,10 +4517,10 @@ and a [=header list=] |newHeaders| (defaults to an empty [=list=]):
To generate attribution report headers given an [=attribution report=] |report|:
1. Let |newHeaders| be a new [=header list=].
-1. If |report| is an [=aggregatable report=]:
- 1. If |report|'s [=aggregatable report/serialized private state token=] is not null,
+1. If |report| is an [=aggregatable attribution report=]:
+ 1. If |report|'s [=aggregatable attribution report/serialized private state token=] is not null,
[=header list/append=] a new [=header=] named "`Sec-Attribution-Reporting-Private-State-Token`" to |newHeaders|
- whose value is |report|'s [=aggregatable report/serialized private state token=].
+ whose value is |report|'s [=aggregatable attribution report/serialized private state token=].
1. Return |newHeaders|.
Issuing a report request
@@ -4254,7 +4530,7 @@ This algorithm constructs a [=request=] and attempts to deliver it to a [=suitab
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
- [=aggregatable report cache=] [=set/contains=] |report|.
+ [=aggregatable attribution report cache=] [=set/contains=] |report|.
1. The user-agent MAY ignore the report; if so, return.
1. Let |url| be the result of executing [=generate an attribution report URL=] on |report|.
1. Let |data| be the result of executing [=serialize an attribution report=] on |report|.
@@ -4292,6 +4568,16 @@ 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.
+1. Let |url| be the result of executing [=generate an aggregatable debug report URL=] on |report|.
+1. Let |data| be the result of executing [=serialize an aggregatable debug report=] on |report|.
+1. Let |request| be the result of executing [=create a report request=] on |url| and |data|.
+1. [=Fetch=] |request|.
+
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.
@@ -4532,7 +4818,7 @@ Note: Without this, reports would be subject to noise and delays, making testing
The [=remote end steps=] are:
-1. [=list/iterate|For each=] |cache| of « [=event-level report cache=], [=aggregatable report cache=] »:
+1. [=list/iterate|For each=] |cache| of « [=event-level report cache=], [=aggregatable attribution report cache=] »:
1. [=set/iterate|For each=] |report| of |cache|:
1. [=set/Remove=] |report| from |cache|.
1. [=Attempt to deliver a report|Attempt to deliver=] |report|.
@@ -4545,7 +4831,7 @@ The [=remote end steps=] are:
*This section is non-normative.*
Writes to the [=attribution source cache=], [=event-level report cache=], and
-[=aggregatable report cache=] are separated by the reporting [=origin=], and reports sent
+[=aggregatable attribution report cache=] are separated by the reporting [=origin=], and reports sent
to a given [=origin=] are generated via data only written to by that [=origin=], via
HTTP response headers.
@@ -4568,7 +4854,7 @@ of many origins colluding together to violate privacy. API deployments should mo
for abuse using these vectors to evaluate the trade-off.
The generation of [=verbose debug reports=] involves reads to the [=attribution source cache=],
-[=event-level report cache=], [=aggregatable report cache=], and [=attribution rate-limit cache=],
+[=event-level report cache=], [=aggregatable attribution report cache=], and [=attribution rate-limit cache=],
and the [=verbose debug data=] sent to a given [=origin=] may encode non-Same-Origin
data that are generated from grouping together data submitted by multiple [=origins=],
e.g. failures due to rate-limits that are not fully compliant with the Same-Origin Policy.
@@ -4580,6 +4866,10 @@ security concern with respect to the Same-Origin Policy. The risk is of less con
trigger registrations as [=attribution sources=] have to be registered to start with and
it requires browsing activity on multiple sites.
+The [=aggregatable debug reports=] may also encode non-Same-Origin data but in
+encrypted form. The security risk is further mitigated by the generation of
+null debug reports and the additive noise in the aggregation service.
+
## Opting in to the API ## {#opting-in-to-the-api}
*This section is non-normative.*
@@ -4640,16 +4930,16 @@ have different channel capacities, given that [=source type/event=] [=attributio
[=user activation=] or top-level navigation. Maximum capacity for each type is governed by the vendor-defined
[=max event-level channel capacity per source=].
-### Aggregatable reports ### {#cross-site-information-disclosure-aggregatable-reports}
+### Aggregatable attribution reports ### {#cross-site-information-disclosure-aggregatable-attribution-reports}
-Aggregatable reports protect against cross-site information disclosure in two primary ways:
+Aggregatable attribution reports protect against cross-site information disclosure in two primary ways:
1. For a given [=attribution trigger=], whether it is [=triggering attribution|attributed=] to a
- source is subject to one-way noise via [=generate null reports|generating null reports=] with
+ source is subject to one-way noise via [=generate null attribution reports|generating null attribution reports=] with
some probability. Note that because the noise does not drop true reports, this is only a partial
- mitigation, as if an [=attribution source=] never generates an [=aggregatable report=], an
+ mitigation, as if an [=attribution source=] never generates an [=aggregatable attribution report=], an
adversary can learn with 100% certainty that an [=attribution source=] was never matched with
an [=attribution trigger=].
-1. Cross-site information embedded in an [=aggregatable report=]'s [=aggregatable report/contributions=]
+1. Cross-site information embedded in an [=aggregatable attribution report=]'s [=aggregatable attribution report/contributions=]
is encrypted with a [=obtain the public key for encryption|public key=], ensuring that individual
contributions cannot be accessed until an aggregation service subjects them to aggregation
and an additive noise process.
@@ -4672,7 +4962,7 @@ had the capability to learn the underlying information.
A primary privacy goal of the API is to make linking identity between two different top-level sites
difficult. This happens when either a request or a JavaScript environment has two user IDs from two
-different sites simultaneously. Both [=event-level reports=] and [=aggregatable reports=] were
+different sites simultaneously. Both [=event-level reports=] and [=aggregatable attribution reports=] were
designed to make this kind of recognition difficult:
### Event-level reports ### {#cross-site-recognition-event-level-reports}
@@ -4685,12 +4975,12 @@ amount (measured via channel capacity) of relative cross-site information from a
information embedded in [=event-level reports=], we make it difficult for an identifier to be passed
through this channel to enable cross-site recognition alone.
-### Aggregatable reports ### {#cross-site-recognition-aggregatable-reports}
+### Aggregatable attribution reports ### {#cross-site-recognition-aggregatable-attribution-reports}
-[=Aggregatable reports=] only contain fine-grained cross-site information in encrypted form.
+[=Aggregatable attribution reports=] only contain fine-grained cross-site information in encrypted form.
In cleartext, they contain only coarse-grained information from the [=attribution source/source site=]
-and [=aggregatable report/effective attribution destination=]. This makes it difficult for an
-[=aggregatable report=] to be associated with a user from either site.
+and [=aggregatable attribution report/effective attribution destination=]. This makes it difficult for an
+[=aggregatable attribution report=] to be associated with a user from either site.
The cross-site recognition risk of the data encrypted in "`aggregation_service_payloads`" is
mitigated by the additive noise addition in the aggregation service.
diff --git a/params/chromium-params.md b/params/chromium-params.md
index 49d2e21726..35e51a6f9f 100644
--- a/params/chromium-params.md
+++ b/params/chromium-params.md
@@ -9,11 +9,11 @@ Chromium's implementation assigns the following values:
| ---- | ----- |
| [Max pending sources per source origin][] | [4096][max pending sources per source origin value] |
| [Max settable event-level epsilon][] | [14][max settable event-level epsilon value] |
-| [Randomized null report rate excluding source registration time][] | [0.05][randomized null report rate excluding source registration time value] |
-| [Randomized null report rate including source registration time][] | [0.008][randomized null report rate including source registration time value] |
+| [Randomized null attribution report rate excluding source registration time][] | [0.05][randomized null attribution report rate excluding source registration time value] |
+| [Randomized null attribution report rate including source registration time][] | [0.008][randomized null attribution report rate including source registration time value] |
| [Max event-level reports per attribution destination][] | [1024][max event-level reports per attribution destination value] |
-| [Max aggregatable reports per attribution destination][] | [1024][max aggregatable reports per attribution destination value] |
-| [Max aggregatable reports per source][] | [20][max aggregatable reports per source value] |
+| [Max aggregatable attribution reports per attribution destination][] | [1024][max aggregatable attribution reports per attribution destination value] |
+| [Max aggregatable reports per source][] | [20][max aggregatable attribution reports per source value] attribution reports, 5 debug reports|
| [Max destinations covered by unexpired sources][] | [100][max destinations covered by unexpired sources value] |
| [Destination rate-limit window][] | [1 minute][destination rate-limit window value]
| [Max destinations per rate-limit window][] | [50][max destinations per rate-limit window per reporting site] per reporting site, [200][max destinations per rate-limit window total] total
@@ -22,7 +22,7 @@ Chromium's implementation assigns the following values:
| [Origin rate-limit window][] | [1 day][origin rate-limit window value]
| [Max attribution reporting origins per rate-limit window][] | [10][max attribution reporting origins per rate-limit window value] |
| [Max attributions per rate-limit window][] | [100][max attributions per rate-limit window value] |
-| [Randomized aggregatable report delay][] | [10 minutes][randomized aggregatable report delay value] |
+| [Randomized aggregatable attribution report delay][] | [10 minutes][randomized aggregatable attribution report delay value] |
| [Max event-level channel capacity for navigation sources][] | [11.5 bits][max event-level channel capacity for navigations value] |
| [Max event-level channel capacity for event sources][] | [6.5 bits][max event-level channel capacity for events value] |
@@ -30,16 +30,16 @@ Chromium's implementation assigns the following values:
[max pending sources per source origin value]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/attribution_reporting/attribution_config.h;l=151;drc=3be0e68c5ed56aba7c321cbaea22558eee61fc50
[Max settable event-level epsilon]: https://wicg.github.io/attribution-reporting-api/#max-settable-event-level-epsilon
[max settable event-level epsilon value]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/attribution_reporting/attribution_config.h;l=57;drc=3733a639d724a4353463a872605119d11a1e4d37
-[Randomized null report rate excluding source registration time]: https://wicg.github.io/attribution-reporting-api/#randomized-null-report-rate-excluding-source-registration-time
-[randomized null report rate excluding source registration time value]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/attribution_reporting/attribution_config.h;l=109;drc=3733a639d724a4353463a872605119d11a1e4d37
-[Randomized null report rate including source registration time]: https://wicg.github.io/attribution-reporting-api/#randomized-null-report-rate-including-source-registration-time
-[randomized null report rate including source registration time value]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/attribution_reporting/attribution_config.h;l=108;drc=3733a639d724a4353463a872605119d11a1e4d37
+[Randomized null attribution report rate excluding source registration time]: https://wicg.github.io/attribution-reporting-api/#randomized-null-attribution-report-rate-excluding-source-registration-time
+[randomized null attribution report rate excluding source registration time value]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/attribution_reporting/attribution_config.h;l=109;drc=3733a639d724a4353463a872605119d11a1e4d37
+[Randomized null attribution report rate including source registration time]: https://wicg.github.io/attribution-reporting-api/#randomized-null-attribution-report-rate-including-source-registration-time
+[randomized null attribution report rate including source registration time value]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/attribution_reporting/attribution_config.h;l=108;drc=3733a639d724a4353463a872605119d11a1e4d37
[Max event-level reports per attribution destination]: https://wicg.github.io/attribution-reporting-api/#max-event-level-reports-per-attribution-destination
[max event-level reports per attribution destination value]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/attribution_reporting/attribution_config.h;l=61;drc=3733a639d724a4353463a872605119d11a1e4d37
-[Max aggregatable reports per attribution destination]: https://wicg.github.io/attribution-reporting-api/#max-aggregatable-reports-per-attribution-destination
-[max aggregatable reports per attribution destination value]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/attribution_reporting/attribution_config.h;l=90;drc=3733a639d724a4353463a872605119d11a1e4d37
+[Max aggregatable attribution reports per attribution destination]: https://wicg.github.io/attribution-reporting-api/#max-aggregatable-attribution-reports-per-attribution-destination
+[max aggregatable attribution reports per attribution destination value]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/attribution_reporting/attribution_config.h;l=90;drc=3733a639d724a4353463a872605119d11a1e4d37
[Max aggregatable reports per source]: https://wicg.github.io/attribution-reporting-api/#max-aggregatable-reports-per-source
-[max aggregatable reports per source value]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/attribution_reporting/attribution_config.h;l=111;drc=3733a639d724a4353463a872605119d11a1e4d37
+[max aggregatable attribution reports per source value]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/attribution_reporting/attribution_config.h;l=111;drc=3733a639d724a4353463a872605119d11a1e4d37
[Max destinations covered by unexpired sources]: https://wicg.github.io/attribution-reporting-api/#max-destinations-covered-by-unexpired-sources
[max destinations covered by unexpired sources value]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/attribution_reporting/attribution_config.h;l=127;drc=3733a639d724a4353463a872605119d11a1e4d37
[Destination rate-limit window]: https://wicg.github.io/attribution-reporting-api/#destination-rate-limit-window
@@ -57,8 +57,8 @@ Chromium's implementation assigns the following values:
[max attribution reporting origins per rate-limit window value]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/attribution_reporting/attribution_config.h;l=32;drc=3733a639d724a4353463a872605119d11a1e4d37
[Max attributions per rate-limit window]: https://wicg.github.io/attribution-reporting-api/#max-attributions-per-rate-limit-window
[max attributions per rate-limit window value]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/attribution_reporting/attribution_config.h;l=36;drc=3733a639d724a4353463a872605119d11a1e4d37
-[Randomized aggregatable report delay]: https://wicg.github.io/attribution-reporting-api/#randomized-aggregatable-report-delay
-[randomized aggregatable report delay value]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/attribution_reporting/attribution_config.h;l=106;drc=3733a639d724a4353463a872605119d11a1e4d37
+[Randomized aggregatable attribution report delay]: https://wicg.github.io/attribution-reporting-api/#randomized-aggregatable-attribution-report-delay
+[randomized aggregatable attribution report delay value]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/attribution_reporting/attribution_config.h;l=106;drc=3733a639d724a4353463a872605119d11a1e4d37
[Max event-level channel capacity for navigation sources]: https://wicg.github.io/attribution-reporting-api/#max-event-level-channel-capacity-per-source
[max event-level channel capacity for navigations value]: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/attribution_reporting/attribution_config.h;l=77;drc=f470a177bbf7e636c598fd8c9e9dee4f936e73ad
[Max event-level channel capacity for event sources]: https://wicg.github.io/attribution-reporting-api/#max-event-level-channel-capacity-per-source