-
Notifications
You must be signed in to change notification settings - Fork 258
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extending FLEDGE to support coordinated experiments #266
Conversation
In [WICG#191](WICG#191) @JensenPaul [suggested](WICG#191 (comment)) that runAdAuction take a 16-bit integer and pass it on the trusted server fetches. Here's a concrete proposal for how this could look. ## Example Usage 1. The browser visits a publisher page. 2. Ad tag JS generates `experimentGroupId`. 3. Ad tag JS invokes `navigator.runAdAuction()` and includes `experimentGroupId`. 4. The browser includes `experimentGroupId` on the Trusted Server calls. 5. Servers divert experiments by considering `experimentGroupId`, and prepare appropriate responses. 6. The buyer trusted server may choose to make `experimentGroupId` available to `generateBid()` by including it in its `trustedBiddingSignals` response. `experimentGroupId` is available to `scoreAd()` via auction config. Consequently, both `generateBid()` and `scoreAd()` will be able to make experiment-specific decisions. 7. `experimentGroupId` is passed to `reportResult()` via auction config to support experiment-specific logic in reporting functions. `reportResult()` may choose to make it available to `reportWin()` via `sellerSignals`.
Should the experiment ID go with seller trusted signals as well? |
Yes, experiment ID (experimentGroupId) should go with seller trusted signals as well. I have added another commit (a94b2b2) for this. Thanks. |
@JensenPaul FYI Paul --- would be good if you double-checked this as I am close to wrapping up tests for the implementation |
Could the experimentGroupId be specified per-buyer? This would allow buyer contextual+fledge experiment coordination without a strong reliance on sellers. The seller could still pass an experiment ID to buyers as part of the contextual flow which buyers could choose to |
@jrmooring , I've added a new commit to address your comment. Please take a look. |
That looks good to me! |
FLEDGE.md
Outdated
@@ -148,7 +148,10 @@ const myAuctionConfig = { | |||
'auctionSignals': {...}, | |||
'sellerSignals': {...}, | |||
'sellerTimeout': 100, | |||
'perBuyerSignals': {'https://www.example-dsp.com': {...}, | |||
'sellerExperimentGroupId': 12345, | |||
'perBuyerSignals': {'https://www.example-dsp.com': { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So what CL I have pending implements has it as a separate perBuyerExperimentGroupId map, similar to perBuyerTimeouts, and also admitting * for setting the default. What do you think of that interface?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thought is that if it is a separate field then it's one more signal a seller has to map from the contextual call to runAdAuction()
. This may be okay as a one-off, but if you can imagine more buyer-controlled fields being added in the future that the browser needs to understand then it's a change all the sellers need to handle as well. Also need to worry about field name conflicts if they're root level in perBuyerSignals.
Maybe a separate perBuyerConfigurations
object that for now just contains the experimentGroupId
, but could, in the future, be extended to take any additional buyer-controlled fields that the browser needs to know about?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#276 also runs into this, with perBuyerGroupLimits
On the other hand, with the way partial updating of auction configurations works, there is some advantage of keeping them separate to allow more granular updates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there anything required on my end?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jeffkaufman could you please expand on "the way partial updating of auction configurations works"?
I like the idea of a perBuyerConfigurations
object that contains all buyer-controlled FLEDGE settings like the experimentGroupId (and buyer limits/timeouts, maybe an exploration factor for IG selection, opt-in for bandit algorithm, I'm just making stuff up here).
The thought is that if an SSP does
foreach dsp:
perBuyerConfigurations[dsp] = contextualResponse[dsp].buyerConfiguration
then buyers don't have to wait for SSP changes to utilize new buyer-controlled FLEDGE parameters if/when FLEDGE adds them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you please expand on "the way partial updating of auction configurations works"?
Sorry, I got confused and thought we were talking about interest groups. Ignore me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which means I'm also in favor of a perBuyer
section. Might as well merge this with interestGroupBuyers
while we're at it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that I've landed https://chromiumdash.appspot.com/commit/9c37c816537202ef21e9447ddfe081093d292c97 which supports this via a separate field, but the intent was very much to incorporate this feedback on better ways of phrasing this in API once a consensus coalesces...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So as implemented, this is:
'perBuyerExperimentGroupIds': {'*': 3498,
'https://example.com': 1203},
As proposed in WICG/turtledove#266 Change-Id: I2c31cbd9fb96ceb2d1f36d42e569ba2a7fe808b0 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3516197 Reviewed-by: Russ Hamilton <behamilton@google.com> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Commit-Queue: Maks Orlovich <morlovich@chromium.org> Cr-Commit-Position: refs/heads/main@{#992957}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is how what's implemented differs from the current proposal:
FLEDGE.md
Outdated
@@ -148,7 +148,10 @@ const myAuctionConfig = { | |||
'auctionSignals': {...}, | |||
'sellerSignals': {...}, | |||
'sellerTimeout': 100, | |||
'perBuyerSignals': {'https://www.example-dsp.com': {...}, | |||
'sellerExperimentGroupId': 12345, | |||
'perBuyerSignals': {'https://www.example-dsp.com': { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So as implemented, this is:
'perBuyerExperimentGroupIds': {'*': 3498,
'https://example.com': 1203},
FLEDGE.md
Outdated
@@ -174,6 +177,8 @@ The returned `auctionResultPromise` object is _opaque_: it is not possible for a | |||
|
|||
Optionally, `sellerTimeout` can be specified to restrict the runtime (in milliseconds) of the seller's `scoreAd()` script, and `perBuyerTimeouts` can be specified to restrict the runtime (in milliseconds) of particular buyer's `generateBid()` scripts. If no value is specified for the seller or a particular buyer, a default timeout of 50 ms will be selected. Any timeout higher than 500 ms will be clamped to 500 ms. A key of `'*'` in `perBuyerTimeouts` is used to change the default of unspecified buyers. | |||
|
|||
Optionally, `sellerExperimentGroupId` parameter can be specified by the seller to support coordinated experiments with seller trusted server. If specified, this must be an integer between zero and 65535 (16 bits). Optionally,`buyerExperimentGroupId` parameter can be specified by the buyer as part of `perBuyerSignals` to support coordinated experiments with buyer trusted server. If specified, this must also be an integer between zero and 65535 (16 bits). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perBuyerExperimentGroupIds (and not per of perBuyerSignals).
Key of '*' can be used to provide a default for buyers whose origin does not have its own value specified.
FLEDGE.md
Outdated
@@ -270,11 +275,11 @@ Buyers have three basic jobs in the on-device ad auction: | |||
|
|||
Buyers may want to make on-device decisions that take into account real-time data (for example, the remaining budget of an ad campaign). This need can be met using the interest group's `trustedBiddingSignalsUrl` and `trustedBiddingSignalsKeys` fields. Once a seller initiates an on-device auction on a publisher page, the browser checks each participating interest group for these fields, and makes an uncredentialed (cookieless) HTTP fetch to a URL of the form: | |||
|
|||
https://www.kv-server.example/getvalues?hostname=publisher.com&keys=key1,key2 | |||
https://www.kv-server.example/getvalues?hostname=publisher.com&buyerExperimentGroupId=12345&keys=key1,key2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just experimentGroupId.
FLEDGE.md
Outdated
|
||
The base URL `https://www.kv-server.example/getvalues` comes from the interest group's `trustedBiddingSignalsUrl`, the hostname of the top-level webpage where the ad will appear `publisher.com` is provided by the browser, and `keys` is a list of `trustedBiddingSignalsKeys` strings, perhaps coalesced (for efficiency) across any number of interest groups that share a `trustedBiddingSignalsUrl`. The response from the server should be a JSON object whose keys are key1, key2, etc., and whose values will be made available to the buyer's bidding functions (un-coalesced). | ||
The base URL `https://www.kv-server.example/getvalues` comes from the interest group's `trustedBiddingSignalsUrl`, the hostname of the top-level webpage where the ad will appear `publisher.com` is provided by the browser, `buyerExperimentGroupId` comes from `perBuyerSignals` if provided, and `keys` is a list of `trustedBiddingSignalsKeys` strings, perhaps coalesced (for efficiency) across any number of interest groups that share a `trustedBiddingSignalsUrl`. The response from the server should be a JSON object whose keys are key1, key2, etc., and whose values will be made available to the buyer's bidding functions (un-coalesced). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
experimentGroupId, perBuyerExperimentGroupIds.
FLEDGE.md
Outdated
|
||
Similarly, sellers may want to fetch information about a specific creative, e.g. the results of some out-of-band ad scanning system. This works in much the same way, with the base URL coming from the `trustedScoringSignalsUrl` property of the seller's auction configuration object. However, it has two sets of keys: "renderUrls=url1,url2,..." and "adComponentRenderUrls=url1,url2,..." for the main and adComponent renderUrls bids offered in the auction. It is up to the client how and whether to aggregate the fetches with the URLs of multiple bidders. The response to this request should be in the form: | ||
Similarly, sellers may want to fetch information about a specific creative, e.g. the results of some out-of-band ad scanning system. This works in much the same way, with the base URL coming from the `trustedScoringSignalsUrl` property of the seller's auction configuration object. The parameter `sellerExperimentGroupId` comes from the auction configuration if provided. However, the URL has two sets of keys: "renderUrls=url1,url2,..." and "adComponentRenderUrls=url1,url2,..." for the main and adComponent renderUrls bids offered in the auction. It is up to the client how and whether to aggregate the fetches with the URLs of multiple bidders. The response to this request should be in the form: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, just experimentGroupId.
@morlovich thanks for the comments. I've updated FLEDGE.md. I think now the PR is in sync. with the implementation. Please take a look. |
So this looks good to me --- thanks! --- but from talking to Paul there is some LawyerProcedureStuff(tm) that it needs to go through before landing which thankfully is something he can help with. |
Co-authored-by: Paul Jensen <JensenPaul@users.noreply.github.com>
In #191 @JensenPaul suggested that runAdAuction take a 16-bit integer and pass it on the trusted server fetches. Here's a concrete proposal for how this could look.
Example Usage
sellerExperimentGroupId
andbuyerExperimentGroupId
as a part of the contextual call.navigator.runAdAuction()
and includessellerExperimentGroupId
as part of auction config andbuyerExperimentGroupId
as part ofperBuyerSignals
.sellerExperimentGroupId
on the seller Trusted Server call andbuyerExperimentGroupId
on the buyer Trusted Server calls.sellerExperimentGroupId
and prepare appropriate responses. Buyer servers divert experiments by consideringbuyerExperimentGroupId
and prepare appropriate responses.buyerExperimentGroupId
is available togenerateBid()
viaperBuyerSignals
.sellerExperimentGroupId
is available toscoreAd()
via auction config. Consequently, bothgenerateBid()
andscoreAd()
will be able to make experiment-specific decisions.sellerExperimentGroupId
is passed toreportResult()
via auction config to support experiment-specific logic.buyerExperimentGroupId
is passed toreportWin()
viaperBuyerSignals
to support experiment-specific logic.reportResult()
may choose to makesellerExperimentGroupId
available toreportWin()
viasellerSignals
.