From 0666f4eb58c8396bab5e6d529800c5effb8158a8 Mon Sep 17 00:00:00 2001
From: camillelamy <33488028+camillelamy@users.noreply.github.com>
Date: Thu, 19 Nov 2020 22:36:09 +0100
Subject: [PATCH] Add cross-origin opener policy reporting

Closes #5260.
---
 source | 1283 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 1161 insertions(+), 122 deletions(-)

diff --git a/source b/source
index 08872ca04d9..c9bb9af8bf7 100644
--- a/source
+++ b/source
@@ -9141,8 +9141,7 @@ partial interface <dfn id="document" data-lt="">Document</dfn> {
   which is a <span>module map</span>, initially empty.</p>
 
   <p>The <code>Document</code> has a <dfn data-x="concept-document-coop">cross-origin opener
-  policy</dfn>, which is a <span>cross-origin opener policy</span>, initially "<code
-  data-x="coop-unsafe-none">unsafe-none</code>".</p>
+  policy</dfn>, which is a <span>cross-origin opener policy</span>.</p>
 
   <h4>The <code>DocumentOrShadowRoot</code> interface</h4>
 
@@ -77257,6 +77256,17 @@ popup4.close();</code></pre></div>
   data-x="navigation-hh">historyHandling</var> set to "<code
   data-x="hh-replace">replace</code>".</p>
 
+  <p>A <span>browsing context</span> has a <dfn data-x="virtual-browsing-context-group-id">virtual
+  browsing context group ID</dfn> integer. It is initially 0. This is used by <span
+  data-x="coop-struct-report-only-value">cross-origin opener policy reporting</span>, to keep track
+  of the browsing context group switches that would have happened if the report-only policy had been
+  enforced.</p>
+
+  <p>A <span>browsing context</span> has an <dfn data-x="browsing-context-initial-url">initial
+  URL</dfn>, which is a <span>URL</span> or null. It is initially null.</p>
+
+  <p>A <span>browsing context</span> has an <dfn data-x="opener-origin-at-creation">opener origin at
+  creation</dfn>, which is an <span>origin</span> or null. It is initially null.</p>
 
   <h4>Creating browsing contexts</h4>
 
@@ -77336,9 +77346,12 @@ popup4.close();</code></pre></div>
    <li id="creator-browsing-context"><p>If <var>creator</var> is non-null, then set
    <var>browsingContext</var>'s <span>creator origin</span> to return <var>creator</var>'s
    <span>origin</span>, <var>browsingContext</var>'s <span>creator URL</span> to return
-   <var>creator</var>'s <span data-x="concept-document-url">URL</span>, and
+   <var>creator</var>'s <span data-x="concept-document-url">URL</span>,
    <var>browsingContext</var>'s <span>creator base URL</span> to return <var>creator</var>'s <span
-   data-x="document base URL">base URL</span>.</p></li>
+   data-x="document base URL">base URL</span>, and <var>browsingContext</var>'s <span
+   data-x="virtual-browsing-context-group-id">virtual browsing context group ID</span> to
+   <var>creator</var>'s <span>top-level browsing context</span>'s <span
+   data-x="virtual-browsing-context-group-id">virtual browsing context group ID</span>.</p></li>
 
    <li><p>Let <var>sandboxFlags</var> be the result of <span>determining the creation sandboxing
    flags</span> given <var>browsingContext</var> and <var>embedder</var>.</p></li>
@@ -77387,7 +77400,7 @@ popup4.close();</code></pre></div>
    settings object">setting up a window environment settings object</span> with <var>realm execution
    context</var>, null, <var>topLevelCreationURL</var>, and <var>topLevelOrigin</var>.</p></li>
 
-   <li><p>Let <var>coop</var> be "<code data-x="coop-unsafe-none">unsafe-none</code>".</p></li>
+   <li><p>Let <var>coop</var> be a new <span>cross-origin opener policy</span>.</p></li>
 
    <li><p>If <var>creator</var> is non-null and <var>creator</var>'s <span>origin</span> is
    <span>same origin</span> with <var>creator</var>'s <span>relevant settings object</span>'s
@@ -77463,6 +77476,15 @@ popup4.close();</code></pre></div>
    <li><p>Set <var>browsingContext</var>'s <span>opener browsing context</span> to
    <var>opener</var>.</p></li>
 
+   <li><p>Set <var>browsingContext</var>'s <span data-x="virtual-browsing-context-group-id">virtual
+   browsing context group ID</span> to <var>opener</var>'s <span>top-level browsing context</span>'s
+   <span data-x="virtual-browsing-context-group-id">virtual browsing context group
+   ID</span>.</p></li>
+
+   <li><p>Set <var>browsingContext</var>'s <span data-x="opener-origin-at-creation">opener origin at
+   creation</span> to <var>opener</var>'s <span>active document</span>'s
+   <span>origin</span>.</p></li>
+
    <li id="copy-session-storage"><p><span>Legacy-clone a browsing session storage shed</span> with
    <var>opener</var>'s <span data-x="tlbc browsing session">browsing session</span> and
    <var>browsingContext</var>'s <span data-x="tlbc browsing session">browsing session</span>. <ref
@@ -78253,9 +78275,10 @@ console.assert(iframeWindow.frameElement === null);
 
        <li>
         <p>If <var>current</var>'s <span>top-level browsing context</span>'s <span>active
-        document</span>'s <span data-x="concept-document-coop">cross-origin opener policy</span> is
-        "<code data-x="coop-same-origin">same-origin</code>" or "<code
-        data-x="coop-same-origin-plus-COEP">same-origin-plus-COEP</code>", then:</p>
+        document</span>'s <span data-x="concept-document-coop">cross-origin opener policy</span>'s
+        <span data-x="coop-struct-value">value</span> is "<code
+        data-x="coop-same-origin">same-origin</code>" or "<code
+        data-x="coop-same-origin-plus-coep">same-origin-plus-COEP</code>", then:</p>
 
         <ol>
          <li><p>Let <var>currentDocument</var> be <var>current</var>'s <span>active
@@ -78429,8 +78452,16 @@ console.assert(iframeWindow.frameElement === null);
    { [[Property]]: "<code data-x="">postMessage</code>" } ยป.</p></li>
   </ol>
 
-  <p class="note">Indexed properties do not need to be safelisted as they are handled directly by
-  the <code>WindowProxy</code> object.</p>
+  <p class="note">Indexed properties do not need to be safelisted in this algorithm, as they are
+  handled directly by the <code>WindowProxy</code> object.</p>
+
+  <p>A JavaScript property name <var>P</var> is a <dfn>cross-origin accessible window property
+  name</dfn> if it is "<code data-x="">window</code>", "<code data-x="">self</code>", "<code
+  data-x="">location</code>", "<code data-x="">close</code>", "<code data-x="">closed</code>",
+  "<code data-x="">focus</code>", "<code data-x="">blur</code>", "<code data-x="">frames</code>",
+  "<code data-x="">length</code>", "<code data-x="">top</code>", "<code data-x="">opener</code>",
+  "<code data-x="">parent</code>", "<code data-x="">postMessage</code>", or an <span>array index
+  property name</span>.</p>
 
   <h5><dfn>CrossOriginPropertyFallback</dfn> ( <var>P</var> )</h5>
 
@@ -79840,6 +79871,12 @@ interface <dfn>BarProp</dfn> {
    <span data-x="concept-windowproxy-window">[[Window]]</span> internal slot of
    <b>this</b>.</p></li>
 
+   <li><p><span data-x="coop-check-access-report">Check if an access between two browsing contexts
+   should be reported</span>, given the <span>current global object</span>'s
+   <span data-x="window bc">browsing context</span>, <var>W</var>'s <span
+   data-x="window bc">browsing context</span>, <var>P</var>, and the <span>current settings
+   object</span>.</p></li>
+
    <li><p>If ! <span>IsPlatformObjectSameOrigin</span>(<var>W</var>) is true, then return ?
    <span>OrdinaryGet</span>(<b>this</b>, <var>P</var>, <var>Receiver</var>).</p></li>
 
@@ -79858,6 +79895,11 @@ interface <dfn>BarProp</dfn> {
    <span data-x="concept-windowproxy-window">[[Window]]</span> internal slot of
    <b>this</b>.</p></li>
 
+   <li><p><span data-x="coop-check-access-report">Check if an access between two browsing contexts
+   should be reported</span>, given the <span>current global object</span>'s <span>browsing
+   context</span>, <var>W</var>'s <span>browsing context</span>, <var>P</var>,
+   and the <span>current settings object</span>.</p></li>
+
    <li><p>If ! <span>IsPlatformObjectSameOrigin</span>(<var>W</var>) is true, then return ?
    <span>OrdinarySet</span>(<b>this</b>, <var>P</var>, <var>V</var>, <var>Receiver</var>).</p></li>
 
@@ -80824,10 +80866,10 @@ interface <dfn>BarProp</dfn> {
 
   <h3>Cross-origin opener policies</h3>
 
-  <p>A <dfn>cross-origin opener policy</dfn> allows a document which is navigated to in a
+  <p>A <dfn>cross-origin opener policy value</dfn> allows a document which is navigated to in a
   <span>top-level browsing context</span> to force the creation of a new <span>top-level browsing
-  context</span>, and a corresponding <span data-x="tlbc group">group</span>. It has one of the
-  following values:</p>
+  context</span>, and a corresponding <span data-x="tlbc group">group</span>. The possible values
+  are:</p>
 
   <dl>
    <dt>"<dfn><code data-x="coop-unsafe-none">unsafe-none</code></dfn>"</dt>
@@ -80864,10 +80906,28 @@ interface <dfn>BarProp</dfn> {
    </dd>
   </dl>
 
-  <p>To <dfn data-x="matching-coop">match cross-origin opener policies</dfn>, given a
-  <span>cross-origin opener policy</span> <var>A</var>, an <span>origin</span> <var>originA</var>, a
-  <span>cross-origin opener policy</span> <var>B</var>, and an <span>origin</span>
-  <var>originB</var>:</p>
+  <p>A <dfn>cross-origin opener policy</dfn> consists of:</p>
+
+  <ul>
+   <li><p>A <dfn data-x="coop-struct-value">value</dfn>, which is a <span data-x="cross-origin
+   opener policy value">cross-origin opener policy value</span>, initially "<code
+   data-x="coop-unsafe-none">unsafe-none</code>".</p></li>
+
+   <li><p>A <dfn data-x="coop-struct-report-endpoint">reporting endpoint</dfn>, which is string or
+   null, initially null.</p></li>
+
+   <li><p>A <dfn data-x="coop-struct-report-only-value">report-only value</dfn>, which is a <span
+   data-x="cross-origin opener policy value">cross-origin opener policy value</span>, initially
+   "<code data-x="coop-unsafe-none">unsafe-none</code>".</p></li>
+
+   <li><p>A <dfn data-x="coop-struct-report-only-endpoint">report-only reporting endpoint</dfn>,
+   which is a string or null, initially null.</p></li>
+  </ul>
+
+  <p>To <dfn data-x="matching-coop">match cross-origin opener policy values</dfn>, given a
+  <span>cross-origin opener policy value</span> <var>A</var>, an <span>origin</span>
+  <var>originA</var>, a <span>cross-origin opener policy value</span> <var>B</var>, and an
+  <span>origin</span> <var>originB</var>:</p>
 
   <ol>
    <li><p>If <var>A</var> is "<code data-x="coop-unsafe-none">unsafe-none</code>" and <var>B</var>
@@ -80882,19 +80942,21 @@ interface <dfn>BarProp</dfn> {
    <li><p>Return false.</p></li>
   </ol>
 
-  <h4>The `<code data-x="http-cross-origin-opener-policy">Cross-Origin-Opener-Policy</code>`
-  header</h4>
+  <h4>The headers</h4>
 
   <p>A <code>Document</code>'s <span data-x="concept-document-coop">cross-origin opener
   policy</span> is derived from the `<code
-  data-x="http-cross-origin-opener-policy">Cross-Origin-Opener-Policy</code>` HTTP response header.
-  This header is a <span data-x="http-structured-header">structured header</span> whose value must
-  be a <span data-x="http-structured-header-token">token</span>. <ref spec=STRUCTURED-FIELDS></p>
-
-  <p>The valid <span data-x="http-structured-header-token">token</span> values are "<code
-  data-x="coop-unsafe-none">unsafe-none</code>", "<code
-  data-x="coop-same-origin-allow-popups">same-origin-allow-popups</code>", and "<code
-  data-x="coop-same-origin">same-origin</code>".</p>
+  data-x="http-cross-origin-opener-policy">Cross-Origin-Opener-Policy</code>`  and the `<code
+  data-x="http-cross-origin-opener-policy-report-only">Cross-Origin-Opener-Policy-Report-Only</code>`
+  HTTP response headers. These headers are <span data-x="http-structured-header">structured
+  headers</span> whose value must be a <span data-x="http-structured-header-token">token</span>.
+  <ref spec=STRUCTURED-FIELDS></p>
+
+  <p>The valid <span data-x="http-structured-header-token">token</span> values are the <span
+  data-x="cross-origin opener policy value">opener policy values</span>. The token may also have
+  attached <span data-x="http-structured-header-parameters">parameters</span>; of these, the "<dfn
+  data-x="coop-report-to"><code>report-to</code></dfn>" parameter can have a <span>valid URL
+  string</span> identifying an appropriate reporting endpoint. <ref spec=REPORTING></p>
 
   <p class="note">Per the processing model described below, user agents will ignore this header if
   it contains an invalid value. Likewise, user agents will ignore this header if the value cannot be
@@ -80907,66 +80969,216 @@ interface <dfn>BarProp</dfn> {
   <var>reservedEnvironment</var>:</p>
 
   <ol>
+   <li><p>Let <var>policy</var> be a new <span>cross-origin opener policy</span>.</p></li>
+
    <li><p>If <var>reservedEnvironment</var> is a <span>non-secure context</span>, then return
-   "<code data-x="coop-unsafe-none">unsafe-none</code>".</p></li>
+   <var>policy</var>.</p></li>
 
    <li><p>Let <var>value</var> be the result of <span>getting a structured field value</span> given
    `<code data-x="http-cross-origin-opener-policy">Cross-Origin-Opener-Policy</code>` and "<code
    data-x="">item</code>" from <var>response</var>'s <span
    data-x="concept-response-header-list">header list</span>.</p></li>
 
-   <li><p>If <var>value</var> is null, then return "<code
-   data-x="coop-unsafe-none">unsafe-none</code>".</p></li>
+   <li>
+    <p>If <var>parsedItem</var> is not null, then:</p>
 
-   <li><p>If <var>value</var>[0] is not "<code data-x="coop-same-origin">same-origin</code>" or
-   "<code data-x="coop-same-origin-allow-popups">same-origin-allow-popups</code>", then return
-   "<code data-x="coop-unsafe-none">unsafe-none</code>".</p></li>
+    <ol>
+     <li>
+      <p>If <var>parsedItem</var>[0] is "<code data-x="coop-same-origin">same-origin</code>", then:</p>
+
+      <ol>
+       <li><p>Let <var>coep</var> be the result of <span data-x="obtain an embedder
+       policy">obtaining a cross-origin embedder policy</span> from <var>response</var>.</p></li>
+
+       <li><p>If <var>coep</var>'s <span data-x="embedder-policy-value">value</span> is "<code
+       data-x="coep-require-corp">require-corp</code>", then set <var>policy</var>'s <span
+       data-x="coop-struct-value">value</span> to "<code
+       data-x="coop-same-origin-plus-COEP">same-origin-plus-COEP</code>".</p></li>
+
+       <li><p>Otherwise, set <var>policy</var>'s <span
+       data-x="coop-struct-value">value</span> to "<code
+       data-x="coop-same-origin">same-origin</code>".</p></li>
+      </ol>
+     </li>
+
+     <li><p>If <var>parsedItem</var>[0] is "<code
+     data-x="coop-same-origin-allow-popups">same-origin-allow-popups</code>", then set
+     <var>policy</var>'s <span data-x="coop-struct-value">value</span> to "<code
+     data-x="coop-same-origin-allow-popups">same-origin-allow-popups</code>".</p></li>
+
+     <li><p>If <var>parsedItem</var>[1]["<code data-x="coop-report-to">report-to</code>"] <span
+     data-x="map exists">exists</span> and it is a string, then set <var>policy</var>'s <span
+     data-x="coop-struct-report-endpoint">reporting endpoint</span> to
+     <var>parsedItem</var>[1]["<code data-x="coop-report-to">report-to</code>"].</p></li>
+    </ol>
+   </li>
+
+   <li><p>Set <var>parsedItem</var> to the result of <span>getting a structured field value</span>
+   given `<code
+   data-x="http-cross-origin-opener-policy">Cross-Origin-Opener-Policy-Report-Only</code>` and
+   "<code data-x="">item</code>" from <var>response</var>'s <span
+   data-x="concept-response-header-list">header list</span>.</p></li>
 
    <li>
-    <p>If <var>value</var>[0] is "<code data-x="coop-same-origin">same-origin</code>", then:</p>
+    <p>If <var>parsedItem</var> is not null, then:</p>
 
     <ol>
-     <li><p>Let <var>coep</var> be the result of <span data-x="obtain an embedder policy">obtaining
-     an embedder policy</span> from <var>response</var>.</p></li>
+     <li>
+      <p>If <var>parsedItem</var>[0] is "<code data-x="coop-same-origin">same-origin</code>", then:</p>
 
-     <li><p>If <var>coep</var>'s <span data-x="embedder-policy-value">value</span> is
-     "<code data-x="">require-corp</code>", then return "<code
-     data-x="coop-same-origin-plus-COEP">same-origin-plus-COEP</code>".</p></li>
+      <ol>
+       <li><p>Let <var>coep</var> be the result of <span data-x="obtain an embedder
+       policy">obtaining a cross-origin embedder policy</span> from <var>response</var>.</p></li>
+
+       <li>
+        <p>If <var>coep</var>'s <span data-x="embedder-policy-value">value</span> is "<code
+        data-x="coep-require-corp">require-corp</code>" or <var>coep</var>'s <span
+        data-x="embedder-policy-report-only-value">report-only value</span> is "<code
+        data-x="coep-require-corp">require-corp</code>", then set <var>policy</var>'s <span
+        data-x="coop-struct-report-only-value">report-only value</span> to "<code
+        data-x="coop-same-origin-plus-COEP">same-origin-plus-COEP</code>".</p>
+
+        <p class="note">Report only COOP also considers report-only COEP to assign the special
+        "<code data-x="coop-same-origin-plus-COEP">same-origin-plus-COEP</code>" value. This allows
+        developers more freedom in the order of deployment of COOP and COEP.</p>
+       </li>
+
+       <li><p>Otherwise, set <var>policy</var>'s <span
+       data-x="coop-struct-report-only-value">report-only value</span> to "<code
+       data-x="coop-same-origin">same-origin</code>".</p></li>
+      </ol>
+     </li>
+
+     <li><p>If <var>parsedItem</var>[0] is "<code
+     data-x="coop-same-origin-allow-popups">same-origin-allow-popups</code>", then set
+     <var>policy</var>'s <span data-x="coop-struct-report-only-value">report-only value</span> to
+     "<code data-x="coop-same-origin-allow-popups">same-origin-allow-popups</code>".</p></li>
+
+     <li><p>If <var>parsedItem</var>[1]["<code data-x="coop-report-to">report-to</code>"] <span
+     data-x="map exists">exists</span> and it is a string, then set <var>policy</var>'s <span
+     data-x="coop-struct-report-only-endpoint">report-only reporting endpoint</span> to
+     <var>parsedItem</var>[1]["<code data-x="coop-report-to">report-to</code>"].</p></li>
     </ol>
    </li>
 
-   <li><p>Return <var>value</var>[0].</p></li>
+   <li><p>Return <var>policy</var>.</p></li>
   </ol>
 
+
   <h4>Browsing context group switches due to cross-origin opener policy</h4>
 
+  <p>To <dfn data-x="check-browsing-context-group-switch-coop-value">check if COOP values require
+  a browsing context group switch</dfn>, given a boolean <var>isInitialAboutBlank</var>, two <span
+  data-x="origin">origins</span> <var>responseOrigin</var>,
+  <var>activeDocumentNavigationOrigin</var>, and two <span data-x="coop-struct-value">cross-origin
+  opener policy values</span> <var>responseCOOPValue</var> and <var>activeDocumentCOOPValue</var>:</p>
+
+  <ol>
+   <li><p>If the result of <span data-x="matching-coop">matching</span>
+   <var>activeDocumentCOOPValue</var>, <var>activeDocumentNavigationOrigin</var>,
+   <var>responseCOOPValue</var>, and <var>responseOrigin</var> is true, return
+   false.</p></li>
+
+   <li>
+    <p>If all of the following are true:</p>
+
+    <ul class="brief">
+     <li><p><var>isInitialAboutBlank</var>,</p></li>
+
+     <li><p><var>activeDocumentCOOPValue</var>'s <span data-x="coop-struct-value">value</span> is
+     "<code data-x="coop-same-origin-allow-popups">same-origin-allow-popups</code>".</p></li>
+
+     <li><p><var>responseCOOPValue</var> is "<code
+     data-x="coop-unsafe-none">unsafe-none</code>",</p></li>
+    </ul>
+
+    <p>then return false.</p>
+   </li>
+
+   <li><p>Return true.</p>
+  </ol>
+
+  <p>To <dfn data-x="check-bcg-switch-navigation-report-only">check if enforcing report-only COOP
+  would require a browsing context group switch</dfn>, given a boolean
+  <var>isInitialAboutBlank</var>, two <span data-x="origin">origins</span>
+  <var>responseOrigin</var>, <var>activeDocumentNavigationOrigin</var>, and two <span
+  data-x="cross-origin opener policy">cross-origin opener policies</span> <var>responseCOOP</var>
+  and <var>activeDocumentCOOP</var>:</p>
+
+  <ol>
+   <li>
+    <p>If the result of <span data-x="check-browsing-context-group-switch-coop-value">checking if
+    COOP values require a browsing context group switch</span> given <var>isInitialAboutBlank</var>,
+    <var>sandboxFlags</var>, <var>responseOrigin</var>, <var>activeDocumentNavigationOrigin</var>,
+    <var>responseCOOP</var>'s <span data-x="coop-struct-report-only-value">report-only value</span>
+    and <var>activeDocumentCOOPReportOnly</var>'s <span
+    data-x="coop-struct-report-only-value">report-only value</span> is false, then return false.</p>
+
+    <p class="note">Matching report-only policies allows a website to specify the same report-only
+    cross-origin opener policy on all its pages and not receive violation reports for navigations
+    between these pages.</p>
+   </li>
+
+   <li><p>If the result of <span data-x="check-browsing-context-group-switch-coop-value">checking if
+   COOP values require a browsing context group switch</span> given <var>isInitialAboutBlank</var>,
+   <var>sandboxFlags</var>, <var>responseOrigin</var>, <var>activeDocumentNavigationOrigin</var>,
+   <var>responseCOOP</var>'s <span data-x="coop-struct-value">value</span> and
+   <var>activeDocumentCOOPReportOnly</var>'s <span
+   data-x="coop-struct-report-only-value">report-only value</span> is true, then return true.</p></li>
+
+   <li><p>If the result of <span data-x="check-browsing-context-group-switch-coop-value">checking if
+   COOP values require a browsing context group switch</span> given <var>isInitialAboutBlank</var>,
+   <var>sandboxFlags</var>, <var>responseOrigin</var>, <var>activeDocumentNavigationOrigin</var>,
+   <var>responseCOOP</var>'s <span data-x="coop-struct-report-only-value">report-only value</span>
+   and <var>activeDocumentCOOPReportOnly</var>'s <span data-x="coop-struct-value">value</span> is
+   true, then return true.</p></li>
+
+   <li><p>Return false.</p></li>
+  </ol>
+
   <p>A <dfn data-x="coop-enforcement-result">cross-origin opener policy enforcement result</dfn> is
   a <span>struct</span> with the following <span data-x="struct item">items</span>:</p>
 
   <ul>
    <li><p>A boolean <dfn data-x="coop-enforcement-bcg-switch">needs a browsing context group
-   switch</dfn>.</p></li>
+   switch</dfn>, initially false.</p></li>
 
-   <li><p>An <span>origin</span> <dfn data-x="coop-enforcement-origin">origin</dfn>.</p></li>
+   <li><p>A boolean <dfn
+   data-x="coop-enforcement-bcg-switch-report-only">would need a browsing context group switch due
+   to report-only</dfn>, initially false.</p></li>
+
+   <li><p>A <span>URL</span> <dfn data-x="coop-enforcement-url">url</dfn>.</p></li>
+
+   <li><p>An <span>origin</span> <dfn data-x="coop-enforcement-origin">current origin</dfn>.</p></li>
 
    <li><p>A <span>cross-origin opener policy</span> <dfn
    data-x="coop-enforcement-coop">cross-origin opener policy</dfn>.</p></li>
+
+   <li><p>A boolean <dfn data-x="coop-enforcement-source">current context is
+   navigation source</dfn>.</p></li>
   </ul>
 
   <p>To <dfn data-x="coop-enforce">enforce a response's cross-origin opener policy</dfn>, given a
-  <span>browsing context</span> <var>browsingContext</var>, an <span>origin</span>
-  <var>responseOrigin</var>, a <span>cross-origin opener policy</span> <var>responseCOOP</var>, and
-  a <span data-x="coop-enforcement-result">cross-origin opener policy enforcement result</span>
-  <var>currentCOOPEnforcementResult</var>:</p>
+  <span>browsing context</span> <var>browsingContext</var>, a <span>URL</span>
+  <var>responseURL</var>, an <span>origin</span> <var>responseOrigin</var>, a <span>cross-origin
+  opener policy</span> <var>responseCOOP</var>, a <span data-x="coop-enforcement-result">cross-origin
+  opener policy enforcement result</span> <var>currentCOOPEnforcementResult</var>, and a <span
+  data-x="concept-request-referrer">referrer</span> <var>referrer</var>:</p>
 
   <ol>
    <li><p>Let <var>newCOOPEnforcementResult</var> be a new <span
    data-x="coop-enforcement-result">cross-origin opener policy enforcement result</span> whose <span
    data-x="coop-enforcement-bcg-switch">needs a browsing context group switch</span> is
    <var>currentCOOPEnforcementResult</var>'s <span data-x="coop-enforcement-bcg-switch">needs a
-   browsing context group switch</span>, <span data-x="coop-enforcement-origin">origin</span> is
-   <var>responseOrigin</var>, and <span data-x="coop-enforcement-coop">cross-origin opener
-   policy</span> is <var>responseCOOP</var>.</p></li>
+   browsing context group switch</span>, <span
+   data-x="coop-enforcement-bcg-switch-report-only">would need a browsing context group switch due
+   to report-only</span> is <var>currentCOOPEnforcementResult</var>'s <span
+   data-x="coop-enforcement-bcg-switch-report-only">would need a browsing context group switch due
+   to report-only</span>, <span data-x="coop-enforcement-url">url</span> is <var>responseURL</var>,
+   <span data-x="coop-enforcement-origin">origin</span> is <var>responseOrigin</var>,
+   <span data-x="coop-enforcement-coop">coop</span> is <var>responseCOOP</var>, and
+   <span data-x="coop-enforcement-source">current context is navigation source</span> is
+   true.</p></li>
 
    <li><p>Let <var>isInitialAboutBlank</var> be false.</p></li>
 
@@ -80975,49 +81187,121 @@ interface <dfn>BarProp</dfn> {
    <span data-x="creating a new browsing context">created</span>, then set
    <var>isInitialAboutBlank</var> to true.</p></li>
 
-   <li><p>If the result of <span data-x="matching-coop">matching</span>
-   <var>currentCOOPEnforcementResult</var>'s <span
-   data-x="coop-enforcement-coop">cross-origin opener policy</span>,
-   <var>currentCOOPEnforcementResult</var>'s <span
-   data-x="coop-enforcement-origin">origin</span>,
-   <var>responseCOOP</var>, and <var>responseOrigin</var> is true, then return
-   <var>newCOOPEnforcementResult</var>.</p></li>
+   <li><p>If <var>isInitialAboutBlank</var> is true and <var>browsingContext</var>'s <span
+   data-x="browsing-context-initial-url">initial URL</span> is null, set
+   <var>browsingContext</var>'s <span data-x="browsing-context-initial-url">initial URL</span> to
+   <var>responseURL</var>.</p></li>
 
    <li>
-    <p>If all of the following are true:</p>
-
-    <ul class="brief">
-     <li><p><var>isInitialAboutBlank</var></p></li>
+    <p>If the result of <span data-x="check-browsing-context-group-switch-coop-value">checking if
+    COOP values require a browsing context group switch</span> given <var>isInitialAboutBlank</var>,
+    <var>currentCOOPEnforcementResult</var>'s <span data-x="coop-enforcement-coop">cross-origin
+    opener policy</span>'s <span data-x="coop-struct-value">value</span>,
+    <var>currentCOOPEnforcementResult</var>'s <span data-x="coop-enforcement-origin">origin</span>,
+    <var>responseCOOP</var>'s <span data-x="coop-struct-value">value</span>, and
+    <var>responseOrigin</var> is true, then:</p>
 
-     <li><p><var>currentCOOPEnforcementResult</var>'s <span
-     data-x="coop-enforcement-coop">cross-origin opener policy</span> is "<code
-     data-x="coop-same-origin-allow-popups">same-origin-allow-popups</code>"</p></li>
+    <ol>
+     <li><p>Set <var>newCOOPEnforcementResult</var>'s <span
+     data-x="coop-enforcement-bcg-switch">needs a browsing context group switch</span> to
+     true.</p></li>
 
-     <li><p><var>responseCOOP</var> is "<code
-     data-x="coop-unsafe-none">unsafe-none</code>"</p></li>
-    </ul>
+     <li>
+      <p>If <var>browsingContext</var>'s <span data-x="tlbc group">group</span>'s <span>browsing
+      context set</span>'s <span data-x="list size">size</span> is greater than 1, then:</p>
 
-    <p>then return <var>newCOOPEnforcementResult</var>.</p>
+      <ol>
+       <li><p><span data-x="coop-violation-navigation-to">Queue a violation report for browsing
+       context group switch when navigating to a COOP response</span> with <var>responseCOOP</var>,
+       "<code data-x="">enforce</code>", <var>responseURL</var>,
+       <var>currentCOOPEnforcementResult</var>'s <span data-x="coop-enforcement-url">url</span>,
+       <var>currentCOOPEnforcementResult</var>'s <span
+       data-x="coop-enforcement-origin">origin</span>, <var>responseOrigin</var>, and
+       <var>referrer</var>.</p></li>
+
+       <li><p><span data-x="coop-violation-navigation-from">Queue a violation report for browsing
+       context group switch when navigating away from a COOP response</span> with
+       <var>activeDocumentCOOP</var>, "<code data-x="">enforce</code>",
+       <var>currentCOOPEnforcementResult</var>'s <span data-x="coop-enforcement-url">url</span>,
+       <var>responseURL</var>, <var>currentCOOPEnforcementResult</var>'s <span
+       data-x="coop-enforcement-origin">origin</span>, <var>responseOrigin</var>, and
+       <var>currentCOOPEnforcementResult</var>'s <span data-x="coop-enforcement-source">current
+       context is navigation source</span>.</p></li>
+      </ol>
+     </li>
+    </ol>
    </li>
 
-   <li><p>Set <var>newCOOPEnforcementResult</var>'s <span data-x="coop-enforcement-bcg-switch">needs
-   a browsing context group switch</span> to true.</p></li>
+   <li>
+    <p>If the result of <span data-x="check-bcg-switch-navigation-report-only">checking if
+    enforcing report-only COOP would require a browsing context group switch</span> given
+    <var>isInitialAboutBlank</var>, <var>responseOrigin</var>,
+    <var>currentCOOPEnforcementResult</var>'s <span data-x="coop-enforcement-origin">origin</span>,
+    <var>responseCOOP</var>, and <var>currentCOOPEnforcementResult</var>'s <span
+    data-x="coop-enforcement-coop">cross-origin opener policy</span>, is true, then:</p>
+
+    <ol>
+     <li><p>Set <var>result</var>'s <span data-x="coop-enforcement-bcg-switch-report-only">would
+     need a browsing context group switch due to report-only</span> to true.</p></li>
+
+     <li>
+      <p>If <var>browsingContext</var>'s <span data-x="tlbc group">group</span>'s <span>browsing
+      context set</span>'s <span data-x="list size">size</span> is greater than 1, then:</p>
+
+      <ol>
+       <li><p><span
+       data-x="coop-violation-navigation-to">Queue a violation report for browsing context group switch
+       when navigating to a COOP response</span> with <var>responseCOOP</var>, "<code
+       data-x="">reporting</code>", <var>responseURL</var>,
+       <var>currentCOOPEnforcementResult</var>'s <span data-x="coop-enforcement-url">url</span>,
+       <var>currentCOOPEnforcementResult</var>'s <span data-x="coop-enforcement-origin">origin</span>,
+       <var>responseOrigin</var>,and <var>referrer</var>.</p></li>
+
+       <li><p><span data-x="coop-violation-navigation-from">Queue a violation report for browsing
+       context group switch when navigating away from a COOP response</span> with
+       <var>activeDocumentCOOP</var>, "<code data-x="">reporting</code>",
+       <var>currentCOOPEnforcementResult</var>'s <span data-x="coop-enforcement-url">url</span>,
+       <var>responseURL</var>, <var>currentCOOPEnforcementResult</var>'s <span
+       data-x="coop-enforcement-origin">origin</span>, <var>responseOrigin</var>, and
+       <var>currentCOOPEnforcementResult</var>'s <span data-x="coop-enforcement-source">current
+       context is navigation source</span>.</p></li>
+      </ol>
+     </li>
+    </ol>
+   </li>
 
    <li><p>Return <var>newCOOPEnforcementResult</var>.</p></li>
   </ol>
 
   <p>To <dfn data-x="obtain-browsing-context-navigation">obtain a browsing context to use for a
-  navigation response</dfn>, given a <span data-x="browsing context">browsing context</span>
-  <var>browsingContext</var>, a <span>sandboxing flag set</span> <var>sandboxFlags</var>, and a
-  <span>cross-origin opener policy</span> <var>navigationCOOP</var>:</p>
+  navigation response</dfn>, given a <span data-x="browsing context">browsing contexts</span>
+  <var>browsingContext</var>, a <span>sandboxing flag set</span> <var>sandboxFlags</var>, a
+  <span>cross-origin opener policy</span> <var>navigationCOOP</var>, and a <span
+  data-x="coop-enforcement-result">cross-origin opener policy enforcement result</span>
+  <var>coopEnforcementResult</var>:</p>
 
   <ol>
    <li><p>Assert: <var>browsingContext</var> is a <span>top-level browsing context</span>.</p></li>
 
+   <li>
+    <p>If <var>coopEnforcementResult</var>'s <span data-x="coop-enforcement-bcg-switch">needs a
+    browsing context group switch</span> is false, then:</p>
+
+    <ol>
+     <li><p>If <var>coopEnforcementResult</var>'s <span
+     data-x="coop-enforcement-bcg-switch-report-only">would need a browsing context group switch due
+     to report-only</span> is true, set <var>browsing context</var>'s <span
+     data-x="virtual-browsing-context-group-id">virtual browsing context group ID</span> to a new
+     unique identifier.</p></li>
+
+     <li><p>Return <var>browsingContext</var>.</p></li>
+    </ol>
+   </li>
+
    <li><p>Let <var>newBrowsingContext</var> be the result of <span>creating a new top-level browsing
    context</span>.</p></li>
 
-   <li><p>If <var>navigationCOOP</var> is "<code
+   <li><p>If <var>navigationCOOP</var>'s <span data-x="coop-struct-value">value</span> is "<code
    data-x="coop-same-origin-plus-COEP">same-origin-plus-COEP</code>", then set
    <var>newBrowsingContext</var>'s <span data-x="tlbc group">group</span>'s <span data-x="bcg
    cross-origin isolated">cross-origin isolated</span> to true.</p></li>
@@ -81025,8 +81309,8 @@ interface <dfn>BarProp</dfn> {
    <li>
     <p>If <var>sandboxFlags</var> is not empty, then:</p>
     <ol>
-     <li><p>Assert: <var>navigationCOOP</var> is "<code
-     data-x="coop-unsafe-none">unsafe-none</code>".</p></li>
+     <li><p>Assert <var>navigationCOOP</var>'s <span data-x="coop-struct-value">value</span> is
+     "<code data-x="coop-unsafe-none">unsafe-none</code>".</p></li>
 
      <li><p>Assert: <var>newBrowsingContext</var>'s <span>popup sandboxing flag set</span>
      <span data-x="list is empty">is empty</span>.</p></li>
@@ -81053,6 +81337,700 @@ interface <dfn>BarProp</dfn> {
   fully defined. It is currently under discussion in <a
   href="https://github.com/whatwg/html/issues/5350">issue #5350</a>.</p>
 
+  <h4>Reporting</h4>
+
+  <p>An <dfn>accessor-accessed relationship</dfn> is an enum that describes the relationship between
+  two <span data-x="browsing context">browsing contexts</span> between which an access happened. It
+  can take the following values:</p>
+
+  <dl>
+   <dt><dfn data-x="accessor-accessed-opener">accessor is opener</dfn></dt>
+   <dd><p>The accessor <span>browsing context</span> or one of its <span data-x="ancestor browsing
+   context">ancestors</span> is the <span>opener browsing context</span> of the accessed
+   <span>browsing context</span>'s <span>top-level browsing context</span>.</p></dd>
+
+   <dt><dfn data-x="accessor-accessed-openee">accessor is openee</dfn></dt>
+   <dd><p>The accessed <span>browsing context</span> or one of its <span data-x="ancestor browsing
+   context">ancestors</span> is the <span>opener browsing context</span> of the accessor
+   <span>browsing context</span>'s <span>top-level browsing context</span>.</p></dd>
+
+   <dt><dfn data-x="accessor-accessed-none">none</dfn></dt>
+   <dd><p>There is no opener relationship between the accessor <span>browsing context</span>, the
+   accessor <span>browsing context</span>, or any of their <span data-x="ancestor browsing
+   context">ancestors</span>.</p></dd>
+  </dl>
+
+  <p>To <dfn data-x="coop-check-access-report">check if an access between two browsing contexts
+  should be reported</dfn>, given two <span data-x="browsing context">browsing contexts</span>
+  <var>accessor</var> and <var>accessed</var>, a JavaScript property name
+  <var>P</var>, and an <span>environment settings object</span> <var>environment</var>:</p>
+
+  <ol>
+   <li><p>If <var>P</var> is not a <span>cross-origin accessible window property name</span>, then
+   return.</p></li>
+
+   <li>
+    <p>If <var>accessor</var>'s <span>active document</span>'s <span>origin</span> or any of its
+    <span data-x="ancestor browsing context">ancestors</span>' <span>active document</span>'s <span
+    data-x="origin">origins</span> are not <span>same origin</span> with <var>ancestor</var>'s
+    <span>top-level browsing context</span>'s <span>active document</span>'s <span>origin</span>, or
+    if <var>accessed</var>'s <span>active document</span>'s <span>origin</span> or any of its <span
+    data-x="ancestor browsing context">ancestors</span>' <span>active document</span>'s <span
+    data-x="origin">origins</span> are not <span>same origin</span> with <var>accessed</var>'s
+    <span>top-level browsing context</span>'s <span>active document</span>'s <span>origin</span>,
+    then return.</p>
+
+    <p class="note">This avoids leaking information about cross-origin iframes to a top level frame
+    with cross-origin opener policy reporting</p>
+   </li>
+
+   <li><p>If <var>accessor</var>'s <span>top-level browsing context</span>'s <span
+   data-x="virtual-browsing-context-group-id">virtual browsing context group ID</span> is
+   <var>accessed</var>'s <span>top-level browsing context</span>'s <span
+   data-x="virtual-browsing-context-group-id">virtual browsing context group ID</span>, then
+   return.</p></li>
+
+   <li><p>Let <var>accessorAccessedRelationship</var> be a new <span>accessor-accessed
+   relationship</span> with value <span data-x="accessor-accessed-none">none</span>.</p></li>
+
+   <li><p>If <var>accessed</var>'s <span>top-level browsing context</span>'s <span>opener browsing
+   context</span> is <var>accessor</var> or an <span data-x="ancestor browsing
+   context">ancestor</span> of <var>accessor</var>, then set <var>accessorAccessedRelationship</var> to
+   <span data-x="accessor-accessed-opener">accessor is opener</span>.</p></li>
+
+   <li><p>If <var>accessor</var>'s <span>top-level browsing context</span>'s <span>opener browsing
+   context</span> is <var>accessed</var> or an <span data-x="ancestor browsing
+   context">ancestor</span> of <var>accessed</var>, then set <var>accessorAccessedRelationship</var> to
+   <span data-x="accessor-accessed-openee">accessor is openee</span>.</p></li>
+
+   <li><p><span data-x="coop-violation-access">Queue violation reports for accesses</span>, given
+   <var>accessorAccessedRelationship</var>, <var>accessor</var>'s <span>top-level browsing
+   context</span>'s <span>active document</span>'s <span data-x="concept-document-coop">cross-origin
+   opener policy</span>, <var>accessed</var>'s <span>top-level browsing context</span>'s <span>active
+   document</span>'s <span data-x="concept-document-coop">cross-origin opener policy</span>,
+   <var>accessor</var>'s <span>active document</span>'s <span data-x="concept-document-url">URL</span>,
+   <var>accessed</var>'s <span>active document</span>'s <span data-x="concept-document-url">URL</span>,
+   <var>accessor</var>'s <span>top-level browsing context</span>'s <span
+   data-x="browsing-context-initial-url">initial URL</span>, <var>accessed</var>'s <span>top-level
+   browsing context</span>'s <span data-x="browsing-context-initial-url">initial URL</span>,
+   <var>accessor</var>'s <span>active document</span>'s <span>origin</span>, <var>accessed</var>'s
+   <span>active document</span>'s <span>origin</span>, <var>accessor</var>'s <span>top-level browsing
+   context</span>'s <span data-x="opener-origin-at-creation">opener origin at creation</span>,
+   <var>accessed</var>'s <span>top-level browsing context</span>'s <span
+   data-x="opener-origin-at-creation">opener origin at creation</span>, <var>accessor</var>'s
+   <span>top-level browsing context</span>'s <span>active document</span>'s <span
+   data-x="dom-document-referrer">referrer</span>, <var>accessed</var>'s <span>top-level browsing
+   context</span>'s <span>active document</span>'s <span
+   data-x="dom-document-referrer">referrer</span>, <var>P</var>, and
+   <var>environment</var>.</p></li>
+
+  </ol>
+
+  <p>To <dfn data-x="sanitize-url-report">sanitize a URL to send in a report</dfn> given a
+  <span>URL</span> <var>url</var>:</p>
+
+  <ol>
+   <li><p>Let <var>sanitizedURL</var> be a copy of <var>url</var>.</p></li>
+
+   <li><p><span data-x="set the username">Set the username</span> given <var>sanitizedURL</var> and
+   the empty string.
+
+   <li><p><span data-x="set the password">Set the password</span> given <var>sanitizedURL</var> and
+   the empty string.
+
+   <li><p>Return the <span data-x="concept-url-serializer">serialization</span> of
+   <var>sanitizedURL</var> with the <var>exclude fragment flag</var> set.</p></li>
+  </ol>
+
+  <p>To <dfn data-x="coop-violation-navigation-to">queue a violation report for browsing context group
+  switch when navigating to a COOP response</dfn> given a <span data-x="cross-origin opener
+  policy">cross-origin opener policy</span> <var>coop</var>, a string <var>disposition</var>, a
+  <span>URL</span> <var>coopURL</var>, a <span>URL</span> <var>previousResponseURL</var>, two <span
+  data-x="origin">origins</span> <var>coopOrigin</var> and <var>previousResponseOrigin</var>, and a
+  <span data-x="concept-request-referrer">referrer</span> <var>referrer</var>:</p>
+
+  <ol>
+   <li><p>If <var>coop</var>'s <span data-x="coop-struct-report-endpoint">reporting endpoint</span>
+   is null, return.</p></li>
+
+   <li><p>Let <var>coopValue</var> be <var>coop</var>'s <span
+   data-x="coop-struct-value">value</span>.</p></li>
+
+   <li><p>If <var>disposition</var> is "<code data-x="">reporting</code>", then set
+   <var>coopValue</var> to <var>coop</var>'s <span
+   data-x="coop-struct-report-only-value">report-only value</span>.</p></li>
+
+   <li><p>Let <var>serializedReferrer</var> be an empty string</p></li>
+
+   <li><p>If <var>referrer</var> is a <span>URL</span>, set <var>serializedReferrer</var> to the
+   <span data-x="concept-url-serializer">serialization</span> of <var>referrer</var>.
+
+   <li>
+    <p>Let <var>body</var> be a new object containing the following properties:</p>
+
+    <table class="data">
+     <thead>
+      <tr>
+       <th>key</th>
+       <th>value</th>
+      </tr>
+     </thead>
+     <tbody>
+      <tr>
+       <td>disposition</td>
+       <td><var>disposition</var></td>
+      </tr>
+      <tr>
+       <td>effectivePolicy</td>
+       <td><var>coopValue</var></td>
+      </tr>
+      <tr>
+       <td>previousResponseURL</td>
+       <td>If <var>coopOrigin</var> and <var>previousResponseOrigin</var> are <span>same
+       origin</span> this is the <span data-x="sanitize-url-report">sanitization</span> of
+       <var>previousResponseURL</var>, null otherwise.</td>
+      </tr>
+      <tr>
+       <td>referrer</td>
+       <td><var>serializedReferrer</var></td>
+      </tr>
+      <tr>
+       <td>type</td>
+       <td>"<code data-x="">navigation-to-response</code>"</td>
+      </tr>
+     </tbody>
+    </table>
+   </li>
+
+   <li><p><span data-x="queue a report">Queue</span> <var>body</var> as "<code data-x="">coop</code>"
+   for <var>coop</var>'s <span data-x="coop-struct-report-endpoint">reporting endpoint</span> with
+   <var>coopURL</var>.</p></li>
+  </ol>
+
+  <p>To <dfn data-x="coop-violation-navigation-from">queue a violation report for browsing context group
+  switch when navigating away from a COOP response</dfn> given a <span data-x="cross-origin opener
+  policy">cross-origin opener policy</span> <var>coop</var>, a string <var>disposition</var>, a
+  <span>URL</span> <var>coopURL</var>, a <span>URL</span> <var>nextResponseURL</var>, two <span
+  data-x="origin">origins</span> <var>coopOrigin</var> and <var>nextResponseOrigin</var>, and a boolean
+  <var>isCOOPResponseNavigationSource</var>:</p>
+
+  <ol>
+   <li><p>If <var>coop</var>'s <span data-x="coop-struct-report-endpoint">reporting endpoint</span>
+   is null, return.</p></li>
+
+   <li><p>Let <var>coopValue</var> be <var>coop</var>'s <span
+   data-x="coop-struct-value">value</span>.</p></li>
+
+   <li><p>If <var>disposition</var> is "<code data-x="">reporting</code>", then set
+   <var>coopValue</var> to <var>coop</var>'s <span
+   data-x="coop-struct-report-only-value">report-only value</span>.</p></li>
+
+   <li>
+    <p>Let <var>body</var> be a new object containing the following properties:</p>
+
+    <table class="data">
+     <thead>
+      <tr>
+       <th>key</th>
+       <th>value</th>
+      </tr>
+     </thead>
+     <tbody>
+      <tr>
+       <td>disposition</td>
+       <td><var>disposition</var></td>
+      </tr>
+      <tr>
+       <td>effectivePolicy</td>
+       <td><var>coopValue</var></td>
+      </tr>
+      <tr>
+       <td>nextResponseURL</td>
+       <td>If <var>coopOrigin</var> and <var>nextResponseOrigin</var> are <span>same origin</span>
+       or <var>isCOOPResponseNavigationSource</var> is true, this is the <span
+       data-x="sanitize-url-report">sanitization</span> of <var>previousResponseURL</var>, null
+       otherwise.</td>
+      </tr>
+      <tr>
+       <td>type</td>
+       <td>"<code data-x="">navigation-to-response</code>"</td>
+      </tr>
+     </tbody>
+    </table>
+   </li>
+
+   <li><p><span data-x="queue a report">Queue</span> <var>body</var> as "<code data-x="">coop</code>"
+   for <var>coop</var>'s <span data-x="coop-struct-report-endpoint">reporting endpoint</span> with
+   <var>coopURL</var>.</p></li>
+  </ol>
+
+  <p>To <dfn data-x="coop-violation-access">queue violation reports for accesses</dfn>, given an
+  <span>accessor-accessed relationship</span> <var>accessorAccessedRelationship</var>, two
+  <span data-x="cross-origin opener policy">cross-origin opener policies</span>
+  <var>accessorCOOP</var> and <var>accessedCOOP</var>, four <span data-x="url">URLs</span>
+  <var>accessorURL</var>, <var>accessedURL</var>, <var>accessorInitialURL</var>,
+  <var>accessedInitialURL</var>, four <span data-x="origin">origins</span>
+  <var>accessorOrigin</var>, <var>accessedOrigin</var>, <var>accessorCreatorOrigin</var> and
+  <var>accessedCreatorOrigin</var>, two <span data-x="dom-document-referrer">referrers</span>
+  <var>accessorReferrer</var> and <var>accessedReferrer</var>, a string <var>propertyName</var>, and
+  an <span>environment settings object</span> <var>environment</var>:</p>
+
+  <ol>
+   <li><p>If <var>coop</var>'s <span data-x="coop-struct-report-endpoint">reporting endpoint</span>
+   is null, return.</p></li>
+
+   <li><p>Let <var>coopValue</var> be <var>coop</var>'s <span
+   data-x="coop-struct-value">value</span>.</p></li>
+
+   <li><p>If <var>disposition</var> is "<code data-x="">reporting</code>", then set
+   <var>coopValue</var> to <var>coop</var>'s <span
+   data-x="coop-struct-report-only-value">report-only value</span>.</p></li>
+
+   <li>
+    <p>If <var>accessorAccessedRelationship</var> is <span
+    data-x="accessor-accessed-opener">accessor is opener</span>:</p>
+
+    <ol>
+     <li><p><span data-x="coop-violation-access-to-opened">Queue a violation report
+     for access to an opened window</span>, given <var>accessorCOOP</var>, <var>accessorURL</var>,
+     <var>accessedURL</var>, <var>accessedInitialURL</var>, <var>accessorOrigin</var>,
+     <var>accessedOrigin</var>, <var>accessedCreatorOrigin</var>, <var>propertyName</var>,
+     and <var>environment</var>.</p></li>
+
+     <li><p><span data-x="coop-violation-access-from-opener">Queue a violation report for access
+     from the opener</span>, given <var>accessedCOOP</var>, <var>accessedURL</var>,
+     <var>accessorURL</var>, <var>accessedOrigin</var>, <var>accessorOrigin</var>,
+     <var>propertyName</var>, and <var>accessedReferrer</var>.</p></li>
+    </ol>
+   </li>
+
+   <li>
+    <p>Otherwise, if <var>accessorAccessedRelationship</var> is <span
+    data-x="accessor-accessed-openee">accessor is openee</span>:</p>
+
+    <ol>
+     <li><p><span data-x="coop-violation-access-to-opener">Queue a violation report for access to
+     the opener</span>, given <var>accessorCOOP</var>, <var>accessorURL</var>,
+     <var>accessedURL</var>, <var>accessorOrigin</var>, <var>accessedOrigin</var>,
+     <var>propertyName</var>, <var>accessorReferrer</var>, and <var>environment</var>.</p></li>
+
+     <li><p><span data-x="coop-violation-access-from-opened">Queue a violation report for access
+     from an opened window</span>, given <var>accessedCOOP</var>, <var>accessedURL</var>,
+     <var>accessorURL</var>, <var>accessorInitialURL</var>, <var>accessedOrigin</var>,
+     <var>accessorOrigin</var>, <var>accessorCreatorOrigin</var>, and
+     <var>propertyName</var>.</p></li>
+    </ol>
+   </li>
+
+   <li>
+    <p>Otherwise:</p>
+
+    <ol>
+     <li><p><span data-x="coop-violation-access-to-opened">Queue a violation report for
+     access to another window</span>, given <var>accessorCOOP</var>, <var>accessorURL</var>,
+     <var>accessedURL</var>, <var>accessorOrigin</var>, <var>accessedOrigin</var>,
+     <var>propertyName</var>, and <var>environment</var></p></li>
+
+     <li><p><span data-x="coop-violation-access-from-other">Queue a violation report for
+     access from another window</span>, given <var>accessedCOOP</var>, <var>accessedURL</var>,
+     <var>accessorURL</var>, <var>accessedOrigin</var>, <var>accessorOrigin</var>, and
+     <var>propertyName</var>.</p></li>
+    </ol>
+   </li>
+  </ol>
+
+  <p>To <dfn data-x="coop-violation-access-to-opener">queue a violation report for access to the
+  opener</dfn>, given a <span data-x="cross-origin opener policy">cross-origin opener
+  policy</span> <var>coop</var>, two <span data-x="URL">URLs</span> <var>coopURL</var> and
+  <var>openerURL</var>, two <span data-x="origin">origins</span> <var>coopOrigin</var> and
+  <var>openerOrigin</var>, a string <var>propertyName</var>, a <span
+  data-x="concept-request-referrer">referrer</span> <var>referrer</var>, and an <span>environment
+  settings object</span> <var>environment</var>:</p>
+
+  <ol>
+   <li><p>Let <var>sourceFile</var>, <var>lineNumber</var> and <var>columnNumber</var> be the
+   relevant script URL and problematic position which triggered this report.</p></li>
+
+   <li><p>Let <var>serializedReferrer</var> be an empty string</p></li>
+
+   <li><p>If <var>referrer</var> is a <span>URL</span>, set <var>serializedReferrer</var> to the
+   <span data-x="concept-url-serializer">serialization</span> of <var>referrer</var>.
+
+   <li>
+    <p>Let <var>body</var> be a new object containing the following properties:</p>
+
+    <table class="data">
+     <thead>
+      <tr>
+       <th>key</th>
+       <th>value</th>
+      </tr>
+     </thead>
+     <tbody>
+      <tr>
+       <td>disposition</td>
+       <td>"<code data-x="">reporting</code>"</td>
+      </tr>
+      <tr>
+       <td>effectivePolicy</td>
+       <td><var>coop</var>'s <span data-x="coop-struct-report-only-value">report-only
+       value</span></td>
+      </tr>
+      <tr>
+       <td>property</td>
+       <td><var>propertyName</var></td>
+      </tr>
+      <tr>
+       <td>openerURL</td>
+       <td>If <var>coopOrigin</var> and <var>openerOrigin</var> are <span>same origin</span>, this
+       is the <span data-x="sanitize-url-report">sanitization</span> of <var>openerURL</var>, null
+       otherwise.</td>
+      </tr>
+      <tr>
+       <td>referrer</td>
+       <td><var>serializedReferrer</var></td>
+      </tr>
+      <tr>
+       <td>sourceFile</td>
+       <td><var>sourceFile</var></td>
+      </tr>
+      <tr>
+       <td>lineNumber</td>
+       <td><var>lineNumber</var></td>
+      </tr>
+      <tr>
+       <td>columnNumber</td>
+       <td><var>columnNumber</var></td>
+      </tr>
+      <tr>
+       <td>type</td>
+       <td>"<code data-x="">access-to-opener</code>"</td>
+      </tr>
+     </tbody>
+    </table>
+   </li>
+
+   <li><p><span data-x="queue a report">Queue</span> <var>body</var> as "<code data-x="">coop</code>"
+   for <var>coop</var>'s <span data-x="coop-struct-report-endpoint">reporting endpoint</span> with
+   <var>coopURL</var> and <var>environment</var>.</p></li>
+  </ol>
+
+  <p>To <dfn data-x="coop-violation-access-to-opened">queue a violation report for access to an
+  opened window</dfn>, given a <span data-x="cross-origin opener policy">cross-origin opener
+  policy</span> <var>coop</var>, three <span data-x="URL">URLs</span> <var>coopURL</var>,
+  <var>openedWindowURL</var> and <var>initialWindowURL</var>, three <span
+  data-x="origin">origins</span> <var>coopOrigin</var>, <var>openedWindowOrigin</var>, and
+  <var>openerInitialOrigin</var>,a string <var>propertyName</var>, and an <span>environment settings
+  object</span> <var>environment</var>:</p>
+
+  <ol>
+   <li><p>Let <var>sourceFile</var>, <var>lineNumber</var> and <var>columnNumber</var> be the
+   relevant script URL and problematic position which triggered this report.</p></li>
+
+   <li>
+    <p>Let <var>body</var> be a new object containing the following properties:</p>
+
+    <table class="data">
+     <thead>
+      <tr>
+       <th>key</th>
+       <th>value</th>
+      </tr>
+     </thead>
+     <tbody>
+      <tr>
+       <td>disposition</td>
+       <td>"<code data-x="">reporting</code>"</td>
+      </tr>
+      <tr>
+       <td>effectivePolicy</td>
+       <td><var>coop</var>'s <span data-x="coop-struct-report-only-value">report-only
+       value</span></td>
+      </tr>
+      <tr>
+       <td>property</td>
+       <td><var>propertyName</var></td>
+      </tr>
+      <tr>
+       <td>openedWindowURL</td>
+       <td>If <var>coopOrigin</var> and <var>openedWindowOrigin</var> are <span>same origin</span>, this
+       is the <span data-x="sanitize-url-report">sanitization</span> of <var>openedWindowURL</var>,
+       null otherwise.</td>
+      </tr>
+      <tr>
+       <td>openedWindowInitialURL</td>
+       <td>If <var>coopOrigin</var> and <var>openerInitialOrigin</var> are <span>same origin</span>,
+       this is the <span data-x="sanitize-url-report">sanitization</span> of
+       <var>initialWindowURL</var>, null otherwise.</td>
+      </tr>
+      <tr>
+       <td>sourceFile</td>
+       <td><var>sourceFile</var></td>
+      </tr>
+      <tr>
+       <td>lineNumber</td>
+       <td><var>lineNumber</var></td>
+      </tr>
+      <tr>
+       <td>columnNumber</td>
+       <td><var>columnNumber</var></td>
+      </tr>
+      <tr>
+       <td>type</td>
+       <td>"<code data-x="">access-to-opener</code>"</td>
+      </tr>
+     </tbody>
+    </table>
+   </li>
+
+   <li><p><span data-x="queue a report">Queue</span> <var>body</var> as "<code data-x="">coop</code>"
+   for <var>coop</var>'s <span data-x="coop-struct-report-endpoint">reporting endpoint</span> with
+   <var>coopURL</var> and <var>environment</var>.</p></li>
+  </ol>
+
+
+  <p>To <dfn data-x="coop-violation-access-to-other">queue a violation report for access to another
+  window</dfn>, given a <span data-x="cross-origin opener policy">cross-origin opener policy</span>
+  <var>coop</var>, two <span data-x="URL">URLs</span> <var>coopURL</var> and
+  <var>otherURL</var>, two <span data-x="origin">origins</span> <var>coopOrigin</var> and
+  <var>otherOrigin</var>, a string <var>propertyName</var>, and an <span>environment settings
+  object</span> <var>environment</var>:</p>
+
+  <ol>
+   <li><p>Let <var>sourceFile</var>, <var>lineNumber</var> and <var>columnNumber</var> be the
+   relevant script URL and problematic position which triggered this report.</p></li>
+
+   <li>
+    <p>Let <var>body</var> be a new object containing the following properties:</p>
+
+    <table class="data">
+     <thead>
+      <tr>
+       <th>key</th>
+       <th>value</th>
+      </tr>
+     </thead>
+     <tbody>
+      <tr>
+       <td>disposition</td>
+       <td>"<code data-x="">reporting</code>"</td>
+      </tr>
+      <tr>
+       <td>effectivePolicy</td>
+       <td><var>coop</var>'s <span data-x="coop-struct-report-only-value">report-only
+       value</span></td>
+      </tr>
+      <tr>
+       <td>property</td>
+       <td><var>propertyName</var></td>
+      </tr>
+      <tr>
+       <td>otherURL</td>
+       <td>If <var>coopOrigin</var> and <var>otherOrigin</var> are <span>same origin</span>, this
+       is the <span data-x="sanitize-url-report">sanitization</span> of <var>otherURL</var>, null
+       otherwise.</td>
+      </tr>
+      <tr>
+       <td>sourceFile</td>
+       <td><var>sourceFile</var></td>
+      </tr>
+      <tr>
+       <td>lineNumber</td>
+       <td><var>lineNumber</var></td>
+      </tr>
+      <tr>
+       <td>columnNumber</td>
+       <td><var>columnNumber</var></td>
+      </tr>
+      <tr>
+       <td>type</td>
+       <td>"<code data-x="">access-to-opener</code>"</td>
+      </tr>
+     </tbody>
+    </table>
+   </li>
+
+   <li><p><span data-x="queue a report">Queue</span> <var>body</var> as "<code data-x="">coop</code>"
+   for <var>coop</var>'s <span data-x="coop-struct-report-endpoint">reporting endpoint</span> with
+   <var>coopURL</var> and <var>environment</var>.</p></li>
+  </ol>
+
+  <p>To <dfn data-x="coop-violation-access-from-opener">queue a violation report for access from the
+  opener</dfn>, given a <span data-x="cross-origin opener policy">cross-origin opener policy</span>
+  <var>coop</var>, two <span data-x="URL">URLs</span> <var>coopURL</var> and
+  <var>openerURL</var>, two <span data-x="origin">origins</span> <var>coopOrigin</var> and
+  <var>openerOrigin</var>, a string <var>propertyName</var>, and a <span
+  data-x="concept-request-referrer">referrer</span> <var>referrer</var>:</p>
+
+  <ol>
+   <li><p>If <var>coop</var>'s <span data-x="coop-struct-report-endpoint">reporting endpoint</span>
+   is null, return.</p></li>
+
+   <li><p>Let <var>serializedReferrer</var> be an empty string</p></li>
+
+   <li><p>If <var>referrer</var> is a <span>URL</span>, set <var>serializedReferrer</var> to the
+   <span data-x="concept-url-serializer">serialization</span> of <var>referrer</var>.
+
+   <li>
+    <p>Let <var>body</var> be a new object containing the following properties:</p>
+
+    <table class="data">
+     <thead>
+      <tr>
+       <th>key</th>
+       <th>value</th>
+      </tr>
+     </thead>
+     <tbody>
+      <tr>
+       <td>disposition</td>
+       <td>"<code data-x="">reporting</code>"</td>
+      </tr>
+      <tr>
+       <td>effectivePolicy</td>
+       <td><var>coop</var>'s <span data-x="coop-struct-report-only-value">report-only
+       value</span></td>
+      </tr>
+      <tr>
+       <td>property</td>
+       <td><var>propertyName</var></td>
+      </tr>
+      <tr>
+       <td>openerURL</td>
+       <td>If <var>coopOrigin</var> and <var>openerOrigin</var> are <span>same origin</span>, this
+       is the <span data-x="sanitize-url-report">sanitization</span> of <var>openerURL</var>, null
+       otherwise.</td>
+      </tr>
+      <tr>
+       <td>referrer</td>
+       <td><var>serializedReferrer</var></td>
+      </tr>
+      <tr>
+       <td>type</td>
+       <td>"<code data-x="">access-to-opener</code>"</td>
+      </tr>
+     </tbody>
+    </table>
+   </li>
+
+   <li><p><span data-x="queue a report">Queue</span> <var>body</var> as "<code data-x="">coop</code>"
+   for <var>coop</var>'s <span data-x="coop-struct-report-endpoint">reporting endpoint</span> with
+   <var>coopURL</var>.</p></li>
+  </ol>
+
+  <p>To <dfn data-x="coop-violation-access-from-opened">queue a violation report for access from an
+  opened window</dfn>, given a <span data-x="cross-origin opener policy">cross-origin opener
+  policy</span> <var>coop</var>, three <span data-x="URL">URLs</span> <var>coopURL</var>,
+  <var>openedWindowURL</var> and <var>initialWindowURL</var>, three <span
+  data-x="origin">origins</span> <var>coopOrigin</var>, <var>openedWindowOrigin</var>, and
+  <var>openerInitialOrigin</var>, and a string <var>propertyName</var>:</p>
+
+  <ol>
+   <li><p>If <var>coop</var>'s <span data-x="coop-struct-report-endpoint">reporting endpoint</span>
+   is null, return.</p></li>
+
+   <li>
+    <p>Let <var>body</var> be a new object containing the following properties:</p>
+
+    <table class="data">
+     <thead>
+      <tr>
+       <th>key</th>
+       <th>value</th>
+      </tr>
+     </thead>
+     <tbody>
+      <tr>
+       <td>disposition</td>
+       <td>"<code data-x="">reporting</code>"</td>
+      </tr>
+      <tr>
+       <td>effectivePolicy</td>
+       <td><var>coopValue</var></td>
+      </tr>
+      <tr>
+       <td>property</td>
+       <td><var>coop</var>'s <span data-x="coop-struct-report-only-value">report-only
+       value</span></td>
+      </tr>
+      <tr>
+       <td>openedWindowURL</td>
+       <td>If <var>coopOrigin</var> and <var>openedWindowOrigin</var> are <span>same origin</span>, this
+       is the <span data-x="sanitize-url-report">sanitization</span> of <var>openedWindowURL</var>,
+       null otherwise.</td>
+      </tr>
+      <tr>
+       <td>openedWindowInitialURL</td>
+       <td>If <var>coopOrigin</var> and <var>openerInitialOrigin</var> are <span>same origin</span>,
+       this is the <span data-x="sanitize-url-report">sanitization</span> of
+       <var>initialWindowURL</var>, null otherwise.</td>
+      </tr>
+      <tr>
+       <td>type</td>
+       <td>"<code data-x="">access-to-opener</code>"</td>
+      </tr>
+     </tbody>
+    </table>
+   </li>
+
+   <li><p><span data-x="queue a report">Queue</span> <var>body</var> as "<code data-x="">coop</code>"
+   for <var>coop</var>'s <span data-x="coop-struct-report-endpoint">reporting endpoint</span> with
+   <var>coopURL</var>.</p></li>
+  </ol>
+
+
+  <p>To <dfn data-x="coop-violation-access-from-other">queue a violation report for access from another
+  window</dfn>, given a <span data-x="cross-origin opener policy">cross-origin opener policy</span>
+  <var>coop</var>, two <span data-x="URL">URLs</span> <var>coopURL</var> and <var>otherURL</var>, two
+  <span data-x="origin">origins</span> <var>coopOrigin</var> and <var>otherOrigin</var>, and a string
+  <var>propertyName</var>:</p>
+
+  <ol>
+   <li><p>If <var>coop</var>'s <span data-x="coop-struct-report-endpoint">reporting endpoint</span>
+   is null, return.</p></li>
+
+   <li>
+    <p>Let <var>body</var> be a new object containing the following properties:</p>
+
+    <table class="data">
+     <thead>
+      <tr>
+       <th>key</th>
+       <th>value</th>
+      </tr>
+     </thead>
+     <tbody>
+      <tr>
+       <td>disposition</td>
+       <td>"<code data-x="">reporting</code>"</td>
+      </tr>
+      <tr>
+       <td>effectivePolicy</td>
+       <td><var>coop</var>'s <span data-x="coop-struct-report-only-value">report-only
+       value</span></td>
+      </tr>
+      <tr>
+       <td>property</td>
+       <td><var>propertyName</var></td>
+      </tr>
+      <tr>
+       <td>otherURL</td>
+       <td>If <var>coopOrigin</var> and <var>otherOrigin</var> are <span>same origin</span>, this
+       is the <span data-x="sanitize-url-report">sanitization</span> of <var>otherURL</var>, null
+       otherwise.</td>
+      </tr>
+      <tr>
+       <td>type</td>
+       <td><code data-x="">access-to-opener</code></td>
+      </tr>
+     </tbody>
+    </table>
+   </li>
+
+   <li><p><span data-x="queue a report">Queue</span> <var>body</var> as "<code data-x="">coop</code>"
+   for <var>coop</var>'s <span data-x="coop-struct-report-endpoint">reporting endpoint</span> with
+   <var>coopURL</var>.</p></li>
+  </ol>
 
 
   <h3 id="coep">Cross-origin embedder policies</h3>
@@ -81198,12 +82176,12 @@ interface <dfn>BarProp</dfn> {
     data-x="">require-corp</code>":</p>
 
     <ol>
-     <li><p>Set <var>policy</var>'s <span data-x="embedder-policy-report-only-value">report only
+     <li><p>Set <var>policy</var>'s <span data-x="embedder-policy-report-only-value">report-only
      value</span> to "<code data-x="coep-require-corp">require-corp</code>".</p></li>.
 
      <li><p>If <var>parsedItem</var>[1]["<code data-x="coep-report-to">report-to</code>"] <span
      data-x="map exists">exists</span>,  then set <var>policy</var>'s <span
-     data-x="embedder-policy-report-only-reporting-endpoint">report only reporting endpoint</span>
+     data-x="embedder-policy-report-only-reporting-endpoint">report-only reporting endpoint</span>
      to <var>parsedItem</var>[1]["<code data-x="coep-report-to">report-to</code>"].</p></li>
     </ol>
    </li>
@@ -81228,7 +82206,7 @@ interface <dfn>BarProp</dfn> {
    data-x="bc-container-document">container document</span>'s <span
    data-x="concept-document-embedder-policy">embedder policy</span>.</p></li>
 
-   <li><p>If <var>parentPolicy</var>'s <span data-x="embedder-policy-report-only-value">report only
+   <li><p>If <var>parentPolicy</var>'s <span data-x="embedder-policy-report-only-value">report-only
    value</span> is "<code data-x="coep-require-corp">require-corp</code>" and
    <var>responsePolicy</var>'s <span data-x="embedder-policy-value">value</span> is "<code
    data-x="coep-unsafe-none">unsafe-none</code>", then <span>queue a cross-origin embedder policy
@@ -81267,7 +82245,7 @@ interface <dfn>BarProp</dfn> {
    <li><p>Let <var>ownerPolicy</var> be <var>owner</var>'s <span
    data-x="concept-settings-object-embedder-policy">embedder policy</span>.
 
-   <li><p>If <var>ownerPolicy</var>'s <span data-x="embedder-policy-report-only-value">report only
+   <li><p>If <var>ownerPolicy</var>'s <span data-x="embedder-policy-report-only-value">report-only
    value</span> is "<code data-x="coep-require-corp">require-corp</code>" and <var>policy</var>'s
    <span data-x="embedder-policy-value">value</span> is "<code
    data-x="coep-unsafe-none">unsafe-none</code>", then <span>queue a cross-origin embedder policy
@@ -83097,16 +84075,19 @@ interface <dfn>Location</dfn> { // but see also <a href="#the-location-interface
    <dt><dfn data-x="navigation-params-coop">cross-origin opener policy</dfn></dt>
    <dd>a <span>cross-origin opener policy</span> to use for the new <code>Document</code></dd>
 
+   <dt><dfn data-x="navigation-params-coop-enforcement-result">COOP enforcement result</dfn></dt>
+   <dd>a <span data-x="coop-enforcement-result">cross-origin opener policy enforcement
+   result</span>, used for reporting and potentially for causing a <a
+   href="#browsing-context-group-switches-due-to-cross-origin-opener-policy">browsing context
+   group switch</a></dd>
+
    <dt><dfn data-x="navigation-params-reserved-environment">reserved environment</dfn></dt>
    <dd>null or an <span>environment</span> reserved for the new <code>Document</code></dd>
 
    <dt><dfn data-x="navigation-params-browsing-context">browsing context</dfn></dt>
-   <dd>the <span>browsing context</span> to be navigated (but see below)</dd>
-
-   <dt><dfn data-x="navigation-params-bc-switch-needed">browsing context switch needed</dfn></dt>
-   <dd>a boolean indicating whether or not the navigation should conclude by <span data-x="a
-   browsing context is discarded">discarding</span> the given <span
-   data-x="navigation-params-browsing-context">browsing context</span> and creating a new one</dd>
+   <dd>the <span>browsing context</span> to be navigated (or discarded, if a <a
+   href="#browsing-context-group-switches-due-to-cross-origin-opener-policy">browsing context group
+   switch</a> occurs)</dd>
 
    <dt><dfn data-x="navigation-params-hh">history handling</dfn></dt>
    <dd>a <span>history handling behavior</span></dd>
@@ -83294,17 +84275,32 @@ interface <dfn>Location</dfn> { // but see also <a href="#the-location-interface
        data-x="concept-response-url">url</span>, <var>finalSandboxFlags</var>,
        <var>incumbentNavigationOrigin</var>, and <var>activeDocumentNavigationOrigin</var>.</p></li>
 
+       <li><p>Let <var>coop</var> be a new <span>cross-origin opener policy</span>.</p></li>
+
+       <li><p>Let <var>coopEnforcementResult</var> be a new <span
+       data-x="coop-enforcement-result">cross-origin opener policy enforcement result</span> whose
+       <span data-x="coop-enforcement-bcg-switch">needs a browsing context group switch</span> is
+       false, <span data-x="coop-enforcement-bcg-switch-report-only">would need a browsing context
+       group switch due to report-only</span> is false, <span
+       data-x="coop-enforcement-url">url</span> is <var>resource</var>'s <span
+       data-x="concept-response-url">url</span>, <span data-x="coop-enforcement-origin">origin</span>
+       is <var>responseOrigin</var>, <span
+       data-x="coop-enforcement-coop">cross-origin opener policy</span> is <var>coop</var>, and
+       <span data-x="coop-enforcement-source">current context is navigation source</span> is
+       false.</p></li>
+
        <li><p>Let <var>navigationParams</var> be a new <span>navigation params</span> whose <span
        data-x="navigation-params-request">request</span> is null, <span
        data-x="navigation-params-response">response</span> is <var>resource</var>, <span
        data-x="navigation-params-origin">origin</span> is <var>responseOrigin</var>, <span
        data-x="navigation-params-sandboxing">final sandboxing flag set</span> is
        <var>finalSandboxFlags</var>, <span data-x="navigation-params-coop">cross-origin opener
-       policy</span> is "<code data-x="coop-unsafe-none">unsafe-none</code>", <span
+       policy</span> is <var>coop</var>, <span
+       data-x="navigation-params-coop-enforcement-result">COOP enforcement result</span> is
+       <var>coopEnforcementResult</var>, <span
        data-x="navigation-params-reserved-environment">reserved environment</span> is null, <span
        data-x="navigation-params-browsing-context">browsing context</span> is
-       <var>browsingContext</var>, <span data-x="navigation-params-bc-switch-needed">browsing
-       context switch needed</span> is false, and <span data-x="navigation-params-hh">history
+       <var>browsingContext</var>, and <span data-x="navigation-params-hh">history
        handling</span> is <var>historyHandling</var>.</p></li>
 
        <li><p>Run <span>process a navigate response</span> with <var>navigationType</var>, the
@@ -83329,6 +84325,20 @@ interface <dfn>Location</dfn> { // but see also <a href="#the-location-interface
        <var>browsingContext</var>'s <span data-x="concept-bc-sandboxing-flags">sandboxing
        flags</span> and <var>response</var>'s <span>forced sandboxing flag set</span>.</p></li>
 
+       <li><p>Let <var>coopEnforcementResult</var> be a new <span
+       data-x="coop-enforcement-result">cross-origin opener policy enforcement result</span> whose
+       <span data-x="coop-enforcement-bcg-switch">needs a browsing context group switch</span> is
+       false, <span data-x="coop-enforcement-bcg-switch-report-only">would need a browsing context
+       group switch due to report-only</span> is false, <span
+       data-x="coop-enforcement-url">url</span> is <var>resource</var>'s <span
+       data-x="concept-request-url">url</span>, <span data-x="coop-enforcement-origin">origin</span>
+       is <var>activeDocumentNavigationOrigin</var>, <span
+       data-x="coop-enforcement-coop">cross-origin opener policy</span> is
+       <var>browsingContext</var>'s <span>active document</span>'s <span
+       data-x="concept-document-coop">cross-origin opener policy</span>, and <span
+       data-x="coop-enforcement-source">current context is navigation source</span> is
+       false.</p></li>
+
        <li><p>Let <var>navigationParams</var> be a new <span>navigation params</span> whose <span
        data-x="navigation-params-request">request</span> is <var>resource</var>, <span
        data-x="navigation-params-response">response</span> is <var>response</var>, <span
@@ -83337,10 +84347,11 @@ interface <dfn>Location</dfn> { // but see also <a href="#the-location-interface
        <var>finalSandboxFlags</var>, <span data-x="navigation-params-coop">cross-origin opener
        policy</span> is <var>browsingContext</var>'s <span>active document</span>'s <span
        data-x="concept-document-coop">cross-origin opener policy</span>, <span
+       data-x="navigation-params-coop-enforcement-result">COOP enforcement result</span> is
+       <var>coopEnforcementResult</var>, <span
        data-x="navigation-params-reserved-environment">reserved environment</span> is null, <span
        data-x="navigation-params-browsing-context">browsing context</span> is
-       <var>browsingContext</var>, <span data-x="navigation-params-bc-switch-needed">browsing
-       context switch needed</span> is false, and <span data-x="navigation-params-hh">history
+       <var>browsingContext</var>, and <span data-x="navigation-params-hh">history
        handling</span> is <var>historyHandling</var>.</p></li>
 
        <li><p>Run <span>process a navigate response</span> with <var>navigationType</var>, the
@@ -83443,20 +84454,25 @@ interface <dfn>Location</dfn> { // but see also <a href="#the-location-interface
 
    <li><p>Let <var>responseOrigin</var> be null.
 
+   <li><p>Let <var>currentContextIsSource</var> be the result of whether
+   <var>browsingContext</var>'s <span>active document</span> is <span>same origin</span> with
+   <var>source</var>'s <span>active document</span>.</p></li>
+
    <li><p>Let <var>coopEnforcementResult</var> be a new <span
    data-x="coop-enforcement-result">cross-origin opener policy enforcement result</span> whose <span
    data-x="coop-enforcement-bcg-switch">needs a browsing context group switch</span> is false, <span
-   data-x="coop-enforcement-origin">origin</span> is <var>browsingContext</var>'s
-   <span>active document</span>'s <span>origin</span>, and <span
-   data-x="coop-enforcement-coop">cross-origin opener policy</span> is <var>browsingContext</var>'s
-   <span>active document</span>'s <span data-x="concept-document-coop">cross-origin opener
-   policy</span>.</p></li>
+   data-x="coop-enforcement-bcg-switch-report-only">would need a browsing context group switch due
+   to report-only</span> is false,<span data-x="coop-enforcement-url">url</span> is
+   <var>browsingContext</var>'s <span>active document</span>'s <span>url</span>, <span
+   data-x="coop-enforcement-origin">origin</span> is <var>browsingContext</var>'s <span>active
+   document</span>'s <span>origin</span>, <span data-x="coop-enforcement-coop">cross-origin opener
+   policy</span> is <var>browsingContext</var>'s <span>active document</span>'s <span
+   data-x="concept-document-coop">cross-origin opener policy</span>, and <span
+   data-x="coop-enforcement-source">current context is navigation source</span> is
+   <var>currentContextIsSource</var>.</p></li>
 
    <li><p>Let <var>finalSandboxFlags</var> be an empty <span>sandboxing flag set</span>.</p></li>
 
-   <li><p>Let <var>responseCOOP</var> be "<code
-   data-x="coop-unsafe-none">unsafe-none</code>".</p></li>
-
    <li>
     <p>While true:</p>
 
@@ -83559,7 +84575,8 @@ interface <dfn>Location</dfn> { // but see also <a href="#the-location-interface
          <var>reservedEnvironment</var>.</p></li>
 
          <li>
-          <p>If <var>sandboxFlags</var> is not empty and <var>responseCOOP</var> is not "<code
+          <p>If <var>sandboxFlags</var> is not empty and <var>responseCOOP</var>'s <span
+          data-x="coop-struct-value">value</span> is not "<code
           data-x="coop-unsafe-none">unsafe-none</code>", then set <var>response</var> to an
           appropriate <span>network error</span> and <span>break</span>.</p>
 
@@ -83570,8 +84587,10 @@ interface <dfn>Location</dfn> { // but see also <a href="#the-location-interface
 
          <li><p>Set <var>coopEnforcementResult</var> to the result of <span
          data-x="coop-enforce">enforcing the response's cross-origin opener policy</span> given
-         <var>browsingContext</var>, <var>responseOrigin</var>, <var>responseCOOP</var>, and
-         <var>coopEnforcementResult</var>.</p></li>
+         <var>browsingContext</var>, <var>request</var>'s <span
+         data-x="concept-request-url">url</span>, <var>responseOrigin</var>,
+         <var>responseCOOP</var>, <var>coopEnforcementResult</var> and <var>request</var>'s <span
+         data-x="concept-request-referrer">referrer</span>.</p></li>
         </ol>
        </li>
 
@@ -83691,7 +84710,6 @@ interface <dfn>Location</dfn> { // but see also <a href="#the-location-interface
     the fallback response actually is.</p>
    </li>
 
-
    <li><p>Let <var>navigationParams</var> be a new <span>navigation params</span> whose <span
    data-x="navigation-params-request">request</span> is <var>request</var>, <span
    data-x="navigation-params-response">response</span> is <var>response</var>, <span
@@ -83699,12 +84717,11 @@ interface <dfn>Location</dfn> { // but see also <a href="#the-location-interface
    data-x="navigation-params-sandboxing">final sandboxing flag set</span> is
    <var>finalSandboxFlags</var>, <span data-x="navigation-params-coop">cross-origin opener
    policy</span> is <var>responseCOOP</var>, <span
+   data-x="navigation-params-coop-enforcement-result">COOP enforcement result</span> is
+   <var>coopEnforcementResult</var>, <span
    data-x="navigation-params-reserved-environment">reserved environment</span> is
    <var>reservedEnvironment</var>, <span data-x="navigation-params-browsing-context">browsing
-   context</span> is <var>browsingContext</var>, <span
-   data-x="navigation-params-bc-switch-needed">browsing context switch needed</span> is
-   <var>coopEnforcementResult</var>'s <span data-x="coop-enforcement-bcg-switch">needs a browsing
-   context group switch</span>, and <span data-x="navigation-params-hh">history
+   context</span> is <var>browsingContext</var>, and <span data-x="navigation-params-hh">history
    handling</span> is <var>historyHandling</var>.</p></li>
 
    <li><p>Run <span>process a navigate response</span> with <var>navigationType</var>, the
@@ -83999,17 +85016,14 @@ interface <dfn>Location</dfn> { // but see also <a href="#the-location-interface
   <span>navigation params</span> <var>navigationParams</var>:</p>
 
   <ol>
-   <li><p>Let <var>browsingContext</var> be <var>navigationParams</var>'s <span
-   data-x="navigation-params-browsing-context">browsing context</span>.</p></li>
-
-   <li><p>If <var>navigationParams</var>'s <span
-   data-x="navigation-params-bc-switch-needed">browsing context switch needed</span> is true, then
-   set <var>browsingContext</var> to the result of the <span
-   data-x="obtain-browsing-context-navigation">obtain a browsing context to use for a navigation
-   response</span> algorithm, given <var>browsingContext</var>, <var>navigationParams</var>'s <span
-   data-x="navigation-params-sandboxing">final sandboxing flag set</span>, and
-   <var>navigationParams</var>'s <span data-x="navigation-params-coop">cross-origin opener
-   policy</span>.</p></li>
+   <li><p>Let <var>browsingContext</var> be the result of the <span
+   data-x="obtain-browsing-context-navigation">obtaining a browsing context to use for a navigation
+   response</span> given <var>navigationParams</var>'s <span
+   data-x="navigation-params-browsing-context">browsing context</span>,
+   <var>navigationParams</var>'s <span data-x="navigation-params-sandboxing">final sandboxing flag
+   set</span>, <var>navigationParams</var>'s <span data-x="navigation-params-coop">cross-origin
+   opener policy</span>, and <var>navigationParams</var>'s <span
+   data-x="navigation-params-coop-enforcement-result">COOP enforcement result</span>.</p></li>
 
    <li>
     <p>Let <var>permissionsPolicy</var> be the result of <span>creating a permissions policy from a
@@ -84643,12 +85657,13 @@ new PaymentRequest(&hellip;); // Allowed to use
     data-x="navigation-params-origin">origin</span> is a new <span
     data-x="concept-origin-opaque">opaque origin</span>, <span
     data-x="navigation-params-sandboxing">final sandboxing flag set</span> is an empty set, <span
-    data-x="navigation-params-coop">cross-origin opener policy</span> is "<code
-    data-x="coop-unsafe-none">unsafe-none</code>", <span
-    data-x="navigation-params-reserved-environment">reserved environment</span> is null, <span
+    data-x="navigation-params-coop">cross-origin opener policy</span> is a new <span>cross-origin
+    opener policy</span>, <span data-x="navigation-params-coop-enforcement-result">COOP enforcement
+    result</span> is a new <span data-x="coop-enforcement-result">cross-origin opener policy
+    enforcement result</span>, <span
+    data-x="navigation-params-reserved-environment">reserved environment</span> is null, and <span
     data-x="navigation-params-browsing-context">browsing context</span> is
-    <var>browsingContext</var>, and <span data-x="navigation-params-bc-switch-needed">browsing
-    context switch needed</span> is false.</p>
+    <var>browsingContext</var>.</p>
 
     <p class="XXX">The algorithm called in the next step is not prepared to deal with a null <span
     data-x="navigation-params-response">response</span>. Probably we should synthesize one
@@ -119178,6 +120193,30 @@ interface <dfn>External</dfn> {
   </dl>
 
 
+  <h3>`<dfn http-header><code
+  data-x="http-cross-origin-opener-policy-report-only">Cross-Origin-Opener-Policy-Report-Only</code></dfn>`</h3>
+
+  <p>This section describes a header for registration in the Permanent Message Header Field
+  Registry. <ref spec=RFC3864></p>
+
+  <dl>
+   <dt>Header field name:</dt>
+   <dd>Cross-Origin-Opener-Policy-Report-Only</dd>
+   <dt>Applicable protocol:</dt>
+   <dd>http</dd>
+   <dt>Status:</dt>
+   <dd>standard</dd>
+   <dt>Author/Change controller:</dt>
+   <dd>WHATWG</dd>
+   <dt>Specification document(s):</dt>
+   <dd>
+    This document is the relevant specification.
+   </dd>
+   <dt>Related information:</dt>
+   <dd>None.</dd>
+  </dl>
+
+
   <h3>`<dfn><code data-x="http-origin-isolation">Origin-Isolation</code></dfn>`</h3>
 
   <p>This section describes a header for registration in the Permanent Message Header Field