diff --git a/spec.bs b/spec.bs
index acd9db511..18f876c6a 100644
--- a/spec.bs
+++ b/spec.bs
@@ -1125,8 +1125,7 @@ To validate and convert auction ad config given an {{AuctionAdConfig}
returned from an associated [=request=], whose [=request/initiator type=] is `"fetch"` and the
{{RequestInit/adAuctionHeaders}} option set to `true`, resolves or rejects. Otherwise, there
will be a race condition that the worklet can run without the direct from seller signals that
- it needs. See [[#handling-direct-from-seller-signals]] for details.
-
+ it needs. See [[#fetch-patch-for-auction-headers]] for details.
* To parse the value |result|:
1. Set |auctionConfig|'s [=auction config/direct from seller signals header ad slot=] to
|result|.
@@ -1401,7 +1400,7 @@ To generate and score bids given an [=auction config=] |auctionConfig
1. Let |leadingBidInfo| be a new [=leading bid info=].
1. Let |queue| be the result of [=starting a new parallel queue=].
1. Let |capturedAuctionHeaders| be |global|'s [=associated Document's=] [=node navigable's=]
- [=traversable navigable's=] [=traversable navigable/captured ad auction headers=].
+ [=traversable navigable's=] [=traversable navigable/captured ad auction signals headers=].
1. If |auctionConfig|'s [=auction config/component auctions=] are not [=list/is empty|empty=]:
1. [=Assert=] |topLevelAuctionConfig| is null.
1. Let |pendingComponentAuctions| be |auctionConfig|'s [=auction config/component auctions=]'s
@@ -3732,16 +3731,39 @@ This specification defines two [=policy-controlled features=] identified by the
Issue(WICG/turtledove#522): Move from "`*`" to "`self`".
-# Handling Direct from Seller Signals # {#handling-direct-from-seller-signals}
+# Fetch Patch for Auction Headers # {#fetch-patch-for-auction-headers}
-This section specifies a manner by which signals may be provided to auctions such that the signals
-are only used within their intended auction.
+This section specifies a manner by which some data, including [=additional bids=] and
+[=direct from seller signals=], may be provided to auctions such that the data is only used within
+their intended auction.
Any {{Document}} in a [=traversable navigable=] may run a Protected Audience auction (with
{{Window/navigator}}.{{Navigator/runAdAuction()}}) whose worklet functions receive signal objects
-derived from JSON from an [:Ad-Auction-Signals:] header captured by a
-{{WindowOrWorkerGlobalScope/fetch()}} call (using the {{RequestInit/adAuctionHeaders}} option)
-initiated by any *other* {{Document}} in the *same* [=traversable navigable=].
+derived from JSON from an [:Ad-Auction-Signals:] header, or [=additional bids=] derived from an
+[:Ad-Auction-Additional-Bid:] header, captured by a {{WindowOrWorkerGlobalScope/fetch()}} call
+(using the {{RequestInit/adAuctionHeaders}} option) initiated by any *other* {{Document}} in the
+*same* [=traversable navigable=].
+
+
+Modify [[FETCH]]'s [[FETCH#infrastructure]] to add a new section called "Per Traversable Navigable
+Structures", with the following content:
+
+Each [=traversable navigable=] has a captured ad auction signals
+headers, which is a [=map=] whose [=map/keys=] are [=direct from seller signals keys=] and
+whose [=map/values=] are [=direct from seller signals=].
+
+NOTE: This is only captured during a [=request=] whose [=request/initiator type=] is `"fetch"`, made
+with the {{RequestInit/adAuctionHeaders}} option set to `true`, as described in the
+[:Ad-Auction-Signals:] header description.
+
+Each [=traversable navigable=] has a captured ad auction additional
+bids headers, which is a [=map=] whose [=map/keys=] are [=auction nonces=] and whose
+[=map/values=] are [=strings=].
+
+NOTE: This is only captured during a [=request=] whose [=request/initiator type=] is `"fetch"`, made
+with the {{RequestInit/adAuctionHeaders}} option set to `true`, as described in the
+[:Ad-Auction-Additional-Bid:] header description.
+
Modify the definition of a [=request=]:
@@ -3780,52 +3802,6 @@ The following step will be added to the [=HTTP-network-or-cache fetch=] algorith
-
-Modify [[FETCH]]'s [[FETCH#infrastructure]] to add a new section called "Per Traversable Navigable
-Structures", with the following content:
-
-
Direct from seller signals key
-A
direct from seller signals key is a [=struct=] with the following [=struct/items=]:
-
-NOTE: This is only captured during a [=request=] whose [=request/initiator type=] is `"fetch"`, made
-with the {{RequestInit/adAuctionHeaders}} option set to `true`, as described in the
-[:Ad-Auction-Signals:] header description.
-
-
-: seller
-:: An [=origin=]. Matches the origin that served the captured [:Ad-Auction-Signals:] header.
-: ad slot
-:: A [=string=]. Matches the `adSlot` key of the JSON dictionaries in the top-level array of the
- [:Ad-Auction-Signals:] value.
-
-
-
-
Direct from seller signals
-A
direct from seller signals is a [=struct=] with the following [=struct/items=]:
-
-NOTE: This is only captured during a [=request=] whose [=request/initiator type=] is `"fetch"`, made
-with the {{RequestInit/adAuctionHeaders}} option set to `true`, as described in the
-[:Ad-Auction-Signals:] header description.
-
-
-: auction signals
-:: Null or a [=string=].
- Opaque JSON data passed to both buyers' and the seller's [=script runners=].
-: seller signals
-:: Null or a [=string=].
- Opaque JSON data passed to the seller's [=script runner=].
-: per buyer signals
-:: A [=map=] whose [=map/keys=] are [=origins=] and whose [=map/values=] are [=strings=].
- [=map/Keys=] are buyers and must be valid HTTPS origins. [=map/Values=] are opaque JSON data
- passed to corresponding buyer's [=script runner=].
-
-
-
-Each [=traversable navigable=] has a
captured ad auction headers
-, which is a [=map=] whose [=map/keys=] are [=direct from seller signals keys=] and whose
-[=map/values=] are [=direct from seller signals=].
-
-
The following will be added to [[Fetch#http-extensions]]:
@@ -3851,15 +3827,17 @@ HTTP response header.
The \`
Ad-Auction-Additional-Bid
\` response header provides value
of a string in the format of `
:`, which
-corresponds to a single additional bid. The response may include more than one additional bid by
-specifying multiple instances of the [:Ad-Auction-Additional-Bid:] response header.
+corresponds to a single [=additional bid=]. The response may include more than one [=additional bid=]
+by specifying multiple instances of the [:Ad-Auction-Additional-Bid:] response header.
-
-The following step will be added to the [=HTTP fetch=] algorithm, immediately under the step "If
+
+The following steps will be added to the [=HTTP fetch=] algorithm, immediately under the step "If
internalResponse’s [=status=] is a [=redirect status=]:"
-1. [=header list/Delete=] "[:Ad-Auction-Signals:]" from response's
+1. [=header list/Delete=] "[:Ad-Auction-Signals:]" from |response|'s
+ [=response/header list=].
+1. [=header list/Delete=] "[:Ad-Auction-Additional-Bid:]" from |response|'s
[=response/header list=].
@@ -3870,40 +3848,65 @@ The following step will be added to the [=HTTP fetch=] algorithm, before step
1. If |response| is not null, |response|'s [=status=] is not a [=redirect status=], |fetchParams|'s
[=fetch params/task destination=] is a [=global object=] that's a {{Window}} object, and
- |request|'s [=request/capture-ad-auction-headers=] is `true`, then run [=update captured headers=]
- with |fetchParams|'s [=fetch params/task destination=]'s [=associated Document's=] [=node
- navigable's=] [=traversable navigable's=] [=traversable navigable/captured ad auction headers=],
- |response|'s [=response/header list=], and |request|'s [=request/URL=]'s [=url/origin=].
+ |request|'s [=request/capture-ad-auction-headers=] is `true`:
+ 1. Let |navigable| be |fetchParams|'s [=fetch params/task destination=]'s [=associated Document=]'s
+ [=node navigable=]'s [=traversable navigable=].
+ 1. Run [=update captured headers=] with |navigable|'s
+ [=traversable navigable/captured ad auction signals headers=], |navigable|'s
+ [=traversable navigable/captured ad auction additional bids headers=], |response|'s
+ [=response/header list=], and |request|'s [=request/URL=]'s [=url/origin=].
The following algorithm will be added to the [[FETCH#fetching]] section:
-
-
To with a [=traversable
- navigable/captured ad auction headers=] |storedHeaders|, [=header list=] |responseHeaders|, and
- [=origin=] |requestOrigin|:
+ navigable/captured ad auction signals headers=] |storedSignalsHeaders|,
+ [=traversable navigable/captured ad auction additional bids headers=] |storedAdditionalBidsHeaders|,
+ [=header list=] |responseHeaders|, and [=origin=] |requestOrigin|:
1. Let |adAuctionSignals| be the result of [=header list/getting=] [:Ad-Auction-Signals:] from
|responseHeaders|.
- 1. If |adAuctionSignals| is null, return.
- 1. [=header list/Delete=] "[:Ad-Auction-Signals:]" from |responseHeaders|.
+ 1. If |adAuctionSignals| is not null:
+ 1. [=header list/Delete=] "[:Ad-Auction-Signals:]" from |responseHeaders|.
+
+ NOTE: This step prevents the header value from being used outside the intended auctions --
+ that is, scripts making the {{WindowOrWorkerGlobalScope/fetch()}} request aren't able to load
+ the header value.
+ 1. [=Handle ad auction signals header value=] given |adAuctionSignals|, |storedSignalsHeaders| and
+ |requestOrigin|.
+ 1. Let |additionalBids| be the result of [=header list/getting, decoding, and splitting=]
+ [:Ad-Auction-Additional-Bid:] from |responseHeaders|.
+ 1. If |additionalBids| is not null:
+ 1. [=header list/Delete=] "[:Ad-Auction-Additional-Bid:]" from |responseHeaders|.
+
+ NOTE: This step prevents the header value from being used outside the intended auctions --
+ that is, scripts making the {{WindowOrWorkerGlobalScope/fetch()}} request aren't able to load
+ the header value.
+ 1. [=list/For each=] |bid| of |additionalBids|:
+ 1. Let |nonceAndAdditionalBid| be the result of [=strictly splitting=] |bid| on U+003A (:).
+ 1. If |nonceAndAdditionalBid|'s [=list/size=] is not 2, then [=iteration/continue=].
+ 1. Let |nonce| be |nonceAndAdditionalBid|[0].
+ 1. If |nonce|'s [=string/length=] is not 36, then [=iteration/continue=].
+ 1. Set |storedAdditionalBidsHeaders|[|nonce|] to |nonceAndAdditionalBid|[1].
+
+
+
+
+To handle ad auction signals header value given a [=byte sequence=] |adAuctionSignals|,
+[=traversable navigable/captured ad auction signals headers=] |storedSignalsHeaders|, and [=origin=]
+|requestOrigin|:
- NOTE: This step prevents the header value from being used outside the intended auctions --
- that is, scripts making the {{WindowOrWorkerGlobalScope/fetch()}} request aren't able to load
- the header value.
1. Let |parsedSignals| be the result of [=parsing JSON bytes to an Infra value=], given
|adAuctionSignals|.
- 1. If |parsedSignals| is failure, return.
- 1. If |parsedSignals| is not a [=list=], return.
- 1. [=list/For each=] |signal| in |parsedSignals|:
+ 1. If |parsedSignals| is failure or not a [=list=], return.
+ 1. [=list/For each=] |signal| of |parsedSignals|:
1. If |signal| is not an [=ordered map=], [=iteration/continue=].
1. If |signal|["`adSlot`"] doesn't exist, [=iteration/continue=].
- 1. Create a new [=direct from seller signals key=] |signalsKey|, with its
+ 1. Let |signalsKey| be a new [=direct from seller signals key=], with its
[=direct from seller signals key/seller=] set to |requestOrigin| and its
[=direct from seller signals key/ad slot=] set to |signal|["`adSlot`"].
- 1. Create a new [=direct from seller signals=] |processedSignals|.
+ 1. Let |processedSignals| be a new [=direct from seller signals=].
1. [=map/Remove=] |signal|["`adSlot`"].
1. [=map/For each=] |key| → |value| of |signal|:
1. Switch on |key|:
@@ -3922,17 +3925,15 @@ The following algorithm will be added to the [[FETCH#fetching]] section:
1. If |value| is not an [=ordered map=], [=iteration/continue=].
1. For each |buyer| → |buyerSignals| of |value|:
- 1. Let |buyerOrigin| be the result of [=parsing an https origin=] on |buyer|. If this
- [=exception/throws=], [=iteration/continue=].
+ 1. Let |buyerOrigin| be the result of [=parsing an https origin=] on |buyer|.
+ 1. If |buyerOrigin| is failure, [=iteration/continue=].
1. Let |buyerSignalsString| be the result of
[=serializing an Infra value to a JSON string=], given |buyerSignals|.
1. Set |processedSignals|'s
[=direct from seller signals/per buyer signals=][|buyerOrigin|] to |buyerSignalsString|.
-
- 1. Set |storedHeaders|[|signalsKey|] to |processedSignals|.
-
+ 1. Set |storedSignalsHeaders|[|signalsKey|] to |processedSignals|.
@@ -4550,7 +4551,6 @@ response headers.
: provided as additional bid
:: A [=boolean=], initially false.
-
Ad descriptor
@@ -4581,6 +4581,33 @@ Width and height of an ad.
+Direct from seller signals
+
+A direct from seller signals key is a [=struct=] with the following [=struct/items=]:
+
+
+ : seller
+ :: An [=origin=]. Matches the origin that served the captured [:Ad-Auction-Signals:] header.
+ : ad slot
+ :: A [=string=]. Matches the `adSlot` key of the JSON dictionaries in the top-level array of the
+ [:Ad-Auction-Signals:] value.
+
+
+A direct from seller signals is a [=struct=] with the following [=struct/items=]:
+
+
+ : auction signals
+ :: Null or a [=string=].
+ Opaque JSON data passed to both buyers' and the seller's [=script runners=].
+ : seller signals
+ :: Null or a [=string=].
+ Opaque JSON data passed to the seller's [=script runner=].
+ : per buyer signals
+ :: A [=map=] whose [=map/keys=] are [=origins=] and whose [=map/values=] are [=strings=].
+ [=map/Keys=] are buyers and must be valid HTTPS origins. [=map/Values=] are opaque JSON data
+ passed to corresponding buyer's [=script runner=].
+
+
Score ad output
The output of running a Protected Audience `scoreAd()` script, is represented using the following type: