Skip to content
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

Merged
merged 7 commits into from
Aug 16, 2022

Conversation

abrik0131
Copy link
Contributor

@abrik0131 abrik0131 commented Mar 11, 2022

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

  1. The browser visits a publisher page.
  2. Ad tag JS receives sellerExperimentGroupId and buyerExperimentGroupId as a part of the contextual call.
  3. Ad tag JS invokes navigator.runAdAuction() and includes sellerExperimentGroupId as part of auction config and buyerExperimentGroupId as part of perBuyerSignals.
  4. The browser includes sellerExperimentGroupId on the seller Trusted Server call and buyerExperimentGroupId on the buyer Trusted Server calls.
  5. Seller trusted servers divert experiments by considering sellerExperimentGroupId and prepare appropriate responses. Buyer servers divert experiments by considering buyerExperimentGroupId and prepare appropriate responses.
  6. buyerExperimentGroupId is available to generateBid() via perBuyerSignals. sellerExperimentGroupId is available to scoreAd() via auction config. Consequently, both generateBid() and scoreAd() will be able to make experiment-specific decisions.
  7. sellerExperimentGroupId is passed to reportResult() via auction config to support experiment-specific logic. buyerExperimentGroupId is passed to reportWin() via perBuyerSignals to support experiment-specific logic. reportResult() may choose to make sellerExperimentGroupId available to reportWin() via sellerSignals.

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`.
@morlovich
Copy link
Collaborator

Should the experiment ID go with seller trusted signals as well?

@abrik0131
Copy link
Contributor Author

Yes, experiment ID (experimentGroupId) should go with seller trusted signals as well. I have added another commit (a94b2b2) for this. Thanks.

@morlovich
Copy link
Collaborator

@JensenPaul FYI Paul --- would be good if you double-checked this as I am close to wrapping up tests for the implementation

@jrmooring
Copy link

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
(1) echo back in an igbid
(2) remap into their own experiment ID space or
(3) ignore, potentially choosing their own experiment ID instead

@abrik0131 abrik0131 changed the title Update FLEDGE.md Extending FLEDGE to support coordinated experiments Mar 24, 2022
@abrik0131
Copy link
Contributor Author

@jrmooring , I've added a new commit to address your comment. Please take a look.

@jrmooring
Copy link

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': {
Copy link
Collaborator

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?

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?

Copy link
Contributor

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.

Copy link
Contributor Author

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?

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.

Copy link
Contributor

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!

Copy link
Contributor

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.

Copy link
Collaborator

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...

Copy link
Collaborator

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},

aarongable pushed a commit to chromium/chromium that referenced this pull request Apr 15, 2022
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}
Copy link
Collaborator

@morlovich morlovich left a 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': {
Copy link
Collaborator

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).
Copy link
Collaborator

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
Copy link
Collaborator

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).
Copy link
Collaborator

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:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, just experimentGroupId.

@abrik0131
Copy link
Contributor Author

@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.

FLEDGE.md Outdated Show resolved Hide resolved
@morlovich
Copy link
Collaborator

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>
@JensenPaul JensenPaul merged commit c6b0c14 into WICG:main Aug 16, 2022
mjfroman pushed a commit to mjfroman/moz-libwebrtc-third-party that referenced this pull request Oct 14, 2022
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}
NOKEYCHECK=True
GitOrigin-RevId: 9c37c816537202ef21e9447ddfe081093d292c97
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants