diff --git a/spec.bs b/spec.bs index 08ddabc42..081eef514 100644 --- a/spec.bs +++ b/spec.bs @@ -1779,14 +1779,20 @@ following steps. They return a failure if failing to fetch the script or wasm, o 1. Let |prevWinElement| be the [=sequence=]<{{PreviousWinElement}}> «|timeDelta|, |prevWinAdIDL|». 1. [=list/Append=] |prevWinElement| to |prevWins|. 1. [=map/Set=] |browserSignals|["{{BiddingBrowserSignals/prevWinsMs}}"] to |prevWins|. + 1. Let |metrics| be the result of [=access per-participant metrics=] given |reportingContext|, + |ig|'s [=interest group/owner=], [=worklet function/generate-bid=]. 1. Let |biddingScriptFetcher| be the result of [=creating a new script fetcher=] with |ig|'s [=interest group/bidding url=], and |settings|. 1. Let |biddingScript| be the result of [=waiting for script body from a fetcher=] given |biddingScriptFetcher|. + 1. [=Add a sample to an averager=] |metrics|'s [=per participant metrics/average code fetch time=] + saying how long this took, in milliseconds (TODO: how?). 1. If |biddingScript| is failure, return failure. 1. If |ig|'s [=interest group/bidding wasm helper url=] is not null: 1. Let |wasmModuleObject| be the result of [=fetching WebAssembly=] with |ig|'s [=interest group/bidding wasm helper url=] and |settings|. + 1. [=Add a sample to an averager=] |metrics|'s [=per participant metrics/average code fetch + time=] saying how long this took, in milliseconds (TODO: how?). 1. If |wasmModuleObject| is not failure, then [=map/set=] |browserSignals|["{{BiddingBrowserSignals/wasmHelper}}"] to |wasmModuleObject|. 1. Otherwise, return failure. @@ -1981,6 +1987,10 @@ and a [=real time reporting contributions map=] |realTimeContributionsMap|: 1. [=map/For each=] slotSizeQueryParam → |perSignalsUrlGenerator| of |perSlotSizeQueryParam|: 1. [=map/For each=] joiningOrigin → |groups| of |perSignalsUrlGenerator|: 1. [=list/Remove=] from |groups| any [=interest group=] [=list/contained=] in |igs|. + 1. Let |metrics| be the result of [=accessing per-participant metrics] for |reportingContext|, + |buyer|, [=worket function/generated-bid]. + 1. Set |metrics|'s [=per participant metrics/participating interest group count=] to the + [=list/size=] of |groups|. 1. Let |perBuyerSignals| be null. 1. If |auctionConfig|'s [=auction config/per buyer signals=] is not null and [=auction config/per buyer signals=][|buyer|] [=map/exists=], then set |perBuyerSignals| to @@ -2309,6 +2319,8 @@ a {{DirectFromSellerSignalsForSeller}} |directFromSellerSignalsForSeller|, an {{ or "component-auction", a [=currency tag=] |componentAuctionExpectedCurrency|, an [=origin=] |topLevelOrigin|, and a [=real time reporting contributions map=] |realTimeContributionsMap|: +1. Let |metrics| be the result of [=access per-participant metrics=] given |reportingContext|, + |auctionConfig|'s [=auction config/seller=], [=worklet function/score-ad=]. 1. Let «|trustedScoringSignalsAreCrossOrigin|, |sameOriginTrustedScoringSignals|, |crossOriginTrustedScoringSignals|, |scoringDataVersion|» be the result of [=fetch and decode trusted scoring signals=] given |trustedScoringSignalsBatcher|, |auctionConfig|, @@ -2349,6 +2361,8 @@ or "component-auction", a [=currency tag=] |componentAuctionExpectedCurrency|, a 1. Let |decisionLogicScript| be the result of [=wait for script body from a fetcher=] given |decisionLogicFetcher|. +1. [=Add a sample to an averager=] |metrics|'s [=per participant metrics/average code fetch time=] + saying how long the fetch |decisionLogicFetcher| performed took, in milliseconds. 1. If |decisionLogicScript| is failure, then: 1. If |auctionConfig|'s [=auction config/seller real time reporting config=] is "`default-local-reporting`", then [=add a platform contribution=] with @@ -2365,10 +2379,11 @@ or "component-auction", a [=currency tag=] |componentAuctionExpectedCurrency|, a contributions, and some special handling of private aggregation requests involving reject-reason); as it would be problematic to report a winner that didn't actually win. - 1. If |reportingContext|'s [=reporting context/debug reporting info=][|generatedBid|'s [=generated - bid/reporting id=]] does not [=map/exist=], set it to a new [=bid debug reporting info=]. + 1. Let |reportingId| be |generatedBid|'s [=generated bid/reporting id=]. + 1. If |reportingContext|'s [=reporting context/debug reporting info=][|reportingId|] does not + [=map/exist=], set it to a new [=bid debug reporting info=]. 1. Let |bidDebugReportInfo| be |reportingContext|'s [=reporting context/debug reporting info=] - [|generatedBid|'s [=generated bid/reporting id=]]. + [|reportingId|]. 1. If |auctionLevel| is "top-level-auction": 1. Set |bidDebugReportInfo|'s [=bid debug reporting info/top level seller debug loss report url=] to |debugLossReportUrl|. @@ -2384,8 +2399,10 @@ or "component-auction", a [=currency tag=] |componentAuctionExpectedCurrency|, a 1. If |auctionConfig|'s [=auction config/seller real time reporting config=] is "`default-local-reporting`", then [=insert entries to map=] given |realTimeContributionsMap|, |seller|, and |realTimeContributions|. - 1. [=Commit private aggregation contributions=] given |paContributions|, |generatedBid|'s - [=generated bid/reporting id=] and |reportingContext|. + 1. [=set/Insert=] |reportingId| into |reportingContext|'s [=reporting context/bidder + participants=]. + 1. [=Commit private aggregation contributions=] given |paContributions|, |reportingId|, and + |reportingContext|. 1. Let |scoreAdOutput| be result of [=processing scoreAd output=] with |scoreAdResult|. 1. Return if any of the following conditions hold: * |scoreAdOutput| is failure; @@ -2890,15 +2907,19 @@ and a [=global object=] |global|: [=generated bid/interest group=], |igAd|, and null is true: 1. If |igAd|'s [=interest group ad/buyer and seller reporting ID=] is not null, [=map/set=] |browserSignals|["{{ReportingBrowserSignals/buyerAndSellerReportingId}}"] to it. + 1. Let |metrics| be the result of [=access per-participant metrics=] given |reportingContext|, + |config|'s [=auction config/seller=], [=worklet function/report-result=]. 1. Let |sellerReportingScriptFetcher| be the result of [=creating a new script fetcher=] with |config|'s [=auction config/decision logic url=] and |global|'s [=relevant settings object=]. 1. Let |sellerReportingScript| be the result of [=waiting for script body from a fetcher=] given |sellerReportingScriptFetcher|. + 1. [=Add a sample to an averager=] |metrics|'s [=per participant metrics/average code fetch time=] + saying how long the fetch |sellerReportingScriptFetcher| performed took, in milliseconds. 1. Let « |sellerSignals|, |reportUrl|, |reportingBeaconMap|, ignored, |paContributions| » be the - result of [=evaluating a reporting script=] with |sellerReportingScript|, "`reportResult`", - |reportingContext|, |config|'s [=auction config/seller=], |config|'s [=auction config/seller - Private Aggregation coordinator=], |config|'s [=auction config/config idl=]'s - {{AuctionAdConfig/reportingTimeout}}, and + result of [=evaluating a reporting script=] with |sellerReportingScript|, [=worklet function/ + report-result=], |reportingContext|, |config|'s [=auction config/seller=], |config|'s + [=auction config/seller Private Aggregation coordinator=], |config|'s [=auction config/ + config idl=]'s {{AuctionAdConfig/reportingTimeout}}, and « |config|'s [=auction config/config idl=], |browserSignals|, |directFromSellerSignals| ». 1. Let |reportingResult| be a [=reporting result=] with the following [=struct/items=]: : [=reporting result/report url=] @@ -2955,6 +2976,8 @@ a {{ReportingBrowserSignals}} |browserSignals|, a [=direct from seller signals=] (TODO: noise and bucket this signal) 1. Let |ig| be |winner|'s [=generated bid/interest group=]. + 1. Let |metrics| be the result of [=access per-participant metrics=] given |reportingContext|, + |ig|'s [=interest group/owner=], [=worklet function/report-win=]. 1. Let |igAd| be the [=interest group ad=] from ig's [=interest group/ads=] whose [=interest group ad/render url=] is |winner|'s [=generated bid/ad descriptor=]'s [=ad descriptor/url=]. @@ -2990,14 +3013,16 @@ a {{ReportingBrowserSignals}} |browserSignals|, a [=direct from seller signals=] |winner|'s [=generated bid/interest group=]'s [=interest group/bidding url=] and |settings|. 1. Let |buyerReportingScript| be the result of [=waiting for script body from a fetcher=] given |buyerReportingScriptFetcher|. + 1. [=Add a sample to an averager=] |metrics|'s [=per participant metrics/average code fetch time=] + saying how long the fetch |buyerReportingScriptFetcher| performed took, in milliseconds. 1. Let |reportFunctionName| be "`reportWin`". 1. If |winner|'s [=generated bid/provided as additional bid=] is true: 1. Set |reportFunctionName| be "`reportAdditionalBidWin`". 1. Let « ignored, |resultUrl|, |reportingBeaconMap|, |reportingMacroMap|, |paContributions| » be - the result of [=evaluating a reporting script=] with |buyerReportingScript|, "`reportWin`", - |reportingContext|, |ig|'s [=interest group/owner=], |ig|'s [=interest group/Private Aggregation - coordinator=], |leadingBidInfo|'s [=leading bid info/auction config=]'s [=auction config/config - idl=]'s {{AuctionAdConfig/reportingTimeout}}, and + the result of [=evaluating a reporting script=] with |buyerReportingScript|, [=worklet function/ + report-win=], |reportingContext|, |ig|'s [=interest group/owner=], |ig|'s [=interest group/ + Private Aggregation coordinator=], |leadingBidInfo|'s [=leading bid info/auction config=]'s + [=auction config/config idl=]'s {{AuctionAdConfig/reportingTimeout}}, and « |leadingBidInfo|'s [=leading bid info/auction config=]'s [=auction config/config idl=]'s {{AuctionAdConfig/auctionSignals}}, |perBuyerSignalsForBuyer|, |sellerSignals|, |reportWinBrowserSignals|, |directFromSellerSignals| ». @@ -3626,8 +3651,30 @@ A reporting context is a [=struct=] with the following [=struct/items :: A [=reporting bid key=] or null, initially null. This can be null even if [=reporting context/ local leader info=] has a leader set, in case this context is for a component auction that lost at top-level. + : bidder participants + :: A [=set=] of [=reporting bid keys=], representing interest groups that got a chance to generate + bids for the auction. This will be empty in top-level auctions, as the relevant state will be + in the component auctions. + : seller participants + :: A [=set=] of [=reporting bid keys=], representing various `scoreAd()` executions. Note that + some of these may be based on bids that started as additional bids or from component auctions + run by Bidding and Auction services, and not interest groups, so this list may be quite + different from [=reporting context/bidder participants=]. + : participant metrics + :: A [=map=] from a pair ([=origin=], [=worklet function=]) to [=per participant metrics=]. +
+To access per-participant metrics given a [=reporting context=] |reportingContext|, +an [=origin=] |origin| and [=worklet function=] |workletFunction|: +1. Let |key| be (|origin|, |workletFunction|). +1. If |reportingContext|'s [=reporting context/participant metrics=][|key|] does not [=map/exist=], + set |reportingContext|'s [=reporting context/participant metrics=][|key|] to a new [=per participant + metrics=]. +1. Return |reportingContext|'s [=reporting context/participant metrics=][|key|]. + +
+ A reporting context map is a [=map=] from [=auction config=] to [=reporting context=]. Here the keys are configurations for auctions that actually produce bids (e.g. not the top-level auction in a multi-party auction). @@ -3665,6 +3712,7 @@ auction in a multi-party auction). :: |ig|'s [=interest group/name=] 1. [=map/Set=] |reportingContext|'s [=reporting context/debug reporting info=][|id|] to |bidDebugReportInfo|. + 1. [=set/Insert=] |id| into |reportingContext|'s [=reporting context/bidder participants=]. 1. [=Commit private aggregation contributions=] given |paContributions|, |id| and |reportingContext|. 1. [=list/For each=] |generatedBid| of |generatedBids|: @@ -4061,6 +4109,13 @@ A signal base value is one of the following: Note: this mapping to an integer is defined in [=determine a signal's numeric value=]. +: "average-code-fetch-time" +:: The numeric value is the average time it took to fetch code resources (JavaScript or WebAssembly) + for this particular worklet function, for this participant. +: "participating-ig-count" +:: The numeric value is the number of interest groups for the buyer actually participating in the + auction, after considering prioritization and capabilities. +

On event contribution entry

@@ -4074,6 +4129,10 @@ An on event contribution entry is a [=struct=] with the following items: :: A [=debug scope=] : debug details :: A [=debug details=] or null (default null) +: worklet function +:: A [=worklet function=]. +: origin +:: The [=origin=] of the script that contributed the entry. @@ -4091,6 +4150,55 @@ A worklet function is one of the following: +
+To find corresponding bid and score phase function given a [=worklet function=] |fn|: + + 1.Switch on on |fn|: +
+ : [=worklet function/generate-bid=] + :: Return [=worklet function/generate-bid=]. + : [=worklet function/score-ad=] + :: Return [=worklet function/score-ad=]. + : [=worklet function/report-result=] + :: Return [=worklet function/score-ad=]. + : [=worklet function/report-win=] + :: Return [=worklet function/generate-bid=]. + +
+
+ +### Averager ### {#private-aggregation-averager} +An averager is a a [=struct=] with the following [=struct/items=]: +
+ : count + :: A {{long}}, initially 0. + : sum + :: A {{double}}, initially 0. +
+ +
+To add a sample to an averager given an [=averager=] |averager|, a {{double}} |sample|: +1. Set |averager|'s [=averager/count=] to |averager|'s [=averager/count=] + 1. +1. Set |averager|'s [=averager/sum=] to |averager|'s [=averager/sum=] + |sample|. + +
+ +
+To get the value to report from an averager given an [=averager=] |averager|: +1. If |averager|'s [=averager/count=] = 0, return 0. +1. Return |averager|'s [=averager/sum=] / [=averager/count=]. + +
+ +### Per-participant metrics ### {#private-aggregation-per-participant-metrics} +A per participant metrics is a [=struct=] with the following [=struct/items=]: +
+ : participating interest group count + :: A {{long}}, initially 0. + : average code fetch time + :: An [=averager=]. +
+

Private Aggregation contributions

Private Aggregation contributions is a [=map=] from [=string=] to a [=list=] of [=on event contribution entries=]. @@ -4099,9 +4207,11 @@ contribution entries=].
To prepare for private aggregation given a -{{InterestGroupScriptRunnerGlobalScope}} |global|, a [=reporting context=] |reportingContext|, -and [=origins=] |origin| and |aggregationCoordinator|: +{{InterestGroupScriptRunnerGlobalScope}} |global|, a [=worklet function=] |workletFunction|, +a [=reporting context=] |reportingContext|, and [=origins=] |origin| and |aggregationCoordinator|: 1. Let |debugScope| be a new [=debug scope=]. +1. Set |global|'s [=InterestGroupScriptRunnerGlobalScope/worklet function=] to |workletFunction|. +1. Set |global|'s [=InterestGroupScriptRunnerGlobalScope/origin=] to |origin|. 1. Set |global|'s [=InterestGroupScriptRunnerGlobalScope/private aggregation=] to a new [=PrivateAggregation=] with the following [=struct/items=]: : allowed to use @@ -4191,14 +4301,26 @@ an [=auction config=] |auctionConfig| and a [=reporting context=] |reportingCont 1. If |auctionConfig|'s [=auction config/aborted=] is true, return. 1. Let |winnerId| be |reportingContext|'s [=reporting context/winner reporting id=] 1. Let |leadingBidInfo| be |reportingContext|'s [=reporting context/local leader info=]. +1. Let |bidderOnceRep| be null. +1. If |reportingContext|'s [=reporting context/bidder participants=] [=set/is not empty=], + set |bidderOnceRep| to a random member of [=reporting context/bidder participants=]. +1. Let |sellerOnceRep| be null. +1. If |reportingContext|'s [=reporting context/seller participants=] [=set/is not empty=], + set |sellerOnceRep| to a random member of [=reporting context/seller participants=]. 1. [=map/For each=] (|bidId|, |event|) → |contributions| of |reportingContext|'s [=reporting context/private aggregation on event contributions=]: 1. If |event| is "`reserved.win`" or does not [=string/start with=] "`reserved.`": 1. If |bidId| is not |winnerId|, [=iteration/continue=]. 1. If |event| is "`reserved.loss`" and |bidId| is |winnerId|, [=iteration/continue=]. 1. [=list/For each=] |onEventEntry| of |contributions|: + 1. If |event| is "`reserved.once`": + 1. If |onEventEntry|'s [=on event contribution entry/worklet function=] is [=worklet function/ + generate-bid=]: + 1. If |bidId| ≠ |bidderOnceRep|, [=iteration/continue=]. + 1. Otherwise: + 1. If |bidId| ≠ |sellerOnceRep|, [=iteration/continue=]. 1. Let |filledInContribution| be the result of [=filling in the contribution=] given - |onEventEntry|'s [=on event contribution entry/contribution=] and |leadingBidInfo|. + |reportingContext|, |onEventEntry| and |leadingBidInfo|. Issue: Once WICG/turtledove#627 is resolved, align 'filling in' logic with `forDebuggingOnly`. @@ -4310,15 +4432,18 @@ an [=auction config=] |auctionConfig| and a [=reporting context=] |reportingCont
-To fill in the contribution given a {{PAExtendedHistogramContribution}} |contribution| -and a [=leading bid info=] |leadingBidInfo|, perform the following steps. They return a -{{PAHistogramContribution}}: +To fill in the contribution given a [=reporting context=] |reportingContext|, +an [=on event contribution entry=] |onEventEntry| and a [=leading bid info=] |leadingBidInfo|, +perform the following steps. They return a {{PAHistogramContribution}}: +1. Let |contribution| be |onEventEntry|'s [=on event contribution entry/contribution=]. 1. Let |bucket| be |contribution|["{{PAExtendedHistogramContribution/bucket}}"]. 1. If |bucket| is a {{PASignalValue}}, set |bucket| to the result of [=filling - in the signal value=] given |bucket|, 2128−1 and |leadingBidInfo|. + in the signal value=] given |reportingContext|, |onEventEntry|, |bucket|, 2128−1 + and |leadingBidInfo|. 1. Let |value| be |contribution|["{{PAExtendedHistogramContribution/value}}"]. 1. If |value| is a {{PASignalValue}}, set |value| to the result of [=filling in - the signal value=] given |value|, 231−1 and |leadingBidInfo|. + the signal value=] given |reportingContext|, |onEventEntry|, |value|, 231−1 and + |leadingBidInfo|. 1. Let |filledInContribution| be a new {{PAHistogramContribution}} with the items: : {{PAHistogramContribution/bucket}} @@ -4332,13 +4457,15 @@ and a [=leading bid info=] |leadingBidInfo|, perform the following steps. They r
-To fill in the signal value given a {{PASignalValue}} |value|, an +To fill in the signal value given a [=reporting context=] |reportingContext|, +an [=on event contribution entry=] |onEventEntry|, a {{PASignalValue}} |value|, an integer |maxAllowed| and a [=leading bid info=] |leadingBidInfo|, perform the following steps. They return an integer. 1. [=Assert=]: |value|["{{PASignalValue/baseValue}}"] is a valid [=signal base value=]. 1. Let |returnValue| be the result of [=determining a signal's numeric value=] - given |value|["{{PASignalValue/baseValue}}"] and |leadingBidInfo|. + given |reportingContext|, |onEventEntry|, |value|["{{PASignalValue/baseValue}}"] and + |leadingBidInfo|. 1. If |value|["{{PASignalValue/scale}}"] [=map/exists=], set |returnValue| to the result of multiplying |value|["{{PASignalValue/scale}}"] with |returnValue|. @@ -4353,9 +4480,17 @@ They return an integer.
-To determine a signal's numeric value given a [=signal base value=] +To determine a signal's numeric value given a [=reporting context=] |reportingContext|, +an [=on event contribution entry=] |onEventEntry|, a [=signal base value=] |signalBaseValue| and a [=leading bid info=] |leadingBidInfo|, perform the following steps. They return a {{double}}. +1. Let |metrics| be the result of [=access per-participant metrics=] given |reportingContext|, + |onEventEntry|'s [=on event contribution entry/origin=], [=on event contribution entry/ + worklet function=]. +1. Let |bidAndScoreMetrics| be the result of [=access per-participant metrics=] given + |reportingContext|, |onEventEntry|'s [=on event contribution entry/origin=], and the result of + [=find corresponding bid and score phase function=] given [=on event contribution entry/worklet + function=]. 1. If |signalBaseValue| is "[=signal base value/winning-bid=]": 1. If |leadingBidInfo|'s [=leading bid info/leading bid=] is null, return 0. 1. Otherwise, return |leadingBidInfo|'s [=leading bid info/leading bid=]'s [=generated bid/bid=]. @@ -4418,6 +4553,11 @@ They return a {{double}}. Issue: Verify handling when the bid was not rejected. +1. If |signalBaseValue| is "[=signal base value/average-code-fetch-time=]": + 1. Return the result of [=getting the value to report from an averager=] given |metrics|'s [=per + participant metrics/average code fetch time=]. +1. If |signalBaseValue| is "[=signal base value/participating-ig-count=]": + 1. Return |bidAndScoreMetrics|'s [=per participant metrics/participating interest group count=].
@@ -5318,8 +5458,9 @@ of the following global objects: [=InterestGroupBiddingScriptRunnerGlobalScope/group has ad components=] to true if |ig|'s [=interest group/ad components=] is not null, or false otherwise. 1. Set |global|'s [=InterestGroupBiddingScriptRunnerGlobalScope/expected currency=] to |expectedCurrency|. - 1. [=Prepare for private aggregation=] given |global|, |reportingContext|, |ig|'s [=interest - group/owner=] and |ig|'s [=interest group/Private Aggregation coordinator=]. + 1. [=Prepare for private aggregation=] given |global|, [=worklet function/generate-bid=], + |reportingContext|, |ig|'s [=interest group/owner=] and |ig|'s [=interest group/Private + Aggregation coordinator=]. 1. Let |isComponentAuction| be true if |browserSignals|["{{BiddingBrowserSignals/topLevelSeller}}"] is not null, or false otherwise. 1. Set |global|'s [=InterestGroupBiddingScriptRunnerGlobalScope/is component auction=] to @@ -5410,9 +5551,9 @@ of the following global objects: {{InterestGroupScoringScriptRunnerGlobalScope}}. 1. Let |global| be |realm|'s [=realm/global object=]. 1. Let |settings| be |realm|'s [=realm/settings object=]. - 1. [=Prepare for private aggregation=] given |global|, |reportingContext|, |auctionConfig|'s - [=auction config/seller=] and |auctionConfig|'s [=auction config/seller Private Aggregation - coordinator=]. + 1. [=Prepare for private aggregation=] given |global|, [=worklet function/score-ad=], + |reportingContext|, |auctionConfig|'s [=auction config/seller=] and |auctionConfig|'s + [=auction config/seller Private Aggregation coordinator=]. 1. Let |browserSignalsJS| be |browserSignals| [=converted to ECMAScript values=]. 1. Let |auctionConfigJS| be |auctionConfig|'s [=auction config/config idl=] [=converted to ECMAScript values=]. @@ -5449,16 +5590,18 @@ of the following global objects:
- To evaluate a reporting script given a [=string=] |script|, a [=string=] - |functionName|, a [=reporting context=] |reportingContext|, an [=origin=] |origin|, an - [=origin=] |privateAggregationCoordinator|, an integer millisecond [=duration=] |timeout|, - and a [=list=] of arguments |arguments|: + To evaluate a reporting script given a [=string=] |script|, a [=worklet function=] + |function|, a [=reporting context=] |reportingContext|, an [=origin=] |origin|, an [=origin=] + |privateAggregationCoordinator|, an integer millisecond [=duration=] |timeout|, and a [=list=] + of arguments |arguments|: 1. Let |realm| be the result of [=creating a new script runner realm=] given {{InterestGroupReportingScriptRunnerGlobalScope}}. 1. Let |global| be |realm|'s [=realm/global object=]. - 1. [=Prepare for private aggregation=] given |global|, |reportingContext|, |origin|, and - |privateAggregationCoordinator|. + 1. Let |functionName| be `"reportWin"`. + 1. If |function| is [=worklet function/report-result=], set |functionName| to `"reportResult"`. + 1. [=Prepare for private aggregation=] given |global|, |function|, |reportingContext|, |origin|, + and |privateAggregationCoordinator|. 1. Let |argumentsJS| be the result of [=converting a Web IDL arguments list to an ECMAScript arguments list|converting=] |arguments| to an ECMAScript arguments list. If this [=exception/throws=] an exception, return « "null", null, null, null ». @@ -5576,6 +5719,12 @@ Each {{InterestGroupScriptRunnerGlobalScope}} has a :: Null, or a [=PrivateAggregation=]. Initially null. : on event contribution map :: A [=map=] from [=string=] to a [=list=] of [=on event contribution entries=]. + : worklet function + :: A [=worklet function=]. Affects some + [Private Aggregation API](https://github.com/patcg-individual-drafts/private-aggregation-api) + functionality. + : origin + :: The [=origin=] of the script being executed.
@@ -5589,16 +5738,21 @@ The privateAggregation The contributeToHistogramOnEvent(DOMString event, PAExtendedHistogramContribution contribution) method steps are: +1. Let |global| be [=this=]'s [=relevant global object=]. +1. Let |function| be |global|'s [=InterestGroupScriptRunnerGlobalScope/worklet function=]. +1. Let |origin| be |global|'s [=InterestGroupScriptRunnerGlobalScope/origin=]. 1. If [=this=]'s allowed to use is false, [=exception/throw=] a {{TypeError}}. 1. Let |scopingDetails| be [=this=]'s scoping details 1. If |event| [=string/starts with=] "`reserved.`" and « "`reserved.always`", - "`reserved.loss`", "`reserved.win`" » does not [=list/contain=] |event|, + "`reserved.loss`", "`reserved.win`", "`reserved.once`" » does not [=list/contain=] |event|, return. Note: No error is thrown to allow forward compatibility if additional reserved event types are added later. +1. If |event| is "`reserved.once`" and |function| is [=worklet function/report-result=] or + [=worklet function/report-win=], [=exception/throw=] a {{TypeError}}. 1. Let |bucket| be |contribution|["{{PAExtendedHistogramContribution/bucket}}"]. 1. If |bucket| is a {{PASignalValue}}: 1. If |bucket|["{{PASignalValue/baseValue}}"] is not a valid [=signal base @@ -5644,8 +5798,10 @@ event, PAExtendedHistogramContribution contribution) method steps are: : [=on event contribution entry/debug scope=] :: The result of running |scopingDetails|' get debug scope steps. - -1. Let |global| be [=this=]'s [=relevant global object=]. + : [=on event contribution entry/worklet function=] + :: |function| + : [=on event contribution entry/origin=] + :: |origin| 1. Let |onEventContributionMap| be |global|'s [=InterestGroupScriptRunnerGlobalScope/on event contribution map=]. 1. If |onEventContributionMap|[|event|] does not [=map/exist=], set