diff --git a/fetch.bs b/fetch.bs
index 4b1f0c2ca..fb383dc84 100644
--- a/fetch.bs
+++ b/fetch.bs
@@ -54,10 +54,28 @@ urlPrefix:https://tc39.es/ecma262/#;type:dfn;spec:ecma-262
     url:realm;text:realm
     url:sec-list-and-record-specification-type;text:Record
     url:current-realm;text:current realm
+
+urlPrefix:https://www.ietf.org/archive/id/draft-annevk-johannhof-httpbis-cookies-00.html#;type:dfn;spec:cookies
+    url:name-cookie-store-and-limits;text:cookie store
+    url:name-parse-and-store-a-cookie;text:parse and store a cookie
+    url:name-parse-a-cookie;text:parse a cookie
+    url:name-store-a-cookie;text:store a cookie
+    url:name-retrieve-cookies;text:retrieve cookies
+    url:name-serialize-cookies;text:serialize cookies
+
+<!-- TODO: pending HTML changes- ancestor enum (https://github.com/whatwg/html/pull/10559), has storage access bit, initiator origin plumbing -->
+urlPrefix:https://html.spec.whatwg.org#;type:dfn;spec:html
+    url:TODO;text:ancestry;for:environment
+    url:TODO;text:has storage access;for:environment
 </pre>
 
 <pre class=biblio>
 {
+    "COOKIES": {
+      "authors": ["Johann Hofmann", "Anne van Kesteren"],
+      "href": "https://www.ietf.org/archive/id/draft-annevk-johannhof-httpbis-cookies-00.html",
+      "title": "Cookies: HTTP State Management Mechanism"
+    },
     "HTTP": {
         "aliasOf": "RFC9110"
     },
@@ -1938,6 +1956,10 @@ not always relevant and might require different behavior.
 "<code>client</code>" or an <a for=/>origin</a>. Unless stated otherwise it is
 "<code>client</code>".
 
+<p>A <a for=/>request</a> has an associated
+<dfn export for=request id=concept-request-navigation-initiator-origin>top-level navigation
+initiator origin</dfn>, which is an <a for=/>origin</a> or null. Unless stated otherwise it is null.
+
 <p class=note>"<code>client</code>" is changed to an <a for=/>origin</a> during
 <a lt=fetch for=/>fetching</a>. It provides a convenient way for standards to not have to set
 <a for=/>request</a>'s <a for=request>origin</a>.
@@ -2226,9 +2248,9 @@ or "<code>object</code>".
 <hr>
 
 <div algorithm>
-<p>A <a for=/>request</a> <var>request</var> has a
-<dfn for=request id=concept-request-tainted-origin>redirect-tainted origin</dfn> if these steps
-return true:
+<p>A <a for=/>request</a> has a <dfn for=request id=concept-request-redirect-taint>redirect-taint</dfn>,
+which is "<code>same-origin</code>", "<code>same-site</code>", or "<code>cross-site</code>".
+<p>To get <a for=/>request</a> <var>request</var>'s <a>redirect-taint</a>:
 
 <ol>
  <li><p><a for=/>Assert</a>: <var>request</var>'s <a for=request>origin</a> is not
@@ -2236,6 +2258,8 @@ return true:
 
  <li><p>Let <var>lastURL</var> be null.
 
+ <li><p>Let <var>computedTaint</var> be "<code>same-origin</code>".
+
  <li>
   <p><a for=list>For each</a> <var>url</var> of <var>request</var>'s <a for=request>URL list</a>:
 
@@ -2243,14 +2267,20 @@ return true:
    <li><p>If <var>lastURL</var> is null, then set <var>lastURL</var> to <var>url</var> and
    <a for=iteration>continue</a>.
 
+   <li><p>If <var>url</var>'s <a for=url>origin</a> is not <a for=/>same site</a> with
+   <var>lastURL</var>'s <a for=url>origin</a> and <var>request</var>'s <a for=request>origin</a> is
+   not <a for=/>same site</a> with <var>lastURL</var>'s <a for=url>origin</a>, then return
+   "<code>cross-site</code>".
+
    <li><p>If <var>url</var>'s <a for=url>origin</a> is not <a>same origin</a> with
    <var>lastURL</var>'s <a for=url>origin</a> and <var>request</var>'s <a for=request>origin</a> is
-   not <a>same origin</a> with <var>lastURL</var>'s <a for=url>origin</a>, then return true.
+   not <a>same origin</a> with <var>lastURL</var>'s <a for=url>origin</a>, then set
+   <var>computedTaint</var> to "<code>same-site</code>".
 
    <li>Set <var>lastURL</var> to <var>url</var>.
   </ol>
 
- <li>Return false.
+ <li>Return <var>computedTaint</var>.
 </ol>
 </div>
 
@@ -2262,8 +2292,8 @@ run these steps:
  <li><p><a for=/>Assert</a>: <var>request</var>'s <a for=request>origin</a> is not
  "<code>client</code>".
 
- <li><p>If <var>request</var> has a <a for=request>redirect-tainted origin</a>, then return
- "<code>null</code>".
+ <li><p>If <var>request</var>'s <a for=request>redirect-taint</a> is not "<code>same-origin</code>",
+ then return "<code>null</code>".
 
  <li><p>Return <var>request</var>'s <a for=request>origin</a>,
  <a lt="ASCII serialization of an origin">serialized</a>.
@@ -2372,8 +2402,8 @@ source of security bugs. Please seek security review for features that deal with
  "<a for="embedder policy value"><code>credentialless</code></a>", then return true.</p>
 
  <li><p>If <var>request</var>'s <a for=request>origin</a> is <a>same origin</a> with
- <var>request</var>'s <a for=request>current URL</a>'s <a for=url>origin</a> and <var>request</var>
- does not have a <a for=request>redirect-tainted origin</a>, then return true.</p>
+ <var>request</var>'s <a for=request>current URL</a>'s <a for=url>origin</a> and <var>request</var>'s
+ <a for=request>redirect-taint</a> is not "<code>same-origin</code>", then return true.</p>
 
  <li><p>Return false.</p>
 </ol>
@@ -2486,8 +2516,9 @@ this is also tracked internally using the request's <a for=request>timing allow
 <dfn export for=response>service worker timing info</dfn> (null or a
 <a for=/>service worker timing info</a>), which is initially null.
 
-<p>A <a for=/>response</a> has an associated <dfn for=response>has-cross-origin-redirects</dfn>
-(a boolean), which is initially false.
+<p>A <a for=/>response</a> has an associated <dfn for=response>redirect taint</dfn>
+("<code>same-origin</code>", "<code>same-site</code>", or "<code>cross-site</code>", which is
+initially "<code>same-origin</code>".
 
 <hr>
 
@@ -4225,7 +4256,108 @@ indicates the request’s purpose is to fetch a resource that is anticipated to
 <p class=note>The server can use this to adjust the caching expiry for prefetches, to disallow the
 prefetch, or to treat it differently when counting page visits.
 
+<h2 id=cookies>Cookies</h2>
+
+<h3 id=cookie-header>`<code>Cookie</code>` header</h3>
+
+<p>The `<code>Cookie</code>` header is largely defined in its own specification. [[COOKIES]].
+We define infrastructure to be able to use them conveniently here.
+
+<div algorithm>
+<p>To <dfn id=append-a-request-cookie-header>append a request `<code>Cookie</code>` header</dfn>,
+given a <a for=/>request</a> <var>request</var>, run these steps:
+
+<ol>
+  <li><p>If the user-agent is configured to disable cookies for <var>request</var>, it should
+  return.
+
+  <li><p>Let |sameSite| be the result of [=determining the same-site mode=] for <var>request</var>.
+
+  <li><p>Let |isSecure| be false.
+
+  <li><p>If <var>request</var>'s <a for=request>client</a> is a <a>secure context</a>, then set
+  |isSecure| to true.
+
+  <li><p>Let |httpOnlyAllowed| be true.
+
+  <p class=note>Fetch implies that the request is http-only, as opposed to document.cookie
+
+  <li><p>Let |cookies| be the result of running <a>retrieve cookies</a> given |isSecure|,
+  <var>request</var>'s <a for=request>current URL</a>'s <a for=url>host</a>, <var>request</var>'s
+  <a for=request>current URL</a>'s <a for=url>path</a>, |httpOnlyAllowed|, and |sameSite|
+
+  <p class=note>It is expected that the cookie store returns an ordered list of cookies
+
+  <li>If |cookies| <a for="list">is empty</a>, then return.
+
+  <li>Let |value| be the result of running <a>serialize cookies</a> given |cookies|.
+
+  <li><a for="header list">Append</a> (`<code>Cookie</code>`, <var>value</var>) to
+  <var>request</var>'s <a for=request>header list</a>.
+</ol>
+</div>
+
+<div algorithm>
+<p>To <dfn id=parse-and-store-response-cookie-headers>parse and store response
+`<code>Set-Cookie</code>` headers</dfn>, given a <a for=/>request</a> <var>request</var> and a <a
+for=/>response</a> <var>response</var>, run these steps:
+
+<ol>
+  <li><p>If the user-agent is configured to disable cookies for <var>request</var>, it should
+  return.
 
+  <li><p>Let |allowNonHostOnlyCookieForPublicSuffix| be false.
+
+  <li><p>Let |isSecure| be false.
+
+  <li><p>If <var>request</var>'s <a for=request>client</a> is a <a>secure context</a>, set
+  |isSecure| to true.
+
+  <li><p>Let |httpOnlyAllowed| be true.
+
+  <p class=note>Fetch implies that the request is http-only, as opposed to document.cookie
+
+  <li><p>Let |sameSiteStrictOrLaxAllowed| be true if the result of [=determine the same-site mode=]
+  for |request| is "<code>StrictOrLess</code>", and false otherwise.
+
+  <li><p><a for=list>For each</a> <var>header</var> of <var>response</var>'s <a for=response>header
+  list</a>:
+
+  <ol>
+    <li><p>If <var>header</var>'s <a for=header>name</a> is not a <a>byte-case-insensitive</a> match
+    for `<code>Set-Cookie</code>`, <a for=iteration>continue</a>.
+
+    <li><p><a>Parse and store a cookie</a> given <var>header</var>'s <a for=header>value</a>,
+    |isSecure|, <var>request</var>'s <a for=request>current URL</a>'s <a for=url>host</a>,
+    <var>request</var>'s <a for=request>current URL</a>'s <a for=url>path</a>, |httpOnlyAllowed|,
+    |allowNonHostOnlyCookieForPublicSuffix|, and |sameSiteStrictOrLaxAllowed|
+  </ol>
+</ol>
+</div>
+
+<div algorithm>
+<p>To <dfn>determine the same-site mode</dfn> for a given <a for=/>request</a> <var>request</var>,
+run these steps:
+
+<ol>
+  <li><p><a for=/>Assert</a>: <var>request</var>'s <a for=request>method</a> is "GET" or "POST".
+
+  <li><p>If <var>request</var>'s <a for=request>top-level navigation initiator origin</a> is not
+  null and is not <a for=/>same site</a> to <var>request</var>'s <a for=request>URL</a>'s
+  <a for=url>origin</a>, return "<code>UnsetOrLess</code>".
+
+  <li><p>If <var>request</var>'s <a for=request>method</a> is "GET" and <var>request</var>'s <a
+  for=request>destination</a> is "document", return "<code>LaxOrLess</code>".
+
+  <li><p>If <var>request</var>'s <a for=request>client</a>'s <a for=environment>ancestry</a> is
+  "<code>cross-site</code>", return "<code>UnsetOrLess</code>".
+
+  <li><p>If <var>request</var>'s <a for=request>redirect-taint</a> is "<code>cross-site</code>",
+  return "<code>UnsetOrLess</code>".
+
+  <li><p>Return "StrictOrLess".
+</ol>
+</div>
 
 <h2 id=fetching>Fetching</h2>
 
@@ -4680,8 +4812,8 @@ steps:
  <!-- If you are ever tempted to move this around, carefully consider responses from about URLs,
       blob URLs, service workers, HTTP cache, HTTP network, etc. -->
 
- <li><p>If <var>request</var> has a <a for=request>redirect-tainted origin</a>, then set
- <var>internalResponse</var>'s <a for=response>has-cross-origin-redirects</a> to true.
+ <li><p>Set <var>internalResponse</var>'s <a for=response>redirect taint</a> to <var>request</var>'s
+ <a for=request>redirect-taint</a>.
 
  <li><p>If <var>request</var>'s <a for=request>timing allow failed flag</a> is unset, then set
  <var>internalResponse</var>'s <a for=response>timing allow passed flag</a>.
@@ -4834,7 +4966,7 @@ steps:
      <li>
       <p>If <var>fetchParams</var>'s <a for="fetch params">request</a>'s <a for=request>mode</a> is
       not "<code>navigate</code>" or <var>response</var>'s
-      <a for=response>has-cross-origin-redirects</a> is false:
+      <a for=response>redirect taint</a> is "<code>same-origin</code>":
 
       <ol>
        <li><p>Set <var>responseStatus</var> to <var>response</var>'s <a for=response>status</a>.
@@ -5710,21 +5842,7 @@ run these steps:
     <p>If <var>includeCredentials</var> is true, then:
 
     <ol>
-     <li>
-      <p>If the user agent is not configured to block cookies for <var>httpRequest</var> (see
-      <a href=https://httpwg.org/specs/rfc6265.html#privacy-considerations>section 7</a> of
-      [[!COOKIES]]), then:
-
-      <ol>
-       <li><p>Let <var>cookies</var> be the result of running the "cookie-string" algorithm (see
-       <a href=https://httpwg.org/specs/rfc6265.html#cookie>section 5.4</a> of
-       [[!COOKIES]]) with the user agent's cookie store and <var>httpRequest</var>'s
-       <a for=request>current URL</a>.
-
-       <li>If <var>cookies</var> is not the empty string, then <a for="header list">append</a>
-       (`<code>Cookie</code>`, <var>cookies</var>) to <var>httpRequest</var>'s
-       <a for=request>header list</a>.
-      </ol>
+     <li><p><a>Append a request `<code>Cookie</code>` header</a> for <var>httpRequest</var>.
 
      <li>
       <p>If <var>httpRequest</var>'s <a for=request>header list</a>
@@ -6288,14 +6406,9 @@ optional boolean <var>forceNewConnection</var> (default false), run these steps:
  <li><p>Set <var>response</var>'s <a for=response>body</a> to a new <a for=/>body</a> whose
  <a for=body>stream</a> is <var>stream</var>.
 
- <li><p tracking-vector>If <var>includeCredentials</var> is true and the user agent is not
- configured to block cookies for <var>request</var> (see
- <a href=https://httpwg.org/specs/rfc6265.html#privacy-considerations>section 7</a> of
- [[!COOKIES]]), then run the "set-cookie-string" parsing algorithm (see
- <a href=https://httpwg.org/specs/rfc6265.html#set-cookie>section 5.2</a> of [[!COOKIES]]) on the
- <a for=header>value</a> of each <a for=/>header</a> whose <a for=header>name</a> is a
- <a>byte-case-insensitive</a> match for `<code>Set-Cookie</code>` in <var>response</var>'s
- <a for=response>header list</a>, if any, and <var>request</var>'s <a for=request>current URL</a>.
+ <li><p tracking-vector>If <var>includeCredentials</var> is true, the user agent should <a>parse and
+ store response `<code>Set-Cookie</code>` headers</a> given <var>request</var> and
+ <var>response</var>.
 
  <li>
   <p>Run these steps <a>in parallel</a>: