WEB / WEB-10.05
Browsing contexts, workers, and service workers
Windows, frames, and workers have distinct execution and storage ownership. Trace messages, controllers, and offline-response boundaries.
1. Core · Mechanism
Read every scenario without motion
Array clone
- Input ready
The window prepares [2,3] for sum-a; the worker has not received a message.
- Window / Duru
- [2,3]; DOM pending
- Dedicated Worker
- No input
- Service Worker
- Unused
- Cache Storage
- Unused
- Origin
- No exchange
- Clone queued
postMessage queues a structured clone while the parent retains its array ownership and values.
- Window / Duru
- [2,3]; clone queued
- Dedicated Worker
- No input yet
- Service Worker
- Unused
- Cache Storage
- Unused
- Origin
- No exchange
- Worker arrival
The Worker MessageEvent receives its own [2,3] copy, neither an HTTP request nor DOM access.
- Window / Duru
- [2,3]; result pending
- Dedicated Worker
- Copied [2,3] received
- Service Worker
- Unused
- Cache Storage
- Unused
- Origin
- No exchange
- Local sum
The worker computes sum=5 and changes only the first element of its own copy to 99.
- Window / Duru
- [2,3]; result pending
- Dedicated Worker
- sum5; copy[99,3]
- Service Worker
- Unused
- Cache Storage
- Unused
- Origin
- No exchange
- Result arrival
The window receives the sum-a/sum5 result while its original [2,3] remains unchanged.
- Window / Duru
- [2,3]; sum5 received
- Dedicated Worker
- copy[99,3]
- Service Worker
- Unused
- Cache Storage
- Unused
- Origin
- No exchange
- Window owns DOM
The window checks the jobRef and result type before updating harmless DOM text to 5.
- Window / Duru
- [2,3]; DOM=5
- Dedicated Worker
- copy[99,3]; no DOM
- Service Worker
- Unused
- Cache Storage
- Unused
- Origin
- No exchange
Buffer transfer
- Buffer ready
The window associates a two-byte [2,3] ArrayBuffer with sum-b; senderLength is 2.
- Window / Duru
- buffer length2
- Dedicated Worker
- No buffer
- Service Worker
- Unused
- Cache Storage
- Unused
- Origin
- No exchange
- Release ownership
Successful postMessage transfer detaches the sender buffer before modeled receiver arrival.
- Window / Duru
- buffer length0; detached
- Dedicated Worker
- No buffer yet
- Service Worker
- Unused
- Cache Storage
- Unused
- Origin
- No exchange
- Buffer arrival
The Worker MessageEvent receives buffer ownership and two bytes; the sender cannot reuse it.
- Window / Duru
- buffer length0
- Dedicated Worker
- buffer length2; bytes[2,3]
- Service Worker
- Unused
- Cache Storage
- Unused
- Origin
- No exchange
- Local sum
The worker computes sum5 from its received buffer; its global has no window document.
- Window / Duru
- buffer length0
- Dedicated Worker
- sum5; buffer length2
- Service Worker
- Unused
- Cache Storage
- Unused
- Origin
- No exchange
- Result arrival
The window receives sum-b=5; this result message does not transfer the original buffer back.
- Window / Duru
- buffer length0; sum5 received
- Dedicated Worker
- buffer length2
- Service Worker
- Unused
- Cache Storage
- Unused
- Origin
- No exchange
- Local presentation
The window updates its own DOM while the sender buffer remains detached at length0.
- Window / Duru
- DOM=5; buffer length0
- Dedicated Worker
- buffer length2; no DOM
- Service Worker
- Unused
- Cache Storage
- Unused
- Origin
- No exchange
Offline cache hit
- Active ≠ controller
The supplied first registration is active while the already-open document has controller=null.
- Window / Duru
- controller=null
- Dedicated Worker
- Unused
- Service Worker
- Active; first client uncontrolled
- Cache Storage
- Seed Offline note present
- Origin
- Online not used
- New client control
After normal reload the new in-scope client is controlled; its navigation exchange is omitted here.
- Window / Duru
- controller present; offline selected
- Dedicated Worker
- Unused
- Service Worker
- Active; client controlled
- Cache Storage
- Seed Offline note present
- Origin
- Offline; unreachable
- FetchEvent arrival
The client selection of /learn/offline.txt reaches the Service Worker as a local FetchEvent, not origin wire.
- Window / Duru
- Fetch pending
- Dedicated Worker
- Unused
- Service Worker
- FetchEvent /learn/offline.txt received
- Cache Storage
- Seed Offline note present
- Origin
- Offline; unreachable
- Local cache match
The Cache API lookup matches the explicit entry, without an invented HTTP request or freshness check.
- Window / Duru
- Fetch pending
- Dedicated Worker
- Unused
- Service Worker
- Waiting local lookup
- Cache Storage
- Matched Offline note response
- Origin
- Offline; unreachable
- Local response
The Service Worker prepares a respondWith result from stored response200/body Offline note.
- Window / Duru
- Fetch pending
- Dedicated Worker
- Unused
- Service Worker
- Response200 Offline note ready
- Cache Storage
- Entry retained
- Origin
- Offline; unreachable
- Client response
The local Service Worker response reaches the client; the origin did not receive this offline hit.
- Window / Duru
- Response200; body Offline note
- Dedicated Worker
- Unused
- Service Worker
- Response delivered locally
- Cache Storage
- Entry retained
- Origin
- No origin arrival
- Coverage result
The window displays content; only this matched public path has an established offline result.
- Window / Duru
- DOM Offline note
- Dedicated Worker
- Unused
- Service Worker
- Controlled handler completed
- Cache Storage
- Entry retained
- Origin
- No origin arrival
Offline cache miss
- Controlled client
The supplied client is controlled and offline, with no entry for the missing path.
- Window / Duru
- GET missing ready
- Dedicated Worker
- Unused
- Service Worker
- Active controller
- Cache Storage
- No missing entry
- Origin
- Offline; unreachable
- FetchEvent arrival
The missing-path local FetchEvent reaches the Service Worker with no response available yet.
- Window / Duru
- Fetch pending
- Dedicated Worker
- Unused
- Service Worker
- FetchEvent missing received
- Cache Storage
- No missing entry
- Origin
- Offline; unreachable
- Local cache miss
The Cache API lookup finds no match; a registered worker does not guarantee an entry.
- Window / Duru
- Fetch pending
- Dedicated Worker
- Unused
- Service Worker
- Waiting local lookup
- Cache Storage
- Match absent
- Origin
- Offline; unreachable
- Fallback failure
The selected network fallback produces a network error while offline, with no origin arrival.
- Window / Duru
- Fetch pending
- Dedicated Worker
- Unused
- Service Worker
- Fallback network error
- Cache Storage
- Entry still absent
- Origin
- Not reached
- Client rejection
The local Fetch operation rejects with TypeError rather than an HTTP status404 response.
- Window / Duru
- Fetch rejected-TypeError
- Dedicated Worker
- Unused
- Service Worker
- No successful response
- Cache Storage
- Entry absent
- Origin
- Not reached
- Offline boundary
The window displays unavailable; this establishes no claim that every URL works offline.
- Window / Duru
- Unavailable shown
- Dedicated Worker
- Unused
- Service Worker
- Handler coverage bounded
- Cache Storage
- Entry absent
- Origin
- Not reached
ACTORS · STATE · DATA FLOW
An iframe creates a separate document context
A top-level tab and its iframe contain different documents. HTML describes a navigable as a user-facing navigation structure such as a tab, window, or frame, and a browsing context through a document sequence around a WindowProxy. Do not equate these with operating-system process counts. An iframe is more than a regular subtree of the parent DOM: its child document has its own URL, global Window, and loading lifecycle.
The selected same-origin parent/frame example may access the child document; a different origin constrains that access. Having a WindowProxy does not grant full child-DOM access. Navigation can replace the child document, leaving an old reference outside the active child state. Record the document, origin, and navigation together when inspecting a frame.
Messaging between contexts does not turn the sender into an application identity. Expected origin, source window, and message schema form part of the application contract; a domain name or a role string inside data does not substitute for server permission. This example only observes same-origin document separation, without a cross-origin bypass or process-isolation experiment.
Worker computation, window presentation
A Dedicated Worker runs in a separate WorkerGlobalScope with no direct window or document DOM. This does not mean it has no network or storage access: capabilities such as Fetch and IndexedDB depend on worker type and API. The window sends work, the worker returns data, and the window updates the DOM. This ownership separation supports responsiveness, without guaranteeing every job completes in parallel or every form of security isolation.
Plain-object and array messages use structured cloning: a worker receiving [2,3] can mutate its copy to [99,3] while the parent retains [2,3]. Not every JavaScript value is serializable. An ArrayBuffer on the transfer list is different: a successful postMessage transfer detaches the sender buffer, showing byteLength 0, while the recipient can use the two bytes. Include the buffer in the message itself; the transfer list alone does not send it. Transfer the buffer ownership rather than a TypedArray view.
Permitted SharedArrayBuffer shared memory differs from ordinary cloning and ArrayBuffer transfer and has separate isolation requirements. The artifact uses no shared memory. The application correlates sum=5 with a jobRef and expected type; a computation result does not prove server authorization. A message queue and an HTTP exchange are different transport models.
Registration, control, and offline coverage
A Service Worker registration associates a script with an origin/storage key and scope URL. The API requires a secure context; a trustworthy local localhost fixture does not measure a normal HTTPS deployment. Fulfilled register(), installing/waiting/active states, and the current document controller are different observations. ready indicates an active worker in a matching registration; controller returns the current client worker or null.
The already-open first registering document can remain uncontrolled after activation in the default flow; a later normal in-scope navigation or reload creates a controlled client. This example uses neither clients.claim nor skipWaiting. During an update, a newly installed worker may wait while old active-worker clients remain. A Service Worker is not a permanently running background thread: browsers can stop it and restart it for events. waitUntil connects suitable async event work to lifecycle, not unlimited global-memory persistence.
Cache API is application-managed Request/Response storage separate from HTTP cache and can also be used in a window. Entries do not automatically refresh or expire through HTTP freshness rules; Cache API does not apply HTTP cache headers for that purpose. Quota or eviction can remove data. Offline success needs a controlled client, suitable handler, and an actually stored matching response. Explicitly seeded /learn/offline.txt gives a hit; /learn/missing.txt gives an offline miss and network failure. A registered worker does not make the whole site offline.
2. Red · Trust & Impact
Read every scenario without motion
Clone/transfer
- Copied input was separated from parent state
For sum-a the parent starts with [2,3] and the worker copy has equal values. After the worker mutates its copy to [99,3], parentAfter remains [2,3]. With nonshared cloning, receiver mutation is not sender mutation.
- Context/message ledger
- Clone: worker[99,3] / parent[2,3]
- Ownership/schema gate
- Ownership gate pending
- Document/data boundary
- No outcome
- Result schema and job correlation became separate gates
sum 5 and jobRef sum-a are ordinary result fields. A message’s role or jobRef does not independently create trusted state. The window checks expected schema and job correlation and owns the DOM-update decision.
- Context/message ledger
- Clone: worker[99,3] / parent[2,3]
- Ownership/schema gate
- Expected jobRef/sum required / DOM owner window
- Document/data boundary
- No outcome
- The worker global did not carry document authority
documentAvailable and windowAvailable are false. A separate worker global is not application permission. In the same-origin iframe example, parent and frame are distinct documents; their origin relationship creates no tenant grant.
- Context/message ledger
- Clone: worker[99,3] / parent[2,3]
- Ownership/schema gate
- Expected jobRef/sum required / DOM owner window
- Document/data boundary
- Worker has no document/window / authority separate
- The transfer branch retained buffer lifecycle
sum-b carries bufferHex 0203. Sender byteLength changes from 2 before posting to 0 afterward while receiver byteLength is 2. This transferred-ArrayBuffer detachment differs from mutation of an independent cloned array.
- Context/message ledger
- Transfer: sender2→0 / receiver2
- Ownership/schema gate
- Expected jobRef/sum required / DOM owner window
- Document/data boundary
- Worker has no document/window / authority separate
- A detached buffer was not accepted as reusable
The sender cannot reuse a detached buffer as its old two-byte state. Without explicit ownership lifecycle, later computation assumes the wrong state. Transfer is not a general rule for all objects; this case is an ArrayBuffer.
- Context/message ledger
- Transfer: sender2→0 / receiver2
- Ownership/schema gate
- Detached sender / receiver owns two bytes
- Document/data boundary
- Worker has no document/window / authority separate
- Context ownership was not protected-data assurance
The sum fixture carries harmless bounded data. Job correlation and correct ownership do not verify tenant/object policy or multi-worker concurrency. DOM updates remain in the window; business permission is another application boundary.
- Context/message ledger
- Transfer: sender2→0 / receiver2
- Ownership/schema gate
- Detached sender / receiver owns two bytes
- Document/data boundary
- Ownership scoped / application permissions separate
Controller/cache
- Active registration was separated from the client controller
registerResolved and activePresent are true while firstClientController is null. A normal reload becomes controlled, without clientsClaim or skipWaiting. Active registration does not mean it controls every existing document.
- Context/message ledger
- Active registration / initial controller null
- Ownership/schema gate
- Ownership gate pending
- Document/data boundary
- No outcome
- Scope was not equated with offline coverage
The script is /learn/worker.js and scope /learn/. A controlled client does not imply offline handling of every URL or entry. The cache plan explicitly seeds the public path /learn/offline.txt.
- Context/message ledger
- Active registration / initial controller null
- Ownership/schema gate
- Controlled scope / explicit seed path only
- Document/data boundary
- No outcome
- A cached response was not fresh origin permission
The offline hit returns Offline note with status 200. The origin has not performed fresh authorization then. This public entry contains no identity/session data; personalized retention and invalidation need another contract.
- Context/message ledger
- Active registration / initial controller null
- Ownership/schema gate
- Controlled scope / explicit seed path only
- Document/data boundary
- Public cached200 / no fresh origin authz claim
- An ordinary miss produced a different availability result
Offline /learn/missing.txt has entryPresent false, fetchOutcome rejected-TypeError and originReached false. This ordinary miss is neither worker compromise nor an origin-outage measurement. Offline guarantees need entry and fallback coverage.
- Context/message ledger
- Offline miss / TypeError / origin not reached
- Ownership/schema gate
- Controlled scope / explicit seed path only
- Document/data boundary
- Public cached200 / no fresh origin authz claim
- Cache API was not treated as an HTTP-freshness engine
cacheAPIHonorsHTTPFreshness is false. Cache API matching and retention depend on the application plan; HTTP-cache directives do not automatically run the same engine. Update waiting and eviction are unmeasured here.
- Context/message ledger
- Offline miss / TypeError / origin not reached
- Ownership/schema gate
- Explicit Cache API plan / HTTP freshness separate
- Document/data boundary
- Public cached200 / no fresh origin authz claim
- Control retained handler and lifecycle scope
Controller, matched entry, selected response and fallback outcome remain separate. An active-registration label guarantees neither availability nor protected-user state. Actual update, eviction and runtime behavior need scoped observations.
- Context/message ledger
- Offline miss / TypeError / origin not reached
- Ownership/schema gate
- Explicit Cache API plan / HTTP freshness separate
- Document/data boundary
- Check controller/entry/fallback; authz independent
ASSUMPTION · BOUNDARY · CONTROL
Reading contexts as one authority
An iframe origin or separate Worker global does not establish application permission. Same-origin child-DOM access is a browser rule in the selected example; tenant, user, and object permissions belong to the server. Treating a message jobRef or role as unchecked trusted state confuses transport with decision ownership. Impact depends on application use; a normal sum calculation alone does not demonstrate a vulnerability.
Missing the clone/transfer distinction also creates failure conditions. Reusing a detached parent buffer can break later computation; interpreting worker mutation of an array clone as parent mutation misdiagnoses state. Keep message schema, job correlation, and ownership lifecycle explicit. The window remains the DOM owner, and the worker response contains only expected bounded data.
Preserve the cached-response boundary
A controlled client receiving cached content does not prove the origin just performed a new permission check. Keeping personalized state under the wrong lifecycle can produce stale UI or unnecessary data persistence; impact depends on cache plan, principal, and invalidation. This lesson stores a public Offline note, never identity or session data. Handler coverage and freshness are explicit application decisions.
Treating an active registration as every existing document controller or an offline guarantee for every URL creates availability risk. With no network, the cache-miss branch rejects Fetch; this does not establish worker compromise. Default update waiting is not automatically a broken-network diagnosis either. Separate scope, controller, matched entry, and fallback outcome to preserve observation boundaries.
3. Blue · Secure development & defense
Read every scenario without motion
Ownership review
- Two iframe documents were distinguished by title
The clone/transfer ledger separates Window input/sender length, Worker copy/receiver length and sum, then Window DOM updates after receiving the jobRef. These are local MessageEvent boundaries, not HTTP hops. An offline Cache Storage hit produces no origin event; an offline miss also supplies no evidence of an origin-received request. Parent note and Frame note belong to distinct documents with sameOriginSupplied true. Parent and frame URLs remain separate. Origin relationships establish neither OS-process allocation nor cross-origin access.
- Context observations
- Parent note ≠ Frame note / two documents
- Ownership/coverage review
- Ownership gate pending
- Evidence verdict
- No outcome
- Clone mutation was compared with the parent invariant
The worker copy becomes [99,3] while parentAfter remains [2,3]. Result sum 5 belongs to the original-input computation. Original input, computed result and later mutation are different checkpoints; deriving sum from the mutated input would be wrong.
- Context observations
- Parent note ≠ Frame note / two documents
- Ownership/coverage review
- Computed sum5 / worker later mutates / parent unchanged
- Evidence verdict
- No outcome
- Transfer before/after values were recorded separately
sum-b reports senderBefore 2, senderAfterPost 0 and receiverLength 2. Receiver content 0203 produces sum 5. Merging sender and receiver lengths into one shared-buffer state hides detachment.
- Context observations
- Sender before2 / after0 / receiver2
- Ownership/coverage review
- Computed sum5 / worker later mutates / parent unchanged
- Evidence verdict
- No outcome
- The transfer oracle used a positive control
Normal XML has senderLength 0 and senderReusable false, yielding zero; positive XML marks the same detached sender reusable true, yielding one. These observations are not a standard log schema or real-worker trace.
- Context observations
- Sender before2 / after0 / receiver2
- Ownership/coverage review
- Normal detached nonreusable / positive inconsistency
- Evidence verdict
- No outcome
- Missing observations did not prove no detachment
If sender length or result jobRef is unobserved, normal-fixture values are not copied. Ownership/result verdicts may remain UNKNOWN. Shared memory, retries and multi-worker concurrency need separate contracts and evidence.
- Context observations
- Sender before2 / after0 / receiver2
- Ownership/coverage review
- Normal detached nonreusable / positive inconsistency
- Evidence verdict
- UNKNOWN without sender/job-result coverage
- Regression retained minimal message scope
Review checks jobRef, input/result schema, sender/receiver lengths and current-document association together without private data or credentials. The window owns DOM updates; worker results are not authorization verdicts.
- Context observations
- Sender before2 / after0 / receiver2
- Ownership/coverage review
- Normal detached nonreusable / positive inconsistency
- Evidence verdict
- Recheck job/schema/length/document association
Offline coverage
- Script, scope and controller became separate fields
The clone/transfer ledger separates Window input/sender length, Worker copy/receiver length and sum, then Window DOM updates after receiving the jobRef. These are local MessageEvent boundaries, not HTTP hops. An offline Cache Storage hit produces no origin event; an offline miss also supplies no evidence of an origin-received request. Registration scope is /learn/ with scriptURL /learn/worker.js. The first controller is null; normal reload becomes controlled. Registration-Promise resolution is not equated with actual current-control evidence.
- Context observations
- Scope/script known / controller state separate
- Ownership/coverage review
- Ownership gate pending
- Evidence verdict
- No outcome
- Entry presence was reviewed as the offline-hit predicate
Cache name atlas-public-v1, seed /learn/offline.txt and content Offline note are explicit. A controlled offline hit with entryPresent true returns 200. Scope matching alone does not prove seed presence.
- Context observations
- Scope/script known / controller state separate
- Ownership/coverage review
- Explicit public entry / offline200 Offline note
- Evidence verdict
- No outcome
- The offline miss became an ordinary negative control
The missing path has entryPresent false and rejected-TypeError while originReached stays false. One handler yields distinct hit and miss outcomes. Unavailable networking and a missing stored entry remain separate conditions.
- Context observations
- Missing entry + offline → rejected-TypeError
- Ownership/coverage review
- Explicit public entry / offline200 Offline note
- Evidence verdict
- No outcome
- HTTP-cache and Cache Storage evidence stayed separate
cacheAPIHonorsHTTPFreshness is false. Request.cache concerns the HTTP cache; an explicit Cache API plan can select another path. A storage entry does not establish current origin responses or permission.
- Context observations
- Missing entry + offline → rejected-TypeError
- Ownership/coverage review
- Cache API plan ≠ HTTP cache freshness
- Evidence verdict
- No outcome
- Coverage did not imply complete offline availability
Expected hit and selected miss are known for this public seed. Update waiting, eviction, arbitrary URLs and actual platform-offline behavior are unmeasured. Claiming offline guarantees for every controlled client exceeds coverage.
- Context observations
- Missing entry + offline → rejected-TypeError
- Ownership/coverage review
- Cache API plan ≠ HTTP cache freshness
- Evidence verdict
- Seed hit/miss scoped / all-URL offline unknown
- Reproducible review accounted for lifecycle cleanup
In an actual local experiment, earlier registrations/caches can affect new observations, requiring cleanup and scoped records. These inert .example URLs are not executed. New browser/runtime claims require their own evidence.
- Context observations
- Missing entry + offline → rejected-TypeError
- Ownership/coverage review
- Cache API plan ≠ HTTP cache freshness
- Evidence verdict
- Record scope and cleanup for actual local experiments
IMPLEMENTATION · SECURITY CONTROL · VERIFICATION
Record document and message ownership
The clone/transfer ledger separates Window input/sender length, Worker copy/receiver length and sum, then Window DOM updates after receiving the jobRef. These are local MessageEvent boundaries, not HTTP hops. An offline Cache Storage hit produces no origin event; an offline miss also supplies no evidence of an origin-received request. First distinguish parent URL, iframe URL, selected origin relationship, and active documents. In the same-origin fixture, parent title Parent note, frame title Frame note, and distinct document identities are separate observations. Stay within browser-policy scope; do not add OS-process mapping or cross-origin claims. After navigation, do not report an old reference as current state.
For the Worker job, keep sender input [2,3], copied receiver input, the worker [99,3] mutation, and unchanged parent input together. In the transfer branch, senderBefore=2, senderAfterPost=0, and receiverLength=2 measure separate lifecycle points. Validate jobRef/sum and update DOM in the window. Shared memory, retries, and multiple-worker concurrency need additional contracts.
Verify offline coverage explicitly
Record registration script and scope, then observe register resolution, ready active state, and controller separately. An uncontrolled first document followed by a controlled reload is the expected flow in a clean profile without clients.claim/skipWaiting. Updates waiting and eviction add real-world branches; this small example does not claim native measurement of them.
Confirm the public seed path and content actually exist in Cache Storage before selecting offline mode. Response200 with Offline note and a rejected miss are two outcomes of the same handler. Notice that the offline branch has no request reaching the origin. Do not label Cache API content as managed through HTTP-cache freshness headers. Clean local registration and cache afterward so the next observation is not influenced by an earlier worker or stored entry.
NOW APPLY IT TO THE CASE
What different evidence is needed for worker ownership and service-worker offline responses?
Mutating a worker clone leaves the parent at [2,3]; ArrayBuffer transfer makes sender length 0. An active service-worker registration does not immediately control the first client. Public Offline note yields an offline HIT, while a missing entry ends with TypeError.
Order response receipt, parsing, callbacks and visible DOM outcome in the case. Try explaining the retained old title through this lesson’s browser-state distinctions.
Open the related case file ↗READ THE EXAMPLE TOGETHER
Context and response ownership ledger
Select a field and examine what it supports and where the evidence ends.
Read the raw artifact and field explanations
{
"iframe": {
"parentPath": "/learn/main",
"framePath": "/learn/frame",
"parentTitle": "Parent note",
"frameTitle": "Frame note",
"differentDocuments": true,
"sameOriginSupplied": true
},
"workerClone": {
"jobRef": "sum-a",
"parentBefore": [
2,
3
],
"workerAfter": [
99,
3
],
"parentAfter": [
2,
3
],
"sum": 5,
"documentAvailable": false,
"windowAvailable": false
},
"workerTransfer": {
"jobRef": "sum-b",
"bufferHex": "0203",
"senderBeforeByteLength": 2,
"senderAfterPostByteLength": 0,
"receiverByteLength": 2,
"sum": 5
},
"registration": {
"scriptURL": "https://learn.atlas.example/learn/worker.js",
"scope": "https://learn.atlas.example/learn/",
"registerResolved": true,
"activePresent": true,
"firstClientController": null,
"afterNormalReloadControlled": true,
"clientsClaimUsed": false,
"skipWaitingUsed": false,
"newUpdateMayWaitForOldClients": true
},
"cachePlan": {
"name": "atlas-public-v1",
"explicitSeedPath": "/learn/offline.txt",
"seedContent": "Offline note",
"cacheAPIHonorsHTTPFreshness": false,
"hit": {
"controlledClientSupplied": true,
"online": false,
"entryPresent": true,
"status": 200,
"body": "Offline note"
},
"miss": {
"path": "/learn/missing.txt",
"controlledClientSupplied": true,
"online": false,
"entryPresent": false,
"fetchOutcome": "rejected-TypeError",
"originReached": false
}
},
"selector": {
"language": "XPath",
"xml": "<observations><transfer senderLength=\"0\" receiverLength=\"2\" senderReusable=\"false\"/></observations>",
"xpath": "count(/observations/transfer[@senderLength=\"0\" and @senderReusable=\"true\"])",
"expected": 0,
"positiveFixtureXml": "<observations><transfer senderLength=\"0\" receiverLength=\"2\" senderReusable=\"true\"/></observations>",
"positiveExpected": 1,
"scope": "Only authored protocol-decision observations, not product log field names or a live HTTP capture.",
"missingFieldBehavior": "Missing observation is insufficient evidence; zero matches is not proof of correct runtime behavior."
}
}- iframe
- Distinct documents with only same-origin access supplied.
- workerClone / workerTransfer
- Copied mutation differs from detached-buffer ownership.
- registration
- Active registration differs from current controller.
- cachePlan
- Explicit public entry with separate hit and offline miss.
Inert authored ledger; .example URLs are never executed. Native localhost is separate; update waiting, eviction, and SAB are not measured.
Two reality checks
Worker messages always share the parent object.
Plain array cloning copies; transferred ArrayBuffers detach. Shared memory has different requirements.
An active Service Worker makes the entire site work offline.
A controller, handler coverage, and stored entry are required; an offline miss can reject Fetch.
YOUR TURN
Work through this story.
Predict the outcome, find the evidence boundary, and explain it in your own words.
A worker changes its cloned array to[99, 3]. What happens to the parent array?
- The parent also becomes[99, 3]; the worker uses the same array reference.
- The parent stays[2, 3]; the worker changed its clone.
Read the explained answer
The parent stays[2, 3]; the worker changed its clone. — workerClone.parentAfter[2, 3] demonstrates separate ownership; the worker has no window/document access.
Registration resolved and activePresent is true; is the first client definitely controlled?
Selected lesson artifact fields; teaching example
- registration.registerResolved
- true
- registration.activePresent
- true
- registration.firstClientController
- null
- registration.afterNormalReloadControlled
- true
- No; firstClientController is null and control follows the selected reload.
- Yes; resolving the register promise immediately controls every page.
Read the explained answer
No; firstClientController is null and control follows the selected reload. — clientsClaim is not used; an active registration is not equivalent to controlling the first document.
Why is an offline Cache API hit 200 not proof of a fresh origin HTTP response? Also state one boundary for transferred-buffer ownership.
Read the explained answer
A seeded entry supplies an offline body for a controlled client; Cache API does not automatically apply HTTP freshness. It is not an origin round trip or server-authorization measurement. In the transfer branch the sender buffer is detached with byteLength=0, while the receiver holds 2 bytes. This differs from the retained parent array in the clone branch.
□ I did not count a Cache API object as origin-freshness proof.
□ I distinguished clone and transfer ownership.
Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples
Sources and scope
- WHATWG HTML — Document sequences7.3.1 Navigables · 7.3.1.3 Child navigables
- WHATWG HTML — Web workers10.2.1.1 The WorkerGlobalScope common interface · 10.2.6.3 Dedicated workers and the Worker interface
- WHATWG HTML — Structured data2.7.1 Serializable objects · 2.7.7 StructuredSerializeWithTransfer · 2.7.8 StructuredDeserializeWithTransfer
- W3C — Service Workers2.1 Service Worker · 2.3 Service Worker Registration · 3.4.1 controller · 3.4.2 ready · 3.4.3 register(scriptURL, options) · 4.4 ExtendableEvent · 4.6 FetchEvent · 5.4 Cache · 2.1.1 Lifetime · 4.4.1 event.waitUntil(f) · 6.1 Secure Context
- MDN — Using Web WorkersWeb Workers API · Dedicated workers · Transferring data to and from workers: further details
- MDN — Worker: postMessage()Parameters · Transfer Example
- MDN — Using Service WorkersThe premise of service workers · Updating your service worker
- MDN — CacheCache · Methods