BuilderProof editorial team29 min read5 views

Does it still know them inside someone else's page? A partitioned-storage posture axis proposal (October 2026)

A builder and its tester only ever occupy the first-party context, where cookies and client storage behave one way. The identical code embedded in someone else's page may be handed a different, empty store, and the governing draft permits a user agent to return an empty cookie-string with no error at all.

Updated on October 5, 2026

Flat minimal diagram, off-white background: two tall rounded rectangles separated by a dashed vertical line. Each holds a small rounded square with an arrow down to three stacked shapes. The left stack is filled solid grey, the right is empty outlines.
Flat minimal diagram, off-white background: two tall rounded rectangles separated by a dashed vertical line. Each holds a small rounded square with an arrow down to three stacked shapes. The left stack is filled solid grey, the right is empty outlines.
On this page

Quick answer (October 2026): this is a pre-registration, not a result. It proposes that AI app builders be scored on partitioned-storage posture: whether the application a builder generates still knows who a person is when it is not the top-level page. The failure is invisible to whoever builds and tests the app, because a builder and its tester only ever occupy one of the two contexts the browser distinguishes, and in that context everything works. Seven weighted signals, four postures and a ten-step protocol are proposed below. No builder is scored and no placement is published.

Why we are proposing this axis

A generated application keeps state. A session cookie so the person stays signed in, a row in localStorage for the theme they picked, an IndexedDB store for the draft they have not saved, a channel so the second tab knows about the first.

Every one of those is keyed by origin. What is less widely understood is that in several shipping browsers they are keyed by two things, and the second one is the site in the address bar rather than the site that stored the value. When those two differ, the application is handed a different, empty store. Nothing errors. Nothing is logged. The code is byte-identical to the code that worked.

This is not a prediction about a future browser change. It is the default behaviour of browsers people are using today, and the documentation says so plainly.

MDN MDN, on the browsers that do this by default, verbatim: "Firefox enables Total Cookie Protection if Enhanced Tracking Protection is enabled, as it is by default. This gives third-party cookies a separate cookie jar per site, preventing cross-site tracking."

And on the others, verbatim: "Safari has a Tracking prevention policy resulting in a similar set of third-party cookie protections that are enabled by default", and "The Brave browser blocks tracking cookies by default."

On the consequence, verbatim: "Cookie blocking can cause website functionality and third-party components (such as social media widgets) not to function as intended."

That last sentence is the whole axis, written by somebody else, in one line.

The trap: the first-party illusion

Every axis we propose names the illusion that hides its defect. This one is the first-party illusion, and it is the thirty-fifth member of the one-actor family we have been tracking: a defect whose only cheap evidence at test time comes from a single source.

The shape here is new to the set, and it is worth naming precisely. In the earlier members, the missing input was a value nobody had authored, or a store the application could not seed, or a string the system had quietly stopped emitting. Here the input is fine. What is missing is a second observation context.

A person building a generated application opens it at a development URL, then at its own domain. They are the top-level document both times. They sign in, the cookie is set and returned, the theme persists, the draft survives a reload. Every observation they can cheaply make is made from the first-party context, and in the first-party context there is nothing wrong.

The other context is the one where the application is not the page. It is loaded in a frame inside a customer's site, or inside a portal, or inside a dashboard that embeds it as a widget, or inside the preview pane of the tool that generated it. There the browser may give it a different cookie jar and a different storage bucket, and the application's own code has no way to tell the difference without looking.

The reason this survives review is that the two contexts are not two code paths. They are the same code path under a different key. There is no branch to inspect, no flag to find, and no error to catch.

What the platform actually specifies

The first-party and third-party distinction is mechanical, not editorial.

MDN, on how the browser decides, verbatim: "If the cookie domain and scheme match the current page the user is looking at (the URL shown in the browser's address bar), the cookie is considered to be from the same site as the page, and is referred to as a first-party cookie."

And, verbatim: "If the domain and scheme are different, the cookie is not considered to be from the same site, and is referred to as a third-party cookie."

Note what decides it: the URL in the address bar. Not a setting, not a header, not anything the generated application emits. The same cookie from the same server is first-party or third-party depending on where it is being viewed from.

The governing draft is more precise, and it is the document that matters most for this axis because it states what a user agent is permitted to do rather than what one vendor has chosen.

IETF draft-ietf-httpbis-rfc6265bis-20, on the classification, verbatim: "A request that is not 'same-site' is instead 'cross-site'."

And on what the user agent may then do, verbatim: "A user agent MAY omit the Cookie header field in its entirety."

And, the sentence this whole axis turns on, verbatim: "A user agent MAY return an empty cookie-string in certain contexts, such as when a retrieval occurs within a third-party context..."

Read that carefully. The permitted behaviour is not an error and not a refusal. It is an empty string. A conforming user agent may hand the application exactly what it would hand an application that had never set a cookie at all, and the specification sanctions it. There is no status code for this, no exception to catch, and no distinguishable value to branch on.

The same draft records the posture as already general rather than as a coming change. Verbatim: "Because of their inherent privacy issues, most user agents now limit third-party cookies in a variety of ways."

Cookies are the part people know about. The part that surprises reviewers is how much else is keyed the same way.

Mozilla, on the mechanism, verbatim: "Rather than block access to certain stateful APIs in a third-party context, Firefox provides embedded resources with a separate storage bucket for every top-level website."

On the key, verbatim: "Firefox double-keys all client-side state by the origin of the resource being loaded and by the top-level site", where "In most instances, the top-level site is the scheme and registrable domain of the top-level page being visited by the user."

And on when it became the default, verbatim: "From Firefox 103, State Partitioning is turned on by default."

The documented list of partitioned storage APIs is longer than a cookie banner would suggest. It names localStorage, sessionStorage, DOM Cache, IndexedDB, Broadcast Channel, Shared Workers and Service Workers as partitioned, with cookies partitioned dynamically. A separate list of network-layer state is described as permanently partitioned, and it includes the HTTP cache, connection pooling, DNS, HTTP authentication, HSTS, the CORS preflight cache and the back and forward cache.

Read that against a generated application and the blast radius is clear. A build that keeps its session in a cookie, its preferences in localStorage, its offline draft in IndexedDB and its cross-tab signalling in a Broadcast Channel has four independent dependencies on a key it never chose and cannot read.

One half of the observable is specified and the other half is not, and the difference matters. For cookies, the empty-cookie-string sentence above is normative and settles it. For the storage APIs we could find no sentence in the documentation stating what a site observes when its bucket is swapped. The State Partitioning page describes the mechanism and not the symptom.

So we will not quote an observable we did not find. What follows from a separate bucket being a bucket rather than an error is that a partitioned store is not a store that refuses to answer: it answers, and it is empty, exactly as the cookie layer is specified to behave. An empty localStorage and a localStorage the application has never written to are the same object. That is an inference from the mechanism, labelled as one, and it is the thing a reviewer of this axis should most want to see tested rather than argued.

The remedy has a precondition a fresh deployment cannot meet

There are two documented remedies. Neither is free, and one has a gate that a newly generated application structurally fails.

The first is to opt the cookie into partitioned storage and accept the partitioning rather than fight it.

MDN, on CHIPS, verbatim: "Cookies Having Independent Partitioned State (CHIPS, also known as Partitioned cookies) allows developers to opt a cookie into partitioned storage, with a separate cookie jar per top-level site."

On the keying, verbatim: "Cookies marked Partitioned are double-keyed: by the origin that sets them and the origin of the top-level page."

On how the key is formed, verbatim: "The partition key is based on the site, including the scheme, of the top-level URL the browser was visiting when the request was made to the URL endpoint that set the cookie."

On the requirement, verbatim: "Partitioned cookies must be set with Secure."

And on scoping, verbatim: "In addition, you can use the __Host prefix when setting partitioned cookies to bind them only to the current domain or subdomain, and this is recommended if you don't need to share cookies between subdomains."

The documentation does not state in a single declarative sentence that a partitioned cookie cannot be shared across top-level sites. It demonstrates it with a worked example instead, and the example is the thing to read.

MDN's own example, verbatim: "When the user visits https://site-b.example, which also embeds https://3rd-party.example, this new embedded instance is no longer able to access the cookie because the partition key doesn't match."

That is the correct outcome under this remedy, not a bug in it. Opting in buys a cookie that works reliably in each embedding site separately and never works across them. For a generated application embedded once per customer, that is exactly right. For a generated application that assumed one session spanning several embedding sites, it is a product change dressed as an attribute.

The second remedy is to ask for unpartitioned access.

MDN MDN, on the Storage Access API, verbatim: "embedded cross-site content can request unrestricted access to third-party cookies and unpartitioned state on a frame-by-frame basis", so that content can "gain access to third-party cookies and unpartitioned state that it would typically only have access to in a first-party context (i.e., when loaded directly in a browser tab)".

And then the preconditions, which are where a generated application tends to come apart.

On the gesture, verbatim: "The permission request must be associated with a user gesture (transient activation) such as a tap or click."

On the one that matters most, verbatim: "Origins that have never been interacted with as a first party do not have a notion of first-party storage. From the user's perspective, they only have a third-party relationship with that origin. Access requests are automatically denied if the browser detects that the user hasn't interacted with the embedded content in a first-party context recently (in Firefox, 'recently' means within 30 days)."

Read that slowly against a newly deployed generated app. The origin was created this week. No visitor has ever opened it directly in a tab. Therefore the obvious remedy is automatically denied, and it is denied for a reason that has nothing to do with the quality of the code and that no amount of implementation can fix. The remedy requires a history the application has not had time to accumulate.

The remaining preconditions are ordinary but easy to miss, and each is a separate way for a correct call to fail. "The document's window must be a secure context." "The document and top-level document must not have a null origin." Usage "may be blocked by a storage-access Permissions Policy set on your server." And for a sandboxed frame, "Sandboxed [iframe]s cannot be granted storage access by default for security reasons", which the API addresses with a sandbox token that "needs to include this to enable storage access requests, along with allow-scripts and allow-same-origin to allow it to execute a script to call the API and execute it in an origin that can have cookies/state."

Two further facts shape the rubric rather than the prose. Permission is recorded against a pair of sites: "Once permission is granted, a permission key is stored in the browser with the structure" a top-level site and an embedded site. And it is not inherited sideways, because "Permission must be explicitly activated for each context. When an embed is granted permission, that permission is also activated for the current context. However, other contexts, such as new browser tabs or content in other [iframe] elements in the page, have their third-party cookie access blocked by default."

Grants also expire. The documented behaviour is roughly thirty days in each of the three browsers described, with one noting that "Successful use of the Storage Access API resets this counter."

One more fact belongs here because it is the most common way a build gets the cookie half wrong without noticing. A cookie that must travel cross-site has to say so, and saying so has a condition. MDN puts it as a requirement: SameSite=None means "Send the cookie with both cross-site and same-site requests. The Secure attribute must also be set when using this value."

The governing draft is harsher than a requirement, and this is worth knowing before anyone treats it as advisory. Verbatim: "If the cookie's 'same-site-flag' is 'None', abort these steps and ignore the cookie entirely unless the cookie's secure-only-flag is true."

The cookie is not downgraded or warned about. It is ignored entirely, which from inside the application is indistinguishable from a cookie that was never set.

Omitting the attribute does not leave the behaviour undefined so much as unpredictable. The draft specifies a fallback, verbatim: "If the 'SameSite' attribute's value is something other than these three known keywords, the attribute's value will be subject to a default enforcement mode that is equivalent to 'Lax'." MDN records that the applied default is itself a variant: "When Lax is applied as a default, a more permissive version is used. In this more permissive version, cookies are also included in POST requests, as long as they were set no more than two minutes before the request was made."

A two-minute window in which a sign-in flow works and after which it does not is a very good way to produce a defect that reproduces for the developer and not for the user.

The rubric

Seven signals, weighted to 100. Scored on the generated application as emitted, with any hand-written configuration removed, which is the control step in the protocol.

Scroll to see more

SignalWeightWhat a failing case looks like
Cross-site cookie declaration22A session cookie that must travel cross-site carries no SameSite attribute at all, so it falls to the default enforcement mode including the two-minute permissive window; or it declares SameSite=None without Secure, which the governing draft says is ignored entirely
Partitioned opt-in correctness20No cookie carries Partitioned in a build designed to be embedded; or Partitioned is set without Secure; or it is set on a cookie the application then expects to read from a different embedding site
Client-storage dependence under partitioning16Session, identity or draft state is kept in localStorage, IndexedDB, a Shared Worker or a Broadcast Channel, with no stated assumption about the partition, so an embedded instance silently reads an empty store
Storage Access API posture14The application needs unpartitioned state and never requests it; or requests it outside a user gesture; or requests it and treats a denial as an exception rather than a supported state
Embedded-context degradation12Partitioned away from its session, the application renders a signed-out shell, an empty list or an infinite spinner, and tells the person nothing about why
Delivery and frame requirements9The embed is sandboxed without the storage-access token, or served from a non-secure context, or a storage-access Permissions Policy on the application's own responses blocks the call it makes
Declared first-party requirement7The build requires a first-party context and says so nowhere, so an integrator discovers it after shipping

Three weighting decisions worth arguing about now

Why cookie declaration is the heaviest signal. An undeclared or wrongly declared SameSite is a defect in every embedding scenario and in none of the first-party ones, which makes it the most reliable predictor on this axis. It also has the harshest documented consequence of anything in the table, because a SameSite=None cookie without Secure is ignored entirely rather than degraded. A missing Partitioned attribute is only a defect for a build that is actually embedded, and plenty of generated applications are not, so we weight the universal failure above the conditional one. If you think a build that is never embedded should be scored on neither, signal 7 is where we put that argument and it is deliberately the lightest.

Why client storage outweighs the Storage Access API posture. Signal 3 catches a build whose cookie work is immaculate and whose session actually lives in localStorage, which is both common in generated output and completely invisible to a cookie-attribute review. Signal 4 scores how well a build asks for a remedy that, per the precondition above, a new deployment may be refused for reasons unrelated to its code. Scoring the dependency above the request is our attempt not to penalise a build for the age of its domain, and it is a judgement rather than a measurement.

Why the declared requirement is scored at all. It is the only signal an application can pass without changing any behaviour, which is an obvious objection to including it. We include it because this axis is about a defect that cannot be discovered from inside the work, so a build that names the constraint has transferred the one piece of knowledge an integrator cannot otherwise obtain. If that reads as rewarding documentation over engineering, it is the weighting we would most like to be talked out of.

Four postures

Level 0, Unconsidered. Nothing in the generated output expresses an assumption about the partition. Cookies carry no explicit SameSite, no cookie carries Partitioned, client storage is used for identity state, and the Storage Access API appears nowhere. This is the level the documented defaults make reachable with no mistakes at all.

Level 1, Accidentally first-party. The build is correct and works, as long as it is the page. Cookie attributes may even be set well. Nothing distinguishes this from Level 2 in a first-party test, which is why the protocol below never scores from one context.

Level 2, Partitioned-correct. Cookies that must cross sites declare it with Secure, cookies that should be per-embedder carry Partitioned with Secure, and client storage is either partition-tolerant or not load-bearing for identity. The application behaves correctly in each embedding site independently and does not assume continuity between them.

Level 3, Declared and degrading honestly. All of Level 2, plus the application requests unpartitioned access only when it needs it and behind a gesture, treats a denial as a first-class state with a message a person can act on, and states its first-party requirement where an integrator will read it before shipping rather than after.

The measurement protocol

Ten steps. Steps 2 and 10 are the controls, and a run that skips either should report the affected signals as not measured rather than scoring them.

  1. Generate the application from the builder's own default prompt for an app with sign-in and persisted user state. Deploy it as the builder deploys it. Record the emitted Set-Cookie headers in full, every attribute, on the sign-in response and on one authenticated route.
  2. Control. Load the deployed application as the top-level document in a clean browser profile. Sign in, set a preference, create an unsaved draft, reload. Record that all three survive. Every later step is read against this baseline, and a build that fails here has a different defect and leaves this axis.
  3. Serve a trivial page from a second, unrelated origin that frames the application, and load that page as the top-level document. Repeat the step 2 sequence. Record what survives, what is empty, and whether anything is said to the person.
  4. Repeat step 3 from a third unrelated top-level origin, in the same profile. This is the partition-key step. A session that works independently in both is partitioned and correct; a session that works in neither is unpartitioned and blocked; a session that carries over is unpartitioned and granted, which is a different posture and must not be scored as the same thing.
  5. Repeat steps 2 to 4 in a browser with state partitioning on by default and in one with third-party cookie protections on by default, recording the browser and version rather than generalising across them.
  6. Inspect the markup of the embed in step 3 for a sandbox attribute. If present, record whether the storage-access token is there alongside the scripts and same-origin tokens, and whether the application's own responses carry a storage-access Permissions Policy that would block the call.
  7. Instrument the embedded instance to record whether it calls for storage access at all, whether the call is inside a user gesture, and what it does with a rejection. Then deny the request and record the rendered result.
  8. Enumerate every client-storage API the application touches and classify each as identity-bearing or not. This is the step that catches a build whose cookie work is immaculate and whose session actually lives in localStorage.
  9. Read whatever the builder publishes about embedding the generated app. Record whether a first-party requirement is stated, and where.
  10. Control. Repeat steps 1 to 4 against a deployment of the same generated application with every hand-added configuration file removed, so the score describes what the builder emits rather than what a reviewer fixed.

A build with nothing to declare is scored as a full pass on the signals it cannot exhibit rather than left blank. An application with no authentication has no session to partition, and an application that stores nothing on the client cannot depend on a partitioned store. We apply the same principle here that we applied in our version skew proposal, where a build that ships "no lazily loaded routes, no client-side navigation and no client-side data fetching has essentially nothing to skew" and the affected signals are scored as a full pass.

How this relates to axes already published here

Three of the axes already proposed on this site touch this territory, and in each case the boundary runs in both directions. In none of them does either axis need amending; what they need is scoping, which is what the sections below do.

Security headers: attribute presence against cross-site function

Our security headers axis carries session cookie attributes as its heaviest signal at weight 22, scoring whether a cookie sets HttpOnly, Secure and an explicit SameSite. That overlaps this axis on exactly one attribute and diverges on what the attribute is for.

There, an explicit SameSite is scored because an inherited default is an unknown security posture. Here, the same attribute is scored because the wrong value is a function failure. Both directions are real. A cookie set SameSite=Strict scores well on a hardening checklist and guarantees this axis a zero on any embedded route. A cookie set SameSite=None with Secure is correct here and is the most permissive cross-site posture available there. Neither rubric is wrong; each is answering its own question, and a build can legitimately sit at opposite ends of the two.

That axis also scores an embedding policy, whether frame-ancestors or X-Frame-Options is delivered where it binds. That is the question of who may embed you. This axis asks whether you still work when you are embedded. A build can score at the top of both by refusing to be framed, and a build designed to be framed cannot.

Our consent gating axis scores whether anything is written to device storage before a visitor has been asked. This axis scores whether what is written survives being read from somewhere else.

Those point opposite ways and both are real. A build can set nothing before consent and then depend entirely on an unpartitioned cookie afterwards, scoring at the top there and at the bottom here. A build can be scrupulous about the partition and set an analytics cookie on first paint, scoring the reverse. Neither axis predicts the other, which is a good reason to keep them separate rather than merge them into a cookie-hygiene composite.

Session lifetime: whether it is accepted against whether it is sent

Our session lifetime axis draws its boundary at the server: it asks whether the server still accepts a credential after it should have stopped. This axis sits one layer earlier and asks whether the credential is sent at all.

That is the sharper tension of the three, because the failure modes look identical from the application's logs. A request that arrives without a cookie because the session expired and a request that arrives without a cookie because the user agent returned an empty cookie-string in a third-party context are the same request. And the direction inverts: a build that shortens its absolute session lifetime scores better there and is more likely to be caught here, because a shorter credential has more opportunities to be re-established in a context where it cannot be. Separating the two needs the step 4 partition-key test, not a log line.

A composition rather than a boundary

Our multi-tab coherence axis rests on localStorage events and BroadcastChannel, and both appear on the documented list of partitioned APIs. Our earlier URL-state proposal rests partly on the back and forward cache, which appears on the documented list of permanently partitioned network state.

This is a composition rather than a boundary dispute, and it is worth stating because it is the one place two axes could silently score the same build twice. A cross-tab channel that works in a first-party tab and not in an embedded frame is a coherence defect by one rubric and a partition defect by this one. Our view is that the coherence axis should keep scoring the channel and this axis should score the assumption, which is the thing a generator chose. We would rather hear that argued than assume it.

What this axis is not

It is not a privacy or tracking axis. Nothing here scores whether an application tracks anybody, and the mechanisms quoted above exist because of tracking rather than because of broken widgets. We are using the documentation of a privacy mechanism to describe a function failure, and we should say so plainly rather than borrow its moral weight.

It is not an anti-framing axis, which the security headers proposal already covers in the opposite direction.

It is not a verdict that embedding is the right architecture for a generated application. Plenty of builders emit apps intended only ever to be the page, and under this rubric such a build can score a full pass on five of the seven signals by construction.

Limitations and open questions

  1. Half the central observable is an inference. The cookie half is settled by a normative sentence permitting an empty cookie-string in a third-party context. The storage half is not: we could find no statement of what a site sees when its bucket is swapped, and we have not invented one. The protocol is written to measure it rather than assume it. If a reviewer can point at a normative statement either way, that is the single most useful correction this page could receive.

  2. Browser behaviour is not one behaviour, and the rubric currently flattens it. The three protections quoted above are a per-site cookie jar, a tracking prevention policy and a tracking-cookie block. They are not the same mechanism, and step 5 records the browser rather than merging them precisely because we do not yet know whether a single posture score across them is defensible.

  3. The Storage Access API precondition may make signal 4 unfair to new builds. An origin nobody has visited first-party is automatically denied, and that is a property of the deployment's age rather than of the generated code. Signal 4 currently scores whether the application asks correctly and degrades correctly, not whether it succeeds. That is a deliberate choice and it may still be the wrong one.

  4. We have not measured how often generated apps are actually embedded. The axis matters in proportion to that, and we do not have the number. If it turns out that essentially no generated application is ever framed, the honest outcome is a lower weight for this axis in any composite rather than a quiet retirement of it.

  5. Step 7 requires instrumenting a build we did not write. Recording whether the application calls for storage access, and inside what, is straightforward with a network and console trace, but recording what it does with a denial may require editing the generated source, which moves the thing being measured. A run that cannot do it without editing should mark signal 4 unmeasured.

  6. Third-party password managers, extensions and enterprise policy are all outside this. Each can change the partition behaviour a visitor actually experiences, and none is reachable from a protocol run against a default profile.

  7. The two remedies are not interchangeable and the rubric treats them as parallel. Opting into partitioning accepts that a session does not span embedding sites. Requesting unpartitioned access tries to keep one that does. A build that needs the second and ships the first is correct by signal 2 and broken by its own product requirement, and we do not currently have a signal that catches that. We would rather publish the gap than paper over it with a weight.

An open question we cannot resolve from documentation. The documented grant expiry is about thirty days in each browser described, one of which resets the counter on successful use. For an application a person uses inside a customer portal once a quarter, that expiry is shorter than the usage interval, so the remedy would fail permanently for exactly the integration pattern that most needs it. We do not know whether any builder's generated output accounts for this, and we have not written a signal for it rather than inventing one.

References

Every claim above is from a document we fetched and read on 5 October 2026. Where a page states its own last-modified date, we have given it. Square brackets inside a quotation mark an editorial substitution for an HTML element name, made so this page renders the quote rather than the element; nothing else inside a quotation has been altered.

We did attempt the CHIPS specification itself at the Privacy Community Group, and it returned no readable text to our fetch, so we have not cited it. We would rather say that than quote a document we could not read.

This is a pre-registration. No builder is scored here, no placement is published, and the weights above are a starting point for argument rather than a settled formula. If you think the declared-requirement signal should not exist at all, that is the argument we most want to have.

Cite this benchmark

Plain text
BuilderProof editorial team. "Does it still know them inside someone else's page? A partitioned-storage posture axis proposal (October 2026)". BuilderProof, October 2026. https://www.builderproof.org/benchmarks/does-it-still-know-them-inside-someone-elses-page-partitioned-storage-axis-october-2026.
BibTeX
@misc{builderproof-does-it-still-know-them-inside-someone-elses-page-partitioned-storage-axis-october-2026,
  title  = {{Does it still know them inside someone else's page? A partitioned-storage posture axis proposal (October 2026)}},
  author = {{BuilderProof editorial team}},
  year   = {2026},
  month  = {oct},
  howpublished = {\url{https://www.builderproof.org/benchmarks/does-it-still-know-them-inside-someone-elses-page-partitioned-storage-axis-october-2026}},
  note   = {BuilderProof, builderproof.org}
}

Frequently asked questions

What is the partitioned-storage posture axis?

It is a proposed BuilderProof benchmark axis that scores whether the application an AI app builder generates still knows who a person is when it is not the top-level page. It is a pre-registration, not a result, and no builder is scored on this page.

Is this about a future browser change?

No. It is the default behaviour of browsers in use today. MDN records that Firefox enables Total Cookie Protection by default, giving third-party cookies a separate cookie jar per site, that Safari has a tracking prevention policy with a similar set of protections enabled by default, and that Brave blocks tracking cookies by default. Firefox has had State Partitioning on by default since version 103.

Why can a developer not see this failure while building?

Because they are the top-level document every time they look. The two contexts are not two code paths, they are the same code path under a different storage key, so there is no branch to inspect and no error to catch. The governing cookie draft permits a user agent to return an empty cookie-string in a third-party context, which from inside the application is indistinguishable from a cookie that was never set.

Does adding the Partitioned attribute or calling the Storage Access API fix it?

Neither is free. A partitioned cookie works in each embedding site separately and never across them, which is a product change rather than a repair. The Storage Access API carries a precondition a newly deployed application structurally fails: MDN records that access requests are automatically denied if the user has not interacted with the embedded content in a first-party context recently, which an origin created this week cannot have.