[GH-ISSUE #4677] [Bug] Page inspection loses COOP and COEP policy tokens with valid report-to parameters #2439

Closed
opened 2026-10-17 21:04:41 +00:00 by bsakaguchi · 3 comments
Owner

Originally created by @coygeek on GitHub (Oct 17, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/4677

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Process capture or runtime observation

Observed behavior

rea inspect-web-page succeeds but reports policies.coop: null and policies.coep: null for responses carrying Cross-Origin-Opener-Policy: same-origin; report-to="coop" and Cross-Origin-Embedder-Policy: require-corp; report-to="coep". The bare-token controls return same-origin and require-corp. A separate real CDP session records the full valid declarations, and Chrome accepts the parameterized response as a cross-origin-isolated top-level document.

Reproduction

  1. For a source checkout, install its locked dependencies with npm ci, then run npm run build:cached using the pinned development toolchain. For the published build, run npm install --prefix ./published rea-agents@6.5.0 in a disposable directory, then cd published/node_modules/rea-agents. Both builds use the same relative launcher path below.
  2. Provide the executable for the pinned Playwright browser through REA_BROWSER_EXECUTABLE, or use the browser installed for the locked Playwright version. From the repository root or installed package directory, run this fixture. It creates a loopback server, a dedicated headless browser profile, and a fresh HOME for the CLI, then removes them.
node --input-type=module <<'JS'
import { createServer } from 'node:http';
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
import { mkdtemp, mkdir, readFile, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { chromium } from 'playwright-core';
const exec = promisify(execFile);
const work = await mkdtemp(join(tmpdir(), 'rea-response-'));
await mkdir(join(work, 'home'));
const env = { HOME: join(work, 'home'), PATH: process.env.PATH };
const headers = {
  '/params': ['Cross-Origin-Opener-Policy', 'same-origin; report-to="coop"', 'Cross-Origin-Embedder-Policy', 'require-corp; report-to="coep"'],
  '/bare': ['Cross-Origin-Opener-Policy', 'same-origin', 'Cross-Origin-Embedder-Policy', 'require-corp'],
  '/invalid': ['Cross-Origin-Opener-Policy', 'same-origin; report-to="coop', 'Cross-Origin-Embedder-Policy', 'require-corp; report-to="coep'],
  '/absent': []
};
const server = createServer((req, res) => {
  const path = new URL(req.url, 'http://127.0.0.1').pathname;
  res.writeHead(200, ['Content-Type', 'text/html', 'Cache-Control', 'no-store', ...(headers[path] ?? [])]);
  res.end(path === '/app' ? `<!doctype html><title>Response fixture</title><script>
    setInterval(() => {
      ['/params','/bare','/invalid','/absent'].forEach(p => fetch(p).catch(() => {}));
    }, 250);
  </script>` : '<!doctype html><title>Response fixture</title>');
});
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
const origin = `http://127.0.0.1:${server.address().port}`;
let context;
try {
  context = await chromium.launchPersistentContext(join(work, 'profile'), {
    executablePath: process.env.REA_BROWSER_EXECUTABLE ?? chromium.executablePath(), headless: true, env,
    args: ['--remote-debugging-address=127.0.0.1', '--remote-debugging-port=0', '--disable-background-networking', '--disable-component-update', '--disable-sync']
  });
  const page = context.pages()[0];
  const cdp = await context.newCDPSession(page);
  const wire = [];
  for (const method of ['Network.responseReceived', 'Network.responseReceivedExtraInfo']) cdp.on(method, params => wire.push({ method, params }));
  await cdp.send('Network.enable');
  await page.goto(origin + '/app');
  const port = (await readFile(join(work, 'profile', 'DevToolsActivePort'), 'utf8')).split('\n')[0];
  const endpoint = `http://127.0.0.1:${port}`;
  const target = (await (await fetch(endpoint + '/json/list')).json()).find(t => t.url === origin + '/app');
  const { stdout, stderr } = await exec(process.execPath, [process.env.REA_CLI_ENTRY ?? 'scripts/rea.mjs', 'inspect-web-page', endpoint, target.id, '--observation-ms', '800', '--json'], { env, maxBuffer: 8 * 1024 * 1024 });
  const result = JSON.parse(stdout);
  const inspection = result.normalized_result;
  if (!inspection) throw new Error(stdout);
  const fields = h => Object.fromEntries(Object.entries(h).filter(([k]) => /^(link|cross-origin-opener-policy|cross-origin-embedder-policy)$/i.test(k)));
  const samples = {};
  for (const path of Object.keys(headers)) {
    const rows = inspection.metadata.responses.filter(r => new URL(r.url).pathname === path);
    if (!rows.length) throw new Error('No captured response for ' + path);
    const event = wire.find(e => e.method === 'Network.responseReceived' && new URL(e.params.response.url).pathname === path);
    const extra = wire.find(e => e.method === 'Network.responseReceivedExtraInfo' && e.params.requestId === event.params.requestId);
    samples[path] = { count: rows.length, type: event.params.type, headers: fields(event.params.response.headers), extra_headers: extra ? fields(extra.params.headers) : null, results: [...new Set(rows.map(r => JSON.stringify({ links: r.links, coop: r.policies.coop, coep: r.policies.coep })))].map(s => JSON.parse(s)) };
  }
  const isolation = {};
  for (const path of ['/params', '/bare', '/invalid', '/absent']) {
    const p = await context.newPage();
    await p.goto(origin + path);
    isolation[path] = await p.evaluate(() => ({ crossOriginIsolated, isSecureContext }));
    await p.close();
  }
  const version = await cdp.send('Browser.getVersion');
  console.log(JSON.stringify({ operation: result.operation, chrome: version.product, revision: version.revision, stderr, samples, hints: inspection.metadata.agent_hints, isolation }, null, 2));
} finally {
  if (context) await context.close();
  await new Promise(resolve => server.close(resolve));
  await rm(work, { recursive: true, force: true });
}
JS
  1. Compare samples["/params"] with /bare, /invalid, and /absent. In each tested build, all three captured parameterized responses lost both policy tokens. Each control also produced three responses with consistent results. Separate top-level navigation returned crossOriginIsolated: true for the valid parameterized and bare cases, and false for the malformed and absent cases.

Expected behavior

Retain the declared same-origin and require-corp tokens for these valid structured headers. The HTML Standard defines both headers as structured-field items whose bare value is a token and whose report-to parameter may contain an endpoint-name string. The parameter does not invalidate the bare token. This expectation concerns the declaration captured in response metadata, not an inferred browser default or the document's full effective policy. See the COOP headers, COEP headers, and structured-field Items.

Impact and scope

Valid response declarations become indistinguishable in these projected fields from absent or malformed declarations. The failure affects the parameterized input form while the CLI and the browser's isolation behavior continue to work. No change to browser enforcement or security-boundary crossing was observed.

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: Successful inspection returns incorrect declaration metadata for valid COOP and COEP headers with reporting parameters.
  • Workaround status: available
  • Workaround basis: The separately recorded real CDP response retained the full declarations for manual inspection without changing the server or removing its reporting parameters. No restoring REA option was demonstrated.

REA version

Published npm package 6.5.0, confirmed as the latest release in the registry and GitHub Releases; independently built current main at e31aa72c9d. Both launchers reported the package version shown above.

Runtime and platform

Node v24.18.0; Darwin arm64; real headless Chrome/145.0.7632.6 matching the repository's locked playwright-core 1.58.2. The source build used npm 11.16.0 and the repository lockfile. Each CLI invocation had a fresh HOME and a minimal environment containing only HOME and PATH.

Target and artifact context

A self-owned loopback HTTP server provides valid parameterized, bare, malformed quoted-parameter, and absent-header fixtures. One local app fetches those responses during the CLI observation. Each fixture is also opened separately as a top-level document in the dedicated browser context to check browser acceptance. No external target or credentials were used.

Interface

CLI

Earliest failure stage

Capture or observation

Relevant output or evidence

  • Expected source: docs/browser-observation.md:18 and :293; src/domain/browserObservationSchemas.ts:254-257; HTML Standard COOP/COEP header definitions.
  • Failure source: src/browser/CdpSafeMetadata.ts:47-48 and :337-339.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

The inline fixture invokes this production command with its discovered local endpoint and target ID:

node scripts/rea.mjs inspect-web-page "$endpoint" "$target_id" --observation-ms 800 --json

In both tested builds, the command exited 0 with empty stderr. The raw CDP response contained these exact header strings:

{
  "Cross-Origin-Opener-Policy": "same-origin; report-to=\"coop\"",
  "Cross-Origin-Embedder-Policy": "require-corp; report-to=\"coep\""
}

The observed result pairs were:

Response fields REA coop REA coep Chrome crossOriginIsolated when opened as a document
Valid report-to parameters null null true
Bare tokens same-origin require-corp true
Missing closing quote in both report-to values null null false
Both headers absent null null false

In both builds, all four top-level document controls reported isSecureContext: true. The minimal fixture output records the number of responses captured for each case. The browser check establishes acceptance of the chosen valid declarations; it does not change the meaning of REA's response-declaration projection.

Typed outcome or recovery expected

For the valid parameterized response, return coop: "same-origin" and coep: "require-corp". Preserve the bare-token control results and keep malformed quoted parameters distinguishable from a valid structured item. The observed malformed and absent controls should continue to return null for this fixture. This restores the same declared-token result with and without the valid reporting parameter.

Analysis or suspected cause

Source-derived reasoning: both policy fields pass the complete header string to a helper that accepts only a restricted bare token. The semicolon-delimited parameter therefore causes the entire declaration to become null. The standards represent the bare token and its parameters separately. The schema's nullable strings do not establish that null uniquely means the header was absent.

Additional context

A search of open and closed issues and pull requests found no matching report using COOP, COEP, both full header names, require-corp, policies.coop, policies.coep, and broader browser-policy queries. The relevant matches concern worker capture and Referrer-Policy, rather than this input form. Repository documentation and tests cover bare COOP/COEP values but do not specify bare-token-only input handling. The documented malformed-token behavior for Referrer-Policy concerns that different field. This reproduction exercises inspect-web-page; screenshot comparison was not exercised. Removing report-to is a discriminating control and would change server reporting behavior. No last-known-good release was established.

Originally created by @coygeek on GitHub (Oct 17, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4677 ### Before submitting - [X] I searched the open and closed issues for a related report. - [X] I removed credentials, tokens, private paths, and sensitive target data. ### Area Process capture or runtime observation ### Observed behavior `rea inspect-web-page` succeeds but reports `policies.coop: null` and `policies.coep: null` for responses carrying `Cross-Origin-Opener-Policy: same-origin; report-to="coop"` and `Cross-Origin-Embedder-Policy: require-corp; report-to="coep"`. The bare-token controls return `same-origin` and `require-corp`. A separate real CDP session records the full valid declarations, and Chrome accepts the parameterized response as a cross-origin-isolated top-level document. ### Reproduction 1. For a source checkout, install its locked dependencies with `npm ci`, then run `npm run build:cached` using the pinned development toolchain. For the published build, run `npm install --prefix ./published rea-agents@6.5.0` in a disposable directory, then `cd published/node_modules/rea-agents`. Both builds use the same relative launcher path below. 2. Provide the executable for the pinned Playwright browser through `REA_BROWSER_EXECUTABLE`, or use the browser installed for the locked Playwright version. From the repository root or installed package directory, run this fixture. It creates a loopback server, a dedicated headless browser profile, and a fresh HOME for the CLI, then removes them. ```sh node --input-type=module <<'JS' import { createServer } from 'node:http'; import { execFile } from 'node:child_process'; import { promisify } from 'node:util'; import { mkdtemp, mkdir, readFile, rm } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { chromium } from 'playwright-core'; const exec = promisify(execFile); const work = await mkdtemp(join(tmpdir(), 'rea-response-')); await mkdir(join(work, 'home')); const env = { HOME: join(work, 'home'), PATH: process.env.PATH }; const headers = { '/params': ['Cross-Origin-Opener-Policy', 'same-origin; report-to="coop"', 'Cross-Origin-Embedder-Policy', 'require-corp; report-to="coep"'], '/bare': ['Cross-Origin-Opener-Policy', 'same-origin', 'Cross-Origin-Embedder-Policy', 'require-corp'], '/invalid': ['Cross-Origin-Opener-Policy', 'same-origin; report-to="coop', 'Cross-Origin-Embedder-Policy', 'require-corp; report-to="coep'], '/absent': [] }; const server = createServer((req, res) => { const path = new URL(req.url, 'http://127.0.0.1').pathname; res.writeHead(200, ['Content-Type', 'text/html', 'Cache-Control', 'no-store', ...(headers[path] ?? [])]); res.end(path === '/app' ? `<!doctype html><title>Response fixture</title><script> setInterval(() => { ['/params','/bare','/invalid','/absent'].forEach(p => fetch(p).catch(() => {})); }, 250); </script>` : '<!doctype html><title>Response fixture</title>'); }); await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)); const origin = `http://127.0.0.1:${server.address().port}`; let context; try { context = await chromium.launchPersistentContext(join(work, 'profile'), { executablePath: process.env.REA_BROWSER_EXECUTABLE ?? chromium.executablePath(), headless: true, env, args: ['--remote-debugging-address=127.0.0.1', '--remote-debugging-port=0', '--disable-background-networking', '--disable-component-update', '--disable-sync'] }); const page = context.pages()[0]; const cdp = await context.newCDPSession(page); const wire = []; for (const method of ['Network.responseReceived', 'Network.responseReceivedExtraInfo']) cdp.on(method, params => wire.push({ method, params })); await cdp.send('Network.enable'); await page.goto(origin + '/app'); const port = (await readFile(join(work, 'profile', 'DevToolsActivePort'), 'utf8')).split('\n')[0]; const endpoint = `http://127.0.0.1:${port}`; const target = (await (await fetch(endpoint + '/json/list')).json()).find(t => t.url === origin + '/app'); const { stdout, stderr } = await exec(process.execPath, [process.env.REA_CLI_ENTRY ?? 'scripts/rea.mjs', 'inspect-web-page', endpoint, target.id, '--observation-ms', '800', '--json'], { env, maxBuffer: 8 * 1024 * 1024 }); const result = JSON.parse(stdout); const inspection = result.normalized_result; if (!inspection) throw new Error(stdout); const fields = h => Object.fromEntries(Object.entries(h).filter(([k]) => /^(link|cross-origin-opener-policy|cross-origin-embedder-policy)$/i.test(k))); const samples = {}; for (const path of Object.keys(headers)) { const rows = inspection.metadata.responses.filter(r => new URL(r.url).pathname === path); if (!rows.length) throw new Error('No captured response for ' + path); const event = wire.find(e => e.method === 'Network.responseReceived' && new URL(e.params.response.url).pathname === path); const extra = wire.find(e => e.method === 'Network.responseReceivedExtraInfo' && e.params.requestId === event.params.requestId); samples[path] = { count: rows.length, type: event.params.type, headers: fields(event.params.response.headers), extra_headers: extra ? fields(extra.params.headers) : null, results: [...new Set(rows.map(r => JSON.stringify({ links: r.links, coop: r.policies.coop, coep: r.policies.coep })))].map(s => JSON.parse(s)) }; } const isolation = {}; for (const path of ['/params', '/bare', '/invalid', '/absent']) { const p = await context.newPage(); await p.goto(origin + path); isolation[path] = await p.evaluate(() => ({ crossOriginIsolated, isSecureContext })); await p.close(); } const version = await cdp.send('Browser.getVersion'); console.log(JSON.stringify({ operation: result.operation, chrome: version.product, revision: version.revision, stderr, samples, hints: inspection.metadata.agent_hints, isolation }, null, 2)); } finally { if (context) await context.close(); await new Promise(resolve => server.close(resolve)); await rm(work, { recursive: true, force: true }); } JS ``` 3. Compare `samples["/params"]` with `/bare`, `/invalid`, and `/absent`. In each tested build, all three captured parameterized responses lost both policy tokens. Each control also produced three responses with consistent results. Separate top-level navigation returned `crossOriginIsolated: true` for the valid parameterized and bare cases, and false for the malformed and absent cases. ### Expected behavior Retain the declared `same-origin` and `require-corp` tokens for these valid structured headers. The HTML Standard defines both headers as structured-field items whose bare value is a token and whose `report-to` parameter may contain an endpoint-name string. The parameter does not invalidate the bare token. This expectation concerns the declaration captured in response metadata, not an inferred browser default or the document's full effective policy. See the [COOP headers](https://html.spec.whatwg.org/multipage/browsers.html#the-coop-headers), [COEP headers](https://html.spec.whatwg.org/multipage/browsers.html#the-coep-headers), and [structured-field Items](https://www.rfc-editor.org/rfc/rfc9651.html#section-3.3). ### Impact and scope Valid response declarations become indistinguishable in these projected fields from absent or malformed declarations. The failure affects the parameterized input form while the CLI and the browser's isolation behavior continue to work. No change to browser enforcement or security-boundary crossing was observed. - Impact level: P2 - Assessment status: supported - Impact basis: Successful inspection returns incorrect declaration metadata for valid COOP and COEP headers with reporting parameters. - Workaround status: available - Workaround basis: The separately recorded real CDP response retained the full declarations for manual inspection without changing the server or removing its reporting parameters. No restoring REA option was demonstrated. ### REA version Published npm package 6.5.0, confirmed as the latest release in the registry and GitHub Releases; independently built current `main` at e31aa72c9d44b22ae4fb86a21700d877496d785b. Both launchers reported the package version shown above. ### Runtime and platform Node v24.18.0; Darwin arm64; real headless Chrome/145.0.7632.6 matching the repository's locked playwright-core 1.58.2. The source build used npm 11.16.0 and the repository lockfile. Each CLI invocation had a fresh HOME and a minimal environment containing only HOME and PATH. ### Target and artifact context A self-owned loopback HTTP server provides valid parameterized, bare, malformed quoted-parameter, and absent-header fixtures. One local app fetches those responses during the CLI observation. Each fixture is also opened separately as a top-level document in the dedicated browser context to check browser acceptance. No external target or credentials were used. ### Interface CLI ### Earliest failure stage Capture or observation ### Relevant output or evidence - Expected source: docs/browser-observation.md:18 and :293; src/domain/browserObservationSchemas.ts:254-257; HTML Standard COOP/COEP header definitions. - Failure source: src/browser/CdpSafeMetadata.ts:47-48 and :337-339. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete The inline fixture invokes this production command with its discovered local endpoint and target ID: ```sh node scripts/rea.mjs inspect-web-page "$endpoint" "$target_id" --observation-ms 800 --json ``` In both tested builds, the command exited 0 with empty stderr. The raw CDP response contained these exact header strings: ```json { "Cross-Origin-Opener-Policy": "same-origin; report-to=\"coop\"", "Cross-Origin-Embedder-Policy": "require-corp; report-to=\"coep\"" } ``` The observed result pairs were: | Response fields | REA coop | REA coep | Chrome crossOriginIsolated when opened as a document | | --- | --- | --- | --- | | Valid report-to parameters | null | null | true | | Bare tokens | same-origin | require-corp | true | | Missing closing quote in both report-to values | null | null | false | | Both headers absent | null | null | false | In both builds, all four top-level document controls reported `isSecureContext: true`. The minimal fixture output records the number of responses captured for each case. The browser check establishes acceptance of the chosen valid declarations; it does not change the meaning of REA's response-declaration projection. ### Typed outcome or recovery expected For the valid parameterized response, return `coop: "same-origin"` and `coep: "require-corp"`. Preserve the bare-token control results and keep malformed quoted parameters distinguishable from a valid structured item. The observed malformed and absent controls should continue to return null for this fixture. This restores the same declared-token result with and without the valid reporting parameter. ### Analysis or suspected cause Source-derived reasoning: both policy fields pass the complete header string to a helper that accepts only a restricted bare token. The semicolon-delimited parameter therefore causes the entire declaration to become null. The standards represent the bare token and its parameters separately. The schema's nullable strings do not establish that null uniquely means the header was absent. ### Additional context A search of open and closed issues and pull requests found no matching report using COOP, COEP, both full header names, require-corp, policies.coop, policies.coep, and broader browser-policy queries. The relevant matches concern worker capture and Referrer-Policy, rather than this input form. Repository documentation and tests cover bare COOP/COEP values but do not specify bare-token-only input handling. The documented malformed-token behavior for Referrer-Policy concerns that different field. This reproduction exercises `inspect-web-page`; screenshot comparison was not exercised. Removing `report-to` is a discriminating control and would change server reporting behavior. No last-known-good release was established.
Author
Owner

@morluto commented on GitHub (Oct 17, 2026):

Published in c360cfcd6d on main.

The old whole-value bare-token helper could not represent a Structured Field Item. COOP/COEP now use a dedicated complete-item parser: preserve the exact token, validate every parameter, and return null for malformed/non-token items. Strings/escapes, tokens, flags, integer/decimal limits, byte sequences, dates and UTF-8 display strings are validated. Other policy fields retain their own grammar. No reporting endpoint values are retained. This follows the HTML COOP, COEP and RFC9651 parsing rules. Returned tokens describe declarations, not the effective browser policy.

Executed the report's real Chrome/145.0.7632.6 public CLI fixture on baseline df2fc251e and candidate, Darwin arm64/Node24.18.0, 800ms observation window. Each run captured three responses per case. Parameterized declarations changed from null/null to same-origin/require-corp for all three responses; bare, malformed-quote and absent controls were unchanged. Both CLI commands succeeded with empty stderr. Separate navigations observed crossOriginIsolated=true for valid parameterized/bare controls and false for malformed/absent controls, all with isSecureContext=true. The fixture closed its browser/server and removed its dedicated workspace.

Validation:

  • Baseline 11 failures/64 passes; final 75 metadata checks passed, including both COOP and COEP, malformed parameters, exact token case, non-token items and unrelated policy fields.
  • 101 focused metadata/network/sensitive-data/existing-MCP checks passed; final 90 overlapping metadata/network checks include the wire Document-event policy regression.
  • A local check against 834 upstream item vectors adapted as direct token items or parameter inputs had zero mismatches and two permitted refusals. Eleven input files pinned to httpwg/structured-field-tests commit 781ba38464b2ec4c547e1e14d007d4f5ace7457e; non-item vectors were excluded. This is projection/parameter validation coverage, not full Structured Fields parser conformance.
  • check:fast, docs:check/five README checks, and normal commit/pre-push hooks passed.

Other browser/platform combinations, policy-specific MCP runtime delivery, performance/full-task tokens and peak-family memory remain unmeasured. No efficiency claim is made. Repeated-field Link behavior from #4679 remains covered. The broader browser/codebase audit remains partial.

<!-- gh-comment-id:6230168335 --> @morluto commented on GitHub (Oct 17, 2026): Published in c360cfcd6d7901514b16dd6113eba2e0b0fdf422 on main. The old whole-value bare-token helper could not represent a Structured Field Item. COOP/COEP now use a dedicated complete-item parser: preserve the exact token, validate every parameter, and return null for malformed/non-token items. Strings/escapes, tokens, flags, integer/decimal limits, byte sequences, dates and UTF-8 display strings are validated. Other policy fields retain their own grammar. No reporting endpoint values are retained. This follows the [HTML COOP](https://html.spec.whatwg.org/multipage/browsers.html#the-coop-headers), [COEP](https://html.spec.whatwg.org/multipage/browsers.html#the-coep-headers) and [RFC9651 parsing](https://www.rfc-editor.org/rfc/rfc9651.html#section-4.2) rules. Returned tokens describe declarations, not the effective browser policy. Executed the report's real Chrome/145.0.7632.6 public CLI fixture on baseline df2fc251e and candidate, Darwin arm64/Node24.18.0, 800ms observation window. Each run captured three responses per case. Parameterized declarations changed from null/null to same-origin/require-corp for all three responses; bare, malformed-quote and absent controls were unchanged. Both CLI commands succeeded with empty stderr. Separate navigations observed crossOriginIsolated=true for valid parameterized/bare controls and false for malformed/absent controls, all with isSecureContext=true. The fixture closed its browser/server and removed its dedicated workspace. Validation: - Baseline 11 failures/64 passes; final 75 metadata checks passed, including both COOP and COEP, malformed parameters, exact token case, non-token items and unrelated policy fields. - 101 focused metadata/network/sensitive-data/existing-MCP checks passed; final 90 overlapping metadata/network checks include the wire Document-event policy regression. - A local check against 834 upstream item vectors adapted as direct token items or parameter inputs had zero mismatches and two permitted refusals. Eleven input files pinned to httpwg/structured-field-tests commit 781ba38464b2ec4c547e1e14d007d4f5ace7457e; non-item vectors were excluded. This is projection/parameter validation coverage, not full Structured Fields parser conformance. - check:fast, docs:check/five README checks, and normal commit/pre-push hooks passed. Other browser/platform combinations, policy-specific MCP runtime delivery, performance/full-task tokens and peak-family memory remain unmeasured. No efficiency claim is made. Repeated-field Link behavior from #4679 remains covered. The broader browser/codebase audit remains partial.
Author
Owner

@coygeek commented on GitHub (Oct 18, 2026):

Closing as addressed on main by c360cfcd6. COOP and COEP now use complete Structured Field Item parsing, preserving valid declared tokens with report-to parameters while leaving malformed declarations unknown. I verified the committed source and regression coverage; I have not rerun the runtime reproduction.

<!-- gh-comment-id:6244110458 --> @coygeek commented on GitHub (Oct 18, 2026): Closing as addressed on `main` by [c360cfcd6](https://github.com/morluto/rea/commit/c360cfcd6d7901514b16dd6113eba2e0b0fdf422). COOP and COEP now use complete Structured Field Item parsing, preserving valid declared tokens with report-to parameters while leaving malformed declarations unknown. I verified the committed source and regression coverage; I have not rerun the runtime reproduction.
Author
Owner

@matbrgz commented on GitHub (Oct 20, 2026):

Cross-referencing with sibling HTTP response header parsing defect #4679 ([Bug] Page inspection drops repeated Link fields from Document responses). Both address header normalization and security token handling (COOP, COEP, Link) in inspect-web-page.

Consolidated under Cluster AP (Web Page Inspection HTTP Header Parsing: Link, COOP, COEP) in tracker #4330.

<!-- gh-comment-id:6291599200 --> @matbrgz commented on GitHub (Oct 20, 2026): Cross-referencing with sibling HTTP response header parsing defect #4679 (`[Bug] Page inspection drops repeated Link fields from Document responses`). Both address header normalization and security token handling (COOP, COEP, Link) in `inspect-web-page`. Consolidated under **Cluster AP (Web Page Inspection HTTP Header Parsing: Link, COOP, COEP)** in tracker #4330.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#2439
No description provided.