Hacker DirectoryHacker Directory

WEB / REFERENCE

Glossary

Search concepts and concrete artifact fields in one place. Each explanation links to its lesson; tables separate responsibilities that can look similar.

Find the field, return to its mechanism.

Find a concept definition or artifact field quickly, then examine its context in the linked lesson.

  1. Search for a concept

    Enter Origin or Content-Type in Search a field or concept. Read matching definitions and use the visible field/term count to narrow the search.

  2. Separate similar responsibilities

    Use the comparison tables to distinguish Origin from schemeful site or Cookie from the session store. Compare which decision each similar-looking term serves.

  3. Check it against a lesson example

    Select Open the mechanism in its lesson or the field’s lesson title. Find the field in that lesson’s artifact and scene, then explain the definition with its concrete value.

You can identify the mechanism and decision behind a field instead of memorizing its name, and connect its definition to a lesson record.

1591 fields / terms
URL

A resource address has components with different roles: scheme, authority, path, query and fragment. Parsing a URL does not mean a request was sent.

WEB-06.01 · Open the mechanism in its lesson ↗
Origin

For HTTP(S), the boundary is scheme, host and effective port. Two addresses sharing a registrable domain may have different origins.

WEB-06.02 · Open the mechanism in its lesson ↗
Schemeful site

Scheme and registrable domain are considered together. The public suffix boundary matters; taking the last two hostname labels is not a general algorithm.

WEB-06.02 · Open the mechanism in its lesson ↗
HTTP method

Describes the intended request semantics. A method name alone does not prove an application authorization decision or whether an effect occurred.

WEB-07.02 · Open the mechanism in its lesson ↗
HTTP status

Classifies a response at the HTTP level. Durable business completion, body parsing and DOM changes require separate observations.

WEB-07.02 · Open the mechanism in its lesson ↗
Content-Type / Accept

Content-Type identifies the media type of sent content. Accept expresses client response preferences; the two headers are not interchangeable.

WEB-07.03 · Open the mechanism in its lesson ↗
Content-Length

Expresses message content length in octets. The character count of a Turkish string need not equal its UTF-8 byte count.

WEB-07.03 · Open the mechanism in its lesson ↗
Intermediary

May receive requests as a server on one connection and send them as a client on another. Direct peer, resource authority and forwarded context are distinct.

WEB-09.01 · Open the mechanism in its lesson ↗
Cache freshness

Freshness and applicable policy govern reuse of a stored response. Being stored does not mean a personalized response may be exposed to another user.

WEB-09.02 · Open the mechanism in its lesson ↗
DOM

The browser’s object tree for a document. Source text and the final DOM need not be identical; a local DOM change does not mutate server data.

WEB-10.02 · Open the mechanism in its lesson ↗
Event loop

Coordinates tasks and microtasks in the browser host. Promise settlement and rendering are separate dependencies.

WEB-10.03 · Open the mechanism in its lesson ↗
Same-Origin Policy

A browser access boundary between origins. Sending a request, embedding a resource and reading its response from script are different decisions.

WEB-11.01 · Open the mechanism in its lesson ↗
CORS

A sharing contract with the browser for exposing a server response to script at an origin. It does not replace application authorization.

WEB-11.02 · Open the mechanism in its lesson ↗
Preflight

An HTTP check performed by the browser before certain cross-origin requests. An OPTIONS response is not evidence of a user’s permission to perform the business action.

WEB-11.02 · Open the mechanism in its lesson ↗
Cookie / Set-Cookie

Set-Cookie proposes a record and attributes in a response. Cookie carries name/value pairs in a request; Path or HttpOnly attributes are not sent back there.

WEB-12.01 · Open the mechanism in its lesson ↗
HttpOnly / Secure

HttpOnly restricts script access to a cookie; Secure sets a transport condition for sending it. Neither produces the server’s session or object authorization decision.

WEB-12.02 · Open the mechanism in its lesson ↗
Session

In this course, a managed binding between an opaque handle and a server record. Cookie is the transport mechanism; authenticated subject and lifecycle are evaluated on the server.

WEB-13.01 · Open the mechanism in its lesson ↗
Session revocation

A server-side decision to invalidate session use. It is a different event from removing the browser cookie; visibility across a distributed store also matters.

WEB-13.03 · Open the mechanism in its lesson ↗
Object authorization

Evaluates whether a verified subject is allowed a particular action on a tenant and object. Successful login does not make every object accessible.

WEB-14.05 · Open the mechanism in its lesson ↗
202 Accepted

Indicates acceptance for processing; alone it does not prove worker completion or a durable business result.

WEB-19.02 · Open the mechanism in its lesson ↗
What does the Web provide; what does the Internet carry?

The Internet provides communication between interconnected networks. The Web offers URL-identified resources, documents and application interactions over HTTP on that infrastructure. Email can also use the Internet; its browser interface may be a web application while mail transport need not use HTTP. Calling every Internet interaction “the Web” obscures the layer being observed.

WEB-01.01 · Core · The actors of a web application ↗
Client and server are roles

The browser is the client sending a request in an HTTP interaction; a handler executes on the server side receiving it. These are not permanent device labels: when the handler calls another HTTP service, it becomes the client for that interaction. One machine may run both a browser and a local server.

WEB-01.01 · Core · The actors of a web application ↗
A resource is not a copy of a stored row

A resource is the target of HTTP: it may be a file, book information or a computed search result. Its URL identifies it. A representation is a view of that resource at a particular time and in a particular format. JSON and an HTML page can represent related book information. A URL need not map to a same-named disk file.

WEB-01.01 · Core · The actors of a web application ↗
How website, application and API fit together

A website is a collection of related pages and resources. A web application provides functions through that surface, such as viewing, searching or listing books. A web API provides a request/response interface for programs. One product may expose HTML pages, a JavaScript application and a JSON API; these are overlapping descriptions.

WEB-01.01 · Core · The actors of a web application ↗
Separate the screen from authority

The browser provides presentation and controls; a trusted server or service makes the final permission decision for protected data. A browser label saying “owner” does not prove server policy ran. The handler’s storage access does not imply every client may read every record.

WEB-01.01 · Core · The actors of a web application ↗
Mistaking a role for an entitlement

The normal handler receives a client selection and evaluates its business rules. Arrival at the backend does not permit disclosure of every stored field. Reachability is not permission; confusing them may expose excessive fields or private resources.

WEB-01.01 · Red · The actors of a web application ↗
Trust changes between boxes

A client request is external input to the handler; the handler owns the storage selection it creates. Treating a submitted object or role label as authoritative server metadata crosses the wrong trust boundary. The issue is assigning different sources the same authority.

WEB-01.01 · Red · The actors of a web application ↗
Not every error is compromise

A 404 for a missing book, unavailable storage and an empty UI are different outcomes. An actor map alone cannot identify which is a security-policy violation. A failed book screen may be an availability problem; disclosure of a private field is a confidentiality violation.

WEB-01.01 · Red · The actors of a web application ↗
Which observation shows which actor?

Browser Network records reveal the HTTP target, status and response visible to the browser. Handler traces may show the selected application branch. Storage-adapter observations explain record lookup. The response alone does not prove the storage schema or every query.

WEB-01.01 · Blue · The actors of a web application ↗
Separate normal from unexpected output

The positive baseline shows the public book with id/title. A benign negative case uses the supplied missing scenario and produces 404 with an explainable empty view. A private field outside the public output contract requires review; an error status alone does not express that issue.

WEB-01.01 · Blue · The actors of a web application ↗
Use the map during maintenance

When adding storage, a proxy or an export job, record its owner, input source and enforcement point. More actors do not automatically provide isolation; identify the control protecting each boundary. Design logging per component and keep credential values out of the inventory.

WEB-01.01 · Blue · The actors of a web application ↗
actors[].owner

Authority operating a component, distinct from record ownership.

WEB-01.01 · The actors of a web application ↗
flows[].kind

Distinguishes HTTP from local function calls and returns.

WEB-01.01 · The actors of a web application ↗
resources[].representation

The form served over HTTP, not a disk file or storage schema.

WEB-01.01 · The actors of a web application ↗
publicFields / excludedFields

Public output contract and an example private field excluded from it.

WEB-01.01 · The actors of a web application ↗
The work started by entering a URL

A URL such as https://books.example/catalog contains a scheme, host and path. The browser treats it as navigation to a document. When needed it obtains DNS information, uses an IP route to the destination and establishes an appropriate connection. HTTP/1.1 and HTTP/2 commonly use TCP with TLS for HTTPS. HTTP/3 runs over QUIC and uses QUIC’s TLS-based secure connection. IP routing does not select /catalog’s application handler.

WEB-01.02 · Core · The end-to-end journey of a request ↗
Navigation and fetch() do different jobs

Navigation connects the received document to construction of a new page; its resources can trigger further loads. Our Atlas Notları screen is already open. Its button uses fetch() for /api/book?case=found. That call does not automatically replace the current document; the program receives a Response and decides how to present the result.

WEB-01.02 · Core · The end-to-end journey of a request ↗
What the handler receives and does

The method is GET, the path /api/book, and the query selector case=found. The selector chooses a benign scenario supplied by the teaching application. The handler chooses the route, recognizes the selector and asks its storage adapter to look up a book. Route selection is local processing, not another HTTP request.

WEB-01.02 · Core · The end-to-end journey of a request ↗
From record to JSON response

For found, the handler puts id and title into a book object, with title Atlas Notları. Serialization produces UTF-8 bytes for a JSON body and a 200 response. Missing has no record and produces a 404 body containing BOOK_NOT_FOUND. This is an HTTP response created by the handler, not a request lost in the network.

WEB-01.02 · Core · The end-to-end journey of a request ↗
A Response does not mean the body has been consumed

fetch() can fulfill with a Response when status and headers are available, before the full body is consumed. A 404 also produces a Response, with response.ok false. The application checks the status; await response.json() separately consumes and parses the body. These are not one promise or one success decision.

WEB-01.02 · Core · The end-to-end journey of a request ↗
Data in memory; a changed view is another step

Parsing produces a JavaScript object in browser memory. The found branch writes title as text into a DOM heading; the missing branch chooses a not-found view. The browser updates the image in its rendering work after DOM mutation. fetch() is not a DOM API, and receipt does not automatically update the book screen.

WEB-01.02 · Core · The end-to-end journey of a request ↗
A client selection is not server authority

The button sends a selector; the handler evaluates its closed list of scenarios. A client “found” label is not authoritative storage state. Identity, ownership or price labels in other applications likewise cannot become verified solely by arriving from the client.

WEB-01.02 · Red · The end-to-end journey of a request ↗
The limits of a success label

HTTP 200 is a protocol outcome, valid JSON a parsing outcome, and the right book a business outcome. Merging them into one success flag can show incorrect data or stale UI state. Treating 404 as a network exception obscures the intended missing branch.

WEB-01.02 · Red · The end-to-end journey of a request ↗
Traces must not disclose their own data

A requestId can correlate handler and browser observations. Logging every body can move private data or credentials into another store. Obtaining debug data differs from deciding who may read it.

WEB-01.02 · Red · The end-to-end journey of a request ↗
Read Network and application traces together

Inspect target, method, status, response headers and body in DevTools. Link X-Lab-Request-Id to the handler trace; its name is a lab contract. Application events reveal route selection, local lookup and response creation, not captured storage packets.

WEB-01.02 · Blue · The end-to-end journey of a request ↗
Found, missing and incomplete evidence

Found expects 200, JSON book.title and that title in the DOM. The benign missing case expects 404, BOOK_NOT_FOUND and a not-found view; fetch() still provides a Response. This intended negative branch is not an attack alarm.

WEB-01.02 · Blue · The end-to-end journey of a request ↗
Explainable consistency checks

Compare the local contract: found→200+book, missing→404+error. Each response body’s UTF-8 byte count matches Content-Length, and the custom requestId matches the trace. This check belongs to the fixture schema, not a universal detector.

WEB-01.02 · Blue · The end-to-end journey of a request ↗
request / response

HTTP/1.1 teaching representation, not raw DevTools capture; an empty CRLF line separates headers and body.

WEB-01.02 · The end-to-end journey of a request ↗
Content-Length / bodyUtf8Bytes

Body octets without compression, potentially different from Unicode character count.

WEB-01.02 · The end-to-end journey of a request ↗
X-Lab-Request-Id / requestId

Custom example correlation field, not an HTTP standard.

WEB-01.02 · The end-to-end journey of a request ↗
trace[].actor / event / transport

Server processing and local adapter calls, not network protocol records.

WEB-01.02 · The end-to-end journey of a request ↗
browserExpected

Distinct expected outcomes for HTTP Response, body reading and view.

WEB-01.02 · The end-to-end journey of a request ↗
A public book and a private note

The public Atlas Notları book title is readable by everyone. In the same application, note-atlas-01 is Duru’s private editorial note. An asset is something valuable to protect: here the note body, accurate ownership metadata and attribution of a read to the right actor. Assets include more than passwords or keys; business records, available services and trustworthy audits can have value.

WEB-01.S01 · Core · Assets, threats and trust assumptions ↗
Threat, weakness, vulnerability and impact

A threat is a circumstance or event capable of harm. Serving a private note outside entitlement is a threat statement; a person or other source capable of causing it is a threat source. Weakness can describe a design or implementation defect class, such as missing trusted authorization. Vulnerability describes a weakness in a particular system that a threat can exploit or trigger. Glossaries use these words at different breadths; our working distinction separates a class from its concrete system instance.

WEB-01.S01 · Core · Assets, threats and trust assumptions ↗
Write the trust assumption down

In normal note.read, the browser selects the target. The server establishes a verified principal and active tenant context. OwnerId and tenantId come from server-held note metadata. Our private-note rule requires verified actor, matching tenant and matching owner before release. Choosing “owner” in a UI does not establish those conditions.

WEB-01.S01 · Core · Assets, threats and trust assumptions ↗
Controls, evidence and remaining scope

The trusted service layer enforces note.read: unverified principal denies, foreign tenant denies, verified own-note allows. The teaching matrix defines what should happen. Claiming an actual vulnerability additionally requires observing the implemented rule and any private data delivered.

WEB-01.S01 · Core · Assets, threats and trust assumptions ↗
Establish conditions before claiming a vulnerability

Private-note access requires the owner/tenant entitlement. A potentially broken assumption is accepting a browser actor assertion in place of a trusted principal. That is a design-review question; without evidence that a particular implementation accepts it, it is not a confirmed vulnerability.

WEB-01.S01 · Red · Assets, threats and trust assumptions ↗
Do not inflate impact

Own-note allow is intended functionality, not realization of a threat. Foreign-tenant denial is a blocking-policy example. Even observing unauthorized private-note disclosure does not automatically prove modified ownership or access to all tenant data.

WEB-01.S01 · Red · Assets, threats and trust assumptions ↗
Name the threat a control reduces

Trusted-principal verification prevents an unsupported identity assertion becoming decision authority. Tenant/ownership checks constrain disclosure outside entitlement. Output projection reduces private fields appearing in an allowed response. These controls address different faults; the presence of one does not prove the others ran.

WEB-01.S01 · Red · Assets, threats and trust assumptions ↗
A threat record is not an event record

The threat record links asset, boundary, assumption, candidate weakness, control and expected observation. It explores possible conditions. A decision event records an application outcome for a particular request. Keep their identity, timing and evidential scope distinct.

WEB-01.S01 · Blue · Assets, threats and trust assumptions ↗
Expected allow, expected deny, unknown

VERIFIED_OWN allow with note body is the normal positive case. UNVERIFIED_ACTOR and OTHER_TENANT deny without protected output are negative controls. Expected denial can be a safe result and may follow benign changes such as role removal. Alerting on every denial creates unnecessary noise.

WEB-01.S01 · Blue · Assets, threats and trust assumptions ↗
What review and regression close

The control owner re-evaluates positive and negative cases after changes. Verified own access remains available, missing verification and foreign tenant remain denied, and deny releases no protected output. This preserves intended functionality rather than making checks green by blocking everything.

WEB-01.S01 · Blue · Assets, threats and trust assumptions ↗
asset / protectedProperty

Protected value and required security property.

WEB-01.S01 · Assets, threats and trust assumptions ↗
candidateWeakness / vulnerabilityStatus

A review hypothesis, not evidence of a real-system vulnerability.

WEB-01.S01 · Assets, threats and trust assumptions ↗
conditionalImpact

Consequence if the specified event occurs; other impact classes are not presumed.

WEB-01.S01 · Assets, threats and trust assumptions ↗
principalVerified / verifiedContextTenant

Server-side teaching inputs, not the same authority as a client actor label.

WEB-01.S01 · Assets, threats and trust assumptions ↗
expected / evidenceRequired

Required outcome and evidence to observe; actual runtime outcomes are separate.

WEB-01.S01 · Assets, threats and trust assumptions ↗
A byte boundary is not a message boundary

These protocols treat a byte as an eight-bit octet. ABCDEF takes six UTF-8 octets; other Unicode characters can take more. Sending one application message does not mean the transport preserves that boundary. TCP offers an ordered byte stream; sender writes and receiver reads may use different chunks.

WEB-02.01 · Core · From bytes to the local network ↗
Stream → segment → packet → frame

TCP segments convey portions of the stream within IP datagrams. An Ethernet frame carries the IP packet as payload. Headers serve different layers: TCP ports/sequences, IP addresses, Ethernet MAC addresses. Naming every unit “packet” can hide which boundary is being examined; label the layer in an artifact.

WEB-02.01 · Core · From bytes to the local network ↗
Interface and local delivery

Our host uses 192.0.2.10 on eth-demo with MAC 02:00:00:00:00:10. The next hop toward remote 198.51.100.200 is gateway 192.0.2.1. The first Ethernet frame addresses the gateway MAC, not the remote server MAC; its IP destination still identifies the remote endpoint.

WEB-02.01 · Core · From bytes to the local network ↗
Which IPv4 address does ARP resolve?

Routing determines the next-hop IP and interface first. On Ethernet, ARP can resolve an unknown IPv4 neighbor’s MAC. The question here concerns 192.0.2.1, not 198.51.100.200. Sender IP/MAC and target IP fields make that distinction. An appropriate reply provides a usable neighbor mapping.

WEB-02.01 · Core · From bytes to the local network ↗
The scope of IPv6 Neighbor Discovery

IPv6 does not use ARP for this Ethernet communication. ICMPv6 Neighbor Discovery covers address resolution, router/prefix discovery and neighbor reachability. Address resolution uses Neighbor Solicitation/Advertisement for an on-link neighbor. A remote destination still needs the first-hop neighbor’s link-layer address, not all MACs along the path.

WEB-02.01 · Core · From bytes to the local network ↗
Misreading stream boundaries

An application completes messages using its protocol grammar. Treating each read as a complete HTTP message can process incomplete data or include later-message bytes. This is a parser/state assumption, not proof that every fragmentation is an incident.

WEB-02.01 · Red · From bytes to the local network ↗
Treating a local mapping as identity proof

ARP/ND mapping supports next-hop delivery. Taking it as application identity or entitlement merges trust layers. Basic ARP does not cryptographically authenticate an application identity; IPv6 ND also has security conditions.

WEB-02.01 · Red · From bytes to the local network ↗
A wrong interface changes the scope

Correctly formatted data on the wrong interface or next hop can fail to reach the intended destination. Confidentiality or availability risks depend on topology and upper-layer protection.

WEB-02.01 · Red · From bytes to the local network ↗
Read a header at its own layer

The hex artifact is only a 14-byte Ethernet II header: six destination-MAC bytes, six source-MAC bytes, then two EtherType bytes. 0800 identifies IPv4 payload. Source/destination IP in the payload summary belong to another layer. This header does not establish HTTP method, TLS identity or permission.

WEB-02.01 · Blue · From bytes to the local network ↗
Known, unknown and another protocol

Normal IPv4 has a usable gateway mapping. Unknown mapping needs resolution before data delivery; absence of HTTP response is not automatically authorization denial. IPv6 uses ND and does not require an ARP event.

WEB-02.01 · Blue · From bytes to the local network ↗
Explainable consistency checks

Require destination MAC to match the next hop while IP destination remains the remote endpoint. Header offsets total 14 bytes. Concatenated write/read chunks preserve the same stream. These checks do not prove NIC or network delivery.

WEB-02.01 · Blue · From bytes to the local network ↗
hex / offset / length

Header bytes and zero-based field positions; no payload/FCS/padding.

WEB-02.01 · From bytes to the local network ↗
destinationMac / nextHopIp

Local frame neighbor, potentially distinct from remote IP destination.

WEB-02.01 · From bytes to the local network ↗
arpSummary.targetProtocolAddress

Local IPv4 next hop to resolve, not a raw ARP packet.

WEB-02.01 · From bytes to the local network ↗
teachingState / resolution

Teaching outcome and IPv4/IPv6 distinction, not an OS state name.

WEB-02.01 · From bytes to the local network ↗
writes / possibleReads

Illustrative TCP stream chunks without preserved message boundaries.

WEB-02.01 · From bytes to the local network ↗
What does an IP address identify?

IP carries source and destination addresses at the network layer. IPv4 uses 32 bits, IPv6 128. Forms such as 192.0.2.10 and 2001:db8:1::10 are readable representations. An interface can have multiple addresses; an address is not a permanent identity of a host, person or account.

WEB-02.02 · Core · IP, routes and NAT ↗
Subnet and on-link decisions

In this simple IPv4 configuration, 192.0.2.10/24 supplies connected route 192.0.2.0/24. The first 24 bits are the prefix, with mask 255.255.255.0. Destination 192.0.2.20 matches and is an on-link next hop. 198.51.100.200 needs another route.

WEB-02.02 · Core · IP, routes and NAT ↗
The route table and default gateway

The artifact has connected 192.0.2.0/24, a special 198.51.100.0/25 route via 192.0.2.254, and default 0.0.0.0/0 via 192.0.2.1. In this single-table model, select the longest matching prefix. 198.51.100.20 matches /25; 198.51.100.200 does not and uses default. Default does not override all other matches.

WEB-02.02 · Core · IP, routes and NAT ↗
NAT translates addresses; PAT also translates ports

Routing selects the path; NAT performs address translation along it. Basic NAT translates IP addresses. NAPT, commonly called PAT, translates address+port tuples for TCP/UDP examples, separating inside flows behind an outside IP. The next lesson expands ports; here they distinguish the local endpoint for returning traffic.

WEB-02.02 · Core · IP, routes and NAT ↗
IPv6, NAT and permission are separate decisions

IPv6’s larger address space does not require IPv4-style NAT for routed communication. Our no-NAT branch preserves 2001:db8:1::10→2001:db8:2::20; ND may still resolve the first-hop link address. This selected path uses no translation; it does not claim translation is absent from every IPv6 deployment.

WEB-02.02 · Core · IP, routes and NAT ↗
Mistaking the next hop for the final target

A gateway forwards toward another hop. Treating it as the location of the web resource mixes link, IP and application layers. Wrong routes can impair reachability; confidentiality effects depend on peer validation and the actual path.

WEB-02.02 · Red · IP, routes and NAT ↗
Treating translation as security policy

Tuple translation is a communication mechanism, not proof of every permission boundary. Static inbound mappings or differing filtering behavior may change reachability and need explicit policy.

WEB-02.02 · Red · IP, routes and NAT ↗
Making an outside IP actor authority

PAT may carry many inside tuples behind one outside IP. Using that IP as authoritative account identity can misattribute activity or create broad allow/deny decisions. IP controls can provide context but cannot replace verified actor identity.

WEB-02.02 · Red · IP, routes and NAT ↗
Route and translation are separate observations

A route table specifies intended next hop/interface; a frame can show that link’s neighbor. A NAT table links inside/outside tuples, and HTTP logs show the application-visible peer. None automatically proves every field of the others.

WEB-02.02 · Blue · IP, routes and NAT ↗
Local, default and more-specific baselines

Expect on-link for 192.0.2.20, /25 via .254 for 198.51.100.20, and default via .1 for 198.51.100.200. Intended mapping is a positive outcome; a more-specific route overriding default is a benign variation. No route is a distinct result.

WEB-02.02 · Blue · IP, routes and NAT ↗
Compare expected fields

Calculate prefix matches and check that route and next-hop explanations agree. The NAT reverse tuple should return to the inside endpoint derived from the forward mapping. This proves neither wire checksums nor live routability.

WEB-02.02 · Blue · IP, routes and NAT ↗
prefix / via / interface

Match scope, gateway or on-link route, and egress interface.

WEB-02.02 · IP, routes and NAT ↗
expectedPrefix / expectedNextHop

Deterministic longest-prefix result, not live route-cache data.

WEB-02.02 · IP, routes and NAT ↗
inside / outside / remote

Three tuple roles in this TCP mapping, not a universal NAT schema.

WEB-02.02 · IP, routes and NAT ↗
replyBeforeTranslation / replyAfterTranslation

Reverse mapping of the destination tuple back to the inside endpoint.

WEB-02.02 · IP, routes and NAT ↗
ipv6NoNat.translation

No translation on this selected IPv6 branch, not a universal deployment rule.

WEB-02.02 · IP, routes and NAT ↗
A port number alone is not an endpoint

TCP and UDP headers contain 16-bit source and destination port fields, giving a numeric field range of 0–65535. That range does not mean every value has identical application allocation semantics. TCP 443 and UDP 443 are distinct transport contexts. IP itself does not contain these TCP/UDP port fields; identify the carried transport too.

WEB-02.03 · Core · Ports, sockets and firewalls ↗
A socket is an OS object; a connection joins endpoints

A network socket is an object an application uses through the OS communication interface. Equating it with a port omits address family, transport and local address scope. A TCP connection is distinguished by the local/remote address-port pair in its transport context. Multiple clients can connect to the same server port.

WEB-02.03 · Core · Ports, sockets and firewalls ↗
Bind, listen and accept have different roles

In the Linux socket API, bind() assigns a local address, listen() marks a suitable connection-oriented socket as passive, and accept() returns another socket for a new connection. Our normal TCP service uses those roles. UDP datagrams should not be forced into the same listener/accepted-connection model.

WEB-02.03 · Core · Ports, sockets and firewalls ↗
Which policy point makes the firewall decision?

Packet filtering can examine addresses, transport, ports, direction and interfaces. Stateful filtering also uses context maintained by the observing firewall. FORWARD inspects transit traffic not addressed to the firewall host; INPUT handles traffic to that host and OUTPUT its locally generated traffic. Chain scope changes what a rule protects.

WEB-02.03 · Core · Ports, sockets and firewalls ↗
Allowed, listening and successful are separate outcomes

Firewall allow describes passage at that policy point. A normal TCP connection cannot be established without a matching listener; even with one, routing, capacity and later layers can change the result. The no-listener branch has fixture-known absence and shows failure to establish. It generates no claimed OS error code or captured RST.

WEB-02.03 · Core · Ports, sockets and firewalls ↗
Broken assumption: a permitted number is a trusted service

Allowing TCP 443 may assume the endpoint is the intended web service. Correct binding and transport, deployment evidence, and application/TLS controls support that assumption. A changed process or interface scope can give the same number a different meaning.

WEB-02.03 · Red · Ports, sockets and firewalls ↗
Broken assumption: state and direction are interchangeable

RETURN requires the reverse tuple of a known flow and state maintained by the relevant observer. Matching only a destination port or the word ESTABLISHED loses that relationship. An observer on an asymmetric path may lack context; implementations and policies need not all respond identically.

WEB-02.03 · Red · Ports, sockets and firewalls ↗
Broken assumption: silence identifies one cause

In the no-listener branch, firewall allow and listener absence are both true. In the filtered branch, listener existence does not show that traffic reached it. Without telemetry, no response cannot distinguish the two.

WEB-02.03 · Red · Ports, sockets and firewalls ↗
Connect listener, flow and application evidence

Listener inventory identifies a process’s waiting local endpoint. A connection record shows both peer tuples and the endpoint’s own state. Firewall observations identify a verdict at a policy point. Application logs separately record requests and permission outcomes. One observation cannot stand in for all four.

WEB-02.03 · Blue · Ports, sockets and firewalls ↗
Use positive and negative baselines together

The normal case permits outbound NEW TCP 443 by WEB_OUT with a matching listener, making establishment possible. UDP 443 does not match. Unsolicited inbound NEW defaults to deny. A known reverse ESTABLISHED flow is allowed by RETURN. These selected outcomes are not an inventory of all product behavior.

WEB-02.03 · Blue · Ports, sockets and firewalls ↗
Verify regression intent through the fields

Review transport, direction, state provenance and exact flow conditions together. A TCP allowance must not accidentally permit UDP; relaxing a return rule must not admit new inbound traffic. A bind change should preserve the intended local address scope.

WEB-02.03 · Blue · Ports, sockets and firewalls ↗
transport + local/remote IP/port

Tuple distinguishing peer endpoints and transport namespace.

WEB-02.03 · Ports, sockets and firewalls ↗
endpointState

Synthetic endpoint state, distinct from firewall conntrack state.

WEB-02.03 · Ports, sockets and firewalls ↗
direction / observerState / knownFlow

Toy firewall conditions; peer assertions are not trusted state.

WEB-02.03 · Ports, sockets and firewalls ↗
expectedRule / expectedDecision

Abstract rule match and transit policy decision.

WEB-02.03 · Ports, sockets and firewalls ↗
listenerPresent / connectionOutcome

Endpoint condition separate from allow; possible does not claim an observed handshake.

WEB-02.03 · Ports, sockets and firewalls ↗
The journey starts after an address result

The question here is how a selected IP datagram traverses next hops. Assume the application obtained an address for notes.example.org and selected 198.51.100.200. This initial condition shows neither DNS resolution nor established TCP/TLS. A warm connection or cache can avoid a new DNS exchange.

WEB-02.04 · Core · A packet’s journey across the Internet ↗
Each router makes its own local decision

The host route selects R1 and the Ethernet frame addresses its interface MAC. On arrival R1 distinguishes local IP delivery from forwarding toward another destination, then uses its own routing table to select R2 and an egress interface. The host’s default gateway does not specify the whole path.

WEB-02.04 · Core · A packet’s journey across the Internet ↗
A new frame is built for each link

The host→R1 MAC pair is not reused on the R1→R2 and R2→endpoint links. The router’s egress-interface MAC becomes the new frame source and the next neighbor’s MAC becomes its destination. We select Ethernet links without asserting all Internet links use Ethernet.

WEB-02.04 · Core · A packet’s journey across the Internet ↗
TTL bounds a path; it is not DNS TTL

The selected IPv4 datagram leaves the host with TTL 4. R1 reduces it to 3 and R2 to 2 when forwarding. Each forwarding router decrements TTL by at least one; the fixture chooses one per router. Although historically a seconds-based field, normal rapid forwarding gives it a hop-limit effect.

WEB-02.04 · Core · A packet’s journey across the Internet ↗
NAT is explicit; destination arrival has limits

The normal path has no translation. Optional PAT rewrites the source at R1 to 203.0.113.5:45000 while preserving the remote destination. R2 and the endpoint see the outside tuple on this selected path. This is a chosen mapping, not live gateway state or a firewall verdict. A return needs its reverse mapping; it need not traverse an identical physical router sequence.

WEB-02.04 · Core · A packet’s journey across the Internet ↗
Broken assumption: the first hop proves the whole path

A frame sent to the expected gateway MAC supports local delivery conditions, not complete evidence of R1 egress, R2 state or endpoint outcome. Set a security conclusion within the observer’s visible fields.

WEB-02.04 · Red · A packet’s journey across the Internet ↗
Broken assumption: every header field is stable

MAC pairs belong to links, translated tuples to observation points, and TTL to forwarding stages. Conflating these scopes can misclassify two observations of one flow. Preserved ordinary addressing is a property of the selected no-NAT branch.

WEB-02.04 · Red · A packet’s journey across the Internet ↗
Broken assumption: reachability grants application rights

IP arrival may be a necessary network condition; it does not decide resource ownership or authorization. Port 443 and a destination address do not replace service identity. Application policy still needs enforcement.

WEB-02.04 · Red · A packet’s journey across the Internet ↗
Read a hop ledger with its observer scope

The artifact records each link’s source/destination MAC pair and IP TTL. Explicit ingress/egress summary scope makes TTL comparisons meaningful. The values are selected fixture data rather than a capture.

WEB-02.04 · Blue · A packet’s journey across the Internet ↗
Compare ordinary, translated and expired branches

On the ordinary path three link summaries retain the IP tuple while TTL changes 4→3→2. With PAT the first link uses inside source and later links outside source. With TTL 1, downstream receivers stay waiting and no forwarding arrow exists.

WEB-02.04 · Blue · A packet’s journey across the Internet ↗
Review through hop and layer conditions

Review a route change through next hop and egress scope, a NAT change through mapping and return path, and an application change through endpoint permissions. One connectivity observation does not complete all three.

WEB-02.04 · Blue · A packet’s journey across the Internet ↗
links.sourceMac / destinationMac

A new Ethernet address pair per link, not end-to-end identity.

WEB-02.04 · A packet’s journey across the Internet ↗
links.ttl

Selected TTL sent over that link, not DNS cache TTL.

WEB-02.04 · A packet’s journey across the Internet ↗
optionalPat

Source address/port mapping applied only at R1.

WEB-02.04 · A packet’s journey across the Internet ↗
applicationOutcome

Application outcome after IP arrival is explicitly omitted.

WEB-02.04 · A packet’s journey across the Internet ↗
Why separate names from addresses?

Permanently binding an application to a numeric address pushes address changes into user choices and configuration. DNS provides a shared hierarchical namespace with typed data; a question has QNAME, QTYPE and QCLASS. A can request an address while other types describe mail or naming authority. DNS is neither a routing nor an application-permission database.

WEB-03.01 · Core · DNS namespace and resolution ↗
Labels, domains, subdomains and FQDNs

The presentation form notes.example.org. contains labels notes, example, org and the root’s empty label. Tree hierarchy reads root → org → example → notes. It is a subdomain of example.org because of label boundaries, not an arbitrary substring match. A domain name can serve as a host name, but not every DNS node must be a web host.

WEB-03.01 · Core · DNS namespace and resolution ↗
Namespace and zones have different scopes

A domain describes subtree relationships; a zone scopes authoritative data management. A subdomain can remain in its parent zone without separate delegation. A dot therefore does not necessarily introduce another server or security tenant. Our example.org zone directly contains notes.example.org.

WEB-03.01 · Core · DNS namespace and resolution ↗
Separate stub and recursive resolver work

A stub generally cannot perform the full referral process and asks a configured recursive resolver for the result. Application-to-local-resolver calls need not be DNS packets; they may be OS/library interfaces. Browsers can have their own resolver/cache choices. We draw one selected stub-to-recursive path rather than asserting universal browser behavior.

WEB-03.01 · Core · DNS namespace and resolution ↗
A recursive result can require iterative exchanges

In the cold fixture the stub question reaches the recursive resolver. It queries root and receives a referral, then separately queries TLD and receives another referral, then queries the authoritative server and receives an answer. Root does not forward the question as a proxy to TLD. The resolver returns a final result to the stub.

WEB-03.01 · Core · DNS namespace and resolution ↗
Results: answer, name error or missing type

The positive-cache example starts at TTL 120 and is examined after 30 seconds, leaving a selected TTL of 90. Cache lookup is local; DNS record TTL differs from IP packet TTL. It bounds cache use without consulting the source again, while application/resolver policy can discard data earlier.

WEB-03.01 · Core · DNS namespace and resolution ↗
Broken assumption: a written name is trusted identity

A name is a resource-selection input; trust decisions need roles and validated evidence. Its appearance does not replace routing, authentication or object access. Data provenance and the selected resolver policy are part of the trust boundary.

WEB-03.01 · Red · DNS namespace and resolution ↗
Broken assumption: every subdomain is independent authority

Equating the name tree with zone cuts, deployment and tenant boundaries creates the wrong scope. The notes label is not a delegated zone in this fixture. Subdomain relationships follow label suffixes rather than visually similar text.

WEB-03.01 · Red · DNS namespace and resolution ↗
Broken assumption: an empty answer proves name absence

Referral, NOERROR/NODATA and NXDOMAIN differ. An empty answer with an NS referral can leave resolution unfinished; SOA and RCODE context change interpretation. The authoritative-answer bit is not cryptographic authenticity.

WEB-03.01 · Red · DNS namespace and resolution ↗
A resolution trace needs roles and results

The artifact separates query sender/receiver, QNAME/QTYPE, referral zone and final result. Resolver-to-stub and authoritative-to-resolver answers have different roles. Trace fields are an original teaching schema, not a DNS product log or hex capture.

WEB-03.01 · Blue · DNS namespace and resolution ↗
Cold, warm and negative baselines

The cold path follows root/TLD referrals; the warm branch answers from a selected cache entry. No root query can be normal with answer or delegation-cache reuse. Its absence alone does not prove DNS was unused.

WEB-03.01 · Blue · DNS namespace and resolution ↗
A good review is more than one hostname result

Retain absolute-name and label boundaries in namespace review, zone scope in authority review, and recursion/cache provenance in resolver review. In the cold trace the root referral returns to the recursive resolver, which sends a new query to TLD. Root does not forward it as an application proxy. In the warm branch a fresh entry skips those upstream steps.

WEB-03.01 · Blue · DNS namespace and resolution ↗
labels / authoritativeZone

Separates the name tree from managed zone scope.

WEB-03.01 · DNS namespace and resolution ↗
coldTrace.from / to / kind

Identifies the sender/receiver roles of query or response arrivals.

WEB-03.01 · DNS namespace and resolution ↗
rd / ra / aa

Recursion request/availability and authoritative-answer context, not validation proof.

WEB-03.01 · DNS namespace and resolution ↗
warmCache.remainingTtl

Selected positive-cache arithmetic, not a live clock or OS cache.

WEB-03.01 · DNS namespace and resolution ↗
negativeCases

Distinct name/type conditions for NXDOMAIN and NOERROR/NODATA.

WEB-03.01 · DNS namespace and resolution ↗
Record owner and data are different fields

A Resource Record attaches type/class/TTL/RDATA to an owner name. Owner answers which name, and type answers what kind of data. Records sharing owner, class and type form an RRset. Two IPv4 addresses in the notes.example.org. A RRset do not mean two domains.

WEB-03.02 · Core · DNS records and aliasing ↗
A and AAAA: address family is separate from transport

An IN-class A record carries a 32-bit IPv4 address; AAAA carries one 128-bit IPv6 address. The fixture gives notes.example.org A addresses 198.51.100.200 and .201 plus AAAA 2001:db8:2::20. They are distinct RRsets; an A answer alone does not determine AAAA presence.

WEB-03.02 · Core · DNS records and aliasing ↗
CNAME owner is an alias; RDATA is the target name

For docs.example.org. CNAME edge.example.org., docs is the alias owner and edge the target. A second CNAME leads to notes.example.org. An A lookup can follow targets to the terminal A RRset. A same-zone target can be resolved locally; each alias link does not require another network exchange.

WEB-03.02 · Core · DNS records and aliasing ↗
An alias-chain result is not an HTTP action

CNAME is DNS name indirection; it carries neither URL scheme/path/port nor HTTP status/location fields. Obtaining an address for docs does not mean a browser received an HTTP redirect response. The subsequent request’s naming and identity conditions remain at the application layer.

WEB-03.02 · Core · DNS records and aliasing ↗
NS, MX, TXT, PTR and SOA describe different roles

NS names an authority server whose address is separate A/AAAA data. MX carries exchange name and preference: 10 is preferred to 20, without guaranteeing uptime or mail delivery. Standard MX and NS targets must not be aliases. Our ns1/mail1/mail2 have direct A records.

WEB-03.02 · Core · DNS records and aliasing ↗
Broken assumption: an alias grants access rights

An alias links names without conveying user or tenant rights to a target resource. A TXT string likewise does not prove correct consumer/policy processing; a security conclusion needs evidence beyond the record.

WEB-03.02 · Red · DNS records and aliasing ↗
Broken assumption: every name-valued record is an alias

CNAME, NS, MX and PTR can all contain names but do not trigger identical resolution actions. PTR is a pointer, MX a mail-routing preference and NS a naming-authority role. A consumer following all of them as CNAME loses type semantics.

WEB-03.02 · Red · DNS records and aliasing ↗
Broken assumption: every chain yields an address

Missing target, missing requested address type and a loop are different conditions. Adding A beside an alias is not a standard fallback for a CNAME conflict. Table review must inspect owner records and the alias path together.

WEB-03.02 · Red · DNS records and aliasing ↗
Record inventory needs type and scope

Store owner/class/type/TTL/RDATA with authority scope. Keeping alias and terminal address RRsets separate reveals the chain’s names. The PTR reverse zone need not be managed by the same party as forward example.org.

WEB-03.02 · Blue · DNS records and aliasing ↗
Valid baselines and conflict/loop checks

The normal docs→edge→notes path reaches the terminal A RRset; an AAAA question has a separate family result. The MX case prioritizes mail1 at preference 10. NS/MX targets are not alias owners. Local grouping checks are not resolver-availability tests.

WEB-03.02 · Blue · DNS records and aliasing ↗
Change review: consumers and lifecycle

Review an alias change alongside terminal data, intended consumer name, TLS/application identity and cache/delegation lifecycle. MX/TXT/NS changes should not be assumed to perform the same job as a web-address change.

WEB-03.02 · Blue · DNS records and aliasing ↗
records.owner / type / class

Keys for RRset grouping and type-specific interpretation.

WEB-03.02 · DNS records and aliasing ↗
records.rdata

Address, name, preference/exchange or text list depending on type.

WEB-03.02 · DNS records and aliasing ↗
aliasQuery.expectedPath

Terminal owner reached after two CNAME indirections.

WEB-03.02 · DNS records and aliasing ↗
loopVariant

Deliberately invalid inert data, not submitted to a live resolver.

WEB-03.02 · DNS records and aliasing ↗
soaSummary.minimum

RFC2308 negative-cache semantics, not a zone-wide lower TTL bound.

WEB-03.02 · DNS records and aliasing ↗
How long does an answer remain fresh?

TTL limits how long a recursive resolver treats a received RRset as fresh cache data. Our notes.lab.example.org A answer arrives at t=0 with TTL=120. Remaining lifetime is 90 at t=30, 1 at t=119 and 0 at t=120. At that equality boundary the ordinary fresh-cache branch is no longer eligible.

WEB-03.03 · Core · TTL, cache and delegation ↗
Negative answers are cached with distinct keys

In these simple cases NXDOMAIN says the queried name is absent, while NODATA says the name exists without an RRset of the requested type. With no aliases, missing.lab.example.org uses a name/class NXDOMAIN key; v4only.lab.example.org has A data and uses a name/type/class key for AAAA NODATA. Reusing AAAA absence as A absence breaks that scope.

WEB-03.03 · Core · TTL, cache and delegation ↗
Delegation hands a subtree to another authority

The example.org parent publishes ns1.lab.example.org as the NS target for lab.example.org. Beneath the zone cut the child has its own SOA and apex NS data. After the parent referral, the resolver sends a separate query to the child authority; the parent has not proxied the query to the child.

WEB-03.03 · Core · TTL, cache and delegation ↗
SOA timers govern a separate lifecycle

SOA REFRESH, RETRY and EXPIRE concern a secondary authoritative server maintaining its zone copy against a primary. The artifact selects REFRESH=3600, RETRY=600 and EXPIRE=86400; these are not product defaults. A successful SOA check with an equal SERIAL may require no transfer and restart the refresh schedule. It does not restart a recursive A entry’s TTL.

WEB-03.03 · Core · TTL, cache and delegation ↗
Serve-stale is distinct from freshness

RFC 8767 permits policy-controlled use of retained expired data when authoritative refresh is unavailable. Our special branch has a positive entry aged 150 seconds with original TTL=120; refresh has failed and serve-stale is enabled. The resolver returns the old address with TTL=30. The entry remains stale; no new authoritative success is invented. Thirty seconds is recommended, not every resolver’s mandatory default.

WEB-03.03 · Core · TTL, cache and delegation ↗
Changes do not reach every cache simultaneously

Delegation NS, nameserver addresses, CNAME and terminal A/AAAA RRsets can have independent cache lifetimes. The artifact’s selected 600/300/120 seconds make that distinction visible. Publishing new zone data does not instantly reset the remaining lifetime of previously received fresh answers; resolvers received them at different times.

WEB-03.03 · Core · TTL, cache and delegation ↗
Broken assumption: absence applies to every type

An application interpreting AAAA NODATA as name-level NXDOMAIN may suppress valid A data too. The necessary condition is losing the negative result’s type scope; no special network operation is required. The impact is an incorrect fallback or rejecting legitimate access.

WEB-03.03 · Red · TTL, cache and delegation ↗
Broken assumption: a referral is the final answer

Passing an NS target or glue address to the application as its requested host address erases the authority transition. The parent’s nameserver address is a way to reach child data, not proof of the notes server’s address. Parent/child disagreement may interrupt resolution.

WEB-03.03 · Red · TTL, cache and delegation ↗
Broken assumption: an answer proves successful refresh

Serve-stale can preserve availability without proving an address is current. It requires retained expired data, inability to refresh and a permitting policy. Losing that distinction can conceal use of an old endpoint after a service moves.

WEB-03.03 · Red · TTL, cache and delegation ↗
Recompute the cache decision

Compute remaining=max(0,TTL−elapsed) from the artifact. At 119, 120 and 150 seconds, test elapsed<TTL before choosing a fresh branch. For a negative entry use min(SOA TTL,MINIMUM) and the correct key family.

WEB-03.03 · Blue · TTL, cache and delegation ↗
Keep separate evidence for authority and timers

A change record should separate RR owner/type, parent zone, child zone, NS target and required glue. Record whether the response came from cache or authority, its selected age and whether stale policy was used.

WEB-03.03 · Blue · TTL, cache and delegation ↗
Turn boundaries into regression cases

Positive TTL equality, negative TTL equality, type-specific NODATA, distinct parent/child data and permitted stale fallback are separate cases. Also check that a record received with TTL=0 cannot later be used as retained stale data.

WEB-03.03 · Blue · TTL, cache and delegation ↗
positive.evaluations

Elapsed age, remaining lifetime and equality-boundary freshness for a received positive RRset.

WEB-03.03 · TTL, cache and delegation ↗
negative.cacheKeyFields

NXDOMAIN name/class versus NODATA name/type/class scope.

WEB-03.03 · TTL, cache and delegation ↗
delegation

Separate roles for parent referral, bootstrap glue and child answer.

WEB-03.03 · TTL, cache and delegation ↗
secondary

Authoritative secondary-zone timers, separate from recursive TTL.

WEB-03.03 · TTL, cache and delegation ↗
serveStale

Selected positive fallback only: fresh=false with returned TTL=30.

WEB-03.03 · TTL, cache and delegation ↗
A public suffix is not simply the last label

A public suffix is an externally listed name boundary and can contain multiple labels. A registrable domain combines that suffix with the label immediately preceding it. Our selected org rule gives notes.example.org a public suffix of org and registrable domain of example.org. This is not a complete PSL parser or current list snapshot.

WEB-03.04 · Core · Domain boundaries and resolver choices ↗
Domain, site and origin answer different questions

For ordinary HTTP(S) URLs, compare origins using scheme, host and effective port. A path change preserves origin; changing to api.example.org or port 8443 does not. Our selected browser-site calculation uses scheme and registrable domain: HTTPS subdomains may be same-site but cross-origin, and port is not part of that site calculation.

WEB-03.04 · Core · Domain boundaries and resolver choices ↗
Split-horizon: the same query with another selected view

Split DNS describes views that return different answers according to query source or other policy attributes. Our fixture returns notes.example.org A=198.51.100.200 in the public view and A=192.0.2.40 in the employee view. Both are documentation addresses; the employee label does not indicate a connection to a real internal network.

WEB-03.04 · Core · Domain boundaries and resolver choices ↗
DoH and DoT can carry the same query differently

DoH carries DNS query/response messages in an HTTPS exchange. DoT carries DNS over TLS, by default on TCP port 853, with another port requiring mutual agreement. It is distinct from plaintext DNS on TCP 53. Normal branches in this example use an already established authenticated channel rather than drawing a new TCP/TLS handshake for every query.

WEB-03.04 · Core · Domain boundaries and resolver choices ↗
The encrypted hop’s peer still sees the question

DoH/DoT protect the transport scope between client and selected resolver; that resolver still sees the DNS question it processes. This choice does not prove every subsequent path to authoritative servers is similarly encrypted. DNSSEC validation is not automatically established by either transport label.

WEB-03.04 · Core · Domain boundaries and resolver choices ↗
DNS selects an address, not proof of backend identity

An A/AAAA answer provides a candidate network endpoint. That address may front a CDN, reverse proxy, load balancer or multiple HTTP hosts; the DNS-visible endpoint need not be the backend application machine. notes.example.org and api.example.org retain different URL origins even when both use 198.51.100.200.

WEB-03.04 · Core · Domain boundaries and resolver choices ↗
Broken assumption: one IP means one origin

An application substituting an IP address for URL origin can merge different hosts on a shared endpoint into one trust scope. The necessary condition is losing scheme/host/port comparison. A shared IP describes network placement, not authorization.

WEB-03.04 · Red · Domain boundaries and resolver choices ↗
Broken assumption: a resolver view is universal

An employee-view answer may differ from one available through a public resolver. Different query contexts can select different endpoints. Losing context or cache/view separation may cause wrong-address selection or unexpected outages, breaking the assumption of one universal answer per name.

WEB-03.04 · Red · Domain boundaries and resolver choices ↗
Broken assumption: encryption settles every trust decision

An encrypted channel can still connect to an incorrectly selected resolver, which sees the question and applies its policy. Mixing Strict Privacy requirements with silent cleartext fallback loses the selected protection level. Authentication context and fallback conditions are decisive.

WEB-03.04 · Red · Domain boundaries and resolver choices ↗
Compute the boundary matrix from URLs

Compare scheme, host and effective port for every artifact URL. /book and /other are same-origin; the api host and port 8443 are cross-origin while remaining in the HTTPS site group. Changing to HTTP also changes the schemeful-site group.

WEB-03.04 · Blue · Domain boundaries and resolver choices ↗
Read resolver and channel context together

Public DoH and employee DoT branches use the same name/type with different view and transport contexts. Record selected resolver, authentication condition, cache/view scope and plaintext-fallback decision separately.

WEB-03.04 · Blue · Domain boundaries and resolver choices ↗
Preserve the boundary after DNS resolution

After selecting an IP candidate, preserve URL host, HTTPS reference identity and HTTP authority. Distinguish resolution, a reachable connection, accepted server identity and an application response as separate evidence.

WEB-03.04 · Blue · Domain boundaries and resolver choices ↗
suffixContext

Selected org educational rule, not a full PSL snapshot.

WEB-03.04 · Domain boundaries and resolver choices ↗
urlCases

Origin and schemeful-site comparisons for ordinary HTTP(S) URLs.

WEB-03.04 · Domain boundaries and resolver choices ↗
views

Two selected view answers for the same query.

WEB-03.04 · Domain boundaries and resolver choices ↗
transportCases

Warm authenticated DoH/DoT conditions and strict-unavailable boundary.

WEB-03.04 · Domain boundaries and resolver choices ↗
endpointContext

A DNS candidate address is not proof of URL host, authority or identity.

WEB-03.04 · Domain boundaries and resolver choices ↗
Transport identifies endpoints within hosts

IP helps carry packets between addressed hosts. TCP and UDP use ports to distinguish transport endpoints within a host, with protocol included in the identity. The artifact selects a TCP endpoint pair between client 192.0.2.10:51000 and server 198.51.100.200:443. A UDP endpoint using the same numeric port is not this TCP connection.

WEB-04.01 · Core · How is a TCP connection established? ↗
A TCP connection is state held at both ends

A connection does not build a physical circuit. TCP endpoints maintain state, sequence numbers, acknowledgments and buffers to provide an ordered reliable byte stream. The two directions need not traverse the same IP path. This lesson focuses on the two transport peers rather than repeating intermediate routing.

WEB-04.01 · Core · How is a TCP connection established? ↗
Separate streams from message boundaries

TCP does not preserve application-write boundaries as matching receiver reads. Writes NO and TE01 may be read as N, OTE and 01, reconstructing NOTE01 in byte order. The application protocol defines message framing. Neither a TCP segment nor a read chunk is automatically one complete HTTP message.

WEB-04.01 · Core · How is a TCP connection established? ↗
First arrival: SYN reached the server

Initially the client is CLOSED and the server LISTEN. A local active open moves the client to SYN-SENT and prepares SYN with selected ISN=1000. On SYN arrival the server becomes SYN-RECEIVED; the client has received nothing from the server and remains SYN-SENT. One arrival does not establish both endpoints simultaneously.

WEB-04.01 · Core · How is a TCP connection established? ↗
Second and third arrivals: readiness is staggered

The server’s SYN+ACK communicates its ISN=7000 and ACK=1001. On valid arrival, the client becomes ESTABLISHED while the server remains SYN-RECEIVED until it receives the final ACK. The client prepares an ACK acknowledging server SYN with 7001. Arrival of that ACK moves the server to ESTABLISHED.

WEB-04.01 · Core · How is a TCP connection established? ↗
An incomplete observation does not prove a failure cause

If final ACK arrival is absent from this trace, the last modeled states are client ESTABLISHED and server SYN-RECEIVED. Without SYN+ACK arrival the client remains SYN-SENT. These are limits of the selected trace, not diagnoses of packet loss, firewall policy, OS timeout or server failure. Real TCP may later retransmit, continue or abort.

WEB-04.01 · Core · How is a TCP connection established? ↗
Broken assumption: an ACK proves the operation finished

A design using a transport ACK as application receipt or database commit confuses distinct acceptance stages. The necessary condition is interpreting transport evidence as a business outcome. The impact can be a misleading success report or missing operation evidence.

WEB-04.01 · Red · How is a TCP connection established? ↗
Broken assumption: every read is one message

A parser assuming matching write/read boundaries can misinterpret legitimate split or coalesced stream data. The necessary condition is tying application framing to transport chunks. Normal I/O behavior can expose this problem without a network attack.

WEB-04.01 · Red · How is a TCP connection established? ↗
Broken assumption: one ready peer means both are ready

Treating client receipt of SYN+ACK as server receipt of the final ACK loses state ownership. It can turn an incomplete trace into false evidence of bilateral success. Separate endpoint snapshots make the mistake visible.

WEB-04.01 · Red · How is a TCP connection established? ↗
Track the endpoint pair and state ownership

Record protocol and both endpoint addresses/ports first. Local active open changes only client state. For SYN, SYN+ACK and ACK arrivals, explain which peer gains information and which remains in its previous state.

WEB-04.01 · Blue · How is a TCP connection established? ↗
Compute sequence arithmetic independently

Compute 1000+1=1001 for client SYN and 7000+1=7001 for server SYN. The payload-free final ACK does not consume the next data start. Sequence-space usage is not identical to payload-byte count; SYN demonstrates the difference.

WEB-04.01 · Blue · How is a TCP connection established? ↗
Attach success evidence to its layer

Concatenate the stream’s read partitions without labeling each chunk a message absent application framing. The UDP comparison’s two successful receives are only a selected case, not a delivery guarantee.

WEB-04.01 · Blue · How is a TCP connection established? ↗
tuple

Local/remote endpoint pair including protocol; distinct from a listener.

WEB-04.01 · How is a TCP connection established? ↗
arrivals.flags/seq/ack

Selected payload-free handshake fields; ack=null denotes no meaningful acknowledgment when ACK is absent.

WEB-04.01 · How is a TCP connection established? ↗
arrivals.sequenceSpaceUsed

SYN consumes one position; a payload-free pure ACK consumes zero.

WEB-04.01 · How is a TCP connection established? ↗
observationalBranches

Separate peer states at the trace boundary, without an actual timeout/error diagnosis.

WEB-04.01 · How is a TCP connection established? ↗
framingComparison

Difference between TCP write/read partitioning and UDP datagram boundaries.

WEB-04.01 · How is a TCP connection established? ↗
Sequence numbers identify byte positions

After the handshake the client stream starts at 1001. ASCII NOTES! contains six bytes: segment SEQ=1001 carries NO, and SEQ=1003 carries TES!. Their ranges are [1001,1003) and [1003,1007). ACK=1007 reports reception of all contiguous bytes before 1007, excluding that position.

WEB-04.02 · Core · TCP data transfer and loss management ↗
Segmentation does not redefine application messages

TCP divides the byte stream into segments carried in IP datagrams, and the receiver reconstructs the stream from sequence ranges. Sizes depend on MSS, path MTU, buffering and implementation decisions. Our two/four-byte segments simplify arithmetic; they are neither real Internet MSS values nor observed browser packetization.

WEB-04.02 · Core · TCP data transfer and loss management ↗
Retransmission does not allocate new byte positions

The sender tracks bytes not yet acknowledged. In our selected branch NO arrival is absent, TES! arrives and the ACK does not advance. A local RTO expiration resends the earliest unacknowledged range [1001,1003). The same NO uses the same sequence positions, creating neither a new application message nor two extra stream bytes.

WEB-04.02 · Core · TCP data transfer and loss management ↗
Fast recovery and timers have different triggers

The baseline RFC 5681 fast-retransmit profile uses three qualifying duplicate ACKs as a loss indication before timer expiry. One repeated ACK is not that threshold; details such as window changes matter to the definition. SACK and newer loss recovery mechanisms can use other information, and the scene does not execute them.

WEB-04.02 · Core · TCP data transfer and loss management ↗
Flow control protects the receiver; congestion control the path

rwnd represents receive-window capacity while cwnd limits outstanding data according to the sender’s congestion control. In our simple unscaled snapshot, new-data budget is max(0,min(rwnd,cwnd)−flightBytes). With rwnd=6,cwnd=8,flight=2 it is four bytes; with rwnd=16,cwnd=4,flight=2 it is two.

WEB-04.02 · Core · TCP data transfer and loss management ↗
Transport receipt and application read are separate events

The receiver can have all bytes in its TCP buffer before the application reads them. ACK 1007 does not eliminate that distinction. The scene’s final local step illustrates consumption of NOTES!, without a network reply or database commit.

WEB-04.02 · Core · TCP data transfer and loss management ↗
Broken assumption: the largest SEQ proves all earlier data

Seeing a later segment does not fill a gap. When TES! arrives first, the prefix is empty and ACK=1001. Ignoring gaps can produce false delivery evidence.

WEB-04.02 · Red · TCP data transfer and loss management ↗
Broken assumption: timeout locates the failure

RTO reflects the sender lacking new acknowledgment information, not a standalone diagnosis of the peer application or a particular router. The broken condition is treating a timer observation as proof of cause.

WEB-04.02 · Red · TCP data transfer and loss management ↗
Broken assumption: large rwnd always permits fast sending

Even with free receiver capacity, cwnd or another sending constraint can be tighter. Conflating rwnd and cwnd mixes path pressure with receiver pressure.

WEB-04.02 · Red · TCP data transfer and loss management ↗
Complete the byte ledger by hand

Compute SEQ, payload-byte length and exclusive end. In the reordered branch record held ranges, then choose the first missing position as the ACK rather than the greatest position seen.

WEB-04.02 · Blue · TCP data transfer and loss management ↗
Evaluate both budgets together

Compute receiver-limited, congestion-limited and zero-window rows. The selected window update reaches the sender through ACK arrival; local receiver-buffer consumption does not instantly update client knowledge.

WEB-04.02 · Blue · TCP data transfer and loss management ↗
Separate observations from business outcomes

Ordered, reordered and selected RTO recovery paths end with the same NOTES! bytes while arrival order and sender knowledge differ. Explaining the separate application read is a key boundary.

WEB-04.02 · Blue · TCP data transfer and loss management ↗
segments

Half-open sequence ranges for ASCII payload.

WEB-04.02 · TCP data transfer and loss management ↗
reorderedArrivals

Received buffered range versus contiguous prefix.

WEB-04.02 · TCP data transfer and loss management ↗
retransmission

Bytes at the same positions and selected RTO backoff.

WEB-04.02 · TCP data transfer and loss management ↗
sendBudgetCases

rwnd/cwnd/flight distinction in an unscaled byte snapshot.

WEB-04.02 · TCP data transfer and loss management ↗
ackEvidence

TCP receipt is not proof of application read/commit.

WEB-04.02 · TCP data transfer and loss management ↗
Leaving established state proceeds separately by direction

TCP is full-duplex: an endpoint may finish sending while continuing to receive in the other direction. A CLOSE intent is distinct from FIN reaching the peer. Our example starts with earlier data acknowledged, client next sequence 1007, server next sequence 7001 and both peers ESTABLISHED.

WEB-04.03 · Core · Connection closure and UDP ↗
FIN says the sender has no more data

The server acknowledges client FIN with ACK=1008. Arrival of that ACK moves the client to FIN-WAIT-2. If the server application has not closed its sending side, it may remain in CLOSE-WAIT and send response bytes. In the half-close branch it sends OK at SEQ=7001, making the client’s next expected position 7003.

WEB-04.03 · Core · Connection closure and UDP ↗
TIME-WAIT is still state in ordinary closing

In the normal branch the server application closes locally and enters LAST-ACK. Server FIN at SEQ=7001 moves the client to TIME-WAIT; arrival of ACK=7002 moves the server to CLOSED. Sending the final ACK does not immediately discard all client connection state.

WEB-04.03 · Core · Connection closure and UDP ↗
RST is different from graceful closure

An accepted valid RST follows an abort path rather than the graceful FIN exchange that completes reliable delivery of queued data. Our selected cause is a local server-application abort. The server closes locally; the peer closes after receiving the assumed-valid reset and conveys abort information to its application.

WEB-04.03 · Core · Connection closure and UDP ↗
A UDP datagram does not carry TCP lifecycle states

UDP has an eight-byte header containing source/destination ports, length and checksum. Our ASCII PING payload is four bytes, giving UDP length 12 including its header. The IP header is excluded. This summary invents no numeric checksum; pseudoheader and complete-datagram computation are omitted.

WEB-04.03 · Core · Connection closure and UDP ↗
Datagram receipt is not an application operation

The UDP branch selects one successful arrival of a PING datagram at the server. Application consumption is a later local step; the server does not automatically generate PONG. One successful arrival proves neither guaranteed delivery nor the behavior of all UDP traffic.

WEB-04.03 · Core · Connection closure and UDP ↗
Broken assumption: EOF ends the entire exchange

An application automatically closing its response direction on peer FIN may truncate an intended half-close exchange. The condition is treating one-direction EOF as completion of both directions.

WEB-04.03 · Red · Connection closure and UDP ↗
Broken assumption: reset rolls back earlier work

TCP abort does not automatically roll back application work already performed. The peer may have processed some bytes; RST ends transport state. The mistaken condition is interpreting transport abort as transaction rollback.

WEB-04.03 · Red · Connection closure and UDP ↗
Broken assumption: a UDP checksum means reliability

Checksum error detection differs from guaranteed delivery/ordering. Seeing a checksum field does not prove lost data was retransmitted or processed by an application.

WEB-04.03 · Red · Connection closure and UDP ↗
Track +1 in the FIN ledger

Compute ACK1008 for client FIN=1007 and ACK7002 for server FIN=7001. Change only the receiver state at each arrival, rather than advancing the peer before its ACK arrives.

WEB-04.03 · Blue · Connection closure and UDP ↗
Separate graceful and abort evidence

The normal branch shows FIN-WAIT-1/2, CLOSE-WAIT, LAST-ACK and TIME-WAIT for an ordinary close. The abort branch does not follow that sequence; its selected valid reset is a different event.

WEB-04.03 · Blue · Connection closure and UDP ↗
Check UDP length and scope by hand

Add the eight-byte header to PING’s ASCII byte count to obtain 12. The scene separates datagram arrival and local read without adding a transport ACK, FIN or automatic application reply.

WEB-04.03 · Blue · Connection closure and UDP ↗
normalFin

FIN consumes one sequence position even without payload.

WEB-04.03 · Connection closure and UDP ↗
normalStates

Separate peer states for ordinary active close.

WEB-04.03 · Connection closure and UDP ↗
timeWait

2×MSL with selected duration, not an OS default.

WEB-04.03 · Connection closure and UDP ↗
halfClose

The response direction may remain open after client sending ends.

WEB-04.03 · Connection closure and UDP ↗
udp.length

UDP header plus payload bytes, excluding IP header.

WEB-04.03 · Connection closure and UDP ↗
QUIC builds its own transport over UDP

QUIC v1 uses UDP datagrams as its carrier but is more than a socket label claiming reliable UDP. Connection context, stream multiplexing, flow/loss/congestion control and packet protection are QUIC mechanisms. UDP supplies its header and ports; QUIC defines packets and frames inside that payload.

WEB-04.04 · Core · QUIC’s transport model ↗
Handshake completion and confirmation are distinct peer knowledge

The normal scene summarizes Initial and Handshake CRYPTO messages as aggregated flights, not actual packet counts, padding or complete TLS encoding. After the server flight, the client performs selected identity/Finished checks; completion is reported once its own Finished is also sent. The server gains completion/confirmation upon receiving client Finished.

WEB-04.04 · Core · QUIC’s transport model ↗
Packet numbers are not stream offsets

Artifact PN10 carries NO at stream0 offset0; PN11 carries TES at offset2 on that stream; PN12 carries OK at stream4 offset0. A packet number identifies a transmission in its packet-number space, while an offset identifies bytes in a stream. Initial, Handshake and Application Data spaces are separate; the same small number across spaces is not the same event.

WEB-04.04 · Core · QUIC’s transport model ↗
Loss recovery resends information, not old packets

ACK frames report packet ranges; acknowledging PN11–12 does not acknowledge PN10. In our selected RFC 9002 time-threshold branch, later PN12 is acknowledged; RTT80 ms times 9/8 gives a 90 ms threshold, exceeded by age100 ms. The sender declares PN10 lost and carries needed stream bytes again at offset0 in new packet PN13.

WEB-04.04 · Core · QUIC’s transport model ↗
Independent streams do not mean unlimited independent resources

QUIC advertises both stream and connection flow-control limits. Our stream0 limit5 and stream4 limit2 meet connection MAX_DATA7 through final offsets 5+2=7. Recovery of the same offsets does not consume flow credit twice. Congestion and transmitted-byte costs still apply; retransmission is not free.

WEB-04.04 · Core · QUIC’s transport model ↗
For the web, a gain is transport-visible multiplexing

HTTP/2 multiplexes application streams over a TCP byte stream whose request boundaries are invisible to TCP. A missing TCP range can delay later ordered delivery on that connection. HTTP/3 maps the same HTTP semantics to QUIC, making streams visible to transport loss recovery.

WEB-04.04 · Core · QUIC’s transport model ↗
0-RTT is early data, not once-only execution

With prior resumption context a client may send some application data before the new handshake finishes; the server need not accept it. Replay risk particularly concerns application side effects. QUIC’s handling of duplicate transport frames does not automatically make business operations execute once.

WEB-04.04 · Core · QUIC’s transport model ↗
Broken assumption: packet ACK is application delivery

A QUIC packet ACK does not prove every earlier stream offset is contiguous or application-processed. A stream with a gap can wait even when later packets are acknowledged.

WEB-04.04 · Red · QUIC’s transport model ↗
Broken assumption: every protected QUIC packet has equal trust

Equating Initial protection with negotiated Handshake/1-RTT confidentiality moves verified-peer state too early. TLS completion and QUIC confirmation carry different endpoint knowledge.

WEB-04.04 · Red · QUIC’s transport model ↗
Broken assumption: early data executes side effects once

Accepting repetition-sensitive operations in 0-RTT exposes application effects to replay risk. It requires unwanted repeated effects and a policy allowing early data.

WEB-04.04 · Red · QUIC’s transport model ↗
Compute the two number families separately

PN10/11/12/13 belong to one Application Data space. Stream0 offsets 0+2 and 2+3 reconstruct NOTES; stream4 offset0+2 gives OK. PN13 is a new transmission carrying the same NO information at offset0.

WEB-04.04 · Blue · QUIC’s transport model ↗
Track completion and confirmation boundaries

Client verification of peer Finished is distinct from sending its own Finished. Server selected completion/confirmation follows peer Finished arrival; the client becomes confirmed at selected HANDSHAKE_DONE arrival.

WEB-04.04 · Blue · QUIC’s transport model ↗
State conditions for performance and early-data policy

Evaluate stream independence alongside connection resources. MAX_DATA7 exhaustion or congestion can affect new data on both streams, with additional application dependencies.

WEB-04.04 · Blue · QUIC’s transport model ↗
handshake

Endpoint-local completion versus selected HANDSHAKE_DONE confirmation.

WEB-04.04 · QUIC’s transport model ↗
streamPackets

Recovery at the same stream offset with a new packet number.

WEB-04.04 · QUIC’s transport model ↗
ackRanges

Inclusive packet ranges, not stream prefixes or business outcomes.

WEB-04.04 · QUIC’s transport model ↗
flowControl

Unique stream-offset totals consume connection credit.

WEB-04.04 · QUIC’s transport model ↗
earlyPolicy

Locally excludes a repetition-sensitive operation from early data.

WEB-04.04 · QUIC’s transport model ↗
HTTP semantics alone do not secure a channel

HTTP methods, statuses and header rules do not by themselves prove who the peer is or that bytes remain private in transit. An https URI requires secure communication to the selected origin and certificate verification; changing one letter in a URL does not execute those mechanisms. This lesson selects an ordinary certificate-authenticated HTTPS channel using TLS 1.3.

WEB-05.01 · Core · TLS guarantees and cryptography ↗
Three guarantees answer different questions

Confidentiality keeps protected application bytes from a channel observer; integrity detects changes before acceptance; authentication binds negotiated keys to a verified peer. Compressing these into one “encrypted” label can make any peer with a public key appear to be the expected server.

WEB-05.01 · Core · TLS guarantees and cryptography ↗
Symmetric keys protect directional traffic

TLS 1.3 protects records with AEAD. Alias c-app-0 represents the client write key and the server read key for that direction; s-app-0 represents the reverse direction. These have distinct direction and phase scopes. Encrypting every HTTP byte with the certificate public key is not this model.

WEB-05.01 · Core · TLS guarantees and cryptography ↗
Asymmetric roles: agreement and signature

The selected new connection uses ephemeral X25519 key shares to calculate a shared secret; a private share is not transmitted. HKDF derives separate traffic secrets and keys from shared input and handshake context. The long-term certificate key instead signs CertificateVerify to bind possession proof to the handshake context. The CA certificate signature has a different signer and signs different content.

WEB-05.01 · Core · TLS guarantees and cryptography ↗
A record arrived but is not yet delivered

The scene separates arrival of a protected record, local AEAD verification and local application delivery at the server. Seeing record header, ciphertext and tag bytes does not establish accepted plaintext. In the integrity-failure branch, the selected AEAD check fails; plaintext is not delivered to the application and the channel is not treated as usable.

WEB-05.01 · Core · TLS guarantees and cryptography ↗
HTTPS stops at its endpoints and application boundaries

A TLS terminator can read application bytes. With termination at a reverse proxy, browser-to-proxy and proxy-to-upstream protection are separate channel and policy questions; protecting the first does not prove protection on the second. TLS also does not hide destination IP, traffic timing and lengths entirely; padding can reduce some observations but provides no anonymity guarantee.

WEB-05.01 · Core · TLS guarantees and cryptography ↗
Broken assumption: encryption supplies authority

An encrypted channel without verification of the intended hostname and certificate path does not establish the requested service identity. The necessary mistake is binding a channel to a public key while skipping its relationship to the expected service.

WEB-05.01 · Red · TLS guarantees and cryptography ↗
Broken assumption: decrypt output is accepted data

Processing provisional plaintext before final verification may leave an application side effect even after integrity failure. The required condition is consuming incomplete authentication output as trusted input.

WEB-05.01 · Red · TLS guarantees and cryptography ↗
Broken assumption: TLS guarantees business rules

A valid channel does not repair missing application permissions. Endpoint plaintext and termination policy also form separate boundaries beyond TLS wire protection.

WEB-05.01 · Red · TLS guarantees and cryptography ↗
Read the key-role ledger

Match aliases for certificate signing, ephemeral agreement and directional traffic keys. Explain why c-app-0 is the server read key and is not selected for the reverse direction.

WEB-05.01 · Blue · TLS guarantees and cryptography ↗
Separate receipt, verification and delivery

In the normal branch, NOTES reaches the application only after successful local verification. The failure branch has arrival but no verified plaintext or application read.

WEB-05.01 · Blue · TLS guarantees and cryptography ↗
Connect the guarantee table to product decisions

Write the conditions for confidentiality, integrity and server authentication; keep user identity, authorization and business outcome separate. This constrains the claim that having TLS completes every security requirement.

WEB-05.01 · Blue · TLS guarantees and cryptography ↗
keyRoles

Distinct key responsibilities without secret bytes.

WEB-05.01 · TLS guarantees and cryptography ↗
record

Inert protected-record summary for one direction and phase.

WEB-05.01 · TLS guarantees and cryptography ↗
cases

Selected verification and delivery conditions.

WEB-05.01 · TLS guarantees and cryptography ↗
guaranteeScope

Boundary separating channel guarantees from application decisions.

WEB-05.01 · TLS guarantees and cryptography ↗
A certificate carries a signed binding

An X.509 certificate binds subject/public-key information, issuer, validity and extensions using a CA signature. It does not contain the private key. Seeing a public leaf certificate alone does not prove that the peer possesses that private key; TLS CertificateVerify separately binds such proof to the handshake context.

WEB-05.02 · Core · Certificate chains and hostname validation ↗
CA authority starts from local trust policy

Trusting the public key of anchor-atlas is a local client input. Sending the same root from the server does not create new authority. Being self-signed is not sufficient for trust either; why and for which scope the anchor is trusted belongs to verifier policy.

WEB-05.02 · Core · Certificate chains and hostname validation ↗
The TLS list and validated path differ in orientation

In a TLS Certificate list, the sender’s end-entity certificate comes first; subsequent entries SHOULD directly certify the previous one. The example sends [leaf-atlas,int-atlas]. The local anchor is omitted and already depends on verifier context. The leaf issuer alias links to the intermediate subject; the intermediate issuer links to the anchor name.

WEB-05.02 · Core · Certificate chains and hostname validation ↗
A signature alone is not path validation

Issuer signatures, validity time, CA basic constraints/key usage, applicable name/policy constraints and critical extensions are distinct checks. The selected TLS-server purpose also matters for the leaf; extendedKeyUsage can constrain use when present. Drawing issuer arrows towards an anchor does not mean all these checks have run.

WEB-05.02 · Core · Certificate chains and hostname validation ↗
Hostname verification does not take its expectation from the certificate

The client constructs reference DNS-ID api.example.org from https://api.example.org/. A presented SAN DNS name must match it; the selected exact ASCII comparison is case-insensitive. A CNAME target or connected IP does not automatically rename the reference DNS-ID in this ordinary web example. Path checks may pass while hostname matching fails.

WEB-05.02 · Core · Certificate chains and hostname validation ↗
IP and IDN require more than one string rule

A literal IP URL produces an IP-ID reference, requiring exact comparison with address octets in an iPAddress SAN. A DNS SAN string of "192.0.2.10" is not a substitute for an iPAddress SAN. Resolving to one IP does not make different DNS names equivalent.

WEB-05.02 · Core · Certificate chains and hostname validation ↗
Broken assumption: a presented root is trusted

A presented root’s self-signature does not explain why the verifier trusts its key. The required mistake is replacing independent trust-anchor policy with peer-supplied data.

WEB-05.02 · Red · Certificate chains and hostname validation ↗
Broken assumption: a valid chain makes hostname irrelevant

A certificate from a selected trusted CA for another service does not automatically authenticate the service named by the URL. The required condition is skipping reference-identity matching because path checks passed.

WEB-05.02 · Red · Certificate chains and hostname validation ↗
Broken assumption: a certificate signature proves possession

The CA signature covers the public-key binding; that data alone does not show that the live peer controls the private key. The CertificateVerify handshake signature and Finished provide separate evidence.

WEB-05.02 · Red · Certificate chains and hostname validation ↗
Draw the two chain orientations

The TLS list is leaf-first; the selected validation path is intermediate-to-leaf, with a local anchor input. Mark issuer/subject aliases and signature-check conditions separately.

WEB-05.02 · Blue · Certificate chains and hostname validation ↗
Calculate the SAN match matrix

Compare exact ASCII, one-label wildcard, apex and deeper-name rows. Case differences do not break matching, while wildcard label count changes the result.

WEB-05.02 · Blue · Certificate chains and hostname validation ↗
The acceptance gate is a conjunction

Path, hostname and peer-key proof are required together. The scene completes only its certificate/path/name slice: even the normal final step leaves live TLS key proof outside the scene.

WEB-05.02 · Blue · Certificate chains and hostname validation ↗
anchor

Local trust input separate from peer-supplied data.

WEB-05.02 · Certificate chains and hostname validation ↗
certificates

Field aliases without real certificate bytes.

WEB-05.02 · Certificate chains and hostname validation ↗
tlsSentList

Selected leaf-first TLS-list order.

WEB-05.02 · Certificate chains and hostname validation ↗
prospectivePathAnchorToTarget

Validation orientation with the anchor as a separate input.

WEB-05.02 · Certificate chains and hostname validation ↗
nameMatrix

Modern SAN-only bounded ASCII/IP examples.

WEB-05.02 · Certificate chains and hostname validation ↗
The selected path for a new TLS connection

The TLS-over-TCP scene starts with an already-established TCP connection. It selects a new TLS1.3 connection with an ephemeral X25519 share, server-certificate authentication, ALPN and ordinary 1-RTT. Client certificates, PSK resumption, 0-RTT, HelloRetryRequest and post-handshake authentication are not executed. A TLS handshake is not a new TCP handshake.

WEB-05.03 · Core · TLS handshake, SNI and ALPN ↗
ClientHello offers; ServerHello selects

ClientHello carries offers such as supported_versions, cipher suites, supported groups/key_share and signature_algorithms. The normal example offers TLS1.3, TLS_AES_128_GCM_SHA256, X25519 and ed25519 capabilities, using key-share aliases instead of bytes. A TLS1.3 cipher suite selects an AEAD/hash pair, not the entire certificate-signature and key-exchange algorithm combination.

WEB-05.03 · Core · TLS handshake, SNI and ALPN ↗
Protected handshake follows ServerHello

EncryptedExtensions is followed, in the certificate-authenticated branch, by Certificate, CertificateVerify and server Finished; handshake messages after ServerHello use handshake traffic keys. Ordinary TLS1.3 ClientHello and ServerHello are outside that protection. EncryptedExtensions carries parameters such as ALPN selection; do not copy the TLS1.2 ALPN diagram’s ServerHello placement into TLS1.3.

WEB-05.03 · Core · TLS handshake, SNI and ALPN ↗
Transcript, key proof and Finished are distinct checks

CertificateVerify binds possession of the selected certificate private key to the handshake through a signature input containing a context string and transcript hash. Finished MACs the transcript using a key derived from the relevant handshake traffic secret. Neither is the CA certificate signature; the peer’s list, negotiated-parameter history and key confirmation provide distinct evidence.

WEB-05.03 · Core · TLS handshake, SNI and ALPN ↗
SNI helps select a service

The host_name field in SNI’s server_name extension indicates the client’s intended DNS hostname; the server can use it to choose a certificate or configuration. api.example.org is a routing hint, not an authenticated user or proof of a matching certificate. Even after server configuration selection, the client independently verifies its reference identity.

WEB-05.03 · Core · TLS handshake, SNI and ALPN ↗
ALPN selects one protocol for a connection

The client offers h2 and http/1.1; the selected server preference finds h2 as a common option and reports it in EncryptedExtensions. This negotiation does not open another TCP connection; it determines which application parser and semantics use the existing TLS connection. Offering h2 or connecting to port443 does not prove that h2 was selected.

WEB-05.03 · Core · TLS handshake, SNI and ALPN ↗
ECH requires additional conditions beyond ordinary TLS1.3

RFC9849 defines public ClientHelloOuter and encrypted ClientHelloInner for ECH. With a usable configuration/public key and client/server support, accepted ECH can protect the real service’s SNI and sensitive offers inside Inner; Outer public_name and external connection information remain. TLS1.3 does not mean every ClientHello is hidden.

WEB-05.03 · Core · TLS handshake, SNI and ALPN ↗
Broken assumption: Hello selection is authentication

Treating a key-share and cipher selection as verified service identity skips path/name/CertificateVerify/Finished gates. SNI configuration selection does not repair that omission.

WEB-05.03 · Red · TLS handshake, SNI and ALPN ↗
Broken assumption: Finished presence establishes validity

Finished arrival without MAC verification does not complete key confirmation. The required mistake is treating received transcript data as a validation result.

WEB-05.03 · Red · TLS handshake, SNI and ALPN ↗
Broken assumption: a privacy extension hides everything

Seeing an ECH extension does not establish acceptance or a validated intended service. Outer context, IP and traffic patterns retain separate information boundaries.

WEB-05.03 · Red · TLS handshake, SNI and ALPN ↗
Connect the flight ledger to local state

Follow CH offer, local server selection, SH arrival at the client, protected flight receipt, client validation/Finished, then server receipt/validation. Protected flight arrival does not yet complete identity verification.

WEB-05.03 · Blue · TLS handshake, SNI and ALPN ↗
Calculate the offer/selection matrix

Evaluate version/cipher/group overlap separately from ALPN overlap. The first shared ALPN in server preference is h2 in the normal case; selectedProtocol remains null when no overlap exists.

WEB-05.03 · Blue · TLS handshake, SNI and ALPN ↗
Preserve conditions in the visibility table

Mark ordinary clear CH/SH context, later encrypted handshake and accepted-ECH Inner protection separately. The Outer visibility field does not claim that every deployment protects all Inner fields.

WEB-05.03 · Blue · TLS handshake, SNI and ALPN ↗
clientHello

Client capabilities and routing/protocol offers.

WEB-05.03 · TLS handshake, SNI and ALPN ↗
serverHello

Selected cryptographic context; ALPN is not here.

WEB-05.03 · TLS handshake, SNI and ALPN ↗
serverProtectedFlight

Handshake-message order without a record/segment count.

WEB-05.03 · TLS handshake, SNI and ALPN ↗
peerGates

Receipt versus local validation/completion.

WEB-05.03 · TLS handshake, SNI and ALPN ↗
ech

Explicit selected configuration/topology limits for accepted ECH.

WEB-05.03 · TLS handshake, SNI and ALPN ↗
What is established again on a new connection?

Atlas Notes opens a second connection to the same service. Reusing an open TCP connection can avoid a new TLS handshake for another HTTP request; session resumption establishes an actually new TLS connection. It does not continue the previous socket. A PSK derived from an earlier handshake becomes an input to a new negotiation, with a new transcript and new traffic secrets. Describing this as reusing the previous encryption key therefore gives the wrong mechanism.

WEB-05.04 · Core · Key exchange and session resumption ↗
A PSK, a ticket, and a binder are different things

In the selected example an initial certificate-based connection completed successfully, and the server supplied an opaque ticket alias in NewSessionTicket. The client associates the ticket with a secret PSK, its KDF hash, the earlier service identity context, and a lifetime. A later ClientHello carries a ticket identity and a binder, not the secret PSK in cleartext. The ticket may represent a server-side lookup or protected server state; this lesson assumes no actual encoding for either design.

WEB-05.04 · Core · Key exchange and session resumption ↗
Why psk_dhe_ke and psk_ke are not equivalent

The client advertises supported choices through psk_key_exchange_modes. In the selected psk_dhe_ke case both peers create fresh X25519 shares; the PSK and the new asymmetric shared secret enter the key schedule together. The “dhe” part of the mode label is historical: the current TLS 1.3 specification also distinguishes asymmetric establishment with extension-defined KEM choices. This example selects X25519 specifically, without claiming every implementation chooses that group.

WEB-05.04 · Core · Key exchange and session resumption ↗
An unsuitable ticket can lead to a full handshake

The artifact selects a 3600-second ticket lifetime and a 900-second client-side elapsed age. Ticket eligibility is computed from age not exceeding lifetime, KDF-hash compatibility, and suitable service context; server acceptance remains a separate policy input. These are small fixture values rather than normative minima or browser defaults. The ticket’s SNI context cannot replace the requirement that the earlier certificate be valid for the new service identity. The current ticket_lifetime limit is seven days; zero requires immediate discard and the server may apply a shorter acceptance policy. The bounded positive-lifetime comparison does not remove those additional rules.

WEB-05.04 · Core · Key exchange and session resumption ↗
0-RTT has a separate acceptance decision

Resumption does not require 0-RTT. Early data can be sent before ServerHello using a separate PSK-derived key context; it does not have the same forward-secrecy and cross-connection non-replay guarantees as ordinary 1-RTT data. Successful AEAD verification does not prove the message has never been processed. Understanding that distinction needs no repeated-send experiment: follow the point where application policy permits a side effect.

WEB-05.04 · Core · Key exchange and session resumption ↗
Which secret affects which past traffic?

A security review needs more than the phrase “the private key leaked.” A certificate signing key, a resumption PSK, a ticket-protection key, and an ephemeral key have different relationships. In the selected psk_ke case, assuming later PSK disclosure changes the assessment of past ordinary application confidentiality; the same conclusion does not directly follow for the fresh-X25519 combined mode. That distinction assumes valid, unreused ephemeral values and appropriate erasure.

WEB-05.04 · Red · Key exchange and session resumption ↗
Resumption context is not permission context

Seeing a selected ticket does not show that the browser user still has the same role. An application can receive many resource requests over a connection; even a service-bound ticket belongs to a different layer from resource ownership and current policy. Authorization after logout, a tenant switch, or account disable needs current server-side state.

WEB-05.04 · Red · Key exchange and session resumption ↗
The necessary condition for encrypted early data

Treating valid integrity as sufficient for 0-RTT breaks an assumption: data may be correctly protected while processing freshness remains a separate question. State in one serving zone does not automatically become shared acceptance state across all zones. Retry and failure recovery can also cause ordinary application duplication; application-level idempotency, operation identity, and deduplication need an explicit scope.

WEB-05.04 · Red · Key exchange and session resumption ↗
Make mode and ticket policy observable

Configuration review should record negotiated mode, selected group, ticket-lifetime policy, and early-data policy separately. “TLS 1.3 enabled” does not prove selection of psk_dhe_ke. Whether PSK-only mode is accepted depends on the implementation and service profile; document the chosen security argument. Because ticket caches contain secret material, use limited outcome categories and short-lived correlation instead of dumping PSKs, tickets, or binders into diagnostic logs. Deployment BCP RFC9325 §3.4 recommends psk_dhe_ke with a fresh share; ticket-protection-key lifecycle and bounded ticket validity also support the security argument. Its older references to RFC8446 do not replace RFC9846 as the current protocol specification used here.

WEB-05.04 · Blue · Key exchange and session resumption ↗
Tie the early-data profile to application behavior

Atlas initially waits on mutating actions during 0-RTT. Opening a read-only class later needs more than a method list: specify side effects, authorization freshness, retries, server topology, and coordinated acceptance. An uncertain operation belongs after ordinary channel verification; resumption performance and early business execution remain separate settings.

WEB-05.04 · Blue · Key exchange and session resumption ↗
Preserve the current profile and its limits

RFC9846 replaces and obsoletes RFC8446 while retaining TLS version 1.3. Fresh key_share values must not be reused across connections under the current requirement. The artifact’s X25519 choice is a small example of asymmetric mode, not an implementation of KEM negotiation, actual HKDF bytes, or hardware-key lifecycle. Binder and Finished outcomes are explicit condition inputs rather than claimed cryptographic verification.

WEB-05.04 · Blue · Key exchange and session resumption ↗
ticket

Identity alias differs from the secret PSK; lifetime and service context constrain client eligibility.

WEB-05.04 · Key exchange and session resumption ↗
cases

Selected mode, fresh share, certificate branch, and completion are separate outcomes.

WEB-05.04 · Key exchange and session resumption ↗
earlyPolicy

A mutating operation waits at its local policy gate; no early message is sent.

WEB-05.04 · Key exchange and session resumption ↗
Between which two peers is HTTPS protected?

Atlas Notes opens at https://notes.example.org. The browser verifies its TLS peer for the service identity in the URL and protects HTTP data on that connection. The endpoint may be a CDN; a valid certificate held by an authorized CDN does not make the backend application a peer of the same TLS connection. Origin authority and a physical server program are different concepts.

WEB-05.05 · Core · HTTPS and the TLS termination chain ↗
Termination exposes plaintext to an endpoint

TLS termination verifies an incoming protected record and makes its HTTP message readable at the endpoint. The CDN can read headers and body there; caching and routing operate on that content. A terminator’s plaintext access is an expected architectural trust boundary, not an integrity failure. If content must remain secret from the CDN, drawing another TLS arrow alone does not solve that requirement; application confidentiality needs a separate design.

WEB-05.05 · Core · HTTPS and the TLS termination chain ↗
The browser does not see an HTTP upstream choice

The normal case uses TLS on all three hops. In the plaintext-upstream case the final Reverse proxy → Application hop uses HTTP while Browser → CDN remains HTTPS. The browser sees the https scheme of its own resource fetch; it does not classify a backend network segment as mixed content. Confidentiality and peer authentication on that server-side HTTP hop do not come from TLS. Calling it an internal network does not automatically supply those guarantees.

WEB-05.05 · Core · HTTPS and the TLS termination chain ↗
HSTS changes the URL before the request is sent

HSTS is a browser cache policy keyed by domain name. A Strict-Transport-Security header received over error-free HTTPS records the host for max-age; a header received over insecure HTTP is ignored. Before loading an http URL for a known host, the browser changes it to https. Explicit port 80 becomes 443; other explicit ports remain unchanged. This is a local URL change before a network request, not a redirect waiting for a server’s 301 response. For a known HSTS host, a certificate or secure-transport error must stop the connection; browser policy does not offer a warning bypass to accept an insecure connection.

WEB-05.05 · Core · HTTPS and the TLS termination chain ↗
Mixed content is a separate resource request

An http script URL inside an HTTPS document describes a second, insecure browser resource request. Under the selected modern standard profile, blockable requests such as scripts and fetch/XHR are stopped by default policy. Certain ordinary image, audio, and video requests can be upgraded to an https URL; image-set/srcset/picture context and IP-address hosts prevent extending that outcome to every image. CORS approval is a separate policy; a mixed-content URL upgrade does not prove it succeeds. The old passive-safe versus active-dangerous shorthand does not replace the current algorithm.

WEB-05.05 · Core · HTTPS and the TLS termination chain ↗
The trusted endpoints behind the lock

A risk review needs to state that the CDN verified by the browser can read the body. TLS confidentiality protects against network observers, not against the selected peer. TLS on hop-B and hop-C does not hide plaintext from the CDN or reverse proxy. More trusted processors enlarge secret handling, log policy, and retention scope; TLS success is not a business-trust decision.

WEB-05.05 · Red · HTTPS and the TLS termination chain ↗
A scheme label is not channel evidence

An application can know its external URL uses https while its direct connection uses HTTP. In a normal termination architecture, transporting the approved edge’s external-scheme context is a separate design problem. Merely seeing the string https proves neither internal certificate verification nor protection of the body on the final hop.

WEB-05.05 · Red · HTTPS and the TLS termination chain ↗
The different scopes of HSTS and mixed content

HSTS depends on prior knowledge of a host policy; a dynamic entry cannot retroactively protect the first insecure request. Mixed-content policy instead considers the subresource context of a secure document. Treating HSTS as encryption of every server-to-server hop, or mixed-content checks as a blanket ban on every insecure link, incorrectly combines different controls.

WEB-05.05 · Red · HTTPS and the TLS termination chain ↗
Keep a ledger for each hop

The Atlas ledger has separate columns for client, server, scheme, reference identity, certificate-check outcome, and key alias. Normally the CDN is the browser’s server for notes.example.org and a TLS client for proxy.example.org. The reverse proxy is another client for app.example.org. Because the selected certificate profile authenticates servers only, it does not claim upstream client identity verification; mTLS would add separate certificate and policy conditions.

WEB-05.05 · Blue · HTTPS and the TLS termination chain ↗
Verify browser policy state separately

HSTS evidence needs more than a header string: secure receipt, matching host scope, and an unexpired cache entry. The fixture computes expiry as 1000+600=1600; it is active at now=1300 and expired at now=1600. Label boundaries, sibling and parent exclusions, explicit port-80 conversion, and preservation of custom ports are meaningful regression points for includeSubDomains.

WEB-05.05 · Blue · HTTPS and the TLS termination chain ↗
Classify subresources with their actual contexts

Mixed-content review needs request destination and initiator as well as a URL list. Document scheme, image versus imageset, host type, and the selected CORS mode affect the result. Blocking an http script under a secure document’s default policy is the outcome for this case, which has no extra policy such as CSP upgrade-insecure-requests. If an additional policy is introduced, reassess upgrade/block ordering with current Fetch integration.

WEB-05.05 · Blue · HTTPS and the TLS termination chain ↗
hops

Independent peers, reference identities, and key contexts; no secret bytes.

WEB-05.05 · HTTPS and the TLS termination chain ↗
hstsCases

Cached dynamic policy changes the local URL according to host, expiry, and port.

WEB-05.05 · HTTPS and the TLS termination chain ↗
mixedCases

Destination and initiator distinguish outcomes under the default secure-document profile.

WEB-05.05 · HTTPS and the TLS termination chain ↗
Separate the resource from its address

Duru opens Atlas in a book catalogue. The resource is the application’s conceptual entity; the URL is an identifier addressing it. The server can offer an HTML or JSON representation of that entity. Reading an address does not establish the returned bytes, existence, or Duru’s permission.

WEB-06.01 · Core · URL anatomy and resource addressing ↗
Read a URL by its components

Read https://books.example:8443/catalog/atlas?lang=tr&tag=network&tag=web#summary as scheme, authority with host/port, path, query, and fragment. Component delimiters matter; splitting everything on slashes is insufficient.

WEB-06.01 · Core · URL anatomy and resource addressing ↗
What does the scheme select?

The scheme selects how an address is interpreted. http and https address web resources; other schemes such as mailto do not promise the same transport or path structure. A valid URL does not universally imply an HTTP GET.

WEB-06.01 · Core · URL anatomy and resource addressing ↗
Host and port are separate from the path

The authority’s host identifies a target and can use a domain name or an IP address form. DNS resolves domain names; a parser producing hostname has not obtained a DNS answer or proved that a server exists.

WEB-06.01 · Core · URL anatomy and resource addressing ↗
A path is an application address

/catalog/atlas is the hierarchical path following the authority. Its segments may be inputs to an application’s route contract. They need not correspond to a catalogue directory and an atlas file on the server: a handler can produce a database-backed response.

WEB-06.01 · Core · URL anatomy and resource addressing ↗
Read query pairs without losing multiplicity

The query starts with ?. Its business meaning is application-defined. Key/value pairs separated by & are a common form representation handled by URLSearchParams; allowed keys and values still need application rules.

WEB-06.01 · Core · URL anatomy and resource addressing ↗
Where does the fragment stay?

#summary is a fragment. It is excluded from the target of a normal HTTP resource request and can guide the client to a part of the representation. The derived origin-form path/query is /catalog/atlas?lang=tr&tag=network&tag=web, without #summary.

WEB-06.01 · Core · URL anatomy and resource addressing ↗
Encoding represents data for transport

Percent-encoding represents a byte using % and two hexadecimal digits. Converting Unicode text to bytes first requires an encoding. URLSearchParams uses UTF-8 and form serialization: the fixture’s q value notlar ı becomes q=notlar+%C4%B1.

WEB-06.01 · Core · URL anatomy and resource addressing ↗
Absolute addresses and relative references

An absolute URL supplies its own scheme and required parsing context. A relative reference such as /catalog/atlas cannot identify its host without a base. new URL("/catalog/atlas") throws TypeError; a valid HTTPS base makes resolution possible.

WEB-06.01 · Core · URL anatomy and resource addressing ↗
Identify the operation that establishes trust

Start a security review by identifying the consumer: browser parser, server router, or application validation. An address can serve different purposes. Familiar-looking text is not a substitute for parsed components or a policy decision.

WEB-06.01 · Red · URL anatomy and resource addressing ↗
Representation loss can lose a decision input

Keeping one of two tags or mistaking a fragment for the request target produces a misleading interpretation. Record the reference, parsed components, and schema result as separate observations.

WEB-06.01 · Red · URL anatomy and resource addressing ↗
Use a consistent parser and explicit application policy

Use a standard parser, then evaluate application requirements such as allowed schemes, destinations, or ports against its structured output. Parsing success is not an allow decision, and query schema validation remains separate.

WEB-06.01 · Blue · URL anatomy and resource addressing ↗
Preserve data boundaries when logging and creating links

Avoid unnecessary secrets or personal data in queries: addresses can appear in logs, history, and telemetry. This fixture contains only public catalogue labels. Select necessary logging fields rather than treating every full URL as a persistent identity record.

WEB-06.01 · Blue · URL anatomy and resource addressing ↗
input

Ordinary catalogue address parsed locally.

WEB-06.01 · URL anatomy and resource addressing ↗
expected.host / expected.hostname

host includes the port; hostname excludes it.

WEB-06.01 · URL anatomy and resource addressing ↗
expected.tags

getAll preserves repeated query values.

WEB-06.01 · URL anatomy and resource addressing ↗
expected.httpOriginForm

Path/query candidate excluding the fragment; no actual request.

WEB-06.01 · URL anatomy and resource addressing ↗
formEncoding

Form serialization and return to the raw value.

WEB-06.01 · URL anatomy and resource addressing ↗
Distinguish the hostname from domain boundaries

The hostname of https://app.example.com/catalog is app.example.com. Labels belong to DNS name structure, but the word domain alone does not specify a boundary. Distinguish a full hostname, a public suffix, and a registrable domain when reviewing configuration.

WEB-06.02 · Core · Domain, site, and origin ↗
Origin identifies a scheme/host/port boundary

For ordinary HTTP(S) URLs, origin comparison uses scheme, host, and normalized port. https://app.example.com/catalog and https://app.example.com/notes?lang=en#new have the same origin: path, query, and fragment do not alter this boundary.

WEB-06.02 · Core · Domain, site, and origin ↗
A schemeful site is a broader boundary

For these HTTP(S) domain examples, a schemeful site combines the scheme with the registrable domain. https://app.example.com and https://api.example.com share site https://example.com. Different hosts make them cross-origin while the HTTPS registrable domain makes them same-site.

WEB-06.02 · Core · Domain, site, and origin ↗
Same-site does not grant same-origin authority

Origin is a fundamental browser isolation boundary; site is a different grouping used, for example, in SameSite cookie evaluation. Same-site applications do not thereby receive unrestricted access to each other’s DOM or response bodies. Identify the specific operation and browser policy.

WEB-06.02 · Core · Domain, site, and origin ↗
Do not reduce an opaque origin to the string null

Origins are not all HTTP(S) tuples. An opaque origin has an internal identity and can serialize as null. Two distinct opaque origins producing the same null string does not establish internal origin equality.

WEB-06.02 · Core · Domain, site, and origin ↗
Ask which boundary the comparison measures

A shared domain family is insufficient for a technical conclusion. App and API hosts can be same-site but cross-origin; a port change also separates origins. Present the address pair, normalized origins, and site result together.

WEB-06.02 · Red · Domain, site, and origin ↗
Separate classification from observed access

Do not infer server responses or user authorization from the origin table. This lesson computes URL tuples without measuring browser read policy, an actual request, or authorization.

WEB-06.02 · Red · Domain, site, and origin ↗
Define origin policy with the complete tuple

An ordinary HTTP(S) origin policy evaluates the full scheme, host, and normalized port tuple. Checking only a registrable domain does not satisfy a same-origin requirement; changing a path alone does not change the origin.

WEB-06.02 · Blue · Domain, site, and origin ↗
Record PSL and exceptional-origin context

For production site calculations, use platform or library behavior with appropriate current PSL data. Do not generalize a final-two-label shortcut from this limited example fixture. IPs, localhost, and opaque contexts need their own rules.

WEB-06.02 · Blue · Domain, site, and origin ↗
baseOrigin / baseSite

Two different boundaries for the base address.

WEB-06.02 · Domain, site, and origin ↗
cases.sameOrigin

Equality of normalized HTTP(S) tuples.

WEB-06.02 · Domain, site, and origin ↗
cases.sameSite

Schemeful-site equality using an explicit registrable-domain fixture.

WEB-06.02 · Domain, site, and origin ↗
opaqueComparison

Equal serialization with distinct supplied identities; no browser enforcement.

WEB-06.02 · Domain, site, and origin ↗
Resolution needs a reference and context

The notes link on Duru’s catalogue page is not an absolute address by itself. Its result depends on processing the reference with a base. Given https://books.example/catalog/lesson.html?lang=tr#old, notes resolves to https://books.example/catalog/notes.

WEB-06.03 · Core · URL resolution ↗
The final slash changes the current directory

Bases ending in /catalog/lesson.html and /catalog/lesson/ provide different current directories. The former ends its current directory at /catalog/, yielding /catalog/notes. The trailing slash in the latter yields /catalog/lesson/notes.

WEB-06.03 · Core · URL resolution ↗
Follow root and parent references

/notes is root-relative: it retains the base origin context but ignores the base directory. Either catalogue base produces https://books.example/notes. This root is not a server filesystem root.

WEB-06.03 · Core · URL resolution ↗
Query-only and fragment-only references differ

?lang=en selects a new query while retaining the base scheme, authority, and path. Because the new reference carries no fragment, #old is not retained. The result is https://books.example/catalog/lesson.html?lang=en.

WEB-06.03 · Core · URL resolution ↗
Document bases and the failure boundary

An HTML Document’s base commonly comes from its document context; the first base element with href can instead provide the standard’s frozen base URL. document.baseURI is not guaranteed to match the address bar text in every context. about:blank and srcdoc also have fallback rules.

WEB-06.03 · Core · URL resolution ↗
Identify the context that produced the final URL

Reporting a reference alone omits context: notes can produce different paths under different bases. Record the reference, declared/effective base, and normalized final URL together.

WEB-06.03 · Red · URL resolution ↗
Do not label local failure as network failure

TypeError from an invalid base is neither a transport timeout nor HTTP404. Identify the incomplete stage: without a parsed result there is no destination for request construction.

WEB-06.03 · Red · URL resolution ↗
Treat the base as explicit context data

Make the base source explicit in code using relative references: configuration, Document context, or caller input. Exercise a fixture set with trailing/non-trailing slash bases and root/query/fragment forms.

WEB-06.03 · Blue · URL resolution ↗
Attach evidence to the correct stage

A resolution record is produced by the URL parser: compare href or error type for the same reference and base. Establishing a Document base requires actual Document context; establishing resource loading requires fetch/response observations. A local parser result is not evidence of those other stages.

WEB-06.03 · Blue · URL resolution ↗
cases.reference

Ordinary link reference to resolve.

WEB-06.03 · URL resolution ↗
cases.base

Declared absolute context for this operation.

WEB-06.03 · URL resolution ↗
cases.expectedHref

Serialization to check against the native URL constructor.

WEB-06.03 · URL resolution ↗
invalidBase.destination

Null after failure; no fallback to a previous success.

WEB-06.03 · URL resolution ↗
What agreement does HTTP establish?

Duru opens a note in Atlas library. A browser request communicates the desired operation on a resource; the Atlas Application interprets it and returns a response. HTTP is an application-level protocol. DNS, connections, and TLS support transport without independently deciding a note’s business meaning or Duru’s permissions.

WEB-07.01 · Core · HTTP request and response anatomy ↗
Request: intent, target, and context

The example request-line is GET /notes/atlas-1?view=summary HTTP/1.1. GET expresses the operation, path/query identifies the request target, and HTTP/1.1 identifies syntax version. Origin-form for a direct origin request carries the path and optional query. Host: library.atlas.example supplies authority information; connection context contributes the scheme.

WEB-07.01 · Core · HTTP request and response anatomy ↗
Response: decision, metadata, and content

In the HTTP/1.1 200 OK status-line, the numeric status supplies semantics. The reason phrase is descriptive and should not serve as an application success key. Response headers supply metadata such as Content-Type and Content-Length. After the blank line, Atlas note is this fixture’s content: being ASCII, its 10 characters also occupy 10 bytes.

WEB-07.01 · Core · HTTP request and response anatomy ↗
Prepared at the server does not mean received by the browser

The scene first shows the browser URL, then the request received by the Application, and finally the response received by the browser. Local route selection is not a network packet. Resource state is an in-process instructional fixture rather than an assumed database call.

WEB-07.01 · Core · HTTP request and response anatomy ↗
Protocol input and a trusted decision originate in different places

The request target and client headers are inputs to routing or content negotiation. Serving a protected resource still requires an Application permission decision. Atlas in a URL or Host field does not prove user identity, and 200 alone cannot prove correct access control.

WEB-07.01 · Red · HTTP request and response anatomy ↗
Do not confuse a displayed format with the wire format

A tool can render an HTTP/2 response as readable status/header lines. That useful view is not the protocol parser’s wire format. An incorrect model can misidentify control data or body boundaries across versions.

WEB-07.01 · Red · HTTP request and response anatomy ↗
Read request and response within one exchange

Begin with method, target, status, relevant headers and completeness. Without request context, HEAD or POST 200 content can be misinterpreted. Actual HTTP matching follows the version’s connection/stream rules; application observations must also bind method, target, operation time and observation point to the same exchange. This artifact supplies its request/response pair without defining a custom correlation header.

WEB-07.01 · Blue · HTTP request and response anatomy ↗
Manual reading: mark boundaries before assigning meaning

Mark the first line, each header field, and the CRLF CRLF boundary in the inert pair. State whether the request has a body and identify the response content’s method/status context. Separately note the browser fragment and request-target query.

WEB-07.01 · Blue · HTTP request and response anatomy ↗
http11

Original inert CRLF-delimited request/response, not a replay command.

WEB-07.01 · HTTP request and response anatomy ↗
semanticProjection

H2/3 semantic fields, without binary frames.

WEB-07.01 · HTTP request and response anatomy ↗
browserStatus

Unknown/null without response arrival; never copied from serverPreparedStatus.

WEB-07.01 · HTTP request and response anatomy ↗
selector

Consistency selector for instructional observations only.

WEB-07.01 · HTTP request and response anatomy ↗
A method expresses intent toward a resource

GET requests a current representation; HEAD requests retrieval metadata without transferring its content. POST asks a target to process content according to its own semantics. PUT asks to create or replace known target state using the supplied representation. DELETE asks to remove the association between the target and current functionality; it does not guarantee erasure of every backup byte.

WEB-07.02 · Core · Methods, semantics, and status codes ↗
Safe and idempotent answer different questions

Safe means that the method’s defined intent is read-only. GET, HEAD, OPTIONS, and TRACE are safe. A server may still write access logs; incidental side effects do not alone invalidate that definition. Resource owners must nevertheless avoid executing requested business mutations through safe methods, which automated retrieval and prefetch also use.

WEB-07.02 · Core · Methods, semantics, and status codes ↗
Status classes communicate results, not every underlying fact

1xx supplies interim information; 2xx signals success; 3xx describes redirection or related additional action; 4xx indicates perceived client error; 5xx indicates server error. Read numeric status with method and headers. 201 signals creation; 202 does not promise completed processing. 204 signals fulfillment without additional content.

WEB-07.02 · Core · Methods, semantics, and status codes ↗
Body rules and the browser result

A HEAD response cannot carry content. Content-Length: 10 here describes the 10 bytes that the corresponding GET would have transferred; HEAD’s expected body is zero bytes. If that field is sent for HEAD, it must match the would-be GET content length. A 204 cannot contain content or trailers, and the server cannot send Content-Length; adding Content-Length: 0 is not the correct way to express this rule.

WEB-07.02 · Core · Methods, semantics, and status codes ↗
A read-only label is not an access grant

A confidential note can be retrieved with GET. Safe means the client did not request state mutation; it says nothing about sensitivity or ownership. Checking permissions only on write methods leaves protected reads uncovered.

WEB-07.02 · Red · Methods, semantics, and status codes ↗
Do not turn retry or status into an incorrect acceptance gate

A normal PUT replacement reaches the same desired state. Assuming every POST shares that guarantee, or that 202 means completion, can duplicate a business action or falsely report an unfinished job as completed. Impact depends on application semantics.

WEB-07.02 · Red · Methods, semantics, and status codes ↗
Correlate method, status, and actual state change

Check intended state effects rather than identical response text when assessing idempotence. The artifact records labels before and after two PUT completions. HEAD observations separate wouldBeGetOctets=10 from actualContentOctets=0. These are instructional records, not an access-log standard.

WEB-07.02 · Blue · Methods, semantics, and status codes ↗
Complete the status catalog with the product contract

Compare PUT repetition, HEAD metadata, and 404 public equivalence in the manual exercise. Do not translate 202 into completed, 404 into definitely absent, or 204 into an empty JSON object. Connect results and user-facing messages to the documented application contract.

WEB-07.02 · Blue · Methods, semantics, and status codes ↗
methods.safe / idempotent

Standard method intent, not a guarantee of permission, encryption, or every API implementation.

WEB-07.02 · Methods, semantics, and status codes ↗
put.attempts

Intended state after two replacements with no concurrent writer.

WEB-07.02 · Methods, semantics, and status codes ↗
head.contentLengthField

Would-be GET metadata, not the size of transferred HEAD content.

WEB-07.02 · Methods, semantics, and status codes ↗
privacy404

Different internal states mapped to the same public status/body.

WEB-07.02 · Methods, semantics, and status codes ↗
fetchOutcomes

HTTP outcome, Promise outcome, and business completion kept separate.

WEB-07.02 · Methods, semantics, and status codes ↗
A header is a field; values do not all combine the same way

HTTP fields carry name/value metadata. Field names are case-insensitive: Content-Type and content-type identify the same field. Value interpretation follows that field’s definition; lowercasing every value or joining every repeated field with commas is not a universal rule. Some fields use list syntax, others require a single value; Content-Type is a singleton.

WEB-07.03 · Core · Headers, bodies, and media types ↗
Request body: bytes → format → data → policy

Duru POSTs {"title":"Çay"} to /note-titles. Ç takes two bytes in UTF-8 serialization. The body has 15 Unicode code points but 16 bytes; Content-Length: 16 is calculated from UTF-8 body bytes. JavaScript string.length is not a general byte measure either: it counts UTF-16 code units. Headers and the blank separator are excluded from this length.

WEB-07.03 · Core · Headers, bodies, and media types ↗
A response body is not a mirror of the request

The normal action sets the title to Çay and returns Çay as its result. Although the request uses application/json, the response is Content-Type: text/plain; charset=utf-8. Its content has 3 code points and 4 bytes. Server response format and client processing must agree; response.json() is not the automatic continuation of every successful request.

WEB-07.03 · Core · Headers, bodies, and media types ↗
Framing, content coding, and media format are separate layers

The HTTP/1.1 fixture announces content length using Content-Length and does not use Transfer-Encoding. Chunked transfer coding can delimit messages differently. A content coding such as Content-Encoding: gzip transforms representation data, while Content-Type describes the decoded representation format. With coding, Content-Length normally counts transferred coded octets, not characters in decompressed text.

WEB-07.03 · Core · Headers, bodies, and media types ↗
A format label cannot serve as a trust decision

A client can select Content-Type; a normal endpoint uses it to select appropriate parsing and policy. Trusting that label while skipping schema or resource permissions can give data unintended business effects, depending on action and persistence scope. application/json does not make every field trusted.

WEB-07.03 · Red · Headers, bodies, and media types ↗
Protect byte boundaries and processing context together

Framing Unicode text by character count or comparing coded content with decoded length creates an incorrect completeness assumption. Copying response type from request type can also direct the client to the wrong parser. These confusions can undermine reliability and interpretation of trust boundaries.

WEB-07.03 · Red · Headers, bodies, and media types ↗
Count bytes on the actual serialization

The artifact includes UTF-8 hex, Unicode code point count, and bodyOctets. Compare 15/16 for {"title":"Çay"} with 3/4 for response Çay. Even adding a pretty-print newline changes bytes; a reserialized view may differ from captured content length.

WEB-07.03 · Blue · Headers, bodies, and media types ↗
Check that rejected decisions leave state unchanged

Teaching observations pair accepted with stateChanged. The XPath selects accepted=false alongside stateChanged=true. Normal rows produce zero; a deliberately inconsistent positive fixture produces one. Missing observations indicate an evidence gap rather than correct controls; these are not claimed production log fields.

WEB-07.03 · Blue · Headers, bodies, and media types ↗
requestBodyOctets / requestCodePoints

UTF-8 bytes and Unicode code points are different measures: 16/15 in the fixture.

WEB-07.03 · Headers, bodies, and media types ↗
parserCalled / schemaValid

Supported format is separate from syntax parsing and schema evaluation.

WEB-07.03 · Headers, bodies, and media types ↗
responseContentType

The response can be text/plain despite an application/json request.

WEB-07.03 · Headers, bodies, and media types ↗
afterTitle

Commit only after acceptance gates pass; both rejections retain Draft.

WEB-07.03 · Headers, bodies, and media types ↗
requestUtf8Hex

Inert UTF-8 body-byte representation, not parser or execution instructions.

WEB-07.03 · Headers, bodies, and media types ↗
Which bytes does Content-Length count?

Atlas returns Çay for GET /tea-label. UTF-8 identity representation has 3 code points and 4 bytes. Content-Length: 4 in HTTP/1.1 gives the expected content octet length, excluding start-line, headers, and separator bytes. A receiver must have the content octets required by framing before treating the message as complete.

WEB-07.04 · Core · Framing, compression, and negotiation ↗
Chunked discovers the content boundary incrementally

Transfer-Encoding: chunked carries HTTP/1.1 content in size-prefixed chunks. Sizes are hexadecimal octet counts, not character counts. This fixture has two valid chunks: Ç occupies 2 UTF-8 bytes and ay another 2. A zero-sized last chunk and empty trailer section finish it. Dechunking produces 4 content bytes; size lines and CRLF wrappers are not content.

WEB-07.04 · Core · Framing, compression, and negotiation ↗
Content-Encoding changes bytes representing the same meaning

Content-Type: text/plain; charset=utf-8 describes decoded representation format. Content-Encoding: gzip declares the need to decode gzip first. This illustration obtains 24 coded bytes, removes gzip, then interprets 4 UTF-8 bytes. Layer order does not require buffering the whole body; a streaming implementation can apply it incrementally. A media parser cannot treat gzip bytes directly as Çay.

WEB-07.04 · Core · Framing, compression, and negotiation ↗
Preferences, selection, and cache reuse

Accept supplies media preferences; Accept-Encoding supplies content-coding preferences. Relative q weights express preference, with q=0 meaning unacceptable and omitted q meaning 1. Server selection uses available variants and policy. Preferences are neither permission lists nor a guaranteed response contract.

WEB-07.04 · Core · Framing, compression, and negotiation ↗
Conflating two lengths creates an incorrect boundary

A normal coded response has Content-Length=24 while decoded text occupies 4 bytes. Comparing decoded size with transferred content size produces incorrect completeness or limit decisions. Chunk-wrapper overhead must also stay separate from content size; real stacks process these layers at different stages.

WEB-07.04 · Red · Framing, compression, and negotiation ↗
Keep negotiated variants within the correct cache scope

One target can select different representations for acceptable coding or media contexts. An incorrect selecting-field inventory can contribute to incompatible cache reuse, with impact depending on the concrete cache and recipient. Client metadata such as Accept or User-Agent is not access-control evidence.

WEB-07.04 · Red · Framing, compression, and negotiation ↗
Compare content after removing the appropriate layers

In the manual exercise, distinguish gzip hex from decoded UTF-8 hex and match Content-Length to coded size. Match each chunk size with data bytes, then remove wrappers to recover the same Çay bytes. Equal text does not imply byte-for-byte equality of complete HTTP messages.

WEB-07.04 · Blue · Framing, compression, and negotiation ↗
Selecting values and missing evidence

Reuse rows compare two Accept-Encoding contexts: a stored gzip request and an identity request do not have matching selecting values when Vary includes that field. Compare actual old/new values for each field, including absence. Origin revalidation is supplied false in this example.

WEB-07.04 · Blue · Framing, compression, and negotiation ↗
gzip.codedOctets / decodedOctets

Native local gzip is 24 bytes, decoded UTF-8 4, excluding full HTTP-message overhead.

WEB-07.04 · Framing, compression, and negotiation ↗
chunked.bodyWireOctets

Valid wrapper included: 19 bytes; dechunked content: 4 bytes.

WEB-07.04 · Framing, compression, and negotiation ↗
variants

Explicit server selection, media, coding, and framing decisions.

WEB-07.04 · Framing, compression, and negotiation ↗
cacheReuseRows

Only Vary selecting-value matching, not an actual cache store.

WEB-07.04 · Framing, compression, and negotiation ↗
A redirect asks the client to select another resource

Duru submits the Atlas title form as POST /note-titles with {"title":"Çay"}. The normal branch applies the action and returns 303 See Other with Location: /notes/atlas-1. The browser resolves Location against the current URL and retrieves the result using GET. This second request does not repeat title submission; it retrieves the created note representation. The artifact separates both requests and the intervening redirect response.

WEB-07.05 · Core · Redirects, connections, and stateless HTTP ↗
Referer and User-Agent provide context rather than identity

Referer retains its historical single-r field spelling, while Referrer-Policy is a different field. Referer can partially describe the initiating page. Policy and navigation context can omit it, reduce it to an origin, or include path/query; fragments and user information are excluded. Its absence alone proves neither malice nor direct navigation.

WEB-07.05 · Core · Redirects, connections, and stateless HTTP ↗
Host describes the intended authority

An origin server can serve several virtual hosts on the same address. HTTP/1.1 Host carries target host/port information to select relevant resources. HTTP/2–3 can use :authority for that control-data role. A connection address and TLS server-identity verification are different layers; URL, Host, and certificate are not one object.

WEB-07.05 · Core · Redirects, connections, and stateless HTTP ↗
Connection persistence preserves transport resources between messages

HTTP/1.1 can use persistent connections by default. After a complete exchange, the same connection can carry another; Connection: close indicates that persistence ends after the current response. Reuse depends on understood message boundaries and consumed prior bodies. Connections can also close asynchronously, with API pools applying their own policies.

WEB-07.05 · Core · Redirects, connections, and stateless HTTP ↗
Stateless request semantics and a stateful application

HTTP statelessness means each request’s semantics can be understood in its own context. It does not forbid resource databases, session stores, caches, or audits from retaining state. Resending a cookie/session reference and evaluating it against trusted server state/policy provide application continuity.

WEB-07.05 · Core · Redirects, connections, and stateless HTTP ↗
Control redirect destinations and action intent together

A normal 303 moves from a completed submission to a read-only result; 307 moves a pending POST to a new endpoint. Wrong method assumptions can duplicate actions or process an incorrect target. A redirect status alone does not say whether an action has applied; the fixture explicitly supplies the server decision state.

WEB-07.05 · Red · Redirects, connections, and stateless HTTP ↗
Do not substitute client metadata or a connection for identity

Referer, User-Agent, and Host supply context, not authenticated subjects. Accepting a protected request solely because its connection succeeded before places trust at the wrong boundary. Impact depends on the protected read/action given incorrect authority.

WEB-07.05 · Red · Redirects, connections, and stateless HTTP ↗
Read a redirect chain with methods and content

Mark the initial request, redirect status/Location, and follow-up request separately. The normal branch applies one POST then follows with GET and null content; 307 initially applies no action, then preserved POST completion makes the count one. Equal final 200 statuses do not mean equal intermediate processing.

WEB-07.05 · Blue · Redirects, connections, and stateless HTTP ↗
Separate connection events from session decisions

A conn-a closed observation describes transport state; SESSION_REF_ALIAS active describes logical session state. The close branch shows both can simultaneously differ and does not invent a logout request. Eligibility on the later request is a local supplied trusted-result assumption.

WEB-07.05 · Blue · Redirects, connections, and stateless HTTP ↗
redirectRows

Initial exchange, follow-up, and action counts kept separate; not a measured trace.

WEB-07.05 · Redirects, connections, and stateless HTTP ↗
redirectMethodMatrix

Fetch behavior distinguished from general HTTP optional POST rewrite qualifications.

WEB-07.05 · Redirects, connections, and stateless HTTP ↗
requestContext

Supplied Host/UA and no-referrer context do not establish identity.

WEB-07.05 · Redirects, connections, and stateless HTTP ↗
connectionSession

Close changes transport state; an active session and fresh request policy remain distinct.

WEB-07.05 · Redirects, connections, and stateless HTTP ↗
HTTP/1.0 as a historical baseline

When Duru’s Atlas client retrieves a note, HTTP/1.0 still carries a method, target, status, and representation metadata. RFC 1945 is an Informational document from May 1996, used here to explain historical behavior rather than define current HTTP/1.1 parser requirements.

WEB-08.01 · Core · HTTP/1.x connections and framing ↗
A byte stream is not a message boundary

TCP delivers ordered bytes, but a socket read need not equal an HTTP message. One read can contain half a header, one message, or several messages together. HTTP/1.1 determines framing from the start-line, CRLF-delimited fields, blank separator, and method/status context.

WEB-08.01 · Core · HTTP/1.x connections and framing ↗
Persistence permits reuse after completion

HTTP/1.1 can keep a connection persistent by default. The normal branch carries two exchanges on conn-h1 and leaves it open after both responses complete. Adding Keep-Alive is not a prerequisite for this default. Explicit close, peer policy, or transport events can end reuse.

WEB-08.01 · Core · HTTP/1.x connections and framing ↗
Pipelining retains response order

A client can send its second request without waiting for the first response: pipelining. Responses on that byte stream must follow received-request order. Safe requests can be processed in parallel, but their content cannot be arbitrarily interleaved without stream identifiers.

WEB-08.01 · Core · HTTP/1.x connections and framing ↗
A wrong boundary produces a wrong exchange interpretation

Treating a socket read as a complete message can fail under normal fragmentation or coalescing. The condition is conflating TCP delivery units with HTTP framing; impact can include associating a response with the wrong resource.

WEB-08.01 · Red · HTTP/1.x connections and framing ↗
Queues and authorization consume different resources

B waits here because A must precede it, not because B is forbidden. Connections and pending responses consume resources, but every delay is not hostile: upstream delay, application work, and ordinary scheduling can expose similar wait states.

WEB-08.01 · Red · HTTP/1.x connections and framing ↗
Record order and completeness in one ledger

Assign instructional A/B order aliases to requests and count response content bytes against declared lengths. These aliases are not HTTP/1.1 stream identifiers; correlation uses request order. Mark the next message starting after each response’s final byte.

WEB-08.01 · Blue · HTTP/1.x connections and framing ↗
Interpret closure in framing context

In the historical branch, receiving four content bytes does not yet end an EOF-delimited response. The supplied closure establishes its boundary and removes connection reuse. Drawing closure as application logout or resource deletion would invent another mechanism.

WEB-08.01 · Blue · HTTP/1.x connections and framing ↗
preparedOrder / deliveredOrder

Server preparation and client arrival are distinct orders.

WEB-08.01 · HTTP/1.x connections and framing ↗
contentOctets / messageOctets

Content-Length counts content; the full message also contains headers.

WEB-08.01 · HTTP/1.x connections and framing ↗
http10.completeBeforeClose

EOF-delimited completeness is false before the supplied close.

WEB-08.01 · HTTP/1.x connections and framing ↗
HTTP semantics remain while message transport changes

Duru requests /atlas-notes and /tea. HTTP/2 retains GET and 200 semantics but uses pseudo-header control data and binary frames rather than textual request/status-lines. Readable :method, :scheme, :authority, :path, and :status are not literal HTTP/1.1 start-lines.

WEB-08.02 · Core · HTTP/2 streams, frames, and HPACK ↗
Multiplexing ties response order to each stream

The server splits stream 1’s Atlas note into DATA carrying Atlas plus a space, then note: 6 and 4 bytes. Stream 3’s four-byte Çay frame interleaves between them. Stream 3 completes first using END_STREAM; stream 1’s final bytes arrive later. HTTP/1.1’s response-order queue no longer imposes that same completion order.

WEB-08.02 · Core · HTTP/2 streams, frames, and HPACK ↗
Frame headers and content lengths are measured separately

An HTTP/2 frame has a fixed nine-octet header: a 24-bit payload Length, Type, Flags, and a reserved bit plus 31-bit Stream Identifier. Length excludes those nine bytes. The artifact uses DATA=0, END_STREAM=1, payloadLength=4, and stream 3; adding UTF-8 Çay produces a 13-byte fragment.

WEB-08.02 · Core · HTTP/2 streams, frames, and HPACK ↗
HPACK maintains shared field context between peers

HPACK compresses field sections rather than bodies, using static and dynamic tables plus literals. The static table has 61 entries: :method GET at 2, :path / at 4, :scheme https at 7, and :status 200 at 8. Indexed encoding reuses a name/value pair; string literals can also use static Huffman coding.

WEB-08.02 · Core · HTTP/2 streams, frames, and HPACK ↗
Transport state is not subject state

Streams 1 and 3 distinguish exchanges; their shared connection does not mean authorization ran once for everything. The failure condition is substituting stream IDs or reuse for trusted subject/resource policy. Impact depends on which protected response is associated with an incorrect subject.

WEB-08.02 · Red · HTTP/2 streams, frames, and HPACK ↗
Compression and multiplexing retain resource limits

Resolving a dynamic index without current context produces a different field, potentially misleading routing, caching, or policy analysis. Decoder state, direction, and field-block order must be known together; the last hex byte alone is insufficient.

WEB-08.02 · Red · HTTP/2 streams, frames, and HPACK ↗
Reassemble a frame ledger by stream

Separate the header projections for streams 1 and 3, then assemble DATA by stream ID. Even with arrival order DATA1(6), DATA3(4), DATA1(4), outputs are Atlas note and Çay. Concatenating every arrival into one body would correlate them incorrectly.

WEB-08.02 · Blue · HTTP/2 streams, frames, and HPACK ↗
Expose wait reasons and compression context

The window branch has stream credit 2, connection credit 10, and four pending content bytes. The smaller credit bounds DATA progress; a peer update changes sender credit only after arrival. Sending then subtracts the used amount from both windows, and ready does not mean sent.

WEB-08.02 · Blue · HTTP/2 streams, frames, and HPACK ↗
dataFrames

Valid DATA fragments: Length counts payload; the header adds 9 bytes.

WEB-08.02 · HTTP/2 streams, frames, and HPACK ↗
hpack.operations

Newest-first indices in the current shared directional context.

WEB-08.02 · HTTP/2 streams, frames, and HPACK ↗
flow / tcpGap

Peer-credit wait differs from ordered TCP-delivery wait.

WEB-08.02 · HTTP/2 streams, frames, and HPACK ↗
QUIC transport and the HTTP/3 application mapping

HTTP/3 maps common HTTP semantics onto QUIC, a UDP-based secure connection transport. It is not HTTP/2 headers placed into UDP datagrams. Handshakes, reliable stream delivery, flow control, and packet protection belong to transport, while HTTP supplies method/status/media semantics.

WEB-08.03 · Core · HTTP/3 and QUIC ↗
Request streams and per-stream delivery

Client-initiated bidirectional HTTP/3 streams carry requests and responses: first 0, then 4 and 8. Unlike HTTP/2, 0 can be a request stream here. Control and QPACK encoder/decoder functions use separate unidirectional streams; stream-number meanings cannot be copied blindly between versions.

WEB-08.03 · Core · HTTP/3 and QUIC ↗
An HTTP/3 frame is not a QUIC packet or STREAM frame

An HTTP/3 frame encodes Type and Length as QUIC variable-length integers, followed by payload. There is no stream ID in its header because the bytes already belong to a QUIC stream. HTTP/2’s fixed nine-byte header and END_STREAM flag do not apply; completion relates to the underlying stream ending.

WEB-08.03 · Core · HTTP/3 and QUIC ↗
QPACK adds field dependencies across independent streams

HPACK relies on ordered field-block context updates. Since QUIC delivers streams independently, HTTP/3 uses QPACK: an encoder stream carries table instructions while encoded field sections reference that state. Encoder/decoder feedback uses separate unidirectional streams; a HEADERS frame does not ensure its table insertion already arrived.

WEB-08.03 · Core · HTTP/3 and QUIC ↗
Do not substitute secure transport for HTTP permission

QUIC connection security supplies peer and packet-protection context rather than deciding a GET’s tenant-resource permission. Substituting an established secure connection or valid stream for subject authorization can associate protected content with the wrong context.

WEB-08.03 · Red · HTTP/3 and QUIC ↗
Independent delivery does not permit unlimited buffering

Stream tails can remain buffered until earlier bytes arrive, while QPACK field sections wait for insertions. These dependencies are different but both retain memory/work. Waits can arise from ordinary loss, reordering, scheduling, or backpressure rather than malice.

WEB-08.03 · Red · HTTP/3 and QUIC ↗
Mark three distinct boundaries

Separate QUIC packet delivery, ordered stream data, and HTTP/3 frame interpretation. Artifact offsets are relative to an illustrated suffix; do not export them as real STREAM Offset fields. Stream 0 can have received tail bytes while its usable prefix remains zero.

WEB-08.03 · Blue · HTTP/3 and QUIC ↗
Separate QPACK arrival from decoding

Record Required Insert Count and current Insert Count in the dependency branch. With 1>0, stream 0 waits; independent stream 4 satisfies 0<=0. Encoder-instruction arrival initially means bytes received, while local processing increments current count.

WEB-08.03 · Blue · HTTP/3 and QUIC ↗
streamSuffixes.frames

HTTP/3 DATA fragments without QUIC packet/protection headers.

WEB-08.03 · HTTP/3 and QUIC ↗
offsetWithinSuffix

Local teaching coordinate rather than an absolute QUIC STREAM offset.

WEB-08.03 · HTTP/3 and QUIC ↗
requiredInsertCount / insertCount

Dynamic-reference prerequisite and decoder’s current insertion count.

WEB-08.03 · HTTP/3 and QUIC ↗
decoderFeedbackRequired

Feedback requirement after dynamic-reference decoding; exchange is outside scope.

WEB-08.03 · HTTP/3 and QUIC ↗
Identify the question that stays the same

Duru requests /tea?view=plain on library.atlas.example using GET. In the example Atlas selects a text/plain representation and returns Çay. The selected method, target, request preference, status, and representation data can stay identical across versions. Three cards show alternative forms of this exchange rather than one request passing through three servers in sequence.

WEB-08.04 · Core · One request across three HTTP transports ↗
Map lines to control data

The direct-origin HTTP/1.1 view has a GET /tea?view=plain HTTP/1.1 request-line and a Host field. HTTPS connection context supplies the scheme in this example. CRLF CRLF ends the header section. The response status-line supplies 200, Content-Type supplies format, and Content-Length counts content octets. Çay has three characters and four UTF-8 bytes; the artifact uses one consistent byte calculation.

WEB-08.04 · Core · One request across three HTTP transports ↗
Equivalent context does not mean identical bytes

HTTP/2 uses HTTP streams over TCP and HPACK context for field sections. HTTP/3 maps the same HTTP intent to QUIC streams with different QPACK state/dependency rules. An identical decoded field list can use literals in one context and references to earlier entries in another. Equal fields therefore establish neither equal compressed bytes nor equal total wire size.

WEB-08.04 · Core · One request across three HTTP transports ↗
Revisit the trust boundary when the format changes

A gateway can translate a decoded request into a different protocol. Its task is to preserve method, target, and field meaning rather than convert client-selected authority text into trusted identity. The public tea example has a simple business decision. With a protected note, the Application still decides which user can perform which action.

WEB-08.04 · Red · One request across three HTTP transports ↗
Do not treat compression state as a portable credential

A dynamic-table reference depends on decoder state for that connection and direction. A tool can display decoded accept while hiding the table that resolved its reference. HTTP/2 and HTTP/3 share pseudo-header names without sharing a codec; this lesson does not claim one protocol’s bytes are valid input to the other parser.

WEB-08.04 · Red · One request across three HTTP transports ↗
Check manually using a mapping ledger

Separate browserUrl, target, and fragment in the artifact. Map the H1 request-line to H2/H3 :method and :path, Host to :authority, and HTTPS context to :scheme. Mark numeric response status, media type, and content bytes separately. The absence of the H1 OK text in the other cards is not a semantic loss.

WEB-08.04 · Blue · One request across three HTTP transports ↗
Keep evidence proportional to what was observed

A useful manual conclusion is: common semantic fields match; wire bytes were not displayed. The cards cannot establish compression ratio, latency, or browser protocol selection. Real capture analysis needs the negotiated version, decoder context, and exchange completion together.

WEB-08.04 · Blue · One request across three HTTP transports ↗
commonRequest

Semantic comparison fields; the fragment is excluded from the target.

WEB-08.04 · One request across three HTTP transports ↗
http11

Valid CRLF text syntax with scheme supplied by connection context.

WEB-08.04 · One request across three HTTP transports ↗
requestFieldsProjection

Decoded pseudo-headers and ordinary fields, not compressed wire bytes.

WEB-08.04 · One request across three HTTP transports ↗
contentOctets

Four UTF-8 bytes for Çay, not a whole-message or frame size.

WEB-08.04 · One request across three HTTP transports ↗
An intermediary takes two roles in the same program

An HTTP intermediary can be a server receiving a request on one connection and a client sending a request on the next. When the Atlas browser requests GET /notes, a CDN or reverse proxy may create a new message for the application, answer from cache, or stop under normal policy. “In the middle” explains neither routing role nor TLS plaintext access by itself; draw connection and message boundaries separately.

WEB-09.01 · Core · Proxy roles and forwarded context ↗
A forward proxy is chosen by the client

A forward proxy is an intermediary chosen through the client’s configuration or policy. The client knows which origin resource it wants; the proxy mediates access to that target. Ordinary HTTP forwarding uses absolute-target information. For HTTPS, a CONNECT tunnel can carry subsequent bytes without terminating TLS; a tunnel does not imply the proxy can read the enclosed HTTP body.

WEB-09.01 · Core · Proxy roles and forwarded context ↗
A reverse proxy is selected on the service side

A reverse proxy acts as a gateway answering the client on behalf of an origin service. An Atlas user requests notes.example.org; service configuration chooses app.example.org upstream. Load balancing, caching, and routing may be present, but the role does not require every feature. A CDN can perform a reverse-proxy role; the CDN and proxy labels do not imply one TLS endpoint or one trust decision.

WEB-09.01 · Core · Proxy roles and forwarded context ↗
The word transparent does not prove plaintext access

In modern HTTP semantics, an interception proxy receives redirected network flows without being selected by the client; transparent is often used in that sense. Obsolete RFC2616 instead defined a transparent proxy by not changing messages beyond necessary proxy processing; its semantically transparent cache preserves response semantics. Those historical uses do not replace the current interception definition. State which meaning applies rather than forcing both into one definition. The interception role does not automatically mean TLS termination either.

WEB-09.01 · Core · Proxy roles and forwarded context ↗
A forwarded message carries its own hop context

An intermediary need not blindly clone the received message. For HTTP/1.1 forwarding, it removes Connection and fields named by it as connection-specific before forwarding to the next hop; some protocol versions prohibit such fields altogether. Via communicates intermediary protocol information, while Forwarded is a separate extension for client-facing context parameters. Matching their positions does not establish one certain topology.

WEB-09.01 · Core · Proxy roles and forwarded context ↗
Provenance for Forwarded and X-Forwarded-*

X-Forwarded-For, X-Forwarded-Proto, and X-Forwarded-Host are common conventions, not one standard syntax or necessarily identical hop lists. Forwarded provides standardized element grouping; separate X-Forwarded-* lists cannot always be converted without loss when their insertion order is unknown. Neither format independently proves identity. An IP address or the word https inside a header does not establish an authenticated peer.

WEB-09.01 · Core · Proxy roles and forwarded context ↗
The assumption that turns context into identity

A parseable Forwarded field does not prove correct provenance. The direct peer and the client described in the field are separate observations; NAT, proxy pooling, and privacy aliases also prevent treating them as one person. The broken assumption is using client-originated context as server-authoritative identity. This model needs no particular hostile value: a provenance class alone distinguishes the trust decision.

WEB-09.01 · Red · Proxy roles and forwarded context ↗
Hop order does not prove the whole route

Forwarded elements preserve the order of participating writers, but omit hops that do not write the field. Equating the first listed address with the actual client requires a defined first trusted observation and treatment of older untrusted prefixes. Atlas selects reset/reconstruction at the edge, so its bounded two-element provenance is explicit; this does not establish a general first-address rule for arbitrary Internet chains.

WEB-09.01 · Red · Proxy roles and forwarded context ↗
The privacy and retention impact of context

A client endpoint can help diagnostics without being a user identity, and may be privacy-sensitive. Retaining a full for-address across every internal hop and log is not required merely because the chain is trusted. Atlas’s privacy branch selects a per-request obfuscated alias at the first writer and makes no IP inference. The alias is neither a stable tracking identity nor an authorization principal.

WEB-09.01 · Red · Proxy roles and forwarded context ↗
One reconstruction policy at the owned edge

The inspected record is a typed ledger of the example edge/proxy operations, not a live proxy log. edgeOutbound and proxyOutbound identify each writer’s appended element; cases record the application peer-gate outcome. The privacy branch reveals _atlasOnce without allowing recovery of the omitted IP. Document the edge’s accepted public-authority mapping, observed incoming scheme, and source for the direct client endpoint. Remove incoming external context from the normal request and reconstruct approved fields from the edge’s own observations. This is not a policy of deleting all unknown HTTP fields or arbitrarily changing client message semantics. One explicit compatibility contract for Forwarded and legacy X-Forwarded-* reduces conflicting interpretations.

WEB-09.01 · Blue · Proxy roles and forwarded context ↗
Regression should observe provenance decisions

Edge reconstruction, proxy append, and application context acceptance are separate local actions in the normal case. A completed message transfer updates receiver receipt state; acceptance occurs only at the later local gate. The unapproved-peer branch brings a normal typed request to the application but refuses derived context because the trust conjunction is false. Network receipt, syntax, and policy trust do not fit into one success field.

WEB-09.01 · Blue · Proxy roles and forwarded context ↗
Preserve forwarding compatibility and privacy

The selected inert HTTP/1.1 message uses the reserved Connection option close for the current hop. Its outbound message removes that field while preserving GET and /notes. This canonical example does not resolve every framing or field-parsing edge case; in particular it does not treat the same Connection field as valid in HTTP/2 or HTTP/3. Gateway authority mapping is separate configuration, not unlimited rewriting permission for a client-selected proxy.

WEB-09.01 · Blue · Proxy roles and forwarded context ↗
roles

Role selection does not guarantee plaintext access.

WEB-09.01 · Proxy roles and forwarded context ↗
forwardedElements

Participating writers appear left to right; each element describes its own incoming context.

WEB-09.01 · Proxy roles and forwarded context ↗
cases

A conjunction of approved peer, topology, transport, and reconstruction; user permissions remain separate.

WEB-09.01 · Proxy roles and forwarded context ↗
Who is the copy stored for?

Duru opens the same public tea page again. A browser HTTP cache can be a private cache for one user, while a shared proxy or CDN serves multiple clients. Service Worker Cache Storage is a separate API/store; this lesson examines HTTP-cache decisions. Shared does not mean every representation is suitable for every user.

WEB-09.02 · Core · Browser and shared HTTP caches ↗
Where does the age clock start?

The artifact has Date 00:00:00, request_time 00:00:08, response_time 00:00:10, and received Age 12 seconds on the same synthetic UTC day. apparent_age=max(0,10−0)=10, response_delay=10−8=2, and corrected_age_value=12+2=14. This fixture selects conservative corrected_initial_age=max(10,14)=14. The RFC also permits corrected_age_value itself; the max form is not presented as the only mandatory formula for every implementation.

WEB-09.02 · Core · Browser and shared HTTP caches ↗
Three directives make different decisions

Unqualified private prevents a shared cache from storing the response; a private browser cache can store it if other rules allow. It is neither content encryption nor session isolation. Unqualified no-cache permits storage but requires forwarding to the origin and successful validation before reuse, even when age is below the freshness lifetime.

WEB-09.02 · Core · Browser and shared HTTP caches ↗
Fresh does not establish the correct user

An account summary can have been generated seconds ago and still violate policy if stored in a shared cache. Correct age arithmetic verifies neither identity, permissions, nor representation selection. The failure condition is classifying a personalized response like public tea and reducing reuse eligibility to time alone.

WEB-09.02 · Red · Browser and shared HTTP caches ↗
Do not substitute policy names for each other

Interpreting no-cache as never store, private as encrypted, and no-store as delete history creates three different incorrect acceptance rules. Reusing a fresh no-cache entry without validation is wrong; a private entry in a private cache is not itself a violation. An older copy surviving a later no-store response illustrates the absence of a retroactive purge.

WEB-09.02 · Red · Browser and shared HTTP caches ↗
Recalculate the timing ledger

The example calculator produces the timing ledger; a synthetic observation fixture supplies validationRequired/validated/reused rows. These are not real cache logs. A public hit sends no request to the origin; origin evidence in private/no-cache branches exists only after that message arrives. A missing response or reuse record cannot prove correct behavior. Begin the manual exercise by finding Date, request_time, response_time, received Age, and now. Calculate apparent age and response delay independently and explain the selected conservative initial age of 14. Record resident_time and current_age at now 20 and 26 separately rather than copying a single Age header.

WEB-09.02 · Blue · Browser and shared HTTP caches ↗
Define separate acceptance criteria for storage and reuse

For the public branch, expect an eligible fresh copy to be served without reaching the origin. For private, check shared store false and browser store true. In no-cache, note that storage is allowed but reuse requires completed origin validation. In no-store, the new response is not stored and there is no general purge guarantee for earlier entries.

WEB-09.02 · Blue · Browser and shared HTTP caches ↗
clock

Response age from origin/cache transit and local residence, not business modification time.

WEB-09.02 · Browser and shared HTTP caches ↗
publicPolicy

Private60/shared30 for the same age; equality makes shared freshness false.

WEB-09.02 · Browser and shared HTTP caches ↗
policies

Separate storage, validation, and reuse decisions.

WEB-09.02 · Browser and shared HTTP caches ↗
priorEntryInLedgerRetained

Instructional state that does not assume no-store automatically erases earlier entries.

WEB-09.02 · Browser and shared HTTP caches ↗
An ETag describes a representation observation

Duru has stored the Çay body with ETag: "atlas-v1" metadata. This opaque value validates the current selected representation; it is not a password, object-owner ID, or permission. Clients need not know its generation method and should not infer timestamps or identity from v1. The instructional names merely make revisions easy to read.

WEB-09.03 · Core · ETags and conditional requests ↗
Conditional GET: can the earlier body still be used?

Duru sends GET with If-None-Match: W/"atlas-v1". With current tag "atlas-v1", weak comparison matches: the none-match condition is false and 304 replaces normal GET content. If-None-Match uses weak comparison for GET/HEAD; listing a strong tag does not select strong comparison. A false matching condition on other methods produces 412.

WEB-09.03 · Core · ETags and conditional requests ↗
If-Match: write against an earlier state

Duru prepared a benign note edit against v1 while the origin now has v2. If-Match: "atlas-v1" makes PUT conditional on a strong match with the current tag. After the supplied normal request/permission checks pass, the precondition is evaluated before applying the method. This fixture chooses 412, applies no update, and retains v2.

WEB-09.03 · Core · ETags and conditional requests ↗
Do not substitute a validator for permission

An ETag can appear in a public response. Knowing it grants no right to change a resource; If-Match compares an observed representation state with current state. The failure condition is treating a matching tag as authentication or object permission. A correct precondition cannot repair an incorrect user policy.

WEB-09.03 · Red · ETags and conditional requests ↗
Keep metadata and body associated

A bodyless 304 does not ask the cache to delete Çay. Failure conditions include updating all URL copies without matching context, clearing retained content, or associating new200 content with old v1 metadata. Effects include wrong displays and incorrect future validation; privacy impact depends on the selected representation.

WEB-09.03 · Red · ETags and conditional requests ↗
Keep two byte counts for 304

The origin fixture produces response304 and changed200; the local-cache ledger produces storedBefore and storedAfter304. PUT separates requestedBody from methodApplied/afterBody. Zero origin-content bytes do not erase four retained cached bytes, and a request body does not prove a write. Correlate byte counts and state results across their distinct producers. storedBefore contentOctets=4 and response304 actualContentOctets=0 are different observations. Find the new Date and Cache-Control, then confirm storedAfter still contains Çay. Empty response content was not written as a replacement body. Header updates occur inside the browser cache rather than transferring new origin content.

WEB-09.03 · Blue · ETags and conditional requests ↗
Apply the precondition table manually

For the same strong pair, record strong/weak true; with a weak side, strong false/weak true; with different opaque values, both false. Then apply the header logic: a match makes If-None-Match false but If-Match true. Finding a match is not the same statement as applying the requested method.

WEB-09.03 · Blue · ETags and conditional requests ↗
comparisonRows

Opaque comparison results; precondition truth is determined separately.

WEB-09.03 · ETags and conditional requests ↗
response304 / storedAfter304

Origin content0; matching stored body4 is retained while Date/policy update.

WEB-09.03 · ETags and conditional requests ↗
changed200

New tag/body replace together; the old copy does not match.

WEB-09.03 · ETags and conditional requests ↗
put412

Normal checks passed and duplicate false are supplied; the failed strong guard applies no method.

WEB-09.03 · ETags and conditional requests ↗
Which server does Duru connect to?

Let the public Atlas catalog URL use books.example. In the selected architecture, Duru connects to a CDN edge as the server peer rather than to the Atlas application process. Delivery introduces another owner without changing the URL’s public authority. A CDN distributes content from multiple locations; the single edge in this diagram does not depict that entire network.

WEB-09.04 · Core · CDN, edge, and origin relationships ↗
Separate the origin role from a machine name

The Atlas origin produces the canonical public catalog representation in this example. Being the source of a response and being every Browser request’s direct socket peer are different roles. An origin might be one process, applications behind a load balancer, or another owned service; this fixture uses one logical origin supplying revision v1.

WEB-09.04 · Core · CDN, edge, and origin relationships ↗
MISS: two exchanges and three owners

The first branch starts with an empty edge cache. Duru prepares GET /catalog; after receipt, the edge finds no matching response. It prepares its own outbound GET and sends it to the origin. The origin prepares the public Atlas catalog body and cache metadata. Preparation is local; only arrival at another actor is drawn as a wire.

WEB-09.04 · Core · CDN, edge, and origin relationships ↗
HIT: an idle origin matters

The second branch begins with a reusable public v1 entry for the selected key. The edge prepares a response from that local entry and sends no new request to the origin. An origin card remaining “not contacted” is meaningful: it shows where the data flow ends early. The public body received by the Browser is not the result of a new origin execution in this branch.

WEB-09.04 · Core · CDN, edge, and origin relationships ↗
Keep personal responses out of public entries

The third branch selects Duru’s harmless /notes/mine representation. This fixture classifies that route as shared-cache bypass before lookup, and the origin response carries no-store. The edge relays the response without writing a public cache entry. The Duru/Atlas context is supplied as allowed; this is not a real login or permission-enforcement test.

WEB-09.04 · Core · CDN, edge, and origin relationships ↗
Each TLS hop has its own trust boundary

For a TLS-terminating edge, Browser-to-edge and edge-to-origin are separate trust boundaries. Securing the first hop alone does not establish encryption or peer verification on the second. Cloudflare Full (strict) documentation is a vendor example of separately applied origin certificate verification; this lesson changes no Cloudflare settings.

WEB-09.04 · Core · CDN, edge, and origin relationships ↗
Ask which owner supplied a body

During review, do not equate the response Duru observes with an origin access-log event. A public HIT can produce no origin request at all. Edge requests, origin requests, and Browser observations need distinct correlation boundaries. The ledger’s originContacted boolean belongs to this selected fixture; it is not a real log field or vendor header name.

WEB-09.04 · Red · CDN, edge, and origin relationships ↗
First-hop success does not validate the entire chain

If the edge already holds the public body, a successful Browser response does not establish current origin health or reachability. A failed MISS does not measure an outage of the entire CDN network either. Keep the review question precise: which hop ran for this request, which owner decided, and what state was observed?

WEB-09.04 · Red · CDN, edge, and origin relationships ↗
Write an explicit public-delivery contract

The example edge adapter produces cache decisions/key membership; the origin server produces its call counter. independentSequence correlates both records before and after each request: MISS 0→1, HIT 1→1 and BYPASS 1→2. A HIT creates no origin-request event; a missing log in another trace does not prove the same decision. For Atlas, define two route classes: reusable public catalog and personal note with bypass and no-store. This is an example policy, not automatic extension guessing. Body and cache metadata derive from the same classification. A changed public freshness lifetime or key should change the corresponding fixture expectation.

WEB-09.04 · Blue · CDN, edge, and origin relationships ↗
Check behavior at ownership boundaries

An independent observation expects one origin request for the first catalog MISS, no additional origin request for the second catalog HIT, and one additional origin request for a personal GET. The personal response must not change cache state. Body equality alone does not prove a HIT; combine it with the origin-call count and decision record.

WEB-09.04 · Blue · CDN, edge, and origin relationships ↗
selectedKey

Local cache key selected only for the public catalog; not a parser for all HTTP cache-key rules.

WEB-09.04 · CDN, edge, and origin relationships ↗
originContacted

Whether this request performs an outbound origin exchange; equal bodies alone do not establish it.

WEB-09.04 · CDN, edge, and origin relationships ↗
originCallsBefore / After

Expected counter for the independent selected sequence; not a benchmark or production log field.

WEB-09.04 · CDN, edge, and origin relationships ↗
routeClass

The personal response bypasses shared lookup first and is relayed with no-store.

WEB-09.04 · CDN, edge, and origin relationships ↗
Which requests does a cache key consider equivalent?

Atlas can show its public catalog in Turkish and English. Two requests can use the same URL while selecting different representations. A key defines equivalence when choosing a reusable response; it is not an arbitrary string added only for speed. This lesson’s selected profile retains GET, the complete public target URI, and Accept-Language together.

WEB-09.S01 · Core · Cache keys, Vary, and personalized content ↗
Vary requests matching of named request headers

The origin uses Vary: Accept-Language to identify that request header as a selection dimension. An entry obtained for en is not a matching candidate for tr here. Vary verifies no identity and grants no authorization. Names come from response metadata; compared values come from the original and new requests.

WEB-09.S01 · Core · Cache keys, Vary, and personalized content ↗
Matching, fresh, and public are separate gates

The normal fixture selects en for both request and stored entry, current_age=8, lifetime=60, and public audience. Together these facts satisfy this profile’s HIT decision. Changing the request to tr can leave the entry fresh while variant matching fails. Freshness cannot make the wrong representation belong to the correct audience.

WEB-09.S01 · Core · Cache keys, Vary, and personalized content ↗
Personalized and tenant-scoped content

The fixture bypasses shared lookup first for Duru’s personal note. Observing a session cookie, an Authorization header, and an origin-produced personal representation are different facts. The profile never treats a client-written tenant or role as trusted public classification; its route/audience information is supplied validated policy input.

WEB-09.S01 · Core · Cache keys, Vary, and personalized content ↗
Why distinguish poisoning from deception?

Cache poisoning concerns an inappropriate or corrupted response becoming reusable for later users. Cache deception concerns sensitive or dynamic content entering shared storage through incorrect classification. Assuming a cached body is trustworthy skips a boundary in either case; consequences and the faulty decision point differ.

WEB-09.S01 · Core · Cache keys, Vary, and personalized content ↗
A decision record should retain its boundaries

The artifact separates decision, reason, bodySelected, and originAction. On MISS, bodySelected is null rather than an invented new origin body. The same applies to VALIDATE. BYPASS is not a user denial here; it leaves shared reuse for origin policy.

WEB-09.S01 · Core · Cache keys, Vary, and personalized content ↗
Review equal-URL results through separate decisions

A cached 200 establishes neither audience nor representation correctness. Ask which method, target, and selected request header produced the public entry. Does the next request match that key, and is the response reusable? The fixture’s en-to-tr comparison uses two ordinary catalog views.

WEB-09.S01 · Red · Cache keys, Vary, and personalized content ↗
Are classification and representation consistent?

The inert conflict record disagrees on public routeClass and personal audience. Review where that disagreement is resolved: response production and storage policy should use the same approved classification. URL appearance alone does not determine audience.

WEB-09.S01 · Red · Cache keys, Vary, and personalized content ↗
Define an approved reuse profile

The producer is a local typed reuse function comparing request facts with a stored entry. decision/reason/bodySelected/originAction belong to one candidate, not a real cache access log. MISS, VALIDATE and BYPASS identify unexecuted work rather than results received from the next owner. Define the public representation set first: only the GET public catalog here. Preserve the complete target URI and selected-language match. The dimension named by Vary and the origin-selected variant should belong to one contract. Use explicit decisions for absent or unsupported values instead of guessed defaults.

WEB-09.S01 · Blue · Cache keys, Vary, and personalized content ↗
Tie independent regressions to ownership decisions

Independently check both decision and selected body for en/en HIT, tr/en MISS, age60 VALIDATE, and personal BYPASS. The latter three must retain a null shared body. Add reject for a public/personal conflict and not-computed for missing evidence; those outcomes differ.

WEB-09.S01 · Blue · Cache keys, Vary, and personalized content ↗
profile

Scope of the selected public-only decision; not a universal policy for every HTTP cache.

WEB-09.S01 · Cache keys, Vary, and personalized content ↗
decision / reason

HIT, MISS, VALIDATE, and BYPASS describe different decisions.

WEB-09.S01 · Cache keys, Vary, and personalized content ↗
bodySelected

Only a matching public fresh HIT selects a body; other outcomes keep null.

WEB-09.S01 · Cache keys, Vary, and personalized content ↗
originAction

Required next flow; this local model executes no HTTP call.

WEB-09.S01 · Cache keys, Vary, and personalized content ↗
policyConflict

Inert counterexample rejecting disagreement between trusted declarations.

WEB-09.S01 · Cache keys, Vary, and personalized content ↗
Authority is routing information

Atlas accepts books.example for its public preview service. Host and :authority carry target host/port information; they are neither an authenticated user nor a trusted proxy identity. A TCP peer address, TLS reference identity, public target, and application route are different observations. This lesson records agreement with an approved public-target mapping separately.

WEB-09.S02 · Core · Authority, forwarded trust, and parser agreement ↗
Who wrote the forwarded context?

A parseable field can have an untrusted source. Forwarded may have been changed by the client or intermediaries, and a trusted proxy list does not authenticate an earlier untrusted prefix. Atlas therefore requires an approved immediate peer, protected hop, and approved reconstruction before accepting that context.

WEB-09.S02 · Core · Authority, forwarded trust, and parser agreement ↗
A message boundary is not a content value

Tea occupies three UTF-8 octets. The ordinary example uses known-length framing, whose boundary determines which octets belong to one message. HTTP/1.1 body-length rules cannot be reduced to a method name or the application’s ability to read JSON. RFC 9112 §6.3 defines precedence and incomplete-message rules; this lesson does not reimplement that grammar.

WEB-09.S02 · Core · Authority, forwarded trust, and parser agreement ↗
What does HTTP version conversion preserve?

The selected normal projection moves from an HTTP/2 semantic record to an HTTP/1.1 descriptor. It retains method, approved public authority, path/query, and content octets. HTTP/2 supplies stream/frame boundaries; where a content-bearing message includes content-length, it must agree with DATA content length. Prohibited connection-specific fields cannot be copied into an HTTP/2 message.

WEB-09.S02 · Core · Authority, forwarded trust, and parser agreement ↗
Why is parser agreement a chain property?

It is tempting to assume the application sees the same message an edge accepted. Across ownership changes, target, field interpretation, and content-boundary contracts must be preserved. Desynchronization concerns layers choosing different message boundaries for a stream or translation. This lesson explains the risk through a defensive invariant.

WEB-09.S02 · Core · Authority, forwarded trust, and parser agreement ↗
Record observation separately from policy

The artifact records provenance category, contextAccepted, boundaryComplete, and dispatchCount instead of raw context. Public-target validation and forwarded-context validation have distinct outcomes. Missing input yields not-computed rather than clean traffic or a security pass. An unknown conversion profile produces no dispatch.

WEB-09.S02 · Core · Authority, forwarded trust, and parser agreement ↗
Review which information is authoritative

Seeing books.example and https in a request summary does not establish approval. Which fact is directly observed, reconstructed by an accepted peer, or externally claimed? Atlas answers the target and provenance questions separately through authorityApproved and contextAccepted. Deriving one from the other misrepresents a routing decision as provenance validation.

WEB-09.S02 · Red · Authority, forwarded trust, and parser agreement ↗
Look for boundary evidence beyond the version name

An h2-to-h1 monitoring label does not prove a correct conversion. Inbound completeness, an outbound known-length descriptor, and preserved content are distinct observations. The incomplete branch keeps its approved authority; its failure belongs to another owner. Combining every denial into a generic network error loses that distinction.

WEB-09.S02 · Red · Authority, forwarded trust, and parser agreement ↗
Make the public-target mapping explicit

A typed admission function produces the observation; facts are inputs and expected contains decision examples. Descriptor comparison examines local byte conversion. Authority-denied skips context/completeness; incomplete accepts context but has no dispatch. This ledger contains neither real proxy logs nor wire receipts. Atlas selects approved authority books.example and fixed catalog-preview routeId together. Unknown authority yields no guessed default or arbitrary internal destination. Keeping public origin and internal service addressing as separate configuration responsibilities avoids deriving routing authority from incoming metadata. The mapping grants no user authorization, which remains an application decision.

WEB-09.S02 · Blue · Authority, forwarded trust, and parser agreement ↗
Verify admission and projection boundaries together

For ordinary Tea, compare descriptor method, authority, path/query, bodyHex, and contentLength against independent expectations. Denied authority and incomplete branches retain a null descriptor and zero dispatchCount. Missing evidence is not-computed; an unknown conversion profile is rejected. Distinct outcomes require distinct reasons in regression records.

WEB-09.S02 · Blue · Authority, forwarded trust, and parser agreement ↗
authority / fixedRouteId

Public target validation and configured route; not user identity.

WEB-09.S02 · Authority, forwarded trust, and parser agreement ↗
peerClass / contextAccepted

Supplied provenance decision, separate from direct-target admission.

WEB-09.S02 · Authority, forwarded trust, and parser agreement ↗
expectedOctets / observedOctets / complete

Inert completeness evidence, not a raw message or parser reproduction.

WEB-09.S02 · Authority, forwarded trust, and parser agreement ↗
profile / bodyHex

Selected normal semantic projection and preserved Tea octets.

WEB-09.S02 · Authority, forwarded trust, and parser agreement ↗
decision / reason / dispatchCount

Accepted local record, rejection, or missing evidence; no real dispatch runs.

WEB-09.S02 · Authority, forwarded trust, and parser agreement ↗
A browser is an application environment

An address bar, document and network socket are distinct components. A browser turns received bytes into documents under web-platform rules, executes scripts, manages storage and permissions, and presents frames. A server returning 200 is one dependency in that journey. Response handling, document creation, code and resource processing, and a usable view have separate outcomes.

WEB-10.01 · Core · Browser processes and navigation ↗
Separate processes and threads

A process is an operating-system execution and resource boundary; threads provide execution flows within it. Chromium divides browser UI and renderer work across processes. A renderer can have a main thread, compositor and helper work, while network and GPU/Viz services have implementation-specific placement. Work done by one application need not share one JavaScript call stack.

WEB-10.01 · Core · Browser processes and navigation ↗
Tab count is not process count

One tab, one renderer is a memorable starting picture rather than a reliable architectural rule. Chromium considers document and worker coexistence, security principals, browsing context groups and platform resources. A cross-site iframe inside one tab can use another renderer, while related same-site documents may share a process. Site and origin isolation details also differ across platforms.

WEB-10.01 · Core · Browser processes and navigation ↗
Navigation intent, response and commit

A cross-document navigation starts with a URL candidate. The browser handles loading decisions, obtains a response when required and selects a suitable document target. Redirects can change the final destination, and cache or service workers mean that every navigation need not perform fresh DNS and TLS. The scene selects a Chromium-style coordination profile after an ordinary HTML response is available.

WEB-10.01 · Core · Browser processes and navigation ↗
A URL can change within the same document

A #summary link in the catalogue can navigate within the existing document. Document identity is retained while URL/history and the scroll target may change; another HTML response is not required. History API URL/history updates can also retain the document, although their observable event behavior is not identical to fragment navigation. This fixture selects an existing #summary fragment target.

WEB-10.01 · Core · Browser processes and navigation ↗
Commit, readiness and pixels are separate gates

Document.readyState distinguishes loading, interactive and complete lifecycle states. DOMContentLoaded normally follows parsing and deferred/module script work, rather than waiting for every image or async script. load covers a broader resource-loading boundary, while lazy resources and later fetches may remain outside it. Neither event records the exact instant of the first visible pixel.

WEB-10.01 · Core · Browser processes and navigation ↗
Ask who owns the signal

For an authorized review, split page opened into observations. Address bar and final URL, response status/Content-Type, document identity and rendered view come from different owners. Recording a final redirect destination does not erase earlier responses. A downloaded file also leaves no new HTML document to inspect in the selected branch.

WEB-10.01 · Red · Browser processes and navigation ↗
Separate navigation evidence from content decisions

A network record can describe an available response, DOM inspection can describe the current document, and a performance record can describe renderer work. These observations complement one another without individually proving the whole timeline. Record the version, navigation type and source path; a cache-served response is not a fresh wire capture.

WEB-10.01 · Red · Browser processes and navigation ↗
Keep lifecycle measurements separate

This artifact is a milestone ledger for the selected navigation model. response-ready, renderer-selected, commit-delivered and confirmation-received belong to distinct owners. Network-service preparation is not browser receipt; renderer commit knowledge is not browser confirmation. Fragment and download branches require no new HTML commit. Defensive telemetry may need separate correlation fields for a request, navigation and presentation. A request ID identifies an exchange, not necessarily a document or entire user session. Linking client navigation observations to a server trace requires an explicit design. The ordinary A-to-B artifact retains response readiness, commit delivery and confirmation as separate records.

WEB-10.01 · Blue · Browser processes and navigation ↗
Browser isolation and application policy work together

Browser process and sandbox boundaries reduce the platform impact of untrusted content. Application tenant, object and action decisions belong to another layer. Browser behavior and policy are evaluated alongside server authorization. Sharing a process is not a permission proof, and using separate processes is not an API data-security proof.

WEB-10.01 · Blue · Browser processes and navigation ↗
newDocument

B for the branch that creates a new document; null otherwise.

WEB-10.01 · Browser processes and navigation ↗
confirmationReceived

Separate acknowledgement before browser UI/state update.

WEB-10.01 · Browser processes and navigation ↗
pixelsMeasured

False: lifecycle evidence does not measure first pixels.

WEB-10.01 · Browser processes and navigation ↗
HTML bytes are not yet a DOM

Response-body decoding supplies a character stream to the HTML parser. Tokenization produces tags, text and comments, while tree construction builds a Document from those tokens. TCP segments and HTTP DATA frames do not define DOM node boundaries. One p element may span network chunks, while one chunk can contain several elements.

WEB-10.02 · Core · From HTML to DOM,layout and paint ↗
Tree construction is not a string copy

HTML has defined processing behavior for incomplete and erroneous markup. Implied html/head/body structure may appear, and a tr inside a table can cause a tbody that was absent from the source. View Source and the Elements tree can therefore differ. Follow parent/child relationships rather than visual indentation when selecting an element.

WEB-10.02 · Core · From HTML to DOM,layout and paint ↗
The DOM is a live data model

The DOM exposes Documents and nodes as a tree-based platform model. JavaScript is a language that can use that model; the DOM is not JavaScript syntax itself. Nodes have identity, attributes and current text. Scripts can change current state while response source remains fixed. Holding a node reference does not mean a source file has been rewritten.

WEB-10.02 · Core · From HTML to DOM,layout and paint ↗
CSSOM and computed style record different things

CSS parsing exposes stylesheet rules through platform objects. An authored CSSOM rule and an element’s resolved/computed style are not the same record. Selector matching, cascade, inheritance and layout-related resolved values affect the result. getComputedStyle is not the original CSS source; this fixture reads only selected width, height, color, display and visibility values.

WEB-10.02 · Core · From HTML to DOM,layout and paint ↗
Render tree is a teaching shorthand

Browsers construct layout and painting data structures from document and style state. Render tree is a useful teaching shorthand, not one universally named public tree with a one-to-one DOM mapping. Chromium RenderingNG describes distinct fragment trees, property trees, display lists and compositor frames.

WEB-10.02 · Core · From HTML to DOM,layout and paint ↗
Layout, paint and frame presentation

Layout resolves sizes and positions. Paint produces drawing instructions; raster turns them into pixels or tiles; compositing and draw combine and present a frame. Chromium spreads this work across stages and threads and can skip unnecessary stages. Describing every CSS change as a mandatory complete reflow-repaint chain is misleading.

WEB-10.02 · Core · From HTML to DOM,layout and paint ↗
Keep source and current DOM evidence distinct

For an authorized review, retain source, parsed DOM and post-script DOM as separate snapshots. Source Atlas &amp; Web alongside current Atlas — revised can be an ordinary local update. Reporting a current DOM serialization as the original response body loses provenance. The artifact places source and final text side by side.

WEB-10.02 · Red · From HTML to DOM,layout and paint ↗
Retain the limits of geometric measurements

Width and height can validate a selected browser fixture without proving pixel-perfect output on every device. Font, viewport, zoom and device pixel ratio have different effects. Dimensions here use fixed CSS pixels; no line-break or glyph-metric baseline is invented.

WEB-10.02 · Red · From HTML to DOM,layout and paint ↗
Place data in its intended context

The artifact stores authored HTML/CSS beside expected API results. In a new browser observation, the parser produces DOM text/TBODY, getComputedStyle supplies style values and getBoundingClientRect supplies CSS-pixel geometry. The expected field cannot replace that measurement; geometry cannot supply a screenshot or paint receipt either. Choosing a text-oriented API such as textContent makes plain-text interpretation explicit. If a product requires HTML parsing, accepted markup and trust policy need their own design. A parser producing a tree does not prove authorization or sanitization. This lesson performs an ordinary text update without claiming the guarantees taught in later output-context lessons.

WEB-10.02 · Blue · From HTML to DOM,layout and paint ↗
Tie checks to observable invariants

The fixture has small observable invariants: decoded character-reference text, implied TBODY, a retained hidden node, fixed note geometry and current text after mutation. Native browser APIs can observe these. Paint instructions and compositor internals require separate capture and are not evidence supplied by this test.

WEB-10.02 · Blue · From HTML to DOM,layout and paint ↗
htmlFragment

Ordinary authored source for native parsing,not a network capture.

WEB-10.02 · From HTML to DOM,layout and paint ↗
expected.impliedTableChild

Parser-created table section absent from authored source.

WEB-10.02 · From HTML to DOM,layout and paint ↗
expected.noteWidth

Fixed border-box geometry,not screenshot or paint evidence.

WEB-10.02 · From HTML to DOM,layout and paint ↗
expected.paintCaptured

False: DOM/geometry is not compositor capture.

WEB-10.02 · From HTML to DOM,layout and paint ↗
Engine,host and browser are distinct

A JavaScript engine parses and evaluates ECMAScript code and may use implementation techniques such as bytecode or JIT. DOM,fetch and timers are web APIs supplied by the browser host. Language semantics can be explained without assuming a particular optimization. JavaScript executing does not establish completion of a network request or creation of the DOM.

WEB-10.03 · Core · JavaScript execution and the event loop ↗
Execution context and call stack

An execution context is the ECMAScript specification’s model for tracking evaluation progress. Function,Realm and environment relationships belong to it; it need not exist as a context object script can inspect. The running context is the top of the context stack. Nested calls transfer control through contexts,but exceptions and async suspension mean every transition is not identical to a simple drawing.

WEB-10.03 · Core · JavaScript execution and the event loop ↗
An event loop schedules callback work

The HTML event loop coordinates scripts,user interaction,networking and rendering. One loop can have several task queues with scheduler choices between task sources. A single global FIFO for every network,click and timer callback is therefore misleading. The microtask queue is also distinct from an ordinary task queue.

WEB-10.03 · Core · JavaScript execution and the event loop ↗
Promise executor is synchronous;reaction is a microtask

new Promise(executor) invokes its executor synchronously during creation. resolve may fulfill the Promise,but a then reaction does not interrupt current synchronous statements;it runs as microtask work at an appropriate checkpoint. Treating everything inside a Promise as async confuses executor and reaction.

WEB-10.03 · Core · JavaScript execution and the event loop ↗
Await suspends control rather than creating a thread

An async function can run synchronously until its await point. Continuation proceeds through later reaction work even for a fulfilled Promise,while the caller can continue its synchronous work. Await creates no independent CPU thread. Parallel work in another agent or worker needs its own mechanism and communication boundary.

WEB-10.03 · Core · JavaScript execution and the event loop ↗
A DOM update is not a frame receipt

A callback can change DOM state,and a rendering opportunity can turn that state into a new view. The current HTML processing model schedules window rendering work through the rendering task source. Do not assume every task forces a paint or every callback is followed by a fixed refresh. Hidden documents and unnecessary rendering also affect updates.

WEB-10.03 · Core · JavaScript execution and the event loop ↗
Do not confuse ordering with timing

For an authorized review,log order verifies a small dependency,while a0ms timer label does not verify execution at exactly0ms. Network panels,console output and DOM snapshots also have different observation owners. A callback invocation alone does not prove a whole response body was consumed or persistent action committed.

WEB-10.03 · Red · JavaScript execution and the event loop ↗
A context drawing is not an engine capture

Stack aliases explain function boundaries. Error stacks or performance samples need not show the same representation: optimization,source maps and async-stack tooling differ. Record which source version matches an observed frame instead of turning three drawn boxes into a native-memory claim.

WEB-10.03 · Red · JavaScript execution and the event loop ↗
Give async work an explicit completion contract

The selected synchronous code, Promise reaction, queueMicrotask callback and timer callback produce log labels. expectedLog is the expected order, not the console record of a new execution. A callback label identifies its own completed work; this fixture produces no body-consumption, server-commit or DOM/pixel result. Application code should state what each callback completes. Data received,body consumed,validated,DOM updated and server committed are different events. Choose the right completion boundary before advancing UI state. A fulfilled Promise describes the work that Promise represents;additional product-contract work needs its own steps.

WEB-10.03 · Blue · JavaScript execution and the event loop ↗
Evaluate responsiveness and evidence separately

Long main-thread work can delay user interaction and rendering work. An async keyword does not move CPU cost to another thread;bounded work or appropriate worker design needs separate evaluation. This lesson supplies no stall-duration,device-speed or universal-refresh guarantee. Its native fixture uses short,finite callbacks.

WEB-10.03 · Blue · JavaScript execution and the event loop ↗
expectedLog

Ordering for one ordinary synchronous start and bounded checkpoint.

WEB-10.03 · JavaScript execution and the event loop ↗
timerDelayArgument

Scheduling request,not a measured callback execution time.

WEB-10.03 · JavaScript execution and the event loop ↗
executionContextModel

Specification aliases,not a native context object accessible to script.

WEB-10.03 · JavaScript execution and the event loop ↗
paintCaptured

False:callback ordering does not establish presentation timing.

WEB-10.03 · JavaScript execution and the event loop ↗
Resource discovery is not execution

Atlas HTML exposes CSS, image, and script URLs; JavaScript can also start Fetch or XMLHttpRequest. Browser scheduling, cache lookup, network transfer, and decode/execute are separate jobs. A Network-table row does not prove complete content or script execution. Preload/scanning can discover resources early, so request order is not simply the order in which the DOM parser advances.

WEB-10.04 · Core · Resource, script, and request loading ↗
Download order and execution order differ

Suppose two external classic scripts appear as defer A followed by B. Fetching can proceed alongside parsing; even if B becomes ready first, this parser-inserted deferred pair executes A then B after parsing finishes. DOMContentLoaded waits for this deferred execution. It does not guarantee all images or every application async task have finished.

WEB-10.04 · Core · Resource, script, and request loading ↗
Response, body, and status are separate gates

Fetch can fulfill with a Response once status and headers are available while content still streams. response.text()/json() is separate async consumption. A disturbed or locked body limits reuse; do not assume the same body can be read twice. JSON parse failure also differs from HTTP-status failure. The GET fixture has no request body; Fetch does not accept a non-null GET/HEAD body.

WEB-10.04 · Core · Resource, script, and request loading ↗
A loaded resource is not a trusted outcome

Loading order is a dependency contract. If A must initialize state before B, trusting declaration order for an async pair is an incorrect acceptance rule. Effects include missing dependencies, incomplete DOM updates, or partial UI state. A downloaded-script observation does not prove initialization finished.

WEB-10.04 · Red · Resource, script, and request loading ↗
Do not overinterpret cancellation or completion

Treating a fulfilled 404 as a successful action leads to incorrect UI decisions. Treating an aborted request as unseen by the server also exceeds the evidence. The failure condition conflates status, body state, and client outcome; impact depends on the operation.

WEB-10.04 · Red · Resource, script, and request loading ↗
Keep two orders in the loading ledger

Loading producers differ: parser declaration, loader readiness and script evaluation. API records separate Fetch/XHR status from body-reader completion. The selector reads authored status/acceptedAsHttpSuccess rows only; it is neither a real browser log nor server-commit measurement. The artifact separately records declarationOrder A/B, readyOrder B/A, and deferredExecution A/B. Identify the attribute preserving execution order and verify the executed list remains empty when B downloads. Selected B/A execution is possible in the async branch without exhausting normal outcomes.

WEB-10.04 · Blue · Resource, script, and request loading ↗
Describe API outcomes in three fields

Record fulfilled-response, status404/okfalse, and body-consumption outcome separately for Fetch. XHR combines event=load with status404. After-headers abort has a Response but bodyRead=AbortError. The selector detects status>=400 with acceptedAsHttpSuccess=true; distinguish normal0, positive1, and missing0 evidence.

WEB-10.04 · Blue · Resource, script, and request loading ↗
readyOrder / execution

Resource availability and JavaScript evaluation are separate orders.

WEB-10.04 · Resource, script, and request loading ↗
fetch404 / xhr404

API completion differs from HTTP success; load/fulfilled 404 is possible.

WEB-10.04 · Resource, script, and request loading ↗
abortAfterHeaders

Header arrival remains observed; incomplete content reading can abort.

WEB-10.04 · Resource, script, and request loading ↗
cacheChoices

Browser HTTP-cache choice, not Cache API or every proxy policy.

WEB-10.04 · Resource, script, and request loading ↗
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.

WEB-10.05 · Core · Browsing contexts, workers, and service workers ↗
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.

WEB-10.05 · Core · Browsing contexts, workers, and service workers ↗
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.

WEB-10.05 · Core · Browsing contexts, workers, and service workers ↗
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.

WEB-10.05 · Red · Browsing contexts, workers, and service workers ↗
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.

WEB-10.05 · Red · Browsing contexts, workers, and service workers ↗
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.

WEB-10.05 · Blue · Browsing contexts, workers, and service workers ↗
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.

WEB-10.05 · Blue · Browsing contexts, workers, and service workers ↗
iframe

Distinct documents with only same-origin access supplied.

WEB-10.05 · Browsing contexts, workers, and service workers ↗
workerClone / workerTransfer

Copied mutation differs from detached-buffer ownership.

WEB-10.05 · Browsing contexts, workers, and service workers ↗
registration

Active registration differs from current controller.

WEB-10.05 · Browsing contexts, workers, and service workers ↗
cachePlan

Explicit public entry with separate hit and offline miss.

WEB-10.05 · Browsing contexts, workers, and service workers ↗
Start with the capture contract

Developer Tools is an observation instrument rather than an automatic judgment of application correctness or vulnerabilities. Network displays requests made while the panel is open and recording. Open it before the action and record capture/filter choices; make Preserve log explicit when retaining a navigation chain. Opening it afterward and seeing an empty table does not prove no request occurred. Cached or Service Worker responses can appear too; not every row represents a new origin round trip.

WEB-10.06 · Core · Observing with Developer Tools ↗
Response HTML and live DOM are different artifacts

Elements shows the active DOM tree. Response HTML is initial content; parsing constructs the tree and scripts can later change nodes or text. In the artifact, p#result begins as Loading and becomes Not found after the client reads 404 content. This does not prove the server later rewrote its HTML. Correlate document response content or View Source separately with live Elements, capture time, and the same navigation.

WEB-10.06 · Core · Observing with Developer Tools ↗
Evidence scope and sensitive fields

HAR exports captured exchanges through a defined JSON format. Chrome default sanitized export excludes headers such as Cookie, Set-Cookie, and Authorization. This does not guarantee every URL query, request/response body, or application identifier is anonymized. Review shared content separately and retain only necessary bounded observations.

WEB-10.06 · Core · Observing with Developer Tools ↗
Do not treat visible state as authority

Treating local DOM text or a storage value as backend permission exceeds observation boundaries. A node labeled Preview can change presentation, but an ordinary client edit does not prove a server object changed. The condition is confusing local presentation with authoritative state; impact depends on the application decision that uses it. This lesson creates no server-policy bypass experiment.

WEB-10.06 · Red · Observing with Developer Tools ↗
Export creates a new data-sharing boundary

Interpreting sanitized HAR header filtering as complete content privacy can accidentally share sensitive application data remaining in queries or bodies. Export from a filtered table may also omit part of the journey. The condition is skipping scope and field inspection. Here only a public-note path and harmless text are shared, with no credentials, cookies, or account data captured.

WEB-10.06 · Red · Observing with Developer Tools ↗
A comparison ledger for one request

This bundle is an authored observation projection, not a new DevTools capture. Its Network row represents browser request/response observation, Elements current DOM, Console an application logger, and theme origin-scoped localStorage. In capture-gap, a displayed result does not establish a late panel recorded the earlier request; the server session store remains unobserved. Enable Network recording before the harmless local-note action and record filter/context choices. Check that GET, /notes/missing, status404, and Not found belong to one exchange. Observe that fulfilled Fetch does not automatically perform status checking and Console messages are application-generated. If response content is incomplete, do not report missing content as an empty successful result.

WEB-10.06 · Blue · Observing with Developer Tools ↗
Preserve observation boundaries in delivery

Retain observed Network Timing phases by name and leave server database duration absent. If Initiator is script, identify this as browser-initiation evidence. An empty table after late recording only establishes a capture gap. A repeated observation must remain harmless and local; a new capture cannot retroactively produce old missing evidence.

WEB-10.06 · Blue · Observing with Developer Tools ↗
network / capture

Exchange fields are bounded by capture scope; timing is not invented.

WEB-10.06 · Observing with Developer Tools ↗
document / console

Original HTML, live DOM, and application logs differ.

WEB-10.06 · Observing with Developer Tools ↗
storage

Client preference is not backend-session/permission evidence.

WEB-10.06 · Observing with Developer Tools ↗
sharing / captureGap

Minimal projection and missing-evidence boundaries are explicit.

WEB-10.06 · Observing with Developer Tools ↗
From controls to the entry list

Atlas search carries the harmless title Tea & Bread under q. An input id supports labels and DOM lookup, while name supplies the submission key. The entry list is not a copy of every visible control: disabled controls, unchecked checkboxes, unnamed controls and unselected submit buttons are excluded. A named readonly text control can still be submitted. Two tag controls produce ordered web/http entries; prematurely turning this list into a plain object can lose a repeated value. Hidden or readonly values are UI/submission properties, not trusted server identity.

WEB-10.S01 · Core · Forms, JavaScript and DOM data flow ↗
Submission contains several decisions

After selecting a submitter, the browser evaluates constraint validation and the cancelable submit event. A listener can stop default navigation with preventDefault. The selected native GET branch prepares a navigation request with UTF-8 URL-encoded entries. In the fetch branch, the listener stops the default and separately prepares its own ordinary read request; fetch is not native form navigation. requestSubmit follows the normal submitter/validation/event path; submit() must not be assumed to have identical event or validation behavior. Browser checks provide user experience, while the server separately evaluates the q contract and resource policy.

WEB-10.S01 · Core · Forms, JavaScript and DOM data flow ↗
JavaScript values, functions and lexical scope

A text control produces the string "2"; adding a number can concatenate, whereas explicit Number conversion produces a number that still needs domain validation. Null, undefined and an absent field need not have the same application meaning. let/const use block scope, unlike function-scoped var. A const object binding does not make its title immutable. Explicit function inputs and returns separate DOM reading from normalization, policy and rendering. A callback can access a surrounding q binding through a lexical closure; capture does not make input trusted. JavaScript execution, body parsing and DOM updates are local scene stages, not network packets.

WEB-10.S01 · Core · Forms, JavaScript and DOM data flow ↗
Mistaking client state for server authority

A required q field gives feedback for empty input on the selected browser’s normal submission path. A readonly or hidden presentation does not justify treating that value as a server-trusted subject or tenant. The trust boundary belongs at the request receiver, which decodes entries and checks shape, size, business meaning and server-owned identity context. This Red perspective does not manipulate a real form; it reasons about the assumption separating UI values from trusted context. Native and fetch branches must use the same server rule.

WEB-10.S01 · Red · Forms, JavaScript and DOM data flow ↗
A local transformation can silently lose data

Reducing repeated tag entries to a single-key object, forgetting the submitter mode, or decoding plus incorrectly changes an ordinary request’s meaning. The ampersand in Tea & Bread is part of a title and must not remain a field separator in serialized data. Unintentionally equating the string "2" with number 2 can also distort limits or UI calculations. A closure does not automatically correlate an asynchronous response with the right search; reply order and correlation require design. In constraint-denied and listener-cancel branches, the model retains no request and an unchanged server card, rather than recording successful server validation. An unchanged card alone in a real trace would also require capture coverage.

WEB-10.S01 · Red · Forms, JavaScript and DOM data flow ↗
Explicit contracts for entries, conversion and policy

The form ledger supplies authored controls, entries and branch predicates; URLSearchParams produces local encoding. In an actual browser observation, the browser produces submitter/constraint/submit events, the server produces q checks/read results, and the client handler produces response parsing/textContent outcomes. Local-stop branches do not reach the server producer. Inventory control name/type/checked/disabled/readonly state and the submitter effect, preserving repeated fields as an entry list. The selected GET profile encodes q/tag/mode with URLSearchParams; decoding must recover the same title and ordered tags. Files and multipart need separate contracts and are not modeled by this text-only fixture. Normalization returns a separate value from the raw string; Number conversion, finite/domain checks and string output are distinct steps. The server obtains subject/tenant from its trusted context rather than from a form member.

WEB-10.S01 · Blue · Forms, JavaScript and DOM data flow ↗
Separate local DOM outcomes from response receipt

A native navigation response follows a new-document parser path, while a fetch response follows handler body reading and UI update. Receiving headers/status does not complete body parsing or DOM rendering. The fetch handler assigns the ordinary book title through h2.textContent, which does not need pre-escaped HTML. Function/scope examples can run on plain data in Node, but a passing closure test does not execute submit events, constraint validation or a DOM parser. Regression branches separately record wire/local decisions for native and fetch success, an invalid constraint and listener cancellation.

WEB-10.S01 · Blue · Forms, JavaScript and DOM data flow ↗
controls

Fixed text-only control inventory with explicit checkbox and submitter inclusion.

WEB-10.S01 · Forms, JavaScript and DOM data flow ↗
entries

Ordered repeated tag entries are preserved.

WEB-10.S01 · Forms, JavaScript and DOM data flow ↗
encoded

UTF-8 form URL-encoding representation of an ordinary title.

WEB-10.S01 · Forms, JavaScript and DOM data flow ↗
branches

Constraint/event/default navigation differs from explicit fetch.

WEB-10.S01 · Forms, JavaScript and DOM data flow ↗
jsFixtures

Finite native type/coercion/function/closure/scope results.

WEB-10.S01 · Forms, JavaScript and DOM data flow ↗
An output context selects an interpreter

The same Tea & Bread string can reach an h2 text node, serialized HTML text, a quoted title attribute, JSON data or a URL query, each with a different consumer. Ordinary h2.textContent does not invoke an HTML parser and should receive the original string. Serialized HTML text protects its ampersand with entity encoding, while a quoted ordinary title attribute also needs its outer quote boundary protected. Keep attribute names fixed: a decision for a plain text title attribute does not automatically apply to URL or event-handler attributes. Context describes the final consumer’s interpretation, not the original input type.

WEB-10.S02 · Core · Output contexts, XSS and DOM trust boundaries ↗
Reflected/stored and DOM describe different axes

Reflected data returns through the ordinary request/response cycle; stored data comes from persistence for later display. This lifetime distinction does not determine encoding: storing user-controlled text does not make it trusted markup. DOM-based risk concerns client code moving a source value into an interpreting sink, and either reflected or stored data can enter that client-side path. XSS requires conditions such as untrusted influence, executable interpretation and execution under document authority. The harmless em formatting declaration or Tea & Bread result here is not evidence of XSS; it teaches mechanisms and control boundaries.

WEB-10.S02 · Core · Output contexts, XSS and DOM trust boundaries ↗
Read source provenance together with sink purpose

The source ledger can identify an ordinary query value, fetched book JSON or a stored-title alias; arriving from the same origin does not turn a title into an HTML instruction. The sink ledger distinguishes literal textContent, innerHTML fragment parsing and URL parsing plus destination policy. JSON serialization creates a value representation; placing it into inline script or event-handler source introduces a different context problem. This fixture parses JSON as data and generates no dynamic script. URLSearchParams protects query-value boundaries but does not approve URL scheme, origin or path. Source-to-sink processing remains local within the browser.

WEB-10.S02 · Core · Output contexts, XSS and DOM trust boundaries ↗
A harmless parser result is not a security certificate

A fixed em formatting declaration is expected to produce emphasis structure in a markup parser, whereas the same bytes assigned to ordinary textContent remain literal markup syntax. The difference explains interpretation without creating an executable attack or reproducing a vulnerability. A real risk assessment separately needs untrusted influence and active semantics. Correct rendering of one benign title does not establish safety for an entire input domain; a generic escaped label is insufficient without source, transformation, sink and surrounding grammar.

WEB-10.S02 · Red · Output contexts, XSS and DOM trust boundaries ↗
A trust label cannot replace context information

Persistence changes a saved title’s provenance, not its output trust. A same-origin response, successful JSON parse or HTML entity encoder proves neither business identity nor safety for every output context. Passing HTML-text-encoded data into textContent can display the literal entity text Tea &amp; Bread; that is a wrong-context/usability failure, not a claim that XSS occurred. URL encoding also cannot replace an approved-destination policy. The fixed external HTTPS example is denied locally without opening a connection. The Red lens identifies the narrow question each label actually answers.

WEB-10.S02 · Red · Output contexts, XSS and DOM trust boundaries ↗
Keep plain text in plain text APIs

These records come from a finite source/encoder/policy ledger. contexts carries representations and interpretation expectations, sourceRows lifetimes, and urlRows local destination decisions. With actualDOM=false and actualHTMLParser=false, expected trees/text are not new browser observations; URL denial selects no link assignment. Use ordinary textContent or createTextNode for titles without HTML pre-encoding, keeping element and attribute names application-owned. Assigning a normal title through a DOM attribute API supplies a string value; producing serialized HTML source requires separate quoted-attribute encoding. Do not collapse HTML source, URL components and JSON data into one global sanitize function. Native runtime calculations can check transformations of the finite benign strings here, but those observations do not certify every parser grammar or browser sink.

WEB-10.S02 · Blue · Output contexts, XSS and DOM trust boundaries ↗
Regressions for provenance and the final interpreter

Record each value’s source alias, storage lifetime, transformation, final sink and expected interpretation. Ordinary reflected/stored titles should give the same literal outcome, and benign formatting in the textContent branch should remain Text. Decoding JSON data into a title string differs from generating script source. URL tests should recover the encoded title and separately enforce the selected https/owned-origin/books-path policy. A local denial produces no link outcome. The educational model executes no browser HTML parsing, XSS or arbitrary student code; control-flow evidence and finite native encoding observations are recorded separately.

WEB-10.S02 · Blue · Output contexts, XSS and DOM trust boundaries ↗
contexts

Different representations/consumers for the same harmless value.

WEB-10.S02 · Output contexts, XSS and DOM trust boundaries ↗
sourceRows

Reflected/stored/response provenance remains data.

WEB-10.S02 · Output contexts, XSS and DOM trust boundaries ↗
benignMarkup

Fixed em declaration; text and structure expectations differ, with no execution.

WEB-10.S02 · Output contexts, XSS and DOM trust boundaries ↗
doubleEncoding

Wrong-context display difference, not a claimed XSS outcome.

WEB-10.S02 · Output contexts, XSS and DOM trust boundaries ↗
urlRows

Fixed reserved example URLs are evaluated only by local policy.

WEB-10.S02 · Output contexts, XSS and DOM trust boundaries ↗
Where does autoescaping protect data?

Template autoescaping keeps a plain title as data according to the output grammar; it does not turn every application value into universally trusted output. Choose text rendering by default and review any separate rich-text path. Escape hatches such as React’s raw-HTML prop reintroduce an HTML sink: sharing the same framework does not remove interpretation. Framework URL handling also cannot replace application-specific destination policy. This lesson runs no framework renderer; its ledger separates controls needed for plain text, declared raw HTML and policy-approved rich text.

WEB-10.S03 · Core · Escaping, sanitization, CSP and Trusted Types ↗
Sanitization is a formatting contract

If rich text genuinely needs p/em/strong structure, entity encoding alone turns formatting into text. Sanitization constrains parsed content under a selected tag, attribute and URL policy; deleting a few words from a string does not solve HTML grammar. Atlas’s benign p/class/em declaration permits p/em/strong and no attributes, removes class="note" styling and preserves Tea & Bread. This expected tree projection is not an actual HTML sanitizer. Verify the chosen library/configuration, parsing behavior, version and subsequent mutations separately; adding markup afterward changes the scope of prior review.

WEB-10.S03 · Core · Escaping, sanitization, CSP and Trusted Types ↗
CSP and Trusted Types are separate gates

CSP script/resource policy restricts execution and loading choices; it does not sanitize untrusted HTML or grant business permission. Report-only monitoring is not enforcement. Trusted Types applies expected-type/policy-conversion gates at selected injection sinks. require-trusted-types-for sink enforcement differs from trusted-types policy-name control. A TrustedHTML brand does not make the browser independently determine that policy content is safe; policy callbacks remain security-critical. This selected profile assumes a supporting browser, enforcement, no default policy and no author-supplied parser options: raw strings fail at the HTML sink and an approved sanitized alias passes. Current draft/implementation coverage and alternate parser-options paths are not generalized from that narrow profile.

WEB-10.S03 · Core · Escaping, sanitization, CSP and Trusted Types ↗
Inferring too much from an approved-type label

An allowed policy name does not prove that its createHTML callback sanitizes correctly. A declared TrustedHTML result likewise proves neither site-wide XSS safety nor server authorization. The failed assumption is that a browser brand check independently audits the entire rich-text policy. The browser checks typed values at selected sinks; the application decides which transformation to trust. The artifact therefore keeps input tree, projected tree, policy alias, revision and sink type separate, and explicitly creates no real TrustedHTML instance. Its type declaration belongs to the model scope.

WEB-10.S03 · Red · Escaping, sanitization, CSP and Trusted Types ↗
Later mutations are outside earlier controls

Appending raw markup from another pipeline or allowing a library to reinterpret sanitized output changes the reviewed final tree. A CSP header does not certify the mutation, and an ordinary script-src allow decision does not approve data semantics. The raw-string mismatch branch uses harmless fixed markup to show rejection under the selected enforcing/no-default gate, with no executable payload or bypass variant. Report-only mismatches do not give the same blocking result, nor can unsupported browsers be assumed to enforce it. Trusted Types is present is insufficient evidence without policy disposition and feature support.

WEB-10.S03 · Red · Escaping, sanitization, CSP and Trusted Types ↗
Default to text and review rich-text exceptions

The tree projector compares only the supplied inputTree with allowedTags/allowedAttributes; TT and CSP tables calculate declared type/policy/disposition predicates. Diagnostic=true is neither reportDelivered nor actualExecution. Type mismatch and policy denial have distinct local reasons; this ledger is not a real sanitizer or browser-enforcement producer. Use an ordinary text API for plain titles and give one explicit renderer ownership of rich-text tag/attribute policy. Choose and pin a maintained sanitizer that understands browser grammar; the lesson’s finite tree projector is not a substitute. The allowed p/em/strong example preserves formatting and removes a disallowed benign class, while the text-only branch never enters a markup parser. Regressions need both expected text and allowed tree/attribute results. Keep source storage values separate from approved render-result revisions.

WEB-10.S03 · Blue · Escaping, sanitization, CSP and Trusted Types ↗
Record type gates and CSP evidence together

Policy-creation permission, sanitizer output, correct sink type and enforcement disposition are separate checks. The selected ledger permits atlas-rich-text, requires reviewed revision 1 and rejects plain strings in its supporting, enforcing, no-default innerHTML profile. Ordinary h2.textContent does not need this HTML type gate and keeps the original text as data. The CSP matrix separates report-only and enforcement without inventing delivered reports. Native encodings/data projections, pure-model outcomes and actual sanitizer/Trusted-Types/browser behavior are distinct evidence levels. A new browser observation must record feature support, applied policy and sink outcome together; this ledger cannot replace that observation.

WEB-10.S03 · Blue · Escaping, sanitization, CSP and Trusted Types ↗
formatPolicy

Allowed formatting-tree projection of a fixed benign declaration; not an HTML sanitizer.

WEB-10.S03 · Escaping, sanitization, CSP and Trusted Types ↗
trustedTypes.rows

Declared type/policy gate for a selected enforcing/no-default profile.

WEB-10.S03 · Escaping, sanitization, CSP and Trusted Types ↗
csp.rows

Owned self-source matrix; no script fetching/execution or report delivery.

WEB-10.S03 · Escaping, sanitization, CSP and Trusted Types ↗
profile

Separately declares absence of actual sanitizer/TT/browser/framework evidence.

WEB-10.S03 · Escaping, sanitization, CSP and Trusted Types ↗
Worker, cache and client hold separate state

Atlas should read the public title Tea & Bread offline. A worker is not a page script with DOM access: it participates in fetch events for controlled clients from its own worker context and can select a response. Secure-context, same-origin registration and script-directory maximum-scope rules apply; Service-Worker-Allowed can adjust the path limit. That path is not a substitute for an origin security boundary between users. Registration success, installed/waiting/active state and control of a document are separate observations. A page opened before initial activation may require reloading by default; clients.claim and skipWaiting are separate lifecycle choices.

WEB-10.S04 · Core · Service worker cache, object trust and DOM clobbering ↗
A cache hit does not decide freshness or permission

Cache API stores request/response pairs in named caches managed by the application. It differs from the HTTP cache: Cache-Control freshness or no-store alone does not manage this storage lifecycle. The app chooses admission, versioning, updates, deletion and fallback; browser quota or eviction can remove data. Atlas-v2 admits only public JSON book-A at an exact URL with schemaVersion=2. This selected application gate does not implement Cache.match; Vary and matching options also matter in a real implementation. Parsing a cached body establishes neither fresh permission nor revocation. Mixing session-bound data into this public offline policy could disclose it after account changes or logout.

WEB-10.S04 · Core · Service worker cache, object trust and DOM clobbering ↗
Own properties and named DOM lookups differ

Require own id/title/schemaVersion fields and expected types on the JSON book object. A readable displayMode inherited from a prototype is not necessarily an input field; Object.hasOwn distinguishes these cases. Prototype pollution concerns unsafe writes or merges changing shared/inherited state later consumed elsewhere; JSON parsing alone is not presented as performing that change. DOM clobbering concerns HTML id/name entering application lookups through legacy Window/form named access, not prototype mutation. The fixed atlasBookForm and bookTitle control produce element references through named access, not title strings. Local module configuration, explicit element lookup and expected element/value types separate these namespaces. Freezing trusted own objects is shallow and is not a general fix for window/document.

WEB-10.S04 · Core · Service worker cache, object trust and DOM clobbering ↗
Mistaking a persisted response for current authority

A normal cache hit can supply content without a network request, given a selected controlled worker/client and eligible stored entry. The broken assumption is that the server reevaluated freshness or authorization during this display. Effects include stale revisions or, with incorrect admission, private content displayed in the wrong user context; a stale public title is not automatically a compromise. A new worker version does not prove deletion of older entries or control of old clients. Keep public/private classification, content revision, key/context and account lifecycle explicit. The offline shape-denied branch selects a local fallback; no server request means no server permission-denial evidence.

WEB-10.S04 · Red · Service worker cache, object trust and DOM clobbering ↗
A readable property may not be expected data

Accepting object.title or a Window-level name merely because it is truthy can create a trust error. Prototype paths and DOM named properties require different conditions: unsafe object-state propagation versus relevant HTML names consumed by application code. Impact depends on the confused field and its eventual sink; a named form or benign inherited option is not itself an exploit. The fixed book form is ordinary and harmless, showing only the type distinction between references and title strings. Controls include a closed own-field schema, explicit local configuration and markup namespace policy. Shallow freezing does not make nested objects immutable, and an XSS sanitizer configuration does not automatically resolve every named-property risk.

WEB-10.S04 · Red · Service worker cache, object trust and DOM clobbering ↗
Observe the cache decision at its owner

The artifact carries supplied row predicates for a cache-selection function plus object/lookup ledgers. The network branch models origin receipt; normal and shape-denied never reach origin. named-dom is not another execution of its cache row: it isolates element-reference versus value-string interpretation. Declared controller/version and expected lookups are not actual browser measurements. Observe client controller identity, worker/cache version, URL, response source and fallback reason together. An absent origin access-log request does not prove the client displayed no content; a cache hit does not reach the origin. Admission evidence records selected public classification and schema revision without logging secrets or private bodies. Response cloning and event.waitUntil support storage work, but a successful clone proves neither successful nor durable writing. Update regression separates old controlled clients, waiting workers, eviction/miss and application-version mismatch. Deleting one named cache does not prove full storage cleanup; any private offline state needs an explicit logout/account-switch lifecycle.

WEB-10.S04 · Blue · Service worker cache, object trust and DOM clobbering ↗
Constrain field ownership and DOM namespaces

Validate accepted own keys and types at the book consumer. Map or null-prototype dictionaries reduce inherited lookup for dynamic data but grant no business permission. Object.hasOwn can return true for null or undefined, so separate presence from value/type checks. Read trusted configuration through local references rather than global named DOM values. The fixed form/control lookup separates the expected interface from its .value string; duplicate names may produce collections or past-name behavior rather than a single string. Regression distinguishes ordinary own objects, missing own fields, benign inherited options and named element references. Pure fixtures or Node property observations do not substitute for DOM named access or Service Worker Cache API execution.

WEB-10.S04 · Blue · Service worker cache, object trust and DOM clobbering ↗
profile

Selected controlled-worker and public-only declaration.

WEB-10.S04 · Service worker cache, object trust and DOM clobbering ↗
entry

Request key, application expiration and HTTP headers are distinct.

WEB-10.S04 · Service worker cache, object trust and DOM clobbering ↗
rows

Cache, network or local fallback choice.

WEB-10.S04 · Service worker cache, object trust and DOM clobbering ↗
objectLedger

Own/inherited fields and shallow-freeze expectations.

WEB-10.S04 · Service worker cache, object trust and DOM clobbering ↗
namedDOM

Fixed benign form/control lookup types; not browser execution.

WEB-10.S04 · Service worker cache, object trust and DOM clobbering ↗
Which authority does the browser separate?

The browser does more than send HTTP to remote servers. It runs scripts, documents, storage and credential contexts for several applications in one user session, so it must limit one application directly reading another’s data. Origin is the basic identity for this client-side authority boundary. The browser decides DOM read access between Atlas and a preview document; the Notes API retains its server-side user/tenant decision. Two pages do not share authority merely because the same person opened both.

WEB-11.01 · Core · Origin and Same-Origin Policy ↗
Not every origin is a URL string

An opaque origin carries an internal identity that cannot be reconstructed from a string. Distinct opaque-A and opaque-B both serialize as null, but are not the same origin; opaque-A equals itself. Thus null in a log or event.origin is not the name of one shared trusted origin. A sandboxed origin flag can make a document opaque even when its URL resembles Atlas. URL.origin alone does not determine every document-origin condition; creation and sandbox context matter too.

WEB-11.01 · Core · Origin and Same-Origin Policy ↗
Read, send and embed are separate decisions

SOP constrains cross-origin DOM and storage reads; it is not a firewall blocking all cross-origin networking. Links/navigation, some ordinary requests and embedding can proceed under their own rules. An image appearing beside an iframe does not open that document’s DOM; image/canvas readability has separate conditions too. A CORS-mode fetch can reach the server without exposing its response to script. A no-cors opaque response does not enable ordinary script body reading either. “Sent” and “readable” therefore require separate evidence.

WEB-11.01 · Core · Origin and Same-Origin Policy ↗
Which data could an incorrect equality expose?

Atlas and preview.example.org can share an operator but have different hosts to the browser. An application helper that opens a DOM sample because domain suffixes look similar creates a trust rule wider than the browser’s origin model. The relevant condition is data crossing from another origin without read permission; a shared screen or DNS IP does not justify it. Impact depends on the document or storage data involved. This lesson does not produce that behavior; it examines the mistaken equality in the policy table.

WEB-11.01 · Red · Origin and Same-Origin Policy ↗
What does request receipt prove?

An ordinary cross-origin GET reaching a server does not prove SOP is broken. The server can respond while script cannot access the body; an embed can be visible while direct DOM read is denied. Keep sent, embedded, script-readable and server-authorized fields separate to name control effects accurately. A design that treats read isolation as request authorization omits a server-side gate the browser does not supply. SOP alone is not positive evidence of CSRF protection or access control.

WEB-11.01 · Red · Origin and Same-Origin Policy ↗
Record the boundary by document and operation

The origin matrix is a local URL/identity ledger. HTTP tuples, document-creation context and read operations are separate inputs; opaque aliases are not browser handles. In a real review, server receipt answers sending and a browser-local gate answers script reading. Here both are declared outcomes and the loaded preview creates no new request. Atlas records ordinary HTTP URLs with normalized scheme/host/port and keeps separate identity aliases for opaque contexts. Same-site information can inform cookie policy but does not enter the DOM read gate. Checks cover path changes preserving origin, default-port normalization and explicit nondefault ports changing it. Designing a narrow messaging contract instead of using the legacy document.domain setter keeps application trust boundaries visible for required cross-document work.

WEB-11.01 · Blue · Origin and Same-Origin Policy ↗
Network and exposure evidence

For network behavior, obtain request receipt and script exposure evidence from different owners: the server sees the normal request while the browser enforces the response gate. Do not force cookie scope and storage-origin relationships into one table; cookie domain/path/site rules differ from the DOM origin tuple. These distinctions are checked locally as source/path and predicate fixtures. Browser process isolation, real storage, canvas, credential sending and embedding-policy enforcement remain separate API/profile tests.

WEB-11.01 · Blue · Origin and Same-Origin Policy ↗
httpOrigins

HTTP URL parsing examples, not every Document-origin rule.

WEB-11.01 · Origin and Same-Origin Policy ↗
identities

A normalized tuple or opaque internal identity alias.

WEB-11.01 · Origin and Same-Origin Policy ↗
comparisons

Identity outcomes independent of serialized null equality.

WEB-11.01 · Origin and Same-Origin Policy ↗
operations

Send, embed, read and server policy are separate categories.

WEB-11.01 · Origin and Same-Origin Policy ↗
documentContexts

Creation and sandbox context goes beyond the URL string.

WEB-11.01 · Origin and Same-Origin Policy ↗
To which script does the server expose a response?

CORS lets a server communicate response-sharing permission to the browser for scripts at particular origins through HTTP. It is not the API authorization system deciding which user can perform which operation. Atlas at https://atlas.example.org requests a normal fetch for https://catalog.example.org/list. In cors mode the browser checks CORS before exposing the response to script. Access-Control-Allow-Origin can be one serialized origin or a wildcard under a suitable credentials mode; a comma-separated origin list does not authorize several origins this way. Passing CORS still leaves body reading and JSON parsing as separate stages.

WEB-11.02 · Core · CORS, preflight and credentials ↗
Preflight checks more than the method

The CORS-safelisted methods are GET, HEAD and POST, but GET alone does not remove preflight. Author-controlled request header names and values must also satisfy safelist conditions. X-Atlas-View is not a safelisted name. Content-Type can be safelisted only when its MIME essence is application/x-www-form-urlencoded, multipart/form-data or text/plain and value conditions pass; JSON is outside that set. Accept has unsafe-byte and 128-byte limits, language headers have character conditions and Range has a single-byte-range condition. Streaming uploads or an explicit preflight flag also matter by profile.

WEB-11.02 · Core · CORS, preflight and credentials ↗
include is not an order to send a Cookie

Fetch defaults to same-origin credentials; include permits eligible credentials for cross-origin use. Cookie existence, Domain/Path/Secure, SameSite and browser privacy policy independently affect sending. Selecting include creates neither an absent cookie nor one blocked by policy. Final CORS checks follow include mode, requiring exact ACAO and case-sensitive true ACAC; wildcard ACAO is rejected in that mode even if no Cookie actually traveled. With omit, a wildcard can allow the selected public response.

WEB-11.02 · Core · CORS, preflight and credentials ↗
Which denial stops the request?

In preflight-denied, normal OPTIONS reaches the server but the browser sends no actual GET because X-Atlas-View permission is missing. In final-blocked, preflight passes and the read-only GET reaches the server; final response exposure is denied because a wildcard is used with include mode. The two denials have different network outcomes. A final CORS error does not undo the server’s GET receipt; the example has no mutation but shows why server-side action permissions need protection beyond CORS.

WEB-11.02 · Red · CORS, preflight and credentials ↗
What changes when sharing expands?

A wider origin allowlist can widen the script-readable data boundary; assess that effect using response sensitivity and credential context. CORS success does not prove a session owner may read every object, and failure does not prove CSRF protection. Combining credential sending and script exposure into one boolean is especially misleading. This lesson uses only ordinary read-only fixtures for owned synthetic endpoints, without header manipulation, third-target or bypass flows.

WEB-11.02 · Red · CORS, preflight and credentials ↗
Operate sharing policy separately from API policy

Catalog API owns preflight/final-response predicates; the Atlas browser owns exposure decisions after receiving them. cases/headerCases/exposureCases are authored policy records, not real access logs. preflight-denied reaches only OPTIONS; final-blocked also reaches GET. Omitted body/JSON/DOM stages cannot be inferred from script exposure. Atlas selects a permitted serialized origin from configuration; in include mode ACAO is exact and ACAC is true. The OPTIONS route handles the browser’s credential-free check, while the actual resource route independently enforces user/session and object rules. The public catalog example selects public-read policy and has no state-changing action. An error response can also be exposed through suitable CORS headers; HTTP status is not identical to a successful business outcome. Preflight, however, requires an ok status.

WEB-11.02 · Blue · CORS, preflight and credentials ↗
Two distinct cache policies

For caches, record both HTTP response variation by Origin and the browser preflight cache’s origin/URL/credentials/method/header scope. Max-Age can be limited by browser caps; the fixture runs no actual cache timer. Script access to response headers requires exposure policy; seeing them in browser devtools does not prove script API access. Actual networking, privacy settings, streaming uploads and endpoint authorization need separate isolated integration evidence.

WEB-11.02 · Blue · CORS, preflight and credentials ↗
headerCases

Method and header name/value together; narrow ASCII examples.

WEB-11.02 · CORS, preflight and credentials ↗
preflight

Credential-free OPTIONS; response must separately allow original include usage.

WEB-11.02 · CORS, preflight and credentials ↗
cases

Actual GET sending and final script exposure are separate outcomes.

WEB-11.02 · CORS, preflight and credentials ↗
exposureCases

Exact origin and byte-case-sensitive true checks.

WEB-11.02 · CORS, preflight and credentials ↗
cookieEligibility

Mode differs from cookie policy; no real cookie is sent.

WEB-11.02 · CORS, preflight and credentials ↗
cacheProfile

Selected dynamic HTTP variation and a separate preflight cache.

WEB-11.02 · CORS, preflight and credentials ↗
Seeing an iframe does not mean reading its document

Atlas embeds a document from preview.example.org in an iframe. In an ordinary cross-origin case, the parent can obtain a WindowProxy through contentWindow, but that reference grants no general access to the preview DOM. Limited surfaces such as postMessage are available while direct document reads depend on the origin gate. A same-origin iframe shares broader script access; the iframe element alone is not strong isolation for every document. Browser process selection is not equivalent to this visible DOM box either.

WEB-11.03 · Core · iframe isolation and postMessage ↗
A message contract is not a network transport

The parent sends only a v1 get-title request with transactionAlias=tx-current and bookAlias=atlas-notlari. postMessage carries data through structured serialization and a queued message event, not an HTTP packet or direct DOM sharing. The selected exact targetOrigin=https://preview.example.org must match the receiver document’s origin when the task runs. A WindowProxy can represent another document after navigation. Returning from the sending call proves neither delivery nor receiver acceptance.

WEB-11.03 · Core · iframe isolation and postMessage ↗
Which reply does origin alone select?

Atlas can open two preview instances at the same origin. In instance-mismatch, the reply origin is correct but source alias preview-two is not the preview-one expected by the pending request. The parent rejects it. This is an ordinary widget-wiring error, not a payload or intervention against another target. Expected origin alone identifies neither the window nor the transaction producing a result. Incorrect acceptance would display the wrong title in this read-only example; stronger message actions require their own authorization boundary.

WEB-11.03 · Red · iframe isolation and postMessage ↗
Opaque identity and message shape

Serialized null does not make all opaque senders one trusted widget here either. Schema fields type, v, transaction and book restrict the permitted read-only job; treating data as HTML or executable text would be outside that contract. This lesson selects a no-eval, text-only result profile without running a real renderer. Control effects stay between event acceptance and selected display binding; an origin check is not presented as API user/tenant authorization.

WEB-11.03 · Red · iframe isolation and postMessage ↗
Narrow, instance-bound message acceptance

This artifact separates Window-message delivery predicates from receiver acceptance. deliveryCases predicts whether a browser-local task creates an event; replyCases predicts the parent’s origin/source/type/transaction comparisons. These are not real postMessage or HTTP records: event receipt precedes acceptance and display binding. frame-navigation creates no preview event; stale-reply and instance-mismatch reach a parent event and are then rejected. Atlas obtains expected origin from configuration and expected WindowProxy from its selected iframe instance. The sender uses an exact targetOrigin; the receiver validates origin, source and schema together. Source identity is not converted into an origin string: two windows at the same origin remain distinct. Type is restricted to get-title/title-result, version to 1, transaction to pending tx-current and book to the selected read-only alias. An unknown type or extra field does not silently become a stronger action; the selected schema rejects it.

WEB-11.03 · Blue · iframe isolation and postMessage ↗
Readiness and lifecycle boundaries

Recipient readiness and lifecycle are part of the contract. Prepare the listener, and cancel or restart instance-specific pending work when iframe navigation changes its document context. The model assumes documents/listeners-ready initially; this is not a measured browser timeout, WindowProxy-navigation or port-transfer outcome. Correlate real lifecycle events with the same instance.

WEB-11.03 · Blue · iframe isolation and postMessage ↗
iframe

A WindowProxy reference is not DOM permission; sandbox adds separate limits.

WEB-11.03 · iframe isolation and postMessage ↗
request

Exact read-only message schema and pending transaction.

WEB-11.03 · iframe isolation and postMessage ↗
deliveryCases

Delivery gate depends on receiver origin at task time.

WEB-11.03 · iframe isolation and postMessage ↗
replyCases

Receiver origin/source/schema/transaction conjunction.

WEB-11.03 · iframe isolation and postMessage ↗
deliverySemantics

API call return, event receipt and acceptance are separate.

WEB-11.03 · iframe isolation and postMessage ↗
Which operation consults which policy?

The Atlas Notes document constrains its script sources and ordinary connection destinations. script-src concerns script execution sources, while connect-src concerns destinations used by script interfaces. Inclusion in a source list does not grant API account or tenant access. The browser permitting a connection to a URL and the server allowing that user to read a note are separate decisions; an ordinary request has to satisfy both.

WEB-11.04 · Core · CSP, sandbox and secure context ↗
Sandbox is not an origin equality

An iframe sandbox restricts script, form, navigation and origin behavior through flags. In this example an empty token set blocks script execution and form submission and makes the origin opaque. allow-scripts relaxes the script restriction alone; it does not restore the ordinary origin. allow-same-origin relaxes a separate origin flag and does not make a cross-origin document same-origin with its parent. An unchanged URL does not imply unchanged effective origin or capabilities.

WEB-11.04 · Core · CSP, sandbox and secure context ↗
Which environment does secure context describe?

Secure context is an environment condition used when exposing powerful browser features. HTTPS is the basic ordinary top-level document example; HTTP loopback addresses in 127.0.0.0/8 and ::1 are also considered potentially trustworthy. localhost names have a trustworthy local-resolution qualification; file and vendor-scheme behavior should not be reduced to one universal URL rule. Current HTML uses the environment’s top-level creation URL context, and a worker’s owner. An HTTPS iframe inside a public HTTP parent cannot be classified solely from its own address.

WEB-11.04 · Core · CSP, sandbox and secure context ↗
A violation and a stopped request

The normal and connect-denied branches use the same read-only endpoint; the enforced connect-src list is what changes. In the denied branch the browser stops at its local check and no GET arrival is shown at the server. The report-only branch records a violation of the same list while the request continues. Its diagnostic is inert local state, not evidence of delivery to a real reporting endpoint. A report record alone does not prove that a request stopped; disposition and the applied policy must be read together.

WEB-11.04 · Red · CSP, sandbox and secure context ↗
Name the effect at the right boundary

Treating the preview’s HTTPS URL as a reason to ignore all ancestor context or sandbox restrictions misdescribes its capabilities. A scripts-allowed row is not a forms-allowed row, and an opaque origin serialized as null is not a trusted preview identity. Relaxing more restrictions than needed may expand browser operations, but the affected data or user action depends on the document and application policy. Here the broken assumption is evaluated through a table, without running a script payload or an external target flow.

WEB-11.04 · Red · CSP, sandbox and secure context ↗
Bind policy to an operation inventory

policyRows records browser connection-gate decisions, while contextRows records expectations for supplied creation contexts. Header/disposition ownership, local violations and endpoint receipt are different observation points. normal and report-only carry a GET to the endpoint; connect-denied and the separate context question do not reach it in this flow. report-gap supplies only a violation, leaving disposition, sending and report delivery unknown. Maintain separate inventories of code sources, connection destinations, child URLs and embedding ancestors for Atlas. Record the response owning the header, its enforce/report disposition and the sandbox flag set. The ordinary preview and read-only request serve as positive controls; comparisons focus on the selected policy’s expected denial. CSP does not replace input handling, output encoding or server authorization. The CSP3 source used here is a Working Draft; the example teaches the established directive meanings within its declared scope.

WEB-11.04 · Blue · CSP, sandbox and secure context ↗
The boundary between browser and model evidence

The context table separates HTTPS, a public HTTP ancestor, loopback and an opaque sandbox inside HTTPS. In a real product API feature detection is evaluated alongside isSecureContext; permission or lifecycle errors can have other causes. This fixture computes only the supplied context snapshots and source-list decisions, without running a browser CSP parser, sandbox navigation or permission UI. Server receipt requires server evidence and enforcement requires browser evidence; animated motion does not produce those independent observations.

WEB-11.04 · Blue · CSP, sandbox and secure context ↗
directions

Maps each directive to its owning document and operation direction.

WEB-11.04 · CSP, sandbox and secure context ↗
policyRows

Self/none and enforce/report decisions for a same-origin GET.

WEB-11.04 · CSP, sandbox and secure context ↗
sandboxRows

Script, form and opaque-origin flags have independent results.

WEB-11.04 · CSP, sandbox and secure context ↗
contextRows

Creation context and origin kind are independent.

WEB-11.04 · CSP, sandbox and secure context ↗
Ambient identity does not establish action intent

Duru saves her Atlas reading view from list to cards. The browser may attach an eligible session cookie as an ambient credential, but carrying her identity does not establish that the request originated from her intended UI action. Eligibility depends on domain/path, scheme/Secure, SameSite, credentials mode and browser storage policy; not every cross-origin request carries cookies. HttpOnly restricts JavaScript reading a cookie, not its attachment to eligible requests. CSRF concerns how expected request provenance and action-intent binding are established for authenticated state changes. Server authentication and object/action authorization remain separate questions.

WEB-11.S01 · Core · CSRF, ambient credentials and action intent ↗
Tokens, Origin and metadata provide different evidence

The selected save-reading-view policy requires a session-bound synchronizer-token validation result. The ledger shows token-present/token-bound booleans, not real secrets. The server verifies the token’s relation to the authenticated session; a signed double-submit design needs session binding as well as a signature. Tokens stay out of URLs and logs. Exact Origin comparison includes scheme, host and port and describes browser source context; opaque null or missing origins do not prove same-origin. Trusted target origin comes from server configuration, not arbitrary forwarded data. Fetch Metadata describes same-origin/same-site/cross-site/none relationships and needs explicit fallback for invalid or unavailable fields. Atlas requires token plus exact origin, accepts that fallback when metadata is absent, and rejects known cross-site state changes.

WEB-11.S01 · Core · CSRF, ambient credentials and action intent ↗
Separate SameSite, origin and business actions

SameSite compares schemeful sites: notes.example.org and atlas.example.org over HTTPS may be different origins within one site. Strict or Lax does not automatically make a sibling origin a trusted actor. Explicit Lax can admit cross-site top-level safe navigation; that does not imply the same result for fetch or POST, and browser default-Lax grace differs from explicit Lax. None requires Secure while third-party policy still applies. Safe methods such as GET/HEAD should not change application state. After provenance passes, the server separately authorizes Duru’s object/tenant action. Sensitive actions may need explicit confirmation or reauthentication bound to the transaction; a header cannot mathematically prove a human’s intent.

WEB-11.S01 · Core · CSRF, ambient credentials and action intent ↗
Accepting a state change merely because a session exists

A normal cookie-backed UI request carries browser state. The broken assumption is that credentials always carry trusted UI intent as well. Risk requires eligible ambient credentials, a relevant state-changing handler and insufficient provenance/intent controls; its scope is limited by the authenticated user’s available actions. CORS or SOP read denial does not prove the server received no request. Missing-token and sibling-origin rows here are inert policy rejections, not executed CSRF requests. Controls bind token validation to server-owned session context and evaluate provenance correctly; a UI checkbox or action name alone does not establish trust.

WEB-11.S01 · Red · CSRF, ambient credentials and action intent ↗
An origin or token result can be overinterpreted

A valid token and trusted origin can still refer to an object in another tenant. The permission-denied branch separates that failure and leaves the reading-view record unchanged. Same-site metadata covers different origins, and none does not imply arbitrary trusted business intent. Compatibility exceptions for missing headers must not silently remove controls; exceptional clients may need a separate authenticated channel/policy. Same-origin code deriving an action or endpoint from untrusted URL data can also lose intent binding; this lesson generates no arbitrary endpoint or code. Expired sessions, old tokens/back-button forms and proxy omissions deserve diagnosis without automatically labeling an attack. Potential impact is the relevant state change, not a blanket account or origin compromise.

WEB-11.S01 · Red · CSRF, ambient credentials and action intent ↗
Log decision reasons separately from identity

The rows table carries supplied validation and permission inputs for the server action gate; sameSite is a separate cookie-eligibility prediction. Cookie sending is not observed here. Every Core branch reaches request arrival: token-missing and sibling-origin stop at provenance, while permission-denied fails the separate action decision after provenance. A retained list cannot distinguish these reasons; gate reasons and a receipt correlated with that action are needed. Record session validity, token presence/validation/binding, origin match, metadata/fallback, ownership and action permission as separate server decision fields. Do not log raw tokens or cookies; validation results and rejection reasons suffice. The ordinary baseline is a trusted origin, valid token and owned object. Classify old sessions or absent metadata at their actual gates. Status alone may not distinguish token failure from object denial, so internal reasons and action correlation complete the observation. Show UI success only after an accepted server transition. The inert matrix records before=list and after=cards or unchanged; modeled responses do not claim execution of a real endpoint action.

WEB-11.S01 · Blue · CSRF, ambient credentials and action intent ↗
Test compatibility and action semantics

Prefer maintained framework CSRF controls while matching session rotation, multiple tabs, back navigation and token lifetimes to the product flow. Atlas regression separates valid provenance with denied action and same-site with different origin. The SameSite table is scoped to explicit attributes and assumed credential eligibility. Test token plus source verification fallback for absent/invalid metadata and do not add null to a trusted origin list. Behind proxies, trusted configuration determines the target origin; approved cross-origin flows must not become a generic exemption. Read GET endpoints remain nonmutating and actions carry an explicit method/intent contract. Choose stronger confirmation for sensitive operations rather than imposing the same challenge on every request, and do not present CORS as the sole CSRF defense.

WEB-11.S01 · Blue · CSRF, ambient credentials and action intent ↗
profile

Harmless reading-view action and before/desired state; token alias is not a secret.

WEB-11.S01 · CSRF, ambient credentials and action intent ↗
rows

Session, provenance and action permission produce separate results.

WEB-11.S01 · CSRF, ambient credentials and action intent ↗
provenancePolicy

Exact origin and session-bound token are selected controls.

WEB-11.S01 · CSRF, ambient credentials and action intent ↗
fallbackRows

Absent metadata creates no trusted-origin assumption.

WEB-11.S01 · CSRF, ambient credentials and action intent ↗
sameSite

Explicit attribute/eligibility model; not a browser cookie test.

WEB-11.S01 · CSRF, ambient credentials and action intent ↗
What does CORS expose?

Reading the Tea & Bread title from Atlas’s owned API concerns resource-server permission to expose a response to a browser origin. Session/object policy is separate. A simple GET can reach the server and receive a normal response while CORS prevents script access to its content; that does not prove absence of server effects. Credentials mode include requires an exact ACAO origin and ACAC true; wildcard ACAO does not allow exposure in that mode, even if no cookie actually exists. Actual credential attachment still depends on SameSite and storage policy. Method/header/value conditions can introduce a preflight before the normal exchange; its permission is not object authorization.

WEB-11.S02 · Core · CORS, framing and cross-window message validation ↗
Framing policy belongs to the response owner

A book-preview document limits its embedders with response-header CSP frame-ancestors. The parent’s frame-src instead limits child resource loading; these control opposite directions. frame-ancestors checks the whole ancestor chain, not just the immediate parent, has no default-src fallback and is ignored in meta delivery. An enforced directive overrides X-Frame-Options in supporting browsers. XFO DENY/SAMEORIGIN supplies legacy compatibility; current SAMEORIGIN requires all ancestors to match, while RFC7034 records historical implementation variation. Obsolete ALLOW-FROM is not a modern allowlist solution. Framing denial is a UI-embedding boundary, not a DOM-read or server-permission decision.

WEB-11.S02 · Core · CORS, framing and cross-window message validation ↗
A Window message passes four gates

Atlas retains the preview-A WindowProxy reference and a pending read-7 transaction. A harmless reply contains kind=book-title, version=1, requestId=read-7 and title=Tea & Bread, queued for the exact parent targetOrigin. The receiver checks event.origin against the expected sender origin, event.source against its retained preview reference, data against a closed schema and requestId against the pending transaction. event.origin reflects send time; the document can later navigate while its WindowProxy reference remains. Payload origin/source strings do not replace browser event identity. Structured cloning copies data without establishing trust or ordering independent async replies. A transferred MessagePort is a separate capability/channel contract, not an assumption that every port message exposes Window origin/source.

WEB-11.S02 · Core · CORS, framing and cross-window message validation ↗
Response reading, embedding and business actions differ

A title read, preview embedding and reply delivery require different capabilities. The broken assumption is that one origin-allow decision authorizes all of them. Generic CORS origin reflection or incorrect credentials-mode handling changes script exposure, whose impact depends on returned data and real object policy. Missing framing policy can permit relevant action UI inside another context; clickjacking additionally requires deceptive user interaction and applicable UI/action conditions. CORS headers are not framing policy, and frame-ancestors does not replace action-intent/CSRF controls. The artifact uses a benign GET and ordinary ancestor matrix, with no overlay, exploit form or third-party request.

WEB-11.S02 · Red · CORS, framing and cross-window message validation ↗
A trusted sender can still return stale or malformed data

A matching origin can still belong to another preview reference, and matching origin/source can still return read-6 after the UI has moved to read-7. Missing titles, extra fields and incorrect versions fail a separate schema gate. These failures also occur during normal multi-window and async lifecycle behavior. The receiver does not use domain-suffix matching or treat payload source aliases as browser identity. Accepted titles remain ordinary h2 text data; message acceptance is not permission to interpret HTML/code. Receiver-handler exceptions do not return synchronous success/failure to the sender of a queued reply. Retained references, expected kinds/types and pending-operation correlation are controls, alongside the sender’s exact targetOrigin privacy boundary.

WEB-11.S02 · Red · CORS, framing and cross-window message validation ↗
Observe evidence where each control executes

corsRows retains API response predicates and expected browser exposure; framing.rows retains resource ancestor policy; messageRows retains parent-receiver acceptance predicates. These are supplied example records. normal/stale-message use a Window task without reaching the API; cors-denied carries a GET to the API, while frame-denied is only local policy evaluation. A title observed in correlation-gap cannot establish which path executed. Record request origin, credentials mode, explicit ACAO/ACAC and exposure result with the response source; server read permission and browser exposure are separate fields. If responses vary by explicit origin, relevant caches need Vary: Origin, which is not itself permission checking. Framing review collects the protected response header, enforce/report disposition and complete ancestor chain rather than counting meta/default-src as protection. Message logs separate origin/source/schema/transaction matches and reasons without logging secrets or full bodies. Browser diagnostics know their network/CORS results and server audit knows its own action; one surface cannot certify the whole chain.

WEB-11.S02 · Blue · CORS, framing and cross-window message validation ↗
Keep the matrices separate

Regression expects blocked script access for credentials mode include with wildcard ACAO; uncredentialed public wildcard and explicit approved origins follow their own policies. The ancestor matrix separates an owned chain from a different outer origin above an owned immediate parent, and distinguishes enforced CSP from legacy XFO fallback. Window checks independently cover same origin with wrong reference, valid reference with stale transaction and invalid schema. Opaque origins or intentional port transfer require different product contracts rather than silently joining this exact tuple-origin Window profile. Native structuredClone only verifies copied ordinary data, not browser event identity, CORS or framing enforcement. Product policy retains text rendering and server action gates independently from these transport/result controls.

WEB-11.S02 · Blue · CORS, framing and cross-window message validation ↗
corsRows

Browser exposure differs from server read permission.

WEB-11.S02 · CORS, framing and cross-window message validation ↗
framing

Response-owned ancestor/XFO matrix uses a selected support profile.

WEB-11.S02 · CORS, framing and cross-window message validation ↗
messageSchema

Expected fields/types for a closed harmless title reply.

WEB-11.S02 · CORS, framing and cross-window message validation ↗
messageRows

Event-identity aliases, target and pending transaction are separate.

WEB-11.S02 · CORS, framing and cross-window message validation ↗
profile

Reserved example origins and no-actual-execution scope.

WEB-11.S02 · CORS, framing and cross-window message validation ↗
How does the next request remember the page language?

Duru selects Turkish and a compact view in the Atlas library. The next page should retain those choices. HTTP being stateless does not prohibit application memory: the meaning of a request does not depend on the connection that carried an earlier message. Continuity is built from information on later requests and application state.

WEB-12.01 · Core · Adding state to HTTP with cookies ↗
Set-Cookie brings the server’s instruction to the Browser

The Application processes Duru’s selection and adds two separate Set-Cookie fields to its response. One contains hd_language=tr; Path=/ and the other hd_view=compact; Path=/. Each describes a separate cookie. Folding the two Set-Cookie fields into one comma-separated list is not a valid general combining method.

WEB-12.01 · Core · Adding state to HTTP with cookies ↗
Cookie expresses the Browser’s selection for a later request

When Duru opens the book list, the Browser selects eligible records and sends Cookie: hd_language=tr; hd_view=compact. The semicolon separates two name/value pairs. Attributes such as Path=/ from Set-Cookie are not repeated in the request Cookie field.

WEB-12.01 · Core · Adding state to HTTP with cookies ↗
The server interprets the incoming data again

The Application parses both preferences on the second request. Our model allows tr/en for language and compact/comfortable for view. Valid pairs affect response presentation. Without them, the Application uses its en/comfortable defaults. Both results are explained by the endpoint contract.

WEB-12.01 · Core · Adding state to HTTP with cookies ↗
Separate the cookie mechanism from the kind of state it carries

A cookie can hold a preference directly or carry an opaque handle to a server record. In the second design, the large state is not inside the Cookie header; the handle tells the Application which record to evaluate. WEB-13.01 develops that separation for sessions.

WEB-12.01 · Core · Adding state to HTTP with cookies ↗
When does this state disappear?

If Duru clears the cookies, the next request may omit the preference pairs and receive the default view. This does not erase Atlas’s database or all server state. Dropping a Browser preference and changing application records are independent operations.

WEB-12.01 · Core · Adding state to HTTP with cookies ↗
Do not turn a preference into authority

The normal function is choosing language and layout. Its control restricts incoming values to two small allowed sets. Treating a cookie as an authority document because “the server wrote it earlier” gives client state excessive authority.

WEB-12.01 · Red · Adding state to HTTP with cookies ↗
Automatic transmission does not remove application controls

A Browser-generated Cookie header does not prove that the user deliberately approved every request. Cookie state carries context to a subsequent operation; it does not independently establish intent or safety.

WEB-12.01 · Red · Adding state to HTTP with cookies ↗
Distinguish the sent header from the accepted record

Compare two Set-Cookie fields on the response, two records in cookie storage and pairs inside one Cookie field on the later request. These are not three copies of one screen. Policy evaluation separates response arrival from cookie acceptance, and later transmission is a fresh selection.

WEB-12.01 · Blue · Adding state to HTTP with cookies ↗
Observe preference decisions without carrying credentials

Our observation record has requestId, cookiePresent, languageDecision and viewDecision. These are fields in an application-owned example schema. Instead of copying the raw Cookie header into general logs, record only the constrained preference decision needed; the same header may later contain a session credential.

WEB-12.01 · Blue · Adding state to HTTP with cookies ↗
Explain the control outcome together with its state source

Document allowed preference values, defaults and behavior under Browser privacy settings at the consuming endpoint. Verify the fallback when cookies are removed. Preserve the distinction between preferences and authenticated handles rather than applying one policy to every cookie class.

WEB-12.01 · Blue · Adding state to HTTP with cookies ↗
responseFields

Separate Set-Cookie fields per cookie, not one comma-separated field.

WEB-12.01 · Adding state to HTTP with cookies ↗
jarAfterArrival

Expected records after arrival and permitted Browser policy, not captured storage.

WEB-12.01 · Adding state to HTTP with cookies ↗
nextRequestFields

Transmitted name/value pairs without Path attributes.

WEB-12.01 · Adding state to HTTP with cookies ↗
applicationPolicy / branches

Preference allowlists and defaults, not authentication or book permissions.

WEB-12.01 · Adding state to HTTP with cookies ↗
observationXML / localXPath

Local selection over our synthetic XML, without network or temporal correlation.

WEB-12.01 · Adding state to HTTP with cookies ↗
The cookie is in the jar; why is it missing from the request?

Duru’s Browser shows an hd_scope record for the Atlas library, yet a request to another URL may omit it. Inclusion is not one “cookie exists” question: scope, lifetime, transport, site context and Browser policy are evaluated together.

WEB-12.02 · Core · Cookie scope, lifetime and flags ↗
Omitting Domain makes a cookie host-only; setting it broadens scope

A cookie set by library.outreason.example without Domain is host-only: it is a candidate for that host, not automatically for api.library.outreason.example. With Domain=outreason.example, it can be a candidate for that domain and eligible subdomains. A server cannot freely choose an unrelated domain or public suffix.

WEB-12.02 · Core · Cookie scope, lifetime and flags ↗
Path matching is more than guessing a string prefix

A cookie with Path=/books can match /books and /books/42, but not /bookstore. The slash boundary matters. An omitted Path defaults from the URL of the request associated with the response; do not assume it is always /.

WEB-12.02 · Core · Cookie scope, lifetime and flags ↗
Lifetime describes retention and the Browser session

Max-Age expresses cookie lifetime in seconds; Expires uses a date. Max-Age takes precedence when both are present. Our artifact assumes Browser creation at t=100 with Max-Age=1200 and considers the cookie expired at t=1300. This explicit model clock is not a captured real clock.

WEB-12.02 · Core · Cookie scope, lifetime and flags ↗
Secure and HttpOnly control different things

In ordinary web use, Secure requires HTTPS transport; this excludes the artifact’s HTTP case. Localhost exceptions and Browser compatibility need separate assessment. Secure alone does not protect the value against disk or script access.

WEB-12.02 · Core · Cookie scope, lifetime and flags ↗
Read SameSite with method and navigation context

Same-site evaluation uses scheme and registrable-domain context; it is not equivalent to same-origin. Lax can allow same-site requests. For cross-site requests, explicit Lax also considers top-level navigation and a safe method: a normal GET link navigation differs from a background POST fetch.

WEB-12.02 · Core · Cookie scope, lifetime and flags ↗
Third-party context adds a policy gate

A library widget embedded on another site can encounter blocked or partitioned third-party state even with SameSite=None; Secure. Without observing application/Browser version, user settings and context, do not claim None works everywhere. The lesson does not treat a vendor roadmap as a Browser guarantee.

WEB-12.02 · Core · Cookie scope, lifetime and flags ↗
Broader scope also broadens the state-sharing boundary

Domain=outreason.example makes the record eligible for multiple hosts. Sharing a preference can be legitimate, but the relevant assumption concerns the trust level of those hosts’ state use. Expanding scope unnecessarily creates additional sharing when host-only would suffice.

WEB-12.02 · Red · Cookie scope, lifetime and flags ↗
Do not substitute one flag for every control

HttpOnly can hide a value from script APIs without establishing who approved a state-changing action in which context. Secure selects eligible transport without restoring authority to a handle the store must reject.

WEB-12.02 · Red · Cookie scope, lifetime and flags ↗
Observe inclusion one condition at a time

Compare Domain/host-only, Path, expiry and flags in cookie storage with the target URL and request context. If Network omits a cookie, inspect Browser exclusion reasons and method/navigation first. A cookie name or server status alone cannot explain the omission.

WEB-12.02 · Blue · Cookie scope, lifetime and flags ↗
Simple selection and missing evidence

XPath /cookieDecisions/decision[@included="false"] selects the model’s excluded cases. Expected benign results include host-only subdomain mismatch, path mismatch, an insecure channel and cross-site POST under Lax. Calling the selected rows attacks would be incorrect.

WEB-12.02 · Blue · Cookie scope, lifetime and flags ↗
Validate policy changes together with compatibility

Narrowing scope or changing SameSite can affect login redirects, embedded widgets and subdomain flows. Inventory which flows are cross-site, cross-origin or same-host. Observe both expected inclusion and expected exclusion with a small user group.

WEB-12.02 · Blue · Cookie scope, lifetime and flags ↗
hostOnly / domain

Only the setter host versus domain-plus-subdomain eligibility.

WEB-12.02 · Cookie scope, lifetime and flags ↗
path

Request-path filtering with slash boundaries, not security isolation.

WEB-12.02 · Cookie scope, lifetime and flags ↗
createdAt_s / maxAge_s / now_s

Explicit Browser-lifetime calculation, not a server session timeout.

WEB-12.02 · Cookie scope, lifetime and flags ↗
secure / httpOnly

Separate transport and script access; HttpOnly does not automatically block inclusion.

WEB-12.02 · Cookie scope, lifetime and flags ↗
sameSite / topLevelNavigation / method

Context for explicit-Lax inclusion. sameSite is supplied input, not a PSL algorithm output.

WEB-12.02 · Cookie scope, lifetime and flags ↗
browserPolicyAllowed

Selected third-party privacy gate, not overridden by None.

WEB-12.02 · Cookie scope, lifetime and flags ↗
expected / decisionXML

Benign include/exclude outcomes and the inert local-XPath schema.

WEB-12.02 · Cookie scope, lifetime and flags ↗
Where should the data live?

In the Atlas reading app, a theme preference is a small string. A book note can be a record containing a title, text, and update time. An offline cover is a different type: an HTTP Response. Deciding to keep something in the Browser does not resolve these differences.

WEB-12.03 · Core · Browser storage options ↗
localStorage: small string state for an origin

localStorage stores string keys and values, and tabs of the same origin use a shared storage area. An origin is determined by scheme, host, and port; HTTP and HTTPS versions have separate storage. Paths such as /books and /profile are not separate security compartments.

WEB-12.03 · Core · Browser storage options ↗
sessionStorage: tab state that does not always start empty

sessionStorage is partitioned by origin and top-level browsing context, usually the tab. Duru’s form draft in tab A is not continuously shared with tab B. The same page session can survive reload and page restore; refreshing a page is not a storage-clearing command.

WEB-12.03 · Core · Browser storage options ↗
IndexedDB: asynchronous records and transactions

IndexedDB offers structured records, object stores, and indexes; reads and writes use asynchronous requests. Duru’s offline book notes are a more natural IndexedDB candidate than a theme string. Supported values are stored using structured-clone rules; arbitrary JavaScript object behavior is not preserved. In particular, custom prototype chains and property descriptors are not copied; do not expect a retrieved record to preserve class methods or readonly behavior. Store explicit data fields and define behavior in application code.

WEB-12.03 · Core · Browser storage options ↗
Cache Storage is distinct from the HTTP cache

Cache Storage holds Request/Response pairs through named caches. An application can store an offline cover Response and select it later. The Cache API is available in window and worker contexts; it does not have to run inside a service worker. It requires a secure context.

WEB-12.03 · Core · Browser storage options ↗
Capacity and privacy are part of the data flow

Browser storage is finite. A write can fail because of quota; default best-effort IndexedDB and Cache Storage data can be evicted under storage pressure. A persistent-storage request depends on the Browser’s decision and does not prevent user deletion. Do not assume one universal capacity number for every API and Browser.

WEB-12.03 · Core · Browser storage options ↗
A storage name is not a security boundary

In a defensive review, first ask which scripts can access the data. localStorage, sessionStorage, and IndexedDB are accessible to JavaScript running in the origin; tab isolation does not make sessionStorage a secret vault. A secret included in a frontend bundle has already been delivered to the client.

WEB-12.03 · Red · Browser storage options ↗
Treat local records as input

A tenant or role field in Duru’s local note record does not make it trusted authority for the server. Local data can be stale, malformed, or changed by the user. Security review focuses on how the server validates that data.

WEB-12.03 · Red · Browser storage options ↗
Tie the storage choice to the state type

Consider localStorage for a small reproducible preference, sessionStorage for a temporary tab draft, IndexedDB for related structured offline records, and Cache Storage for application-managed offline Responses. These are starting choices justified by lifetime and data model, not mandatory pairings.

WEB-12.03 · Blue · Browser storage options ↗
Make failure branches real product states

Preserve the draft in memory and keep the unsaved warning after quota failure or transaction abort. Route cache misses to normal fallback. Cleared Browser storage is not grounds for creating a new authenticated session.

WEB-12.03 · Blue · Browser storage options ↗
Reduce stored secrets and authority

Do not deliver server secrets to the frontend; choose session-credential transport through a separate threat model and prefer established platform session support. Validate business fields stored in client storage on the server. Finding a preference key is not proof of login.

WEB-12.03 · Blue · Browser storage options ↗
boundary

The API visibility scope, not an authenticated authorization boundary.

WEB-12.03 · Browser storage options ↗
transaction / uiSaved

Local success is tied to the transaction result, not merely request success.

WEB-12.03 · Browser storage options ↗
automaticCacheApiExpiry

A named-cache expiry is not implied by Cache-Control.

WEB-12.03 · Browser storage options ↗
selector

A local consistency selector over two synthetic XML fixtures; it is not a Browser-storage measurement.

WEB-12.03 · Browser storage options ↗
A note can have several valid states

Duru writes a note for a book in Atlas. Seeing “new note” in the Browser input does not mean the server record changed. The UI owns the first copy; the trusted server side of the application owns the canonical business record.

WEB-12.04 · Core · Client and server state ownership ↗
Separate a snapshot from authority

The Browser can keep text and a version received from the server. This is a snapshot observed at a particular time. If another tab or worker updates the note, the Browser’s older copy does not become authoritative by itself.

WEB-12.04 · Core · Client and server state ownership ↗
Normal save: make an accepted update visible

Initially, the server has note-v3 and the Browser knows a snapshot of the same version. Duru’s new text is based on that snapshot. The request contains the new text and an If-Match precondition for the strong ETag “note-v3”.

WEB-12.04 · Core · Client and server state ownership ↗
Stale snapshots: do not silently overwrite newer work

In the second branch, the Browser writes from v2 while the server’s current note is v3. An unconditional overwrite could erase a change already accepted elsewhere. If-Match uses strong comparison for the current representation to help prevent this lost update.

WEB-12.04 · Core · Client and server state ownership ↗
A lost response can leave the outcome unknown

After the server commits v4, the response might not reach the Browser. With only v3 known, the Browser has no basis to say either “the server did not save it” or, merely because a request was sent, “saved”. In this branch, server state changed while client knowledge is unknown.

WEB-12.04 · Core · Client and server state ownership ↗
What does an ETag establish?

An ETag is an opaque representation validator, not a credential, role, or ownership proof. Here, note-v3 is a readable instructional alias. The application chooses its validator format; any field that resembles an increasing number is not automatically a strong ETag.

WEB-12.04 · Core · Client and server state ownership ↗
Which state feeds the decision?

In a defensive review, distinguish a visible UI button from the server accepting its action. A hidden/disabled control is interaction state only. Seeing role=editor in the Browser is not a trusted authorization result.

WEB-12.04 · Red · Client and server state ownership ↗
A success label is also a claim

When reviewing a save flow, inspect when optimistic UI claims “saved”. If rejection or an unknown outcome does not correct that claim, the product misleads the user about state.

WEB-12.04 · Red · Client and server state ownership ↗
Write down ownership and success boundaries

Define the Browser as owner of UI input and local drafts, and the trusted server as owner of accepted notes and access policy. Track each state’s source, version, and freshness. When using a cache or snapshot, identify where the authoritative record resides.

WEB-12.04 · Blue · Client and server state ownership ↗
Enforce the condition together with commit

For an endpoint accepting concurrent updates, enforce request authorization and input validation, then perform the precondition comparison and mutation at a consistent commit boundary. Choosing a database conditional update, transaction, or another appropriate primitive depends on the implementation.

WEB-12.04 · Blue · Client and server state ownership ↗
Reobserve an unknown response outcome

After a connection failure, reread the server record and compare it with the known version and draft. If the mutation needs retrying, use the operation’s idempotency and concurrency policy. Explain that the draft is preserved and what remains pending while the server outcome is confirmed.

WEB-12.04 · Blue · Client and server state ownership ↗
browserBase / serverBefore

The Browser snapshot validator and the server current validator; equality is only a concurrency precondition.

WEB-12.04 · Client and server state ownership ↗
serverAfter / serverDecision

The trusted server commit result, independent of whether the response arrived.

WEB-12.04 · Client and server state ownership ↗
responseObserved / browserKnowledge

Whether the Browser learned the outcome; sending alone is not proof of a server save.

WEB-12.04 · Client and server state ownership ↗
selector

Selects fixture records that simultaneously claim a false precondition and a commit.

WEB-12.04 · Client and server state ownership ↗
How is login bound to the next request?

Duru signs in to the Atlas library and then opens another book page. Where does the later request obtain its authenticated subject? Sending the text “Duru” on each page is not identity evidence. The Application establishes a controlled binding between an earlier verified identity and later requests.

WEB-13.01 · Core · Session identifiers and Browser transport ↗
The identifier is a handle to a record, not the identity itself

sid-duru-fixture is an instructional alias pointing to Duru’s authenticated record, not a usable credential. It does not encode “Duru” or “Atlas.” Store lookup supplies that meaning; a Browser role or tenant assertion does not establish it.

WEB-13.01 · Core · Session identifiers and Browser transport ↗
Creation starts from a trusted identity result

The Application first verifies identity through its trusted authentication process. identityVerified=true is a supplied precondition in this fixture, not a claim that real password/MFA verification ran. The server generates a handle using its session mechanism and binds its own Duru/Atlas context to the authenticated record.

WEB-13.01 · Core · Session identifiers and Browser transport ↗
Entropy is not string length

A production identifier must be unpredictable. Prefer an appropriate framework’s session generation; if custom generation is necessary, OWASP recommends a CSPRNG with at least 128 bits and uniqueness checks. This is not one universal policy for every token type.

WEB-13.01 · Core · Session identifiers and Browser transport ↗
The Browser carries the handle; scripts need not read it

The synthetic HTTPS response shows __Host-hd_session=SYNTHETIC_OPAQUE_HANDLE; Path=/; Secure; HttpOnly; SameSite=Lax. An eligible Browser includes this cookie on suitable requests. Frontend code does not need to read its value through document.cookie and manually construct a header for this flow.

WEB-13.01 · Core · Session identifiers and Browser transport ↗
Binding is checked again when the request arrives

The Application takes the supplied handle from the designated exchange mechanism. This model accepts no URL fallback or arbitrary client field. If the recognized record is active and valid, its server-owned Duru/Atlas context supplies an authenticated subject for subsequent resource policy.

WEB-13.01 · Core · Session identifiers and Browser transport ↗
Server binding gives a handle its authority

A valid handle normally reaches authenticated context established earlier by the server. The broken assumption is that client-supplied subject/role text or an audit reference can establish equivalent authority. A well-shaped identifier is not authentication evidence.

WEB-13.01 · Red · Session identifiers and Browser transport ↗
Unpredictability and confidentiality address different risks

High entropy does not magically protect a disclosed value, and HTTPS does not add randomness to weak generation. Generation, transport, Browser/script access and log hygiene are different control surfaces.

WEB-13.01 · Red · Session identifiers and Browser transport ↗
Creation, delivery and lookup need separate evidence

Creation evidence describes server-record preparation; Set-Cookie describes a sent instruction; jar inspection describes Browser storage; a protected decision describes lookup. Observing one does not prove completion of all the others.

WEB-13.01 · Blue · Session identifiers and Browser transport ↗
Correlate lookup decisions without session values

Audit uses a separate sessionRef instead of the raw handle. Missing and unknown cases retain a null subject; inferring userId from cookie presence would be incorrect correlation. Missing can reflect Browser policy, and unknown can reflect store/cache lifecycle; neither is automatically an alarm.

WEB-13.01 · Blue · Session identifiers and Browser transport ↗
Record-based identity, separate resource policy

In manual observation, compare the creation identity, noncredential Browser metadata and the resolved subject of an accepted check. If the record says Duru/Atlas while the UI shows another tenant, inspect the state source that changed; do not “fix” the example by deriving identity from client fields.

WEB-13.01 · Blue · Session identifiers and Browser transport ↗
authenticationPrecondition

A previously verified identity fixture; client username text does not establish authenticated state.

WEB-13.01 · Session identifiers and Browser transport ↗
handleAlias / SYNTHETIC_OPAQUE_HANDLE

Fixed secrets-free instructional labels, not random generation or working credentials.

WEB-13.01 · Session identifiers and Browser transport ↗
storeRecord.subject / tenant

Application-owned binding context, not arbitrary cookie identity claims.

WEB-13.01 · Session identifiers and Browser transport ↗
storeRecord.handleRepresentation

No assumption of raw token database storage; lookup/verifier implementation is outside the drawing.

WEB-13.01 · Session identifiers and Browser transport ↗
sessionRef

Audit correlation reference, never accepted as a credential substitute.

WEB-13.01 · Session identifiers and Browser transport ↗
creationTrace.seq / browserHasNewHandle

Separate server-record creation, sent response and Browser arrival.

WEB-13.01 · Session identifiers and Browser transport ↗
cases.lookup / result / reason

Supplied recognized/missing/unknown cases, not session enumeration results.

WEB-13.01 · Session identifiers and Browser transport ↗
observationXML / localXPath

Synthetic accepted/subject consistency selection, not a complete verifier or multi-host correlation.

WEB-13.01 · Session identifiers and Browser transport ↗
Same handle, different application node

In WEB-13.01, an opaque Browser handle resolved to a server-side binding. Now let one Duru request reach Node A and the next reach Node B. Seeing the same handle text does not automatically prove that the nodes see the same authenticated record.

WEB-13.02 · Core · Session stores and distributed sessions ↗
What does process memory provide and lose?

A single application process can keep session objects in its own memory. This is simple, but another process does not automatically share that area. After a restart, a record held only in volatile memory does not return as though it were durable disk data.

WEB-13.02 · Core · Session stores and distributed sessions ↗
Shared session store: a common record, separate request decisions

Nodes A and B can resolve the same binding through a shared store. When the store is a separate service, application↔store messages use a driver/protocol connection distinct from Browser↔Application HTTP. The scene starts after Node B has received a Browser request and depicts the remote lookup.

WEB-13.02 · Core · Session stores and distributed sessions ↗
Stale state: an old active copy must not overwrite revocation

In another fixture branch, Node A previously read a version-7 active snapshot. Node B’s logout flow changed the shared record to version 8 revoked. A’s snapshot is a historical observation, not current authority.

WEB-13.02 · Core · Session stores and distributed sessions ↗
Evaluate consistency separately from durability

Using a shared endpoint does not guarantee that every reader instantly sees the latest state. Basic Redis replication is asynchronous by default. A replica-read strategy can expose older state; the acceptable consistency boundary for revocation needs an explicit decision.

WEB-13.02 · Core · Session stores and distributed sessions ↗
Expiry, eviction, missing, and failure are different outcomes

Session expiry is the application’s server-side lifetime decision. A store TTL can help clean up obsolete records; a physically present record is not usable after its policy deadline. Do not rely solely on cleanup timing to enforce expiry.

WEB-13.02 · Core · Session stores and distributed sessions ↗
Review more than the happy-path node

In a defensive review, record recognition on Node A separately from recognition on Node B. Lookup source, observed version, and decision belong together. A branch where a local cache shows an old active state helps explain whether current revocation is enforced.

WEB-13.02 · Red · Session stores and distributed sessions ↗
Store access is also a credential boundary

A session store should not be broadly accessible merely because it is called a performance cache. Reading a store that holds raw random tokens can disclose still-valid credentials. High entropy does not prevent disclosure.

WEB-13.02 · Red · Session stores and distributed sessions ↗
Define authoritative state and read policy

Define the same binding source, expected revocation visibility, and approved read path for every node. If replicas or local caches are used, explicitly limit decisions that may accept stale state; a short cache TTL alone is not a strong-consistency guarantee.

WEB-13.02 · Blue · Session stores and distributed sessions ↗
Make lifetime updates an atomic policy

For touch/refresh, evaluate expected version, active state, and lifetime conditions at one atomic boundary. Reread on conflict; reject turning revoked/missing/expired state into active without valid authentication. A generic upsert does not replace this policy.

WEB-13.02 · Blue · Session stores and distributed sessions ↗
Make failure safe and understandable

Distinguish missing records, policy expiry, capacity eviction, and service-unavailable observations. This fixture fails closed when it cannot resolve enough trusted state for authenticated processing; it does not present a service error as proof of logout. Retry and recovery cannot invent authenticated authority.

WEB-13.02 · Blue · Session stores and distributed sessions ↗
lookup / source

Lookup outcome and freshness source; error, missing, and an older snapshot differ.

WEB-13.02 · Session stores and distributed sessions ↗
expectedVersion / observedVersion

The concurrency condition for a conditional update; not a security credential.

WEB-13.02 · Session stores and distributed sessions ↗
recordState / lifetimeValid

Physical record presence does not replace active state and valid lifetime.

WEB-13.02 · Session stores and distributed sessions ↗
sessionAccepted

This fixture’s session decision, not the resource-authorization result.

WEB-13.02 · Session stores and distributed sessions ↗
selector

Queries the known+active+lifetime invariant for acceptance; not actual telemetry.

WEB-13.02 · Session stores and distributed sessions ↗
The cookie carries a handle; the server owns the session decision

After signing in to the Atlas library, Duru opens another page. The new HTTP request does not remember the earlier login. The Browser includes an eligible cookie, and the Application checks its identifier against the Session store. Our example uses an opaque handle: the server record supplies its identity, authentication state and time limits. Possessing a cookie is not proof of an accepted session.

WEB-13.03 · Core · Session lifecycle, login and logout ↗
Login does not reach both sides at once

Initially, the Browser holds an anonymous session shown as sid-a. At t=10, when Duru has been authenticated, the Application creates a new authenticated generation shown as sid-b. It does not promote the anonymous identifier into the authenticated identity. sid-a and sid-b are instructional aliases, not usable credentials or a production identifier format.

WEB-13.03 · Core · Session lifecycle, login and logout ↗
A protected request: lookup, time checks, then resource policy

At t=70, Duru opens a book record. Browser cookie-inclusion rules carry the eligible identifier to the Application. The Application looks up the store record and checks that its generation is active and its deadlines have not passed. A successful check sets lastSeen=70 in this example. Which requests count as activity is application policy; background polling need not count as human activity.

WEB-13.03 · Core · Session lifecycle, login and logout ↗
Three clocks describe different things

Our policy uses a 300-second idle timeout and a 1800-second absolute timeout. These are teaching values, not recommended settings for every product. The new session begins at t=10, giving an absolute deadline of 1810. After the accepted action at t=70, its idle deadline is 370. At t=370, now−lastSeen >= 300 causes rejection; this request cannot rescue itself by advancing lastSeen.

WEB-13.03 · Core · Session lifecycle, login and logout ↗
Logout combines server invalidation and cookie cleanup

The logout branch starts from the accepted session at t=70. Duru selects logout at t=90. The Application marks the current generation revoked, then sends Max-Age=0 for the same cookie name, Path and Domain scope, if one exists. Server invalidation, response receipt and cookie-jar cleanup are separate transitions.

WEB-13.03 · Core · Session lifecycle, login and logout ↗
Cookie flags protect different boundaries

The synthetic HTTPS example uses __Host-hd_session; Path=/; Secure; HttpOnly; SameSite=Lax without Domain. A Browser supporting the __Host- rule requires Secure, host-only scope and Path=/. The prefix is not a compatibility guarantee for every Browser version.

WEB-13.03 · Core · Session lifecycle, login and logout ↗
Self-contained tokens change the logout question

With an opaque handle, the Application ties each acceptance decision to server state. If a self-contained-token verifier independently checks a signature and expected issuer/audience/time conditions, deleting the token in the Browser does not send that verifier new revocation information. Cryptographic validity and current permission to use a token are different questions.

WEB-13.03 · Core · Session lifecycle, login and logout ↗
Why keep pre-authentication state separate?

An anonymous session can hold preferences or temporary UI state. An authenticated session binds Duru’s identity to protected operations. The authority of the latter must not be established by trusting who selected the earlier identifier or where it was previously used.

WEB-13.03 · Red · Session lifecycle, login and logout ↗
Protecting a cookie and invalidating a session are separate controls

When an identifier is a bearer handle sufficient to reach authenticated state, its confidentiality matters. Appropriate HTTPS transport and narrow cookie scope reduce exposure. HttpOnly limits script access to the value; it does not independently prevent the Browser from carrying the identity on eligible script-initiated actions.

WEB-13.03 · Red · Session lifecycle, login and logout ↗
Why must an expired or revoked handle be rejected?

At t=370, the cookie may still be visible while the session no longer meets the idle condition. Relying on a UI timer makes the server decision depend on client presentation. Similarly, logout that only cleans the jar can leave server authority intact. Durable enforcement evaluates the current generation and server deadlines where protected processing is accepted.

WEB-13.03 · Red · Session lifecycle, login and logout ↗
Which observation proves which state?

Seeing Set-Cookie in DevTools Network shows that the Application sent a header. Assess Browser acceptance separately through cookie storage and relevant request inclusion; policy, scope or Browser settings can affect it. A visible cookie does not establish an active server record, and a UI identity label does not prove the latest protected decision succeeded.

WEB-13.03 · Blue · Session lifecycle, login and logout ↗
Lifecycle correlation without credentials

Use an audit correlation reference to connect rotation, expiry and logout; do not log raw session values, Set-Cookie values or credentials. generationRef=ledger-b is an audit reference that cannot be converted into the Browser handle. requestId=demo-session-3 connects only the application check and its decision record.

WEB-13.03 · Blue · Session lifecycle, login and logout ↗
Validation and durable controls

In the manual lab, observe the jar before and after login, the sanitized store view, expiry using the explicit demo clock, and the protected decision after logout. Predict each result first, then record its observation layer. Explain the intermediate view if store invalidation and response arrival are separate steps.

WEB-13.03 · Blue · Session lifecycle, login and logout ↗
SYNTHETIC_AUTH_B / sid-b

A fixed instructional label for following the authenticated handle, not a working secret. It does not demonstrate production identifier generation.

WEB-13.03 · Session lifecycle, login and logout ↗
__Host-hd_session, Path=/, no Domain

Host-only and root-path prefix requirements in supporting Browsers, not permission to access a resource.

WEB-13.03 · Session lifecycle, login and logout ↗
Secure / HttpOnly / SameSite=Lax

Transport, script access and site-context inclusion boundaries, independent of server validity.

WEB-13.03 · Session lifecycle, login and logout ↗
Max-Age=1800 / Max-Age=0

Browser retention/deletion instructions, not a store TTL or server logout result.

WEB-13.03 · Session lifecycle, login and logout ↗
generationRef / previousGenerationRef

Our schema’s audit correlation references, distinct for each generation and never accepted as cookie values.

WEB-13.03 · Session lifecycle, login and logout ↗
clock_s / seq

An explicit model clock and event order within one branch, not real time, Windows Event IDs or distributed global order.

WEB-13.03 · Session lifecycle, login and logout ↗
lastSeen_s / absoluteDeadline_s

The latest accepted activity for idle calculation and the independent absolute deadline. The rejected t=370 request does not update lastSeen.

WEB-13.03 · Session lifecycle, login and logout ↗
event / result / reason

Synthetic application-owned lifecycle events and decision explanations; not an automatic mapping to gateway access logs.

WEB-13.03 · Session lifecycle, login and logout ↗
requestId

Correlates one check/response operation; it is not an authenticated identity or session secret.

WEB-13.03 · Session lifecycle, login and logout ↗
idleBranch / logoutBranch

Alternative scenarios branching from the same accepted state; do not merge them into logout occurring after expiry.

WEB-13.03 · Session lifecycle, login and logout ↗
Identity is a subject within a context

Duru can be a display name, duru.reader a login identifier, and subject-duru the Atlas application’s internal subject reference. These have different jobs. A display name can change or be shared with another user; trusted authorization references should not rely only on that text.

WEB-14.01 · Core · Identity, credentials, and password authentication ↗
A credential differs from an identifier

A login identifier answers which account is being claimed. A credential concerns a password, security token, or other authenticator used to support that claim. Knowing Duru’s subject ID does not establish knowledge of her password.

WEB-14.01 · Core · Identity, credentials, and password authentication ↗
Authentication and authorization are different decisions

Authentication evaluates whether a presented authenticator sufficiently supports the relevant identity claim. Authorization determines whether a trusted actor may perform a specific action on a specific resource in the current context.

WEB-14.01 · Core · Identity, credentials, and password authentication ↗
Password storage: a verifier instead of plaintext

During registration, the application uses password-hashing/KDF support to produce a verifier instead of retaining readable plaintext. It needs a current, password-specific algorithm with adjustable cost; an ordinary fast SHA-256 digest is not an adequate password-storage choice.

WEB-14.01 · Core · Identity, credentials, and password authentication ↗
Login: verification without decryption

A login request delivers an identifier and password input to the application under strong transport protection. HTTPS/TLS provides in-transit confidentiality and integrity; it does not automatically fix server password storage. Consider transport protection for both the login form and authenticated pages.

WEB-14.01 · Core · Identity, credentials, and password authentication ↗
Credential lifecycle extends beyond the first login

Password changes and recovery alter future control of an account. An active session may not provide enough assurance for sensitive credential changes; apply a current authenticator or appropriate reauthentication condition. Do not assume a password change magically invalidates every existing session and token; a revocation policy is needed.

WEB-14.01 · Core · Identity, credentials, and password authentication ↗
Observe subjects, credentials, and permissions separately

In a defensive review, displaying Duru in the UI is not proof of an authenticated subject. Login acceptance, resolved subject, and resource decisions need separate evidence fields. Observe that credential failure establishes no subject, while authn success/authz denial establishes a subject but withholds the resource.

WEB-14.01 · Red · Identity, credentials, and password authentication ↗
Interpret the verifier’s boundary correctly

Salts and slow hashing reduce risks from verifier-database disclosure; they do not solve every issue involving weak passwords, credential reuse, or authenticated-session disclosure. Keeping a salt secret is not the foundation of password security.

WEB-14.01 · Red · Identity, credentials, and password authentication ↗
Apply resource policy after resolving a verified subject

The authentication component should return an explicit subject and assurance context. Downstream policy evaluates action/resource/tenant relationships through trusted data; username or display-name equality is not permission.

WEB-14.01 · Blue · Identity, credentials, and password authentication ↗
Keep password handling within a library boundary

Use an established password-hash verification API, unique salts, recorded algorithm/cost metadata, and a rehash flow when needed. Choose production parameters using current guidance and workload measurements; do not copy this lesson’s cost-profile alias as configuration.

WEB-14.01 · Blue · Identity, credentials, and password authentication ↗
Keep decisions in audit, not credentials

A credential-match result, resolved-subject alias, account-policy result, and action decision can suffice for observation. Raw passwords, verifiers, and session secrets are unnecessary. A hash-profile upgrade can also be recorded as a nonsecret policy event.

WEB-14.01 · Blue · Identity, credentials, and password authentication ↗
loginIdentifier / trustedSubject

The claimed account differs from the trusted subject established after successful verification.

WEB-14.01 · Identity, credentials, and password authentication ↗
credentialRecord

An alias record showing salt/verifier/cost roles, not a real hashing format.

WEB-14.01 · Identity, credentials, and password authentication ↗
credentialMatches / authorized

Separates the authentication predicate from the resource-policy outcome.

WEB-14.01 · Identity, credentials, and password authentication ↗
resourceDelivered

A private representation is delivered only after required authn and authz conditions pass.

WEB-14.01 · Identity, credentials, and password authentication ↗
Request carriers differ from server meaning

A credential string reaching the Atlas API is only a transport observation. The server must determine its scheme, validity, represented client/subject context, and permission for the request.

WEB-14.02 · Core · Basic authentication, API keys, and bearer tokens ↗
HTTP Basic: Base64 encoding, not encryption

RFC 7617 Basic combines a user-id and password into a user-pass value represented using Base64. The Authorization header uses the Basic scheme name. This encoding is a reversible representation; it neither encrypts the password nor produces a hash verifier.

WEB-14.02 · Core · Basic authentication, API keys, and bearer tokens ↗
API key: whose key, or which project?

An API key’s meaning depends on the product contract. It can support application/project attribution, quota, or a paid plan; another design can make it a service-principal credential. “API key valid” does not automatically mean an end user named Duru authenticated.

WEB-14.02 · Core · Basic authentication, API keys, and bearer tokens ↗
Bearer: possession can be the proof

For a bearer credential under RFC 6750, its holder need not prove possession of a separate cryptographic key to use it. This makes token confidentiality critical. Bearer does not mean unreadable contents: an opaque string or a token with a readable JWT payload can be used as bearer.

WEB-14.02 · Core · Basic authentication, API keys, and bearer tokens ↗
Transport, storage, and policy are separate defenses

TLS protects data in transit; it does not automatically prevent logging a token incorrectly or choosing unsuitable client storage. Putting passwords, API keys, or bearer credentials in URLs unnecessarily spreads them into history, logs, and referrers. Prefer the protocol’s protected header/body transport.

WEB-14.02 · Core · Basic authentication, API keys, and bearer tokens ↗
The purpose of 401, 403, and challenges

An HTTP authentication challenge differs from an application permission denial. Basic and Bearer have their own meanings within the challenge/response framework. For OAuth bearer, invalid_token and insufficient_scope are distinct reasons; status and WWW-Authenticate follow the protocol.

WEB-14.02 · Core · Basic authentication, API keys, and bearer tokens ↗
A header is not identity evidence

In a defensive review, separate scheme, presented alias, registry binding, validity, and action decision. A header named Authorization does not prove resource authorization ran; the name is a protocol convention.

WEB-14.02 · Red · Basic authentication, API keys, and bearer tokens ↗
Reduce credential propagation

Raw credentials are unnecessary in logs, error messages, analytics, and cache keys. A scheme and opaque correlation alias can suffice for diagnostics. A URL-carried credential is not safe because it is Base64, and a JWT is not automatically public.

WEB-14.02 · Red · Basic authentication, API keys, and bearer tokens ↗
Write down credential type and subject semantics

Define accepted schemes and credential formats for each endpoint. Does registry/token validation yield an end-user subject, service principal, or project attribution? Preserve that distinction in policy input types.

WEB-14.02 · Blue · Basic authentication, API keys, and bearer tokens ↗
Use strong transport and redaction

Use HTTPS/TLS for sensitive transport such as Basic and bearer; endpoint-certificate validation is part of client responsibility. Also define the trusted transport boundary beyond a reverse proxy.

WEB-14.02 · Blue · Basic authentication, API keys, and bearer tokens ↗
Complete acceptance at the action boundary

After token/key recognition, enforce validity, issuer/audience or registry binding, and action permission. Basic requires a password verifier and account policy. Accepting a valid token for the wrong resource is not justified by successful format parsing.

WEB-14.02 · Blue · Basic authentication, API keys, and bearer tokens ↗
wireShape

An invalid alias string describing a carrier shape; not an executable HTTP request.

WEB-14.02 · Basic authentication, API keys, and bearer tokens ↗
bindingKind / subject

Application attribution differs from end-user context; key recognition does not verify a user.

WEB-14.02 · Basic authentication, API keys, and bearer tokens ↗
credentialValid / actionAllowed

Recognition/validity and resource permission are separate predicates.

WEB-14.02 · Basic authentication, API keys, and bearer tokens ↗
representationDelivered

The final result of this fixture’s private-note policy.

WEB-14.02 · Basic authentication, API keys, and bearer tokens ↗
JWT is a claims representation

JWT is a family of compact representations carrying claims about a subject. The common signed JWS Compact form has three components: protected header, payload, and signature/MAC, represented with Base64url and separated by periods. The header carries cryptographic metadata such as alg; the payload carries claims.

WEB-14.03 · Core · JWT claims and token lifecycle ↗
Which questions do claim names answer?

iss identifies the issuer, sub the subject, and aud the intended recipients. A subject can be unique within its issuer context; the same sub text across two issuers need not represent the same person. aud can be a string or an array, and recipients need the expected identifier in the audience.

WEB-14.03 · Core · JWT claims and token lifecycle ↗
Claims remain tentative after decoding

A parser can read JSON fields, but sub and scope are not yet trusted policy inputs. Cryptographic validation must use the right key, an acceptable algorithm, and every required cryptographic operation. Failure of any required validation rejects the token.

WEB-14.03 · Core · JWT claims and token lifecycle ↗
A valid signature does not establish the intended use

Even after cryptographic validation, enforce exact issuer, intended audience, required claims, token purpose, and time conditions. RFC 9068 requires typ at+jwt or application/at+jwt. Separate an ID token’s different purpose through access-token validation rules; sharing a signed-JWT format does not erase the type boundary.

WEB-14.03 · Core · JWT claims and token lifecycle ↗
Access and refresh tokens go to different recipients

An OAuth access token is a credential for a protected resource server. A refresh token is presented to the authorization server to obtain a new access token and is not sent to the resource API. Refresh-token issuance is optional, and its format need not be JWT.

WEB-14.03 · Core · JWT claims and token lifecycle ↗
Stateless validation does not imply a stateless lifecycle

A self-contained signed access token can let a resource server evaluate signature/claim policy without contacting the issuer on every request. That does not automatically propagate logout, revocation, or permission changes to every server.

WEB-14.03 · Core · JWT claims and token lifecycle ↗
Do not confuse readable with trusted claims

In a defensive review, distinguish decoded, cryptographically verified, profile-valid, and action-authorized states. Seeing sub=subject-duru is not identity acceptance. A valid signature does not establish audience/purpose/time acceptance.

WEB-14.03 · Red · JWT claims and token lifecycle ↗
Observe independent lifecycle states

Browser cleanup, AS refresh-family state, and resource-server acceptance are not one variable. Do not infer another component’s current state from logout or refresh failure without evidence.

WEB-14.03 · Red · JWT claims and token lifecycle ↗
Enforce library and profile boundaries together

Use an established JOSE/JWT library with approved algorithms and an issuer-bound trusted key set. Do not treat a decode helper as a verification API; validate required header/claim shape without turning arbitrary token metadata into trust configuration.

WEB-14.03 · Blue · JWT claims and token lifecycle ↗
Use atomic rotation in refresh lifecycle

Handle refresh tokens only at the correct AS endpoint with protected transport/storage. Preserve client/grant binding and original scope. When choosing rotation, make invalidate-old, issue-new, and family updates one consistent boundary; do not accidentally create two active successors.

WEB-14.03 · Blue · JWT claims and token lifecycle ↗
Tie revocation expectations to product behavior

After logout, which access tokens may remain accepted, which store/denylist checks are needed, and when is the refresh family closed? Choosing JWT does not answer those questions. Evaluate failover and cache freshness against current-authorization expectations.

WEB-14.03 · Blue · JWT claims and token lifecycle ↗
header / claims

A decoded view; not trusted authorization input before verification.

WEB-14.03 · JWT claims and token lifecycle ↗
policy

Issuer/audience/type/algorithm and required-claim choices come from the application’s approved profile.

WEB-14.03 · JWT claims and token lifecycle ↗
signatureValid / tokenAccepted / actionAllowed

Cryptographic predicate, profile acceptance, and resource permission are separate states.

WEB-14.03 · JWT claims and token lifecycle ↗
refreshFamily

AS refresh state, not automatic proof of resource-server access-token revocation.

WEB-14.03 · JWT claims and token lifecycle ↗
Duru passed the password check; authentication is not complete

Atlas receives Duru’s password result for an action requiring another factor. The verified subject from WEB-14.01 is the first-stage input. The Application does not set mfaComplete=true yet: it must verify that another authenticator is bound to this account and produced the required result for this attempt.

WEB-14.04 · Core · Trust assumptions behind MFA ↗
Factor count is not prompt count

Knowledge, possession, and inherence are different factor types. A password followed by another password or centrally checked PIN repeats the knowledge category. Password plus proof of authenticator possession can use different categories. Correct binding to the same account and resistance to replacement through one weak recovery path remain separate requirements.

WEB-14.04 · Core · Trust assumptions behind MFA ↗
Challenge lifecycle: issue, verify, consume

The Application associates challenge-ledger-a with an attempt, subject, factor, and purpose=mfa-login. The alias returned to the Browser is not an OTP; enrolled-authenticator output is represented only by OTP_RESPONSE_ALIAS. OutputMatches=true is a supplied input standing for a trusted verification result.

WEB-14.04 · Core · Trust assumptions behind MFA ↗
OTP, push, and WebAuthn protect different phishing boundaries

MFA can reduce the effect of password disclosure without making every MFA protocol phishing-resistant. NIST uses that term for a protocol property that prevents valid authenticator output reaching an impostor verifier without depending on user vigilance. Manual OTP entry lacks that verifier binding; WebAuthn can provide verifier name binding.

WEB-14.04 · Core · Trust assumptions behind MFA ↗
A verified output cannot authorize the wrong attempt

Normal operation binds enrolled-authenticator output to Duru’s pending attempt. Turning an isolated “output correct” boolean into a global MFA flag loses subject, purpose, and lifecycle relationships. The potential effect is elevated assurance assigned to an incorrect or stale context.

WEB-14.04 · Red · Trust assumptions behind MFA ↗
Independence must survive recovery and fallback

The benefit of multiple factors does not depend only on normal-login prompts. If factor replacement or an alternative API skips the assurance gate, authenticated state can be established under that weaker path’s conditions. Scope is the affected account and granted session/action authority, not automatic access to every resource.

WEB-14.04 · Red · Trust assumptions behind MFA ↗
Observe attempt, factor, and terminal outcome together

Sanitized audit emitted at the Application’s challenge issue/verify/consume decisions differs from observing a Browser prompt. attemptRef, subjectRef, factorType, purposeMatched, challengeState, lifetimeValid, and mfaEstablished belong to our instructional schema, not an existing product’s SIEM fields.

WEB-14.04 · Blue · Trust assumptions behind MFA ↗
An accessible rollout and recovery inventory

Start policy changes with an account/factor inventory: enrolled methods, migration, accessibility needs, and fallback ownership must be understood. Lost devices, delayed output, and cancelled prompts are normal failures; rejection alone is not evidence of malice.

WEB-14.04 · Blue · Trust assumptions behind MFA ↗
Make assurance elevation a server decision

Bind provider or library authenticator-verification results to the account’s enrolled factor and this authentication attempt. Two passwords are not two independent factors; the chosen assurance policy defines acceptable combinations. In this example, subject, purpose, lifetime and unused challenge state must pass before mfaEstablished is granted. Make challenge consumption and assurance elevation one consistent state transition; an unavailable verification service cannot be replaced by a successful-looking Browser prompt.

WEB-14.04 · Blue · Trust assumptions behind MFA ↗
attemptRef / subject / challengeRef

Correlation aliases bind the decision to one attempt, account, and pending record.

WEB-14.04 · Trust assumptions behind MFA ↗
outputMatches / unused / withinLifetime

Supplied verification and lifecycle predicates rather than output bytes or clock measurements.

WEB-14.04 · Trust assumptions behind MFA ↗
distinctFactors / mfaEstablished

Repeating a factor category does not add a factor; completion requires every acceptance gate.

WEB-14.04 · Trust assumptions behind MFA ↗
selector

Authored XML integrity selection; a missing field provides insufficient evidence.

WEB-14.04 · Trust assumptions behind MFA ↗
Which report may Duru read?

Atlas and Orion are tenants for two separate organizations. Duru signs in as an Atlas member. report-atlas-01 belongs to Duru within Atlas. Ekin is a reviewer in the same tenant; reviewing reports is part of Ekin’s work. Orion reports are outside both users’ scope. Each actor in this example belongs to one tenant; products with multiple memberships must also validate active-tenant selection.

WEB-14.05 · Core · Resource authorization and tenant boundaries ↗
Four inputs, and who supplies them

The subject is the verified requesting principal: actorId, active membership and role. The object is the report: objectId, ownerId, tenantId and its state. The action is report.read. Context includes the server-verified active tenant and policy version. Role is a subject attribute; ownership is a relationship between subject and object. Neither substitutes for the other.

WEB-14.05 · Core · Resource authorization and tenant boundaries ↗
Unpacking an allow decision

Duru requests read access to report-atlas-01. The handler establishes an active principal and verified Atlas context. The policy checks that the target metadata belongs to Atlas, recognizes the action, verifies that the member role participates in that action, and compares ownerId with actorId. Only after all required conditions hold does it return allow/OWNER_READ and release the protected report body.

WEB-14.05 · Core · Resource authorization and tenant boundaries ↗
Deny prevents disclosure and execution

An unknown action, missing context or undefined role has no explicit grant and yields deny. Failure of the decision service must not permit a protected operation to continue. A denied read returns no confidential body; a denied write performs no mutation. Error handling cannot become an alternative allow path. Public resources may have an explicit public policy; the tenant check in this example is not a universal requirement for every web resource.

WEB-14.05 · Core · Resource authorization and tenant boundaries ↗
Keep the decision across data paths

The same report may be accessed through a screen, a download or a background export job. Each path must preserve the entitlement. Tenant equality alone is insufficient: Atlas ownership and action rules still apply. The following designs carry this report policy across different paths; middleware does not automatically secure every downstream component.

WEB-14.05 · Core · Resource authorization and tenant boundaries ↗
How long is a decision valid?

Removing Ekin’s reviewer role makes an old allow decision insufficient for the next read. Policy version distinguishes rule sets; it does not itself enforce a role change. Current membership, cache invalidation and the enforcement tier must work together. Delayed or long-running operations need an explicit rule for permission changes before execution.

WEB-14.05 · Core · Resource authorization and tenant boundaries ↗
Which trust assumption breaks?

The normal handler establishes a trusted principal through authentication; the policy then evaluates that principal’s entitlement to this object and action. “Login succeeded, therefore the report is readable” merges distinct decisions. The fault is not failed authentication but disclosure to a verified identity without the required object permission.

WEB-14.05 · Red · Resource authorization and tenant boundaries ↗
Object, function and property ask different questions

Object-level checks ask whether this action is permitted on this report. Function-level checks ask whether a capability such as report.export is available to this subject. Property-level checks restrict which fields may be read from an allowed object or changed during an update. Passing one does not automatically pass the others.

WEB-14.05 · Red · Resource authorization and tenant boundaries ↗
Checking the tenant only once

A tenant check on the API read path does not prove one exists on the cache or private-export path. The broken assumption is a downstream component deciding that arrival already implies permission. A worker evaluating only its service role can also widen the originating actor’s scope.

WEB-14.05 · Red · Resource authorization and tenant boundaries ↗
HTTP logs and decision ledgers have different jobs

An HTTP access log may show path, status and timing; it does not by itself establish that ownership or tenant policy ran. The application policy evaluator emits a decision event with server-verified actorId, subjectTenant, objectTenant, action, objectId, decision, reason and policyVersion. These are our example’s custom fields, not an OWASP event schema.

WEB-14.05 · Blue · Resource authorization and tenant boundaries ↗
Three distinct evidence outcomes

The positive control is Duru’s own-read allow/OWNER_READ with only the expected fields delivered. The negative ownership control is deny/OWNER_REQUIRED with no protected body. The cross-tenant control is deny/TENANT_MISMATCH. Expected denials are a safe baseline, not automatic attack alerts. Ekin’s Atlas reviewer-read allow is also a legitimate ownership exception.

WEB-14.05 · Blue · Resource authorization and tenant boundaries ↗
Explainable review logic for this fixture

Instead of inventing a backend-specific KQL table, use matrix checks: for each caseId compare expected and observed decision/reason, and require empty deliveredFields for deny cases. In this fixture, an allow where subjectTenant differs from objectTenant is a policy-regression candidate. That predicate needs an explicit exception model in products with legitimate cross-tenant grants.

WEB-14.05 · Blue · Resource authorization and tenant boundaries ↗
Fixes need regression evidence

When enforcement is absent on one path, inventory all report access paths and policy ownership. Establish a common trusted evaluator or equivalent controls across tiers; verify that pooled connections or reused workers do not retain another request’s tenant context. Cover private downloads and cached responses as well as the main API.

WEB-14.05 · Blue · Resource authorization and tenant boundaries ↗
subjects / objects

Seeded identity and report metadata, not client assertions of role or ownership.

WEB-14.05 · Resource authorization and tenant boundaries ↗
verifiedContextTenant

Active context established from server-verified membership; null represents missing context.

WEB-14.05 · Resource authorization and tenant boundaries ↗
ruleOrder

This teaching model’s check/reason order; the first failing condition determines the reason.

WEB-14.05 · Resource authorization and tenant boundaries ↗
expected

The required policy outcome, not a runtime observation.

WEB-14.05 · Resource authorization and tenant boundaries ↗
deliveredFields

Permitted response field names for allow; deny should release no protected fields.

WEB-14.05 · Resource authorization and tenant boundaries ↗
requestId / policyVersion

Interaction correlation and rule-set identity, not secrets or credentials.

WEB-14.05 · Resource authorization and tenant boundaries ↗
An account is not one loggedIn boolean

Atlas stores subject-duru with a login identifier, contact verification, account status, credential generation, and authenticator associations. A session is not this account record. A new account can exist in pending-contact state without being eligible for protected login; a disabled account can still have a matching password verifier.

WEB-14.S01 · Core · Account lifecycle and password verification ↗
Registration separates an account claim from contact control

Duru supplies duru.reader and a contact alias on the registration form. The Application checks uniqueness and product eligibility at the trusted boundary and uses suitable adaptive verification from WEB-14.01 for passwords. CandidateAllowed and identifierAvailable are supplied true; the fixture contains neither real registration data nor a password.

WEB-14.S01 · Core · Account lifecycle and password verification ↗
Password policy at enrollment/change; verification at login

An established password library verifies the candidate using the record’s algorithm, salt, and cost metadata without decrypting a hash. Salt is not secret. Even a verifier-only backup is sensitive material; database/backup access, credential logging, and metadata migration need joint assessment.

WEB-14.S01 · Core · Account lifecycle and password verification ↗
Account gates and safe rehash after verification succeeds

Normal login begins with an active account and an allowed attempt. Supplied passwordMatches=true permits subject resolution. If needsRehash=true, an established library can create a new verifier with a new salt/current cost policy while the candidate is available in the controlled verification path. The fixture changes verifier-old-alias to verifier-current-alias while retaining the same subject.

WEB-14.S01 · Core · Account lifecycle and password verification ↗
Throttling state and public failures are different surfaces

Throttling governs whether an attempt is allowed; a source-IP-only counter does not fully express account-level behavior. Atlas rejects a blocked attempt before calling the KDF. Distributed limit state, contention, reset conditions, and legitimate-user lockout depend on implementation; no count is presented as a universal retry policy.

WEB-14.S01 · Core · Account lifecycle and password verification ↗
Disablement, closure, and recovery are not interchangeable

When account eligibility ends, authenticators and access relationships need controlled invalidation. Retention/deletion after closure depends on the product and its obligations; a closed login gate does not imply deletion of every audit record or backup.

WEB-14.S01 · Core · Account lifecycle and password verification ↗
When credential matching is confused with account eligibility

Normal login combines password verification and account policy in one trusted decision chain. Passing a match boolean directly to a session issuer can skip pending, disabled, or closed state. The effect is a new authenticated context for an account whose access should end; resource authorization remains another boundary.

WEB-14.S01 · Red · Account lifecycle and password verification ↗
What does a public response discrepancy expose?

A registration/login response distinguishing “account absent” from “wrong password” adds account-existence information to the public contract. The prerequisite is an endpoint exposing that distinction; an observation does not supply credentials or access permission.

WEB-14.S01 · Red · Account lifecycle and password verification ↗
Relate account transitions to verification decisions

Sanitized application audit can include subjectRef, accountStatus, contactVerified, attemptAllowed, passwordVerified, contextIssued, and verifierGeneration. These fields are not standard log events. Candidate passwords, verifier bytes, and verification tokens stay out of telemetry.

WEB-14.S01 · Blue · Account lifecycle and password verification ↗
Separate response review from rate-limit validation

The public-response matrix expresses absent/wrong/pending/disabled conditions under one contract. Compare text, status, and content envelopes separately. Timing equivalence needs controlled measurements and load conditions; the boolean fixture does not perform those measurements.

WEB-14.S01 · Blue · Account lifecycle and password verification ↗
Durable controls for verifier migration and disablement

Inventory credential generations and cost-policy metadata. Benchmark the capacity effect of migration, and protect successful-verification rehashing against stale-reset overwrites. Salt/cost aliases must not be copied as production parameters.

WEB-14.S01 · Blue · Account lifecycle and password verification ↗
accountStatus / contactVerified

Product eligibility and communication-endpoint control, not identity proofing.

WEB-14.S01 · Account lifecycle and password verification ↗
credentialRecord

Salt/cost/verifier aliases explain an established-library record; neither real hashes nor production cost settings.

WEB-14.S01 · Account lifecycle and password verification ↗
attemptAllowed / verifyCalled

A blocked throttle gate leaves verification unexecuted; passwordMatches=null is unknown.

WEB-14.S01 · Account lifecycle and password verification ↗
contextIssued / rehashCommitted

Context issuance and verifier upgrade are separate outcomes; generation races require separate safeguards.

WEB-14.S01 · Account lifecycle and password verification ↗
publicFailures / selector

A public contract separated from internal reasons and an owned XML integrity selector.

WEB-14.S01 · Account lifecycle and password verification ↗
Future account control is a sensitive permission

Duru wants to add a passkey on a new laptop. This action changes more than profile text: an authenticator controlling the new private key can authenticate subject-duru in the future. Atlas does not treat an active Browser session alone as authority to create this association; it requires fresh reauthentication and trusted account binding.

WEB-14.S02 · Core · Recovery, passkeys, and sensitive account changes ↗
Passkeys replace server passwords with public-key associations

A passkey is a FIDO credential associated with a website/application account. The WebAuthn RP server keeps trusted associations among credential ID, subject/user handle, and public key. The authenticator performs private-key operations; the server does not request the private key or device-unlock PIN.

WEB-14.S02 · Core · Recovery, passkeys, and sensitive account changes ↗
Registration and authentication are separate ceremonies

navigator.credentials.create() produces/registers a new credential; navigator.credentials.get() requests an authentication assertion with an existing credential. The RP server supplies ceremony options/challenge, the Browser uses the authenticator API, and application transport forwards the response to the RP.

WEB-14.S02 · Core · Recovery, passkeys, and sensitive account changes ↗
Challenge, RP ID, and origin are different bindings

Atlas chooses RP ID=library.atlas.example and expected origin=https://library.atlas.example. RP ID describes domain scope; origin includes scheme, host, and port. Their checks are not interchangeable string comparisons. Broader RP-ID scope changes subdomain trust, and credentials do not use cookie Domain/Path scoping.

WEB-14.S02 · Core · Recovery, passkeys, and sensitive account changes ↗
Recovery is not a shortcut to login success

Losing an old authenticator can require recovery. Forgot-password, password replacement using an available authenticator, and account recovery after loss of all required authenticators are different situations. Available proof, account assurance, and product risk analysis determine the permitted recovery path.

WEB-14.S02 · Core · Recovery, passkeys, and sensitive account changes ↗
Boundaries of reset, factor replacement, and notification

A password-reset token is securely generated, purpose-bound, single-use, and lifetime-limited. The request itself should not mutate account state and lock out the user. Restricted reset state completes the update separately from login. Supplying a consumed recovery proof makes unused=false and blocks further mutation.

WEB-14.S02 · Core · Recovery, passkeys, and sensitive account changes ↗
Correct cryptography does not correct a wrong association

Registration normally associates a new authenticator public key with an authorized subject. Skipping fresh reauthentication/account binding or ceremony-origin gates can associate a key with an incorrect subject/purpose. The prerequisite is an unchecked received result reaching the association gate; scope is the account context later established through that credential.

WEB-14.S02 · Red · Recovery, passkeys, and sensitive account changes ↗
Recovery authority must not silently become ordinary access

Normal recovery permits controlled replacement after the specified proof. Elevating its capability into an unrestricted session or leaving proof reusable can grant broader access/change authority. One successful-looking response does not establish closure of every lost-key/session state.

WEB-14.S02 · Red · Recovery, passkeys, and sensitive account changes ↗
What can an association ledger establish?

A sanitized RP decision record can correlate ceremonyRef, subjectRef, originMatched, rpIdHashMatched, challengeMatched, freshReauth, and newCredentialBound. Public-key/credential references do not authenticate like secrets but still require privacy/retention protection. Exclude private keys, recovery secrets, and biometric data.

WEB-14.S02 · Blue · Recovery, passkeys, and sensitive account changes ↗
Track separate outcomes after recovery succeeds

Consumed proof, replacement generation, affected old association/session invalidation, and independent notification are separate transitions. A queued notification does not prove delivery; Browser acceptance of a new password does not establish immediate expiry of an old resource-server access token.

WEB-14.S02 · Blue · Recovery, passkeys, and sensitive account changes ↗
Validate Browser ceremonies alongside account policy

Use an established WebAuthn library and a supported Browser/device matrix to validate RP ID, allowed origins, userVerification, platform/roaming, and sync behavior. API availability does not give every credential identical assurance/recovery properties. Origin allowlists and reverse-proxy external-origin changes need controlled review.

WEB-14.S02 · Blue · Recovery, passkeys, and sensitive account changes ↗
rpId / expectedOrigin

Credential-domain scope differs from scheme/host/port origin and is not cookie scope.

WEB-14.S02 · Recovery, passkeys, and sensitive account changes ↗
credentialAlias / userHandleAlias / publicKeyAlias

Aliases track account-key associations without actual credential bytes or usable keys.

WEB-14.S02 · Recovery, passkeys, and sensitive account changes ↗
registrationRows

Fresh-proof and ceremony-acceptance results with supplied cryptographic predicates.

WEB-14.S02 · Recovery, passkeys, and sensitive account changes ↗
recoveryRows

Approved evidence/assurance are supplied; restricted reset, proof consumption, and affected invalidation are distinct.

WEB-14.S02 · Recovery, passkeys, and sensitive account changes ↗
notificationQueued / ordinarySessionIssued

Queued is not delivered; recovery success does not automatically issue an ordinary login session.

WEB-14.S02 · Recovery, passkeys, and sensitive account changes ↗
Which protection does the token format carry?

Atlas gives Duru a notes-read access context for the public title Tea & Bread. JWT is the claims-bearing format; JWS provides integrity through a signature or MAC, while JWE uses authenticated encryption for confidentiality and integrity. JWS Compact has three parts and JWE Compact five; counting them is not validation. A signed payload is ordinarily readable: base64url is not encryption. Decrypting JWE does not by itself prove the expected issuer; key provenance and the profile still matter. Nested tokens require validation of every required outer and inner cryptographic operation. The artifact separates inert header and claims fields; signatureVerifiedDeclared is an assumed result, not a JWT string or parser output.

WEB-14.S03 · Core · Token verification, purpose and key lifecycle ↗
The verifier owns the acceptance profile

The verifier does not let alg freely choose its cryptography: the application binds allowed algorithms and key usage to the operation. kid selects within a trusted issuer key set and is not a trust anchor. Atlas requires issuer, an issuer-subject pair, audience, typ and notes-read purpose. aud can be one string or an array of strings, matched against the intended recipient. Here purpose is an application-specific claim and atlas-notes+jwt an illustrative profile type, not universal JWT requirements. Registered claims are not all mandatory in every application; this profile explicitly lists requiredClaims. An API access context, ID token and differently purposed signed object need distinct acceptance rules. Object/action authorization still follows accepted identity.

WEB-14.S03 · Core · Token verification, purpose and key lifecycle ↗
Time and key lifecycle are separate decisions

NumericDate counts UTC epoch seconds, unlike JavaScript milliseconds. With zero skew, this fixture requires now >= nbf and now < exp; equality at exp rejects acceptance. iat describes issuance and is not itself not-before or logout enforcement; small skew and maximum age belong to the deployment profile. An active signing key and an older verification key may overlap under explicit policy. Atlas key-v1 is beyond verifyUntil while key-v2 remains active. An unavailable trusted-source refresh for an unknown kid gives no acceptance evidence and does not automatically prove forgery. Rotation, emergency revocation, cache propagation and session logout are separate lifecycle events. Preserve a configured issuer-key binding rather than downloading keys from arbitrary header URLs.

WEB-14.S03 · Core · Token verification, purpose and key lifecycle ↗
Overinterpreting cryptographic success

Normal signature success says the supplied bytes verified under a configured key; it does not establish suitability for this recipient and operation. The broken assumption is that every signed claim set from a trusted issuer means the same thing in every consumer. Confusion requires distinct token purposes/profiles and a consumer failing to separate audience, type or required values. Impact is misinterpreted identity or access scope, not automatically universal account compromise. The wrong-purpose row retains signatureVerifiedDeclared=true yet rejects API acceptance, with no resource delivery or title body. Mutually exclusive profiles and separate object authorization preserve the boundary; encryption alone does not correct purpose confusion.

WEB-14.S03 · Red · Token verification, purpose and key lifecycle ↗
Mistaking key selection for trust provenance

Normal rollout may retain an older verification key for a defined interval; key-v1 does not necessarily mean an expired JWT. The broken assumption is that finding kid proves issuer ownership and continued permitted use. Stale caches, rollover delay or trusted-key-service outage can be benign; the unknown row therefore records key-unavailable separately. The retired row has valid time claims but fails application key policy. Controls bind trusted provenance, algorithm/use and retirement or revocation propagation. Impact is limited to the context accepted by that consumer; there is no key material or bearer token in the artifact.

WEB-14.S03 · Red · Token verification, purpose and key lifecycle ↗
Separate the verifier decision into fields

Observe profile ID, configured issuer, audience and purpose/type matches, subject mapping, key alias/state, cryptographic result and time-gate reason alongside accepted or denied. Keep raw tokens, personal payloads and private keys out of logs. A decoded observation is not positive verification; an upstream 401 or cache miss alone is not key-compromise evidence. Baseline uses an active key, intended recipient/purpose and bounded time. Separate unknown key, invalid signature and retired key, correlating trusted-source freshness and refresh outcome. Here denial visibly lacks a resource message and title body; no service audit schema or JWT library result is invented.

WEB-14.S03 · Blue · Token verification, purpose and key lifecycle ↗
Exercise rotation and acceptance regression together

Manage acceptance-policy versions with issuer-key provenance. Routine rotation defines old-key verification overlap, maximum token lifetime and bounded cache refresh; emergency revocation needs a separate decision. Signature-valid wrong audience/purpose, now=exp, now=nbf and retired key require distinct regression cases. Fail-closed handling of unavailable evidence differs from attack attribution. The library must support the profile’s unknown-header, critical-extension and nested-crypto rules. A signature primitive working on public note bytes does not verify JWT/JWS acceptance rules or a JWKS lifecycle. Session logout requires separate server state or revocation control; JWT format alone supplies no distributed revocation.

WEB-14.S03 · Blue · Token verification, purpose and key lifecycle ↗
formatLedger

Claims versus cryptographic container.

WEB-14.S03 · Token verification, purpose and key lifecycle ↗
profile

Consumer-owned acceptance requirements.

WEB-14.S03 · Token verification, purpose and key lifecycle ↗
keys

Trusted aliases, use and lifecycle without secrets.

WEB-14.S03 · Token verification, purpose and key lifecycle ↗
rows

Declared crypto outcome and independent acceptance decisions.

WEB-14.S03 · Token verification, purpose and key lifecycle ↗
timeRows

Zero-skew NumericDate equality boundaries.

WEB-14.S03 · Token verification, purpose and key lifecycle ↗
Which operation on which object?

Duru wants to rename public note-A from Tea & Bread to Bread & Tea. Public-read policy may permit reading it, while rename is a separate action requiring an owner/tenant relationship. The server combines subject, object, action and context from trusted sources; the client reference only selects an object. Object-level authorization asks whether this subject can perform this action on this resource. IDOR/BOLA describes insufficient relationship enforcement; choosing an integer, UUID or string supplies no permission. Being logged in also establishes no note-A relationship. The ledger compares one owned note and a supplied object-denied outcome without discovering other notes or generating identifiers.

WEB-14.S04 · Core · Object, function and property authorization ↗
Function permission differs from object permission

The notes.rename function requires an explicit product-policy grant. Function-level authorization evaluates access to that business capability; the object gate separately checks the selected resource relationship while using it. An administrative-looking URL, hidden button or route name is not enforcement. A role can grant a function without granting access to every tenant object. In the function-denied row objectRelation=true still supplies no action capability. Apply controls at server enforcement points on every relevant request. A shared policy module improves consistency but cannot make client-supplied context trustworthy. Missing actor or policy information has an explicit deny outcome rather than automatic malicious attribution.

WEB-14.S04 · Core · Object, function and property authorization ↗
Property boundaries operate in both directions

Even after object and function gates pass, the caller cannot necessarily write or read every property. Atlas maps rename input only to title; owner, tenant and publicationState are server-owned context/workflow fields. Type/schema validation establishes an ordinary title string, not permission over publication state. Mass assignment breaks the boundary when generic input binding carries unpermitted internal fields into a business object. Property authorization and explicit input projection constrain that propagation. For output, select fields permitted for this response instead of serializing the entire object. In this all-gates-before-mutation fixture, property denial creates no body or mutation; real transactions, concurrency and side effects must preserve the same decision boundary.

WEB-14.S04 · Core · Object, function and property authorization ↗
Overinterpreting references and capabilities

A normal function call carries a known note selection and authenticated context to the server. The broken assumption is that permission to call the function covers every action on the selected object. Failure requires an absent resource relationship or tenant-scope check for the action; impact follows that read, rename or business operation’s scope. Reading a public title is not public rename permission, and an unpredictable UUID does not complete policy enforcement. The object-denied fixture therefore preserves the title even with functionGrant=true. The function-denied fixture separately lacks capability despite an owned object. Action-bound server policy and reliable resource context support both gates independently of UI or route naming.

WEB-14.S04 · Red · Object, function and property authorization ↗
Trusting every field of an allowed object

Normal rename carries an editable title; object ownership does not establish control over server-owned publishing state. The broken assumption is that validated JSON or an ORM model is automatically an authorized property map. Failure requires unknown/restricted input binding into internal state or output expanding without an authorized read projection. Impact can be incorrect publication state or unnecessary property disclosure for that operation; the note fixture contains no administrative credentials. The property-denied row exposes all gate outcomes while producing neither a write nor a protected response body. Closed input fields, actor/action-specific write allowlists and explicit read DTOs work together; a small denial body alone does not undo transaction side effects.

WEB-14.S04 · Red · Object, function and property authorization ↗
Correlate all three gates to the same action

Audit context separates actor/session validation alias, policy revision, business operation, resource/tenant, function grant, object relationship and property-set decisions. Permitted field names and reason codes may suffice instead of raw bearer tokens or entire objects. Baseline is Duru renaming the owned public note title; the other rows are finite negative controls. A 403/404 choice depends on product disclosure policy and alone does not prove which gate executed. Correlate the server decision with transaction commit and response projection. Missing telemetry does not establish a failed attack; the unknown-evidence row stops acceptance without inventing hostile activity. Fixture decisions are not endpoint or database audit evidence.

WEB-14.S04 · Blue · Object, function and property authorization ↗
Permission regression measures state consequences

Test state consequences as well as an allow/deny return: title before/after, preserved owner/tenant/publicationState, response keys and absence of denied delivery/body. Reevaluate role or policy-version changes against object relationships rather than assuming equal read/write field grants. The server command DTO separates accepted title data from internal context, using explicit projection rather than spreading arbitrary body fields into a model. If resource version or relationship can change between authorization and mutation, concurrency/transaction design also matters. Fixed native object selection demonstrates projection but not real ORM, persistence transactions or tenant enforcement. Durable controls retain the relevant context across handlers and asynchronous work.

WEB-14.S04 · Blue · Object, function and property authorization ↗
profile

Known actor/action and initial public note.

WEB-14.S04 · Object, function and property authorization ↗
rows

Independent function/object/property outcomes.

WEB-14.S04 · Object, function and property authorization ↗
fieldLedger

Write/read and server-owned field classes.

WEB-14.S04 · Object, function and property authorization ↗
projections

Explicit title command/response preserve context.

WEB-14.S04 · Object, function and property authorization ↗
unknownEvidence

Missing evidence denies without attack attribution.

WEB-14.S04 · Object, function and property authorization ↗
Limited authority without sharing a password

Mina’s notes live at Notes API; Atlas Exporter is a separate application that wants to export them. Giving it Mina’s password would create authority and credential storage duties beyond that job. Delegated authorization organizes the transfer of selected access to a client. OAuth addresses API access; by itself it does not define a standard user identity or a shared login result across applications. Federation means accepting authentication information from another identity authority under a trust agreement; OIDC makes that distinction concrete in the next lesson.

WEB-15.01 · Core · OAuth actors, code flow and scopes ↗
A code is an intermediate credential

The client first creates a transaction for the selected AS, storing the redirect URI, requested scopes and browser-bound correlation. The browser visits the AS, which authenticates the owner and decides the grant. The callback carries a short-lived, single-use code. After tying that return to its own transaction, the client exchanges the code at the token endpoint. The code is not presented to the API. The AS checks its client, redirect URI, validity and use bindings; our selected S256 PKCE profile also requires the verifier to match the challenge bound to that code.

WEB-15.01 · Core · OAuth actors, code flow and scopes ↗
The token’s recipient and the limit of scope

An access token is the credential used for access at the selected RS; OAuth does not require every access token to be a JWT. An opaque token’s audience and scope can come from the RS’s trusted validation context. The artifact shows these as readable policy fields rather than token bytes. If requested notes:read notes:write becomes a notes:read grant, the client accepts that reduction. Scope names are case-sensitive values defined by the AS; “read” is not the same permission in every application. The RS combines audience, time and scope checks with its own resource policy on every request.

WEB-15.01 · Core · OAuth actors, code flow and scopes ↗
Which mistaken assumption expands authority?

A save button being visible after Exporter received notes:read is not proof of permission. The artifact allows own-note/read and denies own-note/write for scope. The latter is not a login failure: even a genuine grant can omit that action. In foreign-tenant/read, scope suffices but object policy denies access. A design that substitutes scope for object ownership extends an allowed action class to every object; impact depends on which data could be read or changed.

WEB-15.01 · Red · OAuth actors, code flow and scopes ↗
What bearer possession changes

For bearer use, possession matters for access, so treating a token as ordinary log or frontend display data is a mistaken storage assumption. Sender-constrained mechanisms are mentioned as design choices only; the bearer alias does not claim cryptographic client binding. PKCE also does not sender-constrain the access token at the API or replace a client secret in every context. These limits explain which boundary a credential protects, without providing a payload or intervention method.

WEB-15.01 · Red · OAuth actors, code flow and scopes ↗
Keep the normal flow narrow and auditable

Atlas selects a confidential server-side client, code flow and S256 PKCE. Transaction correlation binds the browser and selected AS; credentials and verifier are not sent to browser code. Registered redirect URIs are compared exactly; the native localhost port exception is outside this web profile. Current BCP mandates PKCE for public clients and recommends it for confidential clients; CSRF prevention is mandatory but every profile need not use the same state mechanism. We additionally select one-use state. A multi-AS client explicitly designs issuer or distinct-redirect mix-up defenses.

WEB-15.01 · Blue · OAuth actors, code flow and scopes ↗
Evidence from resource regression

The regression matrix includes positive own-note/read and three distinct negative boundaries: no write scope, wrong audience and foreign tenant. It tests the code time boundary as expired at 1100 and valid at 1099, under this fixture’s zero-leeway rule. Result records contain aliases, decision names and safe correlation rather than code or token bytes. This model check does not prove real AS interoperability, token signature verification or a learner lab; those need separate implementation and evidence.

WEB-15.01 · Blue · OAuth actors, code flow and scopes ↗
actors

Role ownership; the four roles make separate decisions.

WEB-15.01 · OAuth actors, code flow and scopes ↗
code

Client, redirect, time, use and PKCE bindings; not code bytes.

WEB-15.01 · OAuth actors, code flow and scopes ↗
access

Granted scope and RS audience context; not an asserted JWT claim.

WEB-15.01 · OAuth actors, code flow and scopes ↗
refreshCases

Scope sets that do not exceed the first grant; no credential renewal runs.

WEB-15.01 · OAuth actors, code flow and scopes ↗
resourceCases

Selected decisions that keep scope and object policy separate.

WEB-15.01 · OAuth actors, code flow and scopes ↗
Authentication information on top of OAuth

OIDC adds standardized End-User authentication information to an OAuth flow. The client becomes a Relying Party and the identity authority an OpenID Provider; the broader term IdP can also describe non-OIDC federation systems. In our code flow, openid scope marks an OIDC request. The token response carries different tools: an ID token describes authentication to the RP, while an access token is used at an appropriate resource endpoint. If UserInfo is used, its credential is the access token; we do not use the ID token as a Notes API bearer credential.

WEB-15.02 · Core · OIDC, ID token and SSO ↗
Reading claims is not validating them

The artifact selects iss=https://id.example.org, sub=subject-Mina and aud=[atlas-rp-b]. The stable local user key is the issuer/subject pair; display name or email does not carry that guarantee. The RP exactly compares its pretrusted issuer, checks that its client_id is an audience and that additional audiences are acceptable. The zero-leeway expiration example requires now<exp. If the authentication request sent a nonce, the ID token must contain the matching transaction nonce; this is not generalized into an independent nonce for every new token in every OIDC grant.

WEB-15.02 · Core · OIDC, ID token and SSO ↗
When an authentication result is used at the wrong boundary

If B receives a token whose audience is Atlas A, even an assumed valid signature does not allow authentication at B. The audience-denied branch shows the boundary of an assertion intended for another application; reading its claims does not remove it. In untrusted-key, even an expected kid alias cannot repair failed issuer/key provenance. SignatureValidDeclared=true cannot replace that missing link. Assess which incorrect condition could reach local user binding and RP session creation; “a JWT arrived” is insufficient.

WEB-15.02 · Red · OIDC, ID token and SSO ↗
Resource policy after identity

Deriving a local user from an ID token does not determine which tenant record that user may access. Access token validation and resource authorization continue separately at the API. Using email directly as an account-join key silently introduces a business rule beyond issuer/subject binding. Account linking, organization membership and authentication strength need their own policy and evidence. This lesson examines what valid authentication information does not say and which data decision an incorrect equivalence would affect.

WEB-15.02 · Red · OIDC, ID token and SSO ↗
The RP owns its gates and session

Atlas B first fixes the issuer, client registration and accepted algorithm in configuration, preserving metadata issuer matching and signing-key provenance. Whether the transaction sent a nonce is explicit in the validation plan. Server-side validation rather than a UI that merely decodes the token feeds local identity binding. Normal, wrong-audience, expiry-equality, nonce-mismatch and untrusted-key rows exercise the same gate conjunction. The signature field is a selected synthetic result, not a replacement for a real validator test.

WEB-15.02 · Blue · OIDC, ID token and SSO ↗
Evidence for OP and RP sessions

Evidence distinguishes OP response received, RP validation accepted and RP session created. Independence of A and B sessions is checked in both normal SSO and OP-expired branches. If UserInfo is added, its path-specific conditions, including matching its sub to the ID token sub, are applied separately; the fixture does not call that endpoint. Completing this scene does not verify a real OP, JWS library, key rotation, federated logout or browser third-party-cookie behavior.

WEB-15.02 · Blue · OIDC, ID token and SSO ↗
idToken

Authentication claim aliases; stable identity is the iss/sub pair.

WEB-15.02 · OIDC, ID token and SSO ↗
trustedKeys

Selected issuer metadata and key provenance, separate from kid.

WEB-15.02 · OIDC, ID token and SSO ↗
validationCases

Gates are jointly necessary; not an actual crypto result.

WEB-15.02 · OIDC, ID token and SSO ↗
sessions

OP, A and B session ownership is independent.

WEB-15.02 · OIDC, ID token and SSO ↗
tokenRecipients

Different recipients for ID token, access token and local session.

WEB-15.02 · OIDC, ID token and SSO ↗
One screen, several trust decisions

When Mina opens Atlas, the browser may have no local session cookie alias. Atlas RP server starts an authentication transaction, preparing the selected issuer, its redirect URI, S256 PKCE and browser-bound state/nonce context. The browser visits the OP authorization endpoint. The OP makes authentication and grant decisions and the browser follows the code callback. TLS connections along the way establish transport trust in web origins, not local user binding or Notes API permission. URLs and redirects are not assumed to share a socket or origin.

WEB-15.03 · Core · The modern login journey ↗
From session to resource decision

When Mina opens her notes, the browser makes an ordinary application request to Atlas. Receiving the cookie alias does not guarantee a successful local session lookup: the server separately checks existence, invalidation and timeouts. A valid session establishes user context; the RP uses the appropriate access token for downstream Notes API. The API checks token validation, audience, expiry and notes:read scope before deciding Mina/tenant/object/read policy. A valid ID token and local session do not replace that final policy.

WEB-15.03 · Core · The modern login journey ↗
Do not overinterpret login success

The normal and foreign-resource branches pass the same ID token, session and access token gates. Only object policy changes: Mina is not bound to a note in the selected other tenant. This isolates the condition of an authorization error. If a system treats accepted identity as permission for every resource, impact depends on the data or actions exposed to that session owner. Opening a client-side page, returning a callback or receiving an API request is not sufficient evidence by itself.

WEB-15.03 · Red · The modern login journey ↗
The credential storage boundary

Where a credential is stored is part of the flow. Keeping ID tokens out of this server-side browser profile does not end all browser risks: the session cookie still accompanies application requests, and state-changing operations need their own request protection. HttpOnly restricts script access to the cookie; it does not guarantee authorization for every operation using it. Read each trust boundary together with credential type and recipient to understand what it protects.

WEB-15.03 · Red · The modern login journey ↗
Give each gate an owner and evidence

Atlas tracks transport peers, transaction correlation, OP identity, local sessions and API resource policy separately. Selecting a new session identifier after successful login, rather than promoting an old pre-authentication context, is a session lifecycle decision. The profile selects Secure, HttpOnly and host-bound cookie scope; SameSite is evaluated together with callback type. GET redirects and POST responses are not assumed to have identical cookie behavior. The fixture creates no cookie bytes and does not measure browser enforcement.

WEB-15.03 · Blue · The modern login journey ↗
Each gate produces its own evidence

Operational evidence comes from different owners: an RP validation library supplies a signature result, the session store a timeout result and the API policy engine an object decision. Safe correlation IDs can link events without logging tokens, codes, cookies or private keys. Provider interoperability, key rollover, consent/freshness policy, refresh behavior and browser navigation need separate isolated integration tests. The full journey table helps plan those tests; completing the model does not establish success in those external systems.

WEB-15.03 · Blue · The modern login journey ↗
journey

Each full-journey gate has its own owner and evidence.

WEB-15.03 · The modern login journey ↗
session

Local timeout and cookie policy; not equal to token exp.

WEB-15.03 · The modern login journey ↗
sessionCases

Zero-leeway local session boundary and invalidation.

WEB-15.03 · The modern login journey ↗
cases

OP state alone creates neither an RP session nor API permission.

WEB-15.03 · The modern login journey ↗
credentialRecipients

Separates credential type from its intended validation owner.

WEB-15.03 · The modern login journey ↗
Which transaction owns a code?

PKCE establishes continuity between an authorization code and its initiating client transaction. For each authorization request the client generates a new high-entropy code_verifier; the S256 challenge is the unpadded base64url encoding of SHA-256 over the ASCII verifier. The authorization request carries the challenge and method; the verifier is used later in the TLS token request. The challenge is not an identity claim, and the code is not an API access token. The AS binds the method and challenge to the issued code.

WEB-15.S01 · Core · PKCE, redirects and identity binding ↗
Redirect, state and nonce are different fields

The registered redirect is the endpoint to which the AS sends its response. Current BCP requires exact string matching; the native-app localhost redirect-port exception does not transfer to this server-side HTTPS profile. The same host with a different path or added query is not the registered callback string. The callback transaction is associated with browser-A, the selected issuer and pending state-A. A state match concerns callback correlation alone; it does not validate a token signature or user identity by itself.

WEB-15.S01 · Core · PKCE, redirects and identity binding ↗
Which local account receives the valid identity?

The stable key for a validated OIDC identity is the pair iss and sub. subject-A under another issuer is not automatically the same local user; equal email or preferred_username values are insufficient for account linking. Login through a mapping already established is different from adding a new external identity to an existing local account. The latter is a sensitive account change: the existing account session, authentication of the new identity and the linking transaction binding must all be demonstrated.

WEB-15.S01 · Core · PKCE, redirects and identity binding ↗
The effect of the first failed gate

In the state-denied branch the browser context is correct, but state-B does not match pending state-A; the RP does not begin an ordinary token request. Calling this an AS token denial would be incorrect because no request is drawn to the AS. The PKCE-denied branch passes the callback gate and the ordinary token request reaches the AS, but the selected fixture verifier does not match the code challenge, so the AS prepares an error response. Response arrival and local RP handling of the error are separate states.

WEB-15.S01 · Red · PKCE, redirects and identity binding ↗
Equal profile attributes do not establish identity

In the email-only row, even a valid identity lacks an existing account session and a linking-session binding, so an email resemblance produces no link. Link-pending separates proof of the new identity from approval of the sensitive local change. If that boundary fails, an external identity may be used in the wrong local account context; which records or tenants it can access still depends on application authorization. Reducing the problem to token format hides its owner: the RP owns local mapping and needs a verifiable binding policy.

WEB-15.S01 · Red · PKCE, redirects and identity binding ↗
Build a transaction ledger with clear owners

The RP pending transaction stores the selected issuer, client registration, redirect, user-agent binding, state, nonce and verifier reference together, while preserving each field’s purpose. The AS code ledger binds client, redirect, method/challenge, expiry and one-use conditions. After the local callback gate the token endpoint comes from trusted configuration; incoming callback addresses or key references do not become new trust sources. Token receipt, ID validation and local account mutation are recorded separately.

WEB-15.S01 · Blue · PKCE, redirects and identity binding ↗
Treat account linking as a separate sensitive change

Read existing identity mappings through iss/sub; for a new link check the existing account authentication, new identity validation and current linking-session binding again. Atlas additionally requires user confirmation; account storage stays unchanged in link-pending and the prospective link supplies no new login authority. Necessary reauthentication, access removal after unlinking and user notifications are parts of the lifecycle. This fixture shows only a decision ledger: it sends no notification, downloads no key or token and writes no actual local account store.

WEB-15.S01 · Blue · PKCE, redirects and identity binding ↗
transaction

Browser and correlation references in the pending RP transaction.

WEB-15.S01 · PKCE, redirects and identity binding ↗
publicHashFixture

Fixed noncredential ASCII fixture and S256 result; no entropy claim.

WEB-15.S01 · PKCE, redirects and identity binding ↗
codeAssociation

Method/challenge and other context the AS associates with its code.

WEB-15.S01 · PKCE, redirects and identity binding ↗
accountRows

Existing login, approved linking and no-link are separate local decisions.

WEB-15.S01 · PKCE, redirects and identity binding ↗
Who speaks, and who decides?

In SAML federation the IdP expresses the principal’s authentication result through an assertion; the SP is the relying party evaluating it in a local application context. Atlas selects SP-initiated browser SSO: the SP creates pending request-A, the browser carries the request to the registered IdP, and the IdP response reaches the SP ACS endpoint through the browser. The browser mediates transport, without owning the SP’s trust in the IdP signing identity. The local SP session is established separately from the IdP session.

WEB-15.S02 · Core · Introduction to the SAML federation model ↗
Destination, audience and recipient bind different things

Response Destination matches the ACS location receiving the message; bearer Recipient is the ACS URL where the assertion can be confirmed. Audience is the SP’s unique entity identifier and need not equal its ACS URL. Response and bearer InResponseTo are bound to selected request-A. The SP also preserves its pending request and browser context. Do not confuse a Core field’s generally optional definition with correlation requirements in this selected SP-initiated profile; unsolicited flows have separate rules and are not accepted here.

WEB-15.S02 · Core · Introduction to the SAML federation model ↗
Which business data does the signature protect?

Approved erratum E26 for the POST profile requires digital-signature protection for each assertion; signing the assertion individually or signing a covering Response can provide it. This example selects individual assertion coverage. Signature validation needs a trusted IdP key, an accepted algorithm and known verified-node coverage; a certificate or KeyInfo inside the message is not automatically a trust anchor. Business identity must be read from the node actually verified and evaluated against policy.

WEB-15.S02 · Core · Introduction to the SAML federation model ↗
A valid assertion cannot be used in any context

In the audience-denied branch the response reaches the correct ACS and the issuer and signature fixture remain valid, but the assertion is intended for the catalog SP. Atlas does not create a local session because its entity ID is missing from the audience restriction. Audiences inside one restriction are OR alternatives, while separate restriction groups combine with AND; flattening them into one large allowlist changes the condition. This is a failed intended-relying-party binding, not a transport or XML-format error.

WEB-15.S02 · Red · Introduction to the SAML federation model ↗
A signature result does not hide node selection

The node-denied branch separates verified assertion-A from the business consumer’s assertion-other reference in a typed ledger alone. It contains no XML-signing example, parser manipulation or reproduction flow. The assumption to examine is which issuer/subject/condition node a successful signature result actually covered. Losing key provenance, coverage or consumption of the same node disconnects the identity decision from its evidence. Signed XML supplies integrity; attribute correctness and local role policy still require their own evaluation.

WEB-15.S02 · Red · Introduction to the SAML federation model ↗
Trust configuration precedes the message

Atlas keeps the selected IdP entity ID, SP entity ID, ACS URL and signing-key provenance distinct in configuration. A current library algorithm policy is used; historical signature-algorithm recommendations from the 2005 standard are not carried forward as current deployment defaults. XML parser/schema/ID uniqueness, signature validation and business-node selection stay together within a reviewed library boundary. An unknown schema or a new key reference carried by a message is not an automatic network trust source.

WEB-15.S02 · Blue · Introduction to the SAML federation model ↗
Separate session creation from assertion reuse

In the normal branch the SP creates a new local session only after all selected gates pass, consumes pending request state and retains the used assertion ID through confirmation validity. The POST profile requires this for bearer-reuse control; a real product separately verifies storage concurrency and clock policy. Accepting an assertion does not make the SP session indefinite; local session lifetime and any AuthnStatement SessionNotOnOrAfter context are tracked separately.

WEB-15.S02 · Blue · Introduction to the SAML federation model ↗
profile

Selected SP-initiated binding and trust contexts; XML is not executed.

WEB-15.S02 · Introduction to the SAML federation model ↗
normal.response

Response ID, Destination and request correlation.

WEB-15.S02 · Introduction to the SAML federation model ↗
normal.assertion

Subject, audience, Conditions and bearer confirmation are separate fields.

WEB-15.S02 · Introduction to the SAML federation model ↗
normal.signature

Declared trusted key and the same verified/consumed-node relationship.

WEB-15.S02 · Introduction to the SAML federation model ↗
timeRows

UTC teaching offsets; the confirmation ending instant is excluded.

WEB-15.S02 · Introduction to the SAML federation model ↗
Server roles are broader than product names

A web server is the role that accepts HTTP requests and returns appropriate responses, serving static content or forwarding work. An application server connects requests to application logic and produces its result. These roles do not always require two machines, two processes, or separate products. A Node http.createServer callback lets one process handle both HTTP serving and application execution. A framework organizes routing and middleware; it does not replace the runtime code-execution and I/O capabilities.

WEB-16.01 · Core · Web server, runtime, and execution model ↗
A reverse proxy creates another HTTP hop

A reverse proxy accepts the client request, sends its own request to a selected upstream, receives the upstream response, and responds to the client. Client-to-edge and edge-to-application are separate exchanges, not one socket or an in-process function call. The fixture preserves method/path and harmless content. Real proxies may also map URIs, cache, buffer, or apply connection policies, depending on configuration.

WEB-16.01 · Core · Web server, runtime, and execution model ↗
Async work is not automatic CPU parallelism

Default Node JavaScript callbacks run on one event-loop thread. Suitable network I/O can be offloaded to the kernel, and selected filesystem/crypto APIs use the libuv worker pool. This does not automatically move a long application JavaScript loop into that pool. An async function executes synchronously until its first await; returning a Promise does not place that part on another CPU.

WEB-16.01 · Core · Web server, runtime, and execution model ↗
Shared execution capacity is a boundary

Synchronous JavaScript in one handler can delay the same event-loop callback queue. The broken assumption is that the async keyword makes all work nonblocking; sufficiently large normal computation can affect other requests. Impact is availability latency depending on runtime, concurrency, and workload. This 10000-term example is neither a load attack nor a production benchmark.

WEB-16.01 · Red · Web server, runtime, and execution model ↗
Identify the owner of served content

Treating static content as the result of an application permission check confuses hop and handler ownership. Public Static note is normal; with personalized data the same assumption can misinterpret confidentiality or stale results. Letting an edge route/cache choice stand in for application policy requires an explicit correct contract. A product name or edge status 200 is not proof of that contract.

WEB-16.01 · Red · Web server, runtime, and execution model ↗
Build the role and hop ledger

First observe the listening endpoint and where the selected request dispatches. For /notes, correlate harmless edge/application request observations; for /static/note, expect no increase in application request count. Client status/body and edge upstream observation are different telemetry points. Do not present native API event names as a real proxy access-log schema; field mapping depends on the server product.

WEB-16.01 · Blue · Web server, runtime, and execution model ↗
Separate execution model from measurement

Record entry/exit, caller continuation, and queued callback order for the async CPU fixture. Independently check the sum with n(n+1)/2; looking fast is not the pass criterion. Reporting queue effects as production latency needs actual workload and timing measurements. Small bounded work is enough to explain an async function synchronous portion.

WEB-16.01 · Blue · Web server, runtime, and execution model ↗
Bound execution cost at the request boundary

Async does not remove CPU cost. Define the accepted request size and maximum work before entering the handler; avoid unbounded computation on the event loop. Use appropriate asynchronous APIs for network and disk I/O, while CPU work may move to a worker pool. Bound its pending jobs and define time limits and failure behavior; unlimited worker creation is not a safe capacity policy.

WEB-16.01 · Blue · Web server, runtime, and execution model ↗
roles

HTTP, runtime, and framework roles need not be one product/process.

WEB-16.01 · Web server, runtime, and execution model ↗
proxyExchange / staticExchange

Upstream arrival and edge-owned responses follow different paths.

WEB-16.01 · Web server, runtime, and execution model ↗
cpu / memory

Bounded sum/order and ordinary process-memory ownership.

WEB-16.01 · Web server, runtime, and execution model ↗
Environment carries input, not a type contract

Environment variables are key/value inputs associated with the process startup environment. Node process.env exposes that process environment object; DotEnv parses additional values as text. The strings false, 0, or JSON-looking text do not automatically become booleans, numbers, or objects. Configuration loading must specify its input source and conversion to typed values.

WEB-16.02 · Core · Configuration and secrets ↗
A running process has its own consumption lifecycle

Configuration can be read once at startup and converted to a frozen object. Moving a deployment source to cfg-b does not automatically refresh a running process using a cfg-a snapshot. This is not because environment is forever immutable: application code can change process.env. Read timing and reconstruction of cached clients or connections are application decisions.

WEB-16.02 · Core · Configuration and secrets ↗
Secret delivery, use, and revocation differ

A secret is material whose exposure affects access or cryptographic protection; not every configuration field is secret. A public theme or limit differs from a database credential/private key. Environment injection can deliver a secret, but alone provides no vault, access control, encryption at rest, auditing, or rotation. Protect lifecycle separately across source repositories, build images, plaintext logs, and dumps.

WEB-16.02 · Core · Configuration and secrets ↗
Breaking text and snapshot assumptions

Accepting the strings false or two as truthy without converting to expected types can make mode/limit decisions incorrect. The broken assumption is that environment input is already normalized. Impact depends on how the application uses the field: wrong readiness, availability, or policy branches. This lesson rejects ordinary invalid input at startup without constructing an exploit payload or production-parameter recipe.

WEB-16.02 · Red · Configuration and secrets ↗
Do not confuse delivery with secret protection

Treating injected material as an automatically protected vault loses the access boundary. Evaluate required roles, source-read permission, and consumption context; dumping full configuration into plaintext logs can expose secrets. Impact depends on the secret privileges and consumer. Limit source access, separate values from output, and connect lifecycle to an operational inventory.

WEB-16.02 · Red · Configuration and secrets ↗
Observe effective configuration without revealing values

Evaluate startup input against enum/type/required-field rules. Normal public/"2" normalizes to limit=2, while two rejects startup. Record accepted cfg-a separately from source cfg-b. Observe public mode and harmless limit fields without credentials. Missing-field observations do not automatically imply false or safe defaults.

WEB-16.02 · Blue · Configuration and secrets ↗
Track both owners of version transitions

Secret-source current alias, process-consumed alias, and downstream-accepted alias are different fields. Audit needs consumer role, outcome, version alias, and actual observation time without logging values. In the supplied current=b/process=a/accepted=b branch, rejection is explained by the old snapshot. Bind that conclusion to the downstream predicate rather than source-only rotation.

WEB-16.02 · Blue · Configuration and secrets ↗
validationContract / input

Only explicit synthetic text input; range is educational.

WEB-16.02 · Configuration and secrets ↗
normalized / snapshotChange

Typed accepted state differs from source metadata.

WEB-16.02 · Configuration and secrets ↗
secretVersions

Noncredential aliases and an acceptance-lifecycle predicate.

WEB-16.02 · Configuration and secrets ↗
A framework organizes execution

A web framework organizes request/response handling above a runtime using abstractions such as routers, middleware composition, handlers/controllers, and error paths. Its name does not itself define HTTP parsing or JavaScript execution. The Express guides describe routing and middleware as a sequence of function calls in a request-response cycle. This small manual Node pipeline demonstrates that role distinction without implementing every Express matching or error rule.

WEB-16.03 · Core · Routing, middleware, and handlers ↗
Middleware produces state or ends the cycle

Middleware can read/change request context, prepare a response, raise an error, or pass control through a continuation. Express normal middleware that does not end the cycle must call next(); doing neither can leave a hanging request. The presence of middleware does not prove it ran for a request in the correct order. Mount/path, method, and earlier cycle completion affect execution.

WEB-16.03 · Core · Routing, middleware, and handlers ↗
One response owner and bounded completion

A handler/controller connects input to application logic and maps a domain result/representation to an HTTP response. The controller name guarantees no database write or transaction. This public handler only reads Routed note, with no persistence operation. For stateful actions, commit, response preparation, and client observation are different events requiring the storage contract in WEB-18.

WEB-16.03 · Core · Routing, middleware, and handlers ↗
Do not equate route matching with permission

Method/path matching chooses the code reached, without automatically validating user, tenant, or object authorization. Middleware presence does not prove a check ran on the route before the handler. The broken assumption is treating routing/presentation context as authoritative access control. Personalized operations can be affected according to the application control chain; this public reader accepts no identity.

WEB-16.03 · Red · Routing, middleware, and handlers ↗
Overtrusting completion

Interpreting server finish as client action success or a committed transaction exceeds observation boundaries. For a normal read, the client can separately confirm content; persistence needs storage results. The condition is collapsing transport/local lifecycle and business state into one success field. Impact can include stale UI, wrong confirmations, or confused error handling depending on operation.

WEB-16.03 · Red · Routing, middleware, and handlers ↗
Correlate selection and stage trace

Correlate harmless requestRef, method, parsed pathname, query view, and selected handler. GET /notes?view=plain records pathname /notes, noteRead, and expected stages. A method mismatch has handlerInvoked=false with 405 with Allow: GET, while an absent route has handlerInvoked=false with 404. Real telemetry mappings depend on server/framework; the artifact is not a runtime access-log format.

WEB-16.03 · Blue · Routing, middleware, and handlers ↗
Separate final response from business result

Correlate terminal owner and final status/content bytes with the selected exchange. Compare normal Routed note status 200/body 11 bytes, controlled 500 Service unavailable, method-mismatch 405 Method not allowed, and missing 404 Route not found. Keep the error beforeHeaders condition explicit; do not infer post-header stream behavior from this fixture.

WEB-16.03 · Blue · Routing, middleware, and handlers ↗
Make pass and terminal decisions one control flow

Route and middleware order controls progression, not just log layout. Do not enter a personalized handler before its required request context is ready; complete any required access decision separately before handler execution. Middleware either ends the cycle or explicitly passes control onward. A denial or error must not continue into the normal handler, and the response owner must reject a second completion. In Express, follow the next and error-handling middleware contract; this small dispatcher does not establish that Express was executed.

WEB-16.03 · Blue · Routing, middleware, and handlers ↗
routeTable / normal

Separate method/path selection and query with expected local stages.

WEB-16.03 · Routing, middleware, and handlers ↗
methodMismatch / routeAbsent

Distinct terminal decisions that never invoke a handler.

WEB-16.03 · Routing, middleware, and handlers ↗
handlerError / completion

Controlled pre-header error and transport/business completion distinction.

WEB-16.03 · Routing, middleware, and handlers ↗
The controller carries results; the domain selects them

A service layer organizes a use-case flow: invokes suitable data access, applies a domain rule, and returns a result the controller can consume. This public-note rule permits presentation when published=true. The controller maps a path to a note key, the repository reads the record, and the domain determines availability. Service does not mean a remote HTTP microservice or separate process here; these are function calls inside the selected process.

WEB-16.04 · Core · Service layer, business logic, and templates ↗
Templates place data in an interpreter context

A template is a trusted output structure selected by the application; its view model is data. Placing Tea & Bread in the HTML text slot produces <h1>Tea &amp; Bread</h1>. A JSON representation can retain Tea & Bread as its string value. Encoding decisions cannot be copied blindly between contexts: HTML text, attributes, URLs, JavaScript, and CSS have different interpretation rules.

WEB-16.04 · Core · Service layer, business logic, and templates ↗
Ownership of one rule across different entry points

Start by identifying which service/domain result each controller consumes. If an HTML route gets published from the service while a JSON route directly serializes repository records, one availability contract is applied differently. The possible impact is a broken intended presentation boundary; a method or framework name cannot explain it. The control is a shared rule owner and evidence that both presentations depend on its result.

WEB-16.04 · Red · Service layer, business logic, and templates ↗
Interpreting output and completion accurately

The encoded Tea & Bread HTML body demonstrates data transformation for the selected text slot. Reusing that transformation as a URL or script-context security control changes its meaning. The failure condition is a mismatch between context and encoder; possible effects include incorrect rendering or unexpected interpretation. Keep contexts fixed, use appropriate engine/library controls, and review the reasons for raw-output choices.

WEB-16.04 · Red · Service layer, business logic, and templates ↗
Record boundaries separately in the decision ledger

The ledger records repositoryFound=true, published=true, serviceOutcome=available, and rendererInvoked=true for tea. draft exists but becomes unavailable with no renderer invocation; absent has no record. These are selected teaching observations, not a product log schema. Reading outcome-to-status mapping independently separates HTTP policy from a business rule.

WEB-16.04 · Blue · Service layer, business logic, and templates ↗
Limits of the selector and context check

XPath count(/audit/decision[@outcome="unavailable" and @rendered="true"]) counts authored observations that reach rendering despite an unavailable decision. Normal data gives 0; a deliberately inconsistent positive fixture gives 1. A normal draft 404 is benign and expected. An absent event can also produce 0, meaning insufficient evidence rather than proven rule enforcement. The selector evaluates this observation contract only.

WEB-16.04 · Blue · Service layer, business logic, and templates ↗
Keep the business decision independent of adapters

Finding a repository record is not permission to publish it. The service explicitly evaluates published and unavailable; JSON and HTML adapters must not bypass that shared decision. The renderer receives only the required title view model rather than automatically exposing every repository field. Use the appropriate encoder or verified engine auto-escaping for HTML text; JSON serialization is a different control.

WEB-16.04 · Blue · Service layer, business logic, and templates ↗
serviceOutcome

Domain decision between repository result and HTTP status.

WEB-16.04 · Service layer, business logic, and templates ↗
htmlBody

Encoded output of one fixed HTML text context.

WEB-16.04 · Service layer, business logic, and templates ↗
completion

Boundary that does not equate result, arrival, and commit.

WEB-16.04 · Service layer, business logic, and templates ↗
A URL path is not a filesystem path

Static serving returns selected file bytes as an HTTP representation through a public mapping. The URL /assets/tea.txt maps to fixtureRoot/tea.txt; a physical /assets directory need not exist. The Express static-mount example documents this virtual-prefix distinction. A physical dirname can be absent from the URL, and the process entire filesystem is not automatically a public web area.

WEB-16.05 · Core · Static files, filesystem, and request processing ↗
Request processing produces bytes and metadata

Processing accepts the method/target, selects the URL pathname, resolves the public map, performs necessary file I/O, and applies response policy. Query view=plain is excluded from this example map key, leaving /assets/tea.txt. A different application may give the query its own contract. As with a repository function, the filesystem read is a local process API here, not an HTTP packet between diagram actors.

WEB-16.05 · Core · Static files, filesystem, and request processing ↗
Separate the public map boundary from the physical file

For a benign review, connect the documented public asset to the server map entry. The existence of tea.txt alone is not a public-exposure decision; the controlled route, map, and selected response matter together. In designs with multiple static roots, lookup order can choose different assets for one URL. This lesson uses a fixed map without arbitrary paths or directory enumeration.

WEB-16.05 · Red · Static files, filesystem, and request processing ↗
Scope of HEAD and content metadata

An empty HEAD body does not mean an empty file. Content-Length: 4 describes the selected GET representation, while HEAD transfers zero content octets. Receiving Çay through GET also does not prove security controls for the whole processing chain; it connects the whitelist entry, bytes, and selected response contract.

WEB-16.05 · Red · Static files, filesystem, and request processing ↗
Read the mapping and I/O ledger together

The normal artifact records target=/assets/tea.txt?view=plain, pathname=/assets/tea.txt, mapping=tea.txt, and fileContentHex=c3876179. These are synthetic relationship observations, not predefined server telemetry fields. Four client octets match the UTF-8 calculation. HEAD has declaredLength=4 but receivedContentOctets=0, which is expected behavior.

WEB-16.05 · Blue · Static files, filesystem, and request processing ↗
Do not equate missing observations with a clean result

XPath count(/audit/asset[@mapping="none" and @reads!="0"]) selects authored observations with file reads despite no public mapping. Normal missing.txt gives 0 and a deliberately inconsistent positive fixture gives 1. gone.txt has a mapping, so its single read attempt is benign and outside this condition. With no event, zero still means insufficient evidence.

WEB-16.05 · Blue · Static files, filesystem, and request processing ↗
Select the public file boundary explicitly

The static root should contain assets intended for publication, not the entire project. In Express, root selects the physical directory and the mount prefix selects its public URL space; a relative root depends on the process launch directory. Resolve the intended root explicitly and review lookup order when multiple roots exist. This example uses a narrower fixed map: no filesystem read begins without an allowed mapping.

WEB-16.05 · Blue · Static files, filesystem, and request processing ↗
mapping

Selected mapping from fixed URL keys to fixture paths only.

WEB-16.05 · Static files, filesystem, and request processing ↗
declaredLength

Octets of the GET representation, not transferred HEAD content.

WEB-16.05 · Static files, filesystem, and request processing ↗
readAttempts

Separates unmapped and backing-missing internal causes.

WEB-16.05 · Static files, filesystem, and request processing ↗
Parsing is not an application decision

Atlas receives title and quantity for a public book preview. Use Cafe plus a combining acute accent and quantity=2 as ordinary input. A JSON parser turns text into values without establishing an allowed quantity or permission for a business action. Byte admission, parsing, schema, and domain decisions yield distinct outcomes.

WEB-16.S01 · Core · Validation, normalization, and interpretation boundaries ↗
Schema and domain rules ask different questions

The closed schema admits only title:string and quantity:integer. Missing, null, extra fields, and incorrect types fail structural rules. Quantity=5 passes the integer type check but fails Atlas’s 1..3 preview rule. The string “2” is never silently coerced, leaving the API’s admitted representation explicit.

WEB-16.S01 · Core · Validation, normalization, and interpretation boundaries ↗
Which equivalence does normalization select?

The selected title policy uses NFC. Cafe plus U+0301 and Café can have different byte and code-point sequences; canonical normalization makes these ordinary examples equal. Normalization chooses the representation for comparison and storage. Here length means 1..40 Unicode code points after NFC, distinct from bytes, grapheme clusters, or visible glyph count.

WEB-16.S01 · Core · Validation, normalization, and interpretation boundaries ↗
Encoding and parameterization belong to a sink

The preview consumes a plain title. HTML text serialization, when needed, has its own context encoding. For ordinary Tea & Bread, the native observation serializes the ampersand as an entity while the domain title stays Tea & Bread. Keep the representations distinct. HTML text encoding is not a general safety transform for JavaScript source, URL destinations, or SQL structure.

WEB-16.S01 · Core · Validation, normalization, and interpretation boundaries ↗
Do not consume a partially checked record

The artifact distinguishes parsed, schemaValid, domainValid, normalizedTitle, and previewRecord. Wrong type can leave parsed=true while previewRecord stays null. A domain limit leaves schemaValid=true and domainValid=false. Extra fields are not silently discarded into an accepted record. These outcomes identify the rejecting owner instead of one generic invalid label.

WEB-16.S01 · Core · Validation, normalization, and interpretation boundaries ↗
What follows from valid JSON?

Reporting quantity “two” as a parse failure identifies the wrong owner. It fits the grammar but fails the schema. Quantity=5 fits the type but not the operation rule. Keep grammar, field/type, and domain success distinct in review; native evidence explains why these branches differ.

WEB-16.S01 · Red · Validation, normalization, and interpretation boundaries ↗
Similar-looking titles need not share bytes

Native composed and decomposed Café examples distinguish appearance from raw equality. Selected NFC unifies their comparison representation without equating all Unicode strings. NFC preserving the fullwidth-A distinction supplies another observation: normalization is a choice about application semantics.

WEB-16.S01 · Red · Validation, normalization, and interpretation boundaries ↗
Define an accepted-representation contract

The public-preview contract defines two fields, exact types, quantity range, and NFC title length together. Missing, extra, and null values need explicit outcomes. Apply the byte limit before parsing and type/domain rules to values. Python bool/int inheritance does not define the API’s quantity type: the native profile rejects booleans. Unknown input produces no guessed record.

WEB-16.S01 · Blue · Validation, normalization, and interpretation boundaries ↗
Compare results against an independent artifact

Expect Café/2 for normal input, schema rejection for wrong type, domain rejection for quantity=5, and closed-shape rejection for reviewed. The last three retain a null record. Read parsed types, normalized titles, and HTML text representations from separate fields. Success at one stage is not evidence of success at another.

WEB-16.S01 · Blue · Validation, normalization, and interpretation boundaries ↗
raw

Fixed ordinary JSON text; byte admission is separate from parsing.

WEB-16.S01 · Validation, normalization, and interpretation boundaries ↗
schemaValid / domainValid

Fields/types and operation range are separate gates.

WEB-16.S01 · Validation, normalization, and interpretation boundaries ↗
previewRecord

Accepted NFC title and quantity; null on rejection.

WEB-16.S01 · Validation, normalization, and interpretation boundaries ↗
representations

Raw, normalized, and HTML-text-serialized forms differ.

WEB-16.S01 · Validation, normalization, and interpretation boundaries ↗
Choosing the interpreter is not an input responsibility

An Atlas book title can be an argument to a fixed program, a value in a fixed template, or a field in a fixed XML record. Those roles do not share one universal string rule. The application selects the operation profile; supplying a title does not grant authorship of an executable, template source, or XML query expression. The typed record from the validation lesson now meets a contract governing its next interpretation boundary.

WEB-16.S02 · Core · Command, template, and XML interpretation boundaries ↗
Command arguments and shell programs are distinct

The native check starts its own Python executable with fixed child code and one title argument supplied as a sequence. It uses shell=False. The child returns only an argument count and title as JSON: O'Reilly & Tea remains one title and argc=1 is observed. This is not a shell-escaping recipe. Program source and executable are application constants; the title cannot choose them.

WEB-16.S02 · Core · Command, template, and XML interpretation boundaries ↗
Template source is fixed and values remain separate

Here Python string.Template uses application-owned source <p>$title</p>. Tea & Bread is serialized as Tea &amp; Bread for HTML text context, then substituted as the title value. The completed string is <p>Tea &amp; Bread</p>. Selecting template source and encoding output answer different questions: which presentation program the server interprets, and how a value is represented in the target text context.

WEB-16.S02 · Core · Command, template, and XML interpretation boundaries ↗
XML parsing and domain records are separate stages

The XML case reads a memory stream within 128 UTF-8 bytes and a selected small tree budget. The installed SAX parser has external-general and external-parameter entity features set to false. Its lexical startDTD callback rejects every DTD declaration. The entity resolver rejects instead of opening an outside resource. These selections are not inferred from a generic parser name: native evidence records actual feature values.

WEB-16.S02 · Core · Command, template, and XML interpretation boundaries ↗
XML trees, XPath selection, and external resources differ

An application-owned title path is selected with ElementTree find. This library provides a limited ElementPath/XPath subset; the native check does not execute a full XPath engine. The caller’s title value is not appended to a selection expression. Validating XML fields and owning a query-language expression are separate responsibilities. Namespaces and other schema profiles are outside this small book format.

WEB-16.S02 · Core · Command, template, and XML interpretation boundaries ↗
A review follows who chooses each source

The same ownership question helps with commands, templates, and XPath: which trusted code selects the interpretation source, and which fields arrive only as data? Program identity, child source, template source, and fixed title path remain distinct in the artifact. Preserving an ordinary title is evidence about a value boundary. It does not imply that the caller may choose executables or expressions.

WEB-16.S02 · Red · Command, template, and XML interpretation boundaries ↗
An interpreter may succeed while its consumer rejects

In the XML wrong-root case, parsing completion is an observed fact; admitting a book record is a different application decision. Execution count=1 and null output are retained together. Calling it only a parse error would hide the real failure boundary. For commands, the result view waits for actual child stdout. For templates, no browser-render outcome is attached to the serialized output.

WEB-16.S02 · Red · Command, template, and XML interpretation boundaries ↗
Close the profile and consumer contracts together

Prefer built-in libraries where they can remove the need for process invocation. When a process is required, begin with an application-owned executable and fixed arguments rather than assembling text as a shell program. This child only returns a title. A real conversion tool additionally needs option/destination policy, privileges, and resource limits. Successful argc=1 does not establish those controls.

WEB-16.S02 · Blue · Command, template, and XML interpretation boundaries ↗
Consume only admitted completed output

Do not hand consumers an entire parsed tree or incomplete child state. Approved records/projections are prepared after completed interpretation; rejected shapes retain null output. The XML display root never becomes an admitted Tea book in the view. Missing a required template value produces an observed KeyError; missing data is not assumed to become automatic empty success.

WEB-16.S02 · Blue · Command, template, and XML interpretation boundaries ↗
profiles

Application-owned sources, configuration, and selected consumer contracts.

WEB-16.S02 · Command, template, and XML interpretation boundaries ↗
executions

Completed child/substitution/parse; XML shape rejection may follow parsing.

WEB-16.S02 · Command, template, and XML interpretation boundaries ↗
output

Admitted consumer output; null for rejected shape.

WEB-16.S02 · Command, template, and XML interpretation boundaries ↗
missing

No interpretation outcome is invented for absent profile evidence.

WEB-16.S02 · Command, template, and XML interpretation boundaries ↗
Resource IDs, display filenames, and storage paths differ

Atlas keeps three names for a text attachment. asset-01 is the resource ID, memo.txt is a presented display filename, and asset-01.dat is the application’s own storage key. A client filename does not directly become a filesystem path. The download handler receives a resource ID, locates its metadata record, and chooses a path from that record. Opaque naming does not replace authorization; the relevant policy is still evaluated on each read.

WEB-16.S03 · Core · Paths, upload, and download authorization ↗
A canonical path is not a permission decision

Python Path.resolve resolves symlinks in the own filesystem and produces an absolute path. Here public-link.dat points to asset-01.dat inside the same root: the lexical basename differs while the resolved target is the same file. Allowed-root decisions do not use a raw string prefix. The selected profile requires the resolved parent to equal the own root exactly; it does not support nested directories.

WEB-16.S03 · Core · Paths, upload, and download authorization ↗
Upload admission includes more than a filename

This teaching profile accepts only memo.txt/catalog.txt display choices, declared text/plain, 1–16 bytes, and strict UTF-8 text. Supplied Alice context permits upload, while Bob causes no write. A declared image/png with ordinary Tea bytes stops at the text-profile gate. Content-Type is a client declaration; putting a value in a header does not prove that the bytes have the required format.

WEB-16.S03 · Core · Paths, upload, and download authorization ↗
Download permission precedes reading bytes

The download branch evaluates a finite policy between the supplied principal and metadata owner before reading a body. Alice is admitted for asset-01, the resolved storage root is checked, and Tea bytes are then read. Bob receives resource-policy rejection for the same known resource: reads=0, null body, and null headers. Successful resource lookup and delivery to a caller are separate facts.

WEB-16.S03 · Core · Paths, upload, and download authorization ↗
Content-Type and Content-Disposition have different roles

For an admitted download, the application selects text/plain; charset=utf-8 and attachment; filename="memo.txt" in a response record. Content-Type indicates the representation’s media type. Content-Disposition attachment suggests default save handling to a recipient; the filename is advisory rather than the recipient’s storage path or the server’s resource ID. Preparing a header does not establish that a browser actually saved the file.

WEB-16.S03 · Core · Paths, upload, and download authorization ↗
Keep four stages of operation evidence separate

The artifact distinguishes intent, policy, storage I/O, and consumer outcome. Upload success produces writes=1 and a storedId, without a download body. Download success produces reads=1 and body Tea, without mutating the file. Media mismatch and denied read retain I/O count=0. The consumer changes only after a completed approved operation, so an earlier success cannot hide a new rejection.

WEB-16.S03 · Core · Paths, upload, and download authorization ↗
Review metadata mapping alongside access decisions

In a file review, separate names influenced by the client from names selected by the backend. Display filename, resource ID, and actual storage key differ in the artifact. A UI link labeled memo.txt does not establish a disk path. Likewise, hard-to-guess asset IDs do not replace owner/resource policy; consider the read decision in every request context.

WEB-16.S03 · Red · Paths, upload, and download authorization ↗
Ordinary failures do not certify format safety

A declared-media mismatch shows upload admission taking effect. A text/plain declaration alone does not establish content safety; selected bytes are separately decoded as strict UTF-8. This profile is not an HTML, PDF, archive, or media-processing pipeline. Passing strings to another interpreter involves separate boundaries in the preceding interpretation and following isolation lessons.

WEB-16.S03 · Red · Paths, upload, and download authorization ↗
Generate storage keys and authorize before reads

Use an approved application key mapping rather than reusing client filenames as storage identifiers. The fixed generated asset-02 key differs from existing asset-01; exclusive creation prevents overwriting existing bytes. Download metadata-owner policy runs before reading a body. Root checking remains a separate storage responsibility, so successful authorization does not legitimize a wrong mapping.

WEB-16.S03 · Blue · Paths, upload, and download authorization ↗
Include headers and format policy in regression evidence

Do not treat an upload declaration as the sole proof of byte format. Record admitted-format validation, byte budgets, and storage naming together. Download metadata should select the right media type and an approved safe display name; recipients should not trust advisory filenames as storage-path instructions. Attachment handling does not replace authorization. The header check here is neither a browser-save nor a general serializer test.

WEB-16.S03 · Blue · Paths, upload, and download authorization ↗
seed / inputs

Own ordinary text and supplied identity aliases; opaque IDs, paths, and displays differ.

WEB-16.S03 · Paths, upload, and download authorization ↗
reads / writes

Operation I/O counts, separate from proof inspection.

WEB-16.S03 · Paths, upload, and download authorization ↗
storedId / body

Upload metadata differs from completed download delivery.

WEB-16.S03 · Paths, upload, and download authorization ↗
headers

Approved local response record, not actual HTTP/browser execution.

WEB-16.S03 · Paths, upload, and download authorization ↗
Upload admission is not processing permission

Storing an attachment does not establish that every parser or converter may process it. Atlas uses two selected profiles here: reading public catalog text records from its own tiny ZIP and reading its own minimal P6 image bytes in a narrow worker. Processing profiles, formats, budgets, and consumer outputs are application-owned decisions. A client filename chooses neither a decoder nor an archive extraction destination.

WEB-16.S04 · Core · Archives and media processing isolation ↗
Compressed bytes, expanded bytes, and entry counts have different budgets

The native ZIP has 226 bytes. Its member uncompressed lengths are 3 and 5, totaling 8. The selected profile requires at most 1024 input bytes, exactly two approved member names, DEFLATE, and an expanded budget of 16. Selecting budget=7 rejects advertised total 8 before decompression: decompressedMembers=0, expandedBytes=0, and null output. Small input size does not replace expanded-size policy.

WEB-16.S04 · Core · Archives and media processing isolation ↗
Member names do not become extraction destinations

The model uses neither extractall nor arbitrary directory extraction. Selected members are read from memory streams and mapped to application-owned record-1 / record-2 identifiers. catalog.txt and notes.txt are archive metadata, not assembled filesystem output paths. Ordinary draft.txt fails the selected manifest before any member decompresses. Storage naming/root containment in the preceding lesson remains a separate responsibility.

WEB-16.S04 · Core · Archives and media processing isolation ↗
Media bytes, dimensions, and rasters are distinct facts

The native worker accepts only a minimal P6 profile: P6 newline, width height newline, 255 newline, and an RGB-channel raster. Normal input has 14 bytes; width=1,height=1 requires exactly 3 raster bytes. The returned channel values are 15, 118, 110, not a color-calibration or browser-render measurement. It is no full Netpbm decoder accepting comments, multiple images, different Maxval values, or other variants.

WEB-16.S04 · Core · Archives and media processing isolation ↗
Separate processes do not prove isolation

Media processing runs in an actual separate Python child. The native check observes a PID different from its parent, starts fixed worker code through an argument sequence without a shell, supplies a literal child environment, and chooses timeout=5. Python -I narrows interpreter import/environment behavior; it does not claim an OS sandbox or a network/filesystem privilege boundary.

WEB-16.S04 · Core · Archives and media processing isolation ↗
The publish gate needs completed records

Archive output consists of two validated public records; media output is a completed pixel list. Worker startup, a read header, or an opened member is not published success. The scene consequently separates work snapshots from Result-consumer snapshots. Archive-budget rejection expands nothing, while incomplete media records parsed dimensions without delivering pixels.

WEB-16.S04 · Core · Archives and media processing isolation ↗
A review asks which authority interprets the bytes

A processing review does not finish with an upload extension. After admission, which decoder, resource budget, and output contract are selected? Deriving filesystem paths from archive metadata or external delegates from media names opens another interpretation boundary. This example uses fixed selected sources/paths and actual work only on own ordinary bytes.

WEB-16.S04 · Red · Archives and media processing isolation ↗
Naming a worker does not invent a trust boundary

Different child/parent PIDs prove process separation. They do not establish an independently enforced memory, disk, network, or kernel-privilege boundary. Python -I does not provide those controls either. Isolation review needs separate evidence for enforcement, admitted format/delegate sets, and publication. One working sample cannot be generalized across decoder families.

WEB-16.S04 · Red · Archives and media processing isolation ↗
Separate admission, work, and publication gates

Measure archive entry counts, compressed input, advertised expanded size, and actual emitted bytes separately. Validate the selected manifest before bounded reads and domain admission. Use application-owned names for stored output; this example uses memory-record projection. Adding general extraction would require separate path, permissions, and cleanup design.

WEB-16.S04 · Blue · Archives and media processing isolation ↗
Keep incomplete output away from consumers

Process exit or a parsed header alone is not success. Archives require every admitted text record, while media require the exact expected raster. Native checks compare null-output branches with independent results. A second-member failure publishes no earlier prepared record; raster-length failure delivers no pixels even when dimensions are known. Model state preserves this failure boundary with motion disabled.

WEB-16.S04 · Blue · Archives and media processing isolation ↗
profiles

Selected format, size, and consumer contracts; not general decoders.

WEB-16.S04 · Archives and media processing isolation ↗
decompressedMembers / expandedBytes

Actual completed bounded work, distinct from advertised headers.

WEB-16.S04 · Archives and media processing isolation ↗
dimensions / pixels

Parsed dimensions do not establish delivery of a valid raster.

WEB-16.S04 · Archives and media processing isolation ↗
output

Publication admits only completed approved records/pixels.

WEB-16.S04 · Archives and media processing isolation ↗
Invariant, transition and authority

A business invariant is a domain condition that must remain true after every accepted operation. In a one-copy catalog, remaining capacity cannot become negative, one copy cannot have two active reservation owners, and a completed command cannot create a second effect. A workflow state machine expresses these conditions using state, action and guards. The available -> reserved transition requires current permission, quantity, capacity and revision checks.

WEB-16.S05 · Core · Business invariants and workflow state machines ↗
Revision and idempotency solve different problems

Revision 7 identifies the state on which this command intends to decide. A conditional update changes one row only when current revision is 7 and state is available; zero affected rows means the stale decision produces no write. The guard and write share a transaction boundary. Successful commit advances revision to 8 and records the receipt. The local SQLite fixture runs sequentially and tests neither parallel requests, every isolation mode nor distributed locking.

WEB-16.S05 · Core · Business invariants and workflow state machines ↗
Comparing invite, booking, coupon and recovery

An invite needs pending, unexpired state bound to a designated recipient and workspace. Booking consumes availability using current capacity and an authorized reserver. A coupon needs eligibility, approved terms, remaining uses and a validity period; a client-requested benefit is not itself a server condition. Recovery has a different purpose: account-bound verified evidence and an unexpired, unused transaction. A normal login role is not substituted for recovery proof.

WEB-16.S05 · Core · Business invariants and workflow state machines ↗
Broken assumption: the right sequence grants domain permission

The Red perspective does not treat following screen order as authorization evidence. Seeing an available page proves neither current reservation state nor actor permission. Permission-missing carries null evidence; it is not claimed false, but lacks the positive evidence needed to write. Denial is prepared before dispatch into the command store, with no receipt or public result body.

WEB-16.S05 · Red · Business invariants and workflow state machines ↗
Broken assumption: attempting an effect completes success

In effect-failed, the local transaction performs an explicit rollback after a controlled failure. Return a receipt only after commit; an unsuccessful attempt must not produce a reserved body. This fixture knows the rollback outcome. The conceptual external-result-absent row instead carries null commitEvidence: a lost response does not establish that no write occurred. A local transaction cannot make another service’s effect atomic.

WEB-16.S05 · Red · Business invariants and workflow state machines ↗
One local transaction for guard and commit

The Blue implementation changes the fake catalog row under conditions on current revision and available state. Exactly one affected row advances revision and saves the command receipt in the same transaction. An explicit rollback in a local failure branch undoes both state update and receipt insert. Do not rely on the assumption that every SQLite error automatically rolls back the whole transaction; observe the rollback decision and outcome separately.

WEB-16.S05 · Blue · Business invariants and workflow state machines ↗
Testing an invariant through outcomes

The initial row is available at revision=7. A normal reservation produces one committed effect and a reserved row at revision=8. Re-evaluating the same retained command leaves the effect count at one. Stale revisions, missing permission, and a rolled-back operation preserve the initial row and produce no new receipt. A previously successful command must not return a cached body after current permission is denied.

WEB-16.S05 · Blue · Business invariants and workflow state machines ↗
profile

Fake copy, authoritative priceUnits, revision and command scope.

WEB-16.S05 · Business invariants and workflow state machines ↗
rows

Current permission/revision/effect evidence and committed state/receipt outcomes.

WEB-16.S05 · Business invariants and workflow state machines ↗
transitionTable

Guarded state transitions versus retained-command receipts.

WEB-16.S05 · Business invariants and workflow state machines ↗
authorityLedger

Server-owned authority sources for price/role/state.

WEB-16.S05 · Business invariants and workflow state machines ↗
idempotencyLedger

One effect and current authorization for bound-command retries.

WEB-16.S05 · Business invariants and workflow state machines ↗
flowFamilies

Purpose-specific guards for invite/booking/coupon/recovery.

WEB-16.S05 · Business invariants and workflow state machines ↗
failureLedger

Pre-dispatch denial, known rollback and unknown external commit.

WEB-16.S05 · Business invariants and workflow state machines ↗
boundaries

Evidence limits of key possession, local transactions and sequential tests.

WEB-16.S05 · Business invariants and workflow state machines ↗
An API is an interaction contract

An API describes operations/data one component exposes to another; not every API runs over the web. A Web API makes that interaction accessible through a web protocol. Atlas GET /api/notes/tea selects a read operation through method and target together. Adding api to a URL or returning JSON does not define the complete contract. Allowed methods, headers, representation shape, and error meaning matter too.

WEB-17.01 · Core · API contracts, endpoints, and REST ↗
REST constraints, representations, and hypermedia

REST is Fielding architectural style: client-server, stateless interaction, cache constraints, uniform interface, and layered system work together; code-on-demand is optional. Uniform interface includes resource identification, manipulation through representations, self-descriptive messages, and hypermedia guiding application state. JSON and CRUD resemblance alone do not establish all these constraints.

WEB-17.01 · Core · API contracts, endpoints, and REST ↗
Compare the contract with the observed result

Review a controlled public endpoint by method/target, selected media type, status, and schema. A numeric JSON id at /api/notes/tea violates the contract despite successful parsing. A client predicate evaluates this supplied harmless candidate; no malformed protocol or attack response is generated from a production server. Possible effects include a wrong application branch or an unusable typed result. Separate transport success from application-contract validation.

WEB-17.01 · Red · API contracts, endpoints, and REST ↗
REST labels and state dependencies

A JSON API labeled REST requires more than resource URLs. If understanding a request requires stored server context from an earlier client interaction, strict statelessness needs a different assessment. That alone is neither a vulnerability nor an unusable product; it is a distinction between an architectural claim and behavior. Keeping domain data in a database is not the same session dependency.

WEB-17.01 · Red · API contracts, endpoints, and REST ↗
Contract ledger and independent predicates

The artifact records GET/HEAD methods, target /api/notes/tea, supported JSON/plain media types, and required id/title/links JSON fields. Normal status=200, media=application/json, and schemaValid=true. A client predicate calculates string id/title and array links separately. It rejects the harmless id=7 candidate; this is a local schema observation, not a real gateway log schema.

WEB-17.01 · Blue · API contracts, endpoints, and REST ↗
Schema selectors and hypermedia evidence

XPath count(/audit/response[@status="200" and @media="application/json" and @schema="invalid"]) counts authored observations pairing successful HTTP with an invalid application shape. The normal valid fixture gives 0 and a supplied positive fixture gives 1. Expected 406/405 responses are separate branches outside this schema condition. With no observation, zero is not proof of clean behavior; response/validation evidence is missing.

WEB-17.01 · Blue · API contracts, endpoints, and REST ↗
Enforce the operation and representation contract

Bind supported methods and media types to dispatch decisions rather than documentation alone. GET and HEAD in this read contract do not initiate business mutation; POST does not enter the selected operation. Safe method semantics do not mean every user may read every resource: private resources require a separate identity and permission decision. The JSON Content-Type must match serialization, and the client validates id/title/links types before use.

WEB-17.01 · Blue · API contracts, endpoints, and REST ↗
contract

Joint definition of method, target, media, shape, and supported operation.

WEB-17.01 · API contracts, endpoints, and REST ↗
invalidCandidate

Harmless supplied local schema counterexample, not a wire response.

WEB-17.01 · API contracts, endpoints, and REST ↗
hypermedia

Target selected through an entry relation, without full REST conformity claim.

WEB-17.01 · API contracts, endpoints, and REST ↗
JSON carries a value model

The Atlas book list begins as an application object, is serialized into UTF-8 JSON text, and is parsed into a new value tree at the other end. These are not the same in-memory object. Object member order is not its semantic ordering; array order matters. A top-level value need not be an object. Strings, numbers, booleans and null are distinct: "2" and 2 need not pass the same schema. Dates, class methods and database connections are not JSON value types.

WEB-17.02 · Core · Schemas, serialization and API evolution ↗
What question does a schema answer?

The request schema requires an integer pageSize from 1 through 3 and permits an optional string cursor. The response schema defines a books array with required id and title. These are structural checks after parsing; they do not decide which tenant’s books a user may read. In JSON Schema, properties alone does not require a field, and additionalProperties is not closed by default. This fixture rejects unknown request fields while preserving unknown response fields. The two directions need not use the same rejection policy.

WEB-17.02 · Core · Schemas, serialization and API evolution ↗
Evolution and pagination belong together

Adding subtitle in a v1.1 response while retaining title:string is compatible for the reader that preserves unknown response fields. Renaming title to heading within v1 behaves like removal plus addition and breaks the old reader’s expectation. This fixture selects its major version through the URI; it is a product choice, not a universal HTTP requirement. Compatibility is more than parseable JSON: ask separately whether old client code still builds, whether wire types still match, and whether users receive the same business meaning.

WEB-17.02 · Core · Schemas, serialization and API evolution ↗
Drawing the wrong conclusion from format acceptance

A parsed request proves only that the selected parser accepted its text. Passing the schema proves that pageSize and cursor have acceptable shapes. Neither result proves the tenant binding, the subject’s read permission or that a cursor still belongs to a valid snapshot. The risky assumption is compressing every green result into a single valid-request label. The artifact therefore records parsing, schema, continuation and business permission separately so the reader can identify the rejection boundary.

WEB-17.02 · Red · Schemas, serialization and API evolution ↗
A small change can break business meaning

If an old client interprets an empty books array as an empty archive, adding pagination later changes more than one field. A user may see only the first page and mistake an incomplete list for the whole collection. Changing title from a string to an object can also break the old UI while JSON remains valid. Compatibility review therefore separates required names, wire types, field preservation and collection-completion meaning, identifying which old expectation is broken.

WEB-17.02 · Red · Schemas, serialization and API evolution ↗
Write producer and reader policies together

Specify each field’s name, wire type, required or optional status, nullability, default and unknown-field policy. A producer can keep emitting title while a reader preserves an unfamiliar subtitle; test that round-trip contract explicitly. A closed request schema returns a clear error for an unknown field rather than silently deleting it during normalization. Define numeric domains, string size and collection limits alongside parser limits; JSON number grammar does not itself guarantee business units or precision.

WEB-17.02 · Blue · Schemas, serialization and API evolution ↗
Separate the page boundary from the permission boundary

Document pagination defaults and maximums, ordering tie-breakers, the meaning of an absent nextCursor and the filter/order binding. This fixture uses a fixed in-memory snapshot, applies the tenant filter before pagination, and uses cursor-A only to select the next starting position. If its bound filter changes, return a binding error instead of inventing another page. Explain how clients restart after cursor expiry or snapshot loss; the lesson does not supply a production storage implementation.

WEB-17.02 · Blue · Schemas, serialization and API evolution ↗
requestSchema

Selected closed request rules; not a complete validator.

WEB-17.02 · Schemas, serialization and API evolution ↗
bookSchema

Current producer book schema; subtitle may be string or null.

WEB-17.02 · Schemas, serialization and API evolution ↗
pages

Two pages of the fixed snapshot after tenant filtering.

WEB-17.02 · Schemas, serialization and API evolution ↗
compatibilityRows

Old-reader expectations for addition, rename and null.

WEB-17.02 · Schemas, serialization and API evolution ↗
cursorLedger

Local snapshot/filter/order continuation binding of an opaque alias.

WEB-17.02 · Schemas, serialization and API evolution ↗
oldReaderSchema

The old reader knows only id/title and preserves unknown subtitle without interpreting it.

WEB-17.02 · Schemas, serialization and API evolution ↗
A selection set is not a business workflow

GraphQL lets a client select response fields from a typed schema. Atlas uses Query.book(id: ID!): Book and selects id/title/subtitle. The schema is an API field/type contract, not necessarily a one-to-one database schema. A query produces a read result, a mutation describes a top-level change operation, and a subscription produces a response stream tied to source events. This lesson follows an ordinary read query only; subscription transport and mutation transactions are outside the animation.

WEB-17.03 · Core · GraphQL execution model ↗
From resolver result to typed response

A resolver produces a field value using its parent value, field arguments and server-created context. Atlas uses declared session/tenant permission and reads book-A from a fixed local record. A resolver call is not automatically an HTTP request; this in-memory lookup is a local step in the scene. Field completion follows the schema type, executing selected child fields or coercing a scalar result. Copying every runtime object member into the response is not equivalent to executing a selection set.

WEB-17.03 · Core · GraphQL execution model ↗
Execution results and HTTP results differ

A request that never starts execution because of parsing, validation or input coercion errors returns errors without a data member. Field failures after execution starts can produce data together with errors; data:null is different from an absent data member. Browser network success or an HTTP status alone does not prove that every selected field succeeded. A UI can inspect the book value and error paths together, show title, and choose a local subtitle error state without exposing raw internal exception text.

WEB-17.03 · Core · GraphQL execution model ↗
Does a visible schema grant resource access?

The presence of a book field means that the field exists in the API contract. Accepting an ID variable, authenticating a connection or validating a selection does not authorize the subject to read that resource. Enforce object/action decisions from trusted server context in the resolver or its service boundary. A risky assumption is that one general allow at the root automatically covers every nested field. Adding a sensitive author/profile field may require its own field/resource policy; the public schema is not a permission list.

WEB-17.03 · Red · GraphQL execution model ↗
Mistaking a partial result for complete success

A subtitle error can accompany a successful title. Turning every errors member into a global failure discards useful data unnecessarily; ignoring errors merely because data exists can display incorrect subtitle information. Non-null decisions have a failure radius: making optional information non-null can erase the whole Book view after a small resolver failure. The artifact compares two field-error results for the same normal record; the difference is the schema’s nullability chain rather than network speed.

WEB-17.03 · Red · GraphQL execution model ↗
Observe pipeline decisions separately

Pin the schema edition and operation contract, then observe parsing, validation, variable coercion, resolver invocation and completion separately. An operation alias, correlation ID and bounded error path can provide evidence without logging sensitive values or every query text. The unknown-field branch proves no execution through resolver count=0. In the normal branch, invocation evidence matches the response selection. These counts belong to the local fixture ledger, not a production engine, distributed trace or query-planner benchmark. The artifact count belongs to a profile with all selected field outcomes prepared before completion; a real executor may cancel pending sibling work.

WEB-17.03 · Blue · GraphQL execution model ↗
Tie client rendering to nullability

Keep four ordinary outcomes for the same book: a full result, validation denial before execution, nullable subtitle failure and non-null title propagation. The client distinguishes absent data from data:null and must not present a stale title as the new book result after propagation. In the partial subtitle branch, title remains usable while the subtitle error state stays visible. Test alias-aware UI mapping when error paths change; human-readable messages are not stable identifiers.

WEB-17.03 · Blue · GraphQL execution model ↗
schemaSDL

Selected query schema and nullable Book/subtitle chain.

WEB-17.03 · GraphQL execution model ↗
rows

Four outcomes for the same record; no claim of an executed GraphQL engine.

WEB-17.03 · GraphQL execution model ↗
types

Which nullable ancestor stops field-error propagation.

WEB-17.03 · GraphQL execution model ↗
context

Declared permission; client variables differ from trusted context.

WEB-17.03 · GraphQL execution model ↗
httpScope

Boundary between released core and changing HTTP draft/profile.

WEB-17.03 · GraphQL execution model ↗
WebSocket messages, frames and permission

WebSocket is a long-lived bidirectional message channel: browser and server can send application messages independently. The HTTP/1.1 profile establishes it using a GET/Upgrade handshake and a successful 101 response. With negotiated RFC 8441 support, HTTP/2 uses extended CONNECT and :protocol=websocket rather than copying H1 Connection/Upgrade headers or a 101 response. One H2 stream can carry WebSocket while other streams continue ordinary HTTP work. Support is not assumed for every browser/proxy combination.

WEB-17.04 · Core · WebSocket, SSE and webhooks ↗
SSE: receiving an event is not acknowledging work

Server-Sent Events carries text/event-stream from server to browser in an HTTP response body; EventSource does not send browser-to-server application messages through that same stream. In UTF-8 lines, data supplies payload, event selects the event type, id affects reconnection context, and numeric retry adjusts reconnection timing. A blank line triggers dispatch of accumulated data; a TCP chunk alone is not a complete event. Our block contains id:event-2 and an ordinary book title, keeping the parser’s line buffer separate from UI state.

WEB-17.04 · Core · WebSocket, SSE and webhooks ↗
Webhook: provider server to owned receiver

A webhook is not a browser-opened stream: a provider server delivers an event to an owned receiver using a separate HTTP request. A 2xx receipt indicates acceptance, not automatic completion of downstream business work. The reviewed Stripe provider profile describes possible duplicates and out-of-order arrivals. Atlas uses a generic book.updated event alias, with no real Stripe event, account or endpoint. A browser reading a book from an API and a provider delivering a webhook have different authentication, direction and lifetimes.

WEB-17.04 · Core · WebSocket, SSE and webhooks ↗
Treating an established channel as unlimited permission

Accepting a WebSocket handshake does not authorize every subsequent message. A subject’s session can expire, an object can belong to another tenant, or an action can lie outside the channel profile. Even a structurally valid message needs a resource decision. The fixture’s policy-denied branch receives an ordinary book-read message, creates no service call when declared object permission is absent, and returns a normal denial result. This models the required control boundary rather than a bypass attempt against a real target.

WEB-17.04 · Red · WebSocket, SSE and webhooks ↗
Delivered and processed once are different claims

SSE lastEventId is not an application acknowledgement protocol; updating a parser’s ID and applying an event to UI state are separate events. Likewise, a valid webhook signature promises no exactly-once delivery. If an ordinary duplicate causes a second business effect, the failed assumption equates integrity with idempotency. Normalizing JSON before verification is a different issue: an equivalent value tree can alter the signed byte representation. This lesson demonstrates raw-body inequality with two inert strings rather than generating and redelivering a signed event.

WEB-17.04 · Red · WebSocket, SSE and webhooks ↗
Decisions and lifetime at the message boundary

An owned channel profile defines message types, actions, allowed object scope, size and ordinary rate limits. The server establishes trusted session/context, evaluates object/action permission per message and produces protected data only after allowing it. Define channel invalidation after session expiry or logout; a login check performed only at the handshake is insufficient for a long-lived connection. Proxy timeout, application heartbeat and protocol ping/pong are different liveness signals; a pong proves no book-read permission.

WEB-17.04 · Blue · WebSocket, SSE and webhooks ↗
Resume, receipt and durable-effect ledgers

An SSE contract defines retained history, Last-Event-ID interpretation, expired-cursor recovery and application event deduplication. The fixture keeps the UI apply count at one across two ordinary deliveries of event-2; parser ID state and the application’s seen-ID set are distinct. Client close and a server HTTP 204 that stops reconnection belong in recovery design. A numeric retry value is not a delivery guarantee, and browser backoff or network conditions prevent a claim of an exact wall-clock schedule.

WEB-17.04 · Blue · WebSocket, SSE and webhooks ↗
channelComparison

Three different actor directions and lifetimes.

WEB-17.04 · WebSocket, SSE and webhooks ↗
websocketProfiles

H1 Upgrade differs from negotiated H2 extended CONNECT.

WEB-17.04 · WebSocket, SSE and webhooks ↗
messageRows

Selected per-message resource gate after connection establishment.

WEB-17.04 · WebSocket, SSE and webhooks ↗
sse

Normal event block, parser ID and separate application apply count.

WEB-17.04 · WebSocket, SSE and webhooks ↗
webhook

Raw bytes and declared integrity/freshness/idempotency receipt ledger.

WEB-17.04 · WebSocket, SSE and webhooks ↗
Which deployment does the API contract describe?

Atlas’s notes contract describes readPublicNote. Inventory is more than an endpoint list: host, environment, owner, API version, lifecycle, policy revision, data class and integration flow must align. notes-v2 is active and notes-v1 retired; that marker alone does not prove a real deployment has been removed. Even a public title needs a known store-to-consumer data flow. OpenAPI openapi specifies the description-format version, info.version the document version, and /v2 a product API-version choice; these need not share one version number. The artifact contractFragment is incomplete and illustrates selected fields for a read-only GET and ordinary Tea & Bread response shape.

WEB-17.S01 · Core · API inventory and authorization contracts ↗
Description and authorization are separate layers

OpenAPI operationId links a uniquely described operation, and security declares applicable schemes. Multiple schemes in one Security Requirement Object are jointly required, while an array lists alternatives of which one suffices. An empty requirement object {} supports an anonymous alternative; operation-level security: [] removes the top-level declaration, a different representation. Describing these fields does not install runtime enforcement. Atlas separately requires notes.read function permission, a public-note relationship and a title-only response projection. Schema type checks replace none of these business decisions. The response contract restricts exposure to permitted title fields; having a token or scope does not grant reading every object.

WEB-17.S01 · Core · API inventory and authorization contracts ↗
Version drift is an evidence question

The fixture checks inventory binding and lifecycle before comparing observed runtime-policy revision with the contract. In policy-drift, the v2 name is correct but declared runtime policy 6 conflicts with contract 7, stopping resource delivery. The unknown-version row lacks inventory evidence and records unknown scope rather than automatically attributing hostility to a host. A deprecated operation warns consumers to migrate; it does not disable a route. Retirement plans need ownership, client migration and removal/deny evidence across ingress and worker integrations. A schema or authorization improvement limited to the new version may leave older deployments connected to the same data under another policy; inventory makes this relationship visible.

WEB-17.S01 · Core · API inventory and authorization contracts ↗
Treating the documented route as the whole surface

A normal consumer uses the supported notes-v2 contract. The broken assumption is that a deployment absent from current documentation no longer runs or necessarily enforces the same policy. Failure requires parallel versions/environments retaining access to the same data flow with different enforcement; impact follows that integration’s read/action scope. An older version alone is not a vulnerability or breach: retirement and policy evidence matter. The notes-v1 fixture denies at its declared lifecycle gate but does not establish external reachability. Controls reconcile owner-maintained inventory, apply relevant policy to all exposed versions and verify migration/removal. These supplied records explain the boundary without network discovery or calling undocumented operations.

WEB-17.S01 · Red · API inventory and authorization contracts ↗
Mistaking contract validity for business permission

Normal request shape and a described security scheme can indicate use of the intended interface. The broken assumption is that they automatically enforce object relationships or response-field permission. Failure requires handlers omitting function/object/property decisions after schema validation or gateway authentication. Impact can be schema-valid unauthorized resource reading or unnecessary field delivery. PermissionRows supply a public-note positive case and each separate denial gate without API calls or discovery. Explicit operation-to-policy binding and minimal response projection preserve the boundary. Missing inventory evidence and object denial are different reasons; collapsing diagnostic fields hides the missing control.

WEB-17.S01 · Red · API inventory and authorization contracts ↗
Reconcile inventory with runtime evidence

Owner inventory records host/environment/API version, contract and policy revisions and data-flow ownership. Runtime observations correlate deployment/route identity and policy revision to the operation; successful documentation builds or absent access logs do not prove retirement. Baseline is active v2/policy7 and an allowed public-note title response. Retired, revision-mismatch and unknown records need distinct reasons; unknown evidence prompts investigation, and no acceptance is not attack attribution. Unavailable telemetry leaves observed state unknown. This local JSON is not an inventory generated from actual exposed services. Reconciliation can record resource class and approved integration direction without moving customer data.

WEB-17.S01 · Blue · API inventory and authorization contracts ↗
Connect version controls to migration decisions

Contract regression checks expected response keys and function/object/property denial together for readPublicNote. Compare operation security overrides with root policy without losing empty-object, empty-array or alternative semantics. Description-format updates differ from business API changes; raising a schema version does not backport authorization fixes to older deployments. After ownership and consumer migration evidence are complete, independently verify removal/deny state; legacy clients or staging data coupling can cause benign drift. Finite native JSON comparisons check selected revisions/properties, not complete OpenAPI validation or deployed enforcement. Choose backport, a controlled compatibility interval or retirement according to impact and policy differences.

WEB-17.S01 · Blue · API inventory and authorization contracts ↗
inventory

Host/environment/owner/lifecycle and revision records.

WEB-17.S01 · API inventory and authorization contracts ↗
contractFragment

Selected description fields, not a complete schema document.

WEB-17.S01 · API inventory and authorization contracts ↗
rows

Binding/lifecycle/revision admission and delivery outcomes.

WEB-17.S01 · API inventory and authorization contracts ↗
permissionRows

Function/object/property read policy as separate gates.

WEB-17.S01 · API inventory and authorization contracts ↗
securitySemantics

OAS requirement composition and override distinctions.

WEB-17.S01 · API inventory and authorization contracts ↗
A resolver is a permission boundary

A GraphQL schema describes expressible fields and types; it does not decide whether Duru may read a property of a particular note. After parsing and validation, the resolver must evaluate the authenticated actor, object relationship, action and field policy in the same context. Atlas Notes models only reading the title of note-A. The selected title field is nullable: denial produces null and an error at the relevant response path, while permitted sibling fields can be evaluated separately. A Non-Null field could instead propagate null to an appropriate nullable parent. This is an explicit application authorization-error policy, not a universal access-control library or HTTP status requirement imposed by GraphQL. The presence of both data and errors does not mean the protected title was returned.

WEB-17.S02 · Core · GraphQL, streaming and message authorization ↗
Cost, types and permission answer different questions

Even a permitted resolver can consume different resources as list size and nested selections grow. Query cost is therefore a separate admission decision; depth alone does not describe all fan-out. The ledger’s title weight of 1 and list limit of 10 are selected teaching values, not constants defined by GraphQL. Cost approval does not grant permission, and permission approval does not grant an unlimited work budget. Different node and relationship paths to the same object should apply the same policy. Where a cache or batch loader is used, its key and result projection must account for the relevant actor, tenant and field context. The scene runs no query parser, HTTP binding, actual resolver or cache. It exposes the conditions under which a permitted title projection may be prepared.

WEB-17.S02 · Core · GraphQL, streaming and message authorization ↗
From WebSocket connection to message

Accepting a WebSocket handshake opens a communication channel. That decision does not automatically permit every future message or object. A browser Origin check helps evaluate a connection initiated by an expected web application; it is not independent identity proof for a non-browser client. Cookie attachment also depends on cookie and browser rules. The message handler interprets an expected shape and action, then applies current actor/session state and object policy. In the expired branch the channel was previously accepted, but a new notes.read message is denied at now=120 and validUntil=120. Equality is invalid in this selected application profile; the WebSocket protocol does not define that session timer. No read reaches the store and no title body is prepared.

WEB-17.S02 · Core · GraphQL, streaming and message authorization ↗
The lifetime of an SSE subscription

SSE normally streams events from server to client; EventSource is not a bidirectional command channel. Besides initial subscription admission, future events need the correct recipient and object scope. An event ID or reconnect cursor describes where to resume; it creates neither actor identity nor fresh permission. A revoked subscription withholds the next title event. This scene branch ends at the server’s local gate: client observation of closure, reconnection and withdrawal of previously received data are not simulated. EventSource can attempt to reconnect after a connection closes, so the server must evaluate fresh admission using current context. A retry interval assists transport behavior; it guarantees neither exactly-once business delivery nor lossless replay of every event. Transport progress and permission decisions remain separate states.

WEB-17.S02 · Core · GraphQL, streaming and message authorization ↗
A precise introduction to gRPC and SOAP

gRPC expresses a service method call with typed inputs and outputs, commonly using Protocol Buffers by default. Unary, server streaming, client streaming and bidirectional streaming are different message flows. Ordering within an individual RPC is not permission for another RPC or a business action. Channel credentials and call credentials have different scopes; the application still decides method and object access. SOAP 1.2 describes an XML Envelope with an optional Header and a required Body. Processing a header at a particular node and directing the Body to the ultimate recipient do not prove that a notes.read operation is permitted. Security features belong to additional bindings/extensions and application profiles. The artifact is a typed comparison ledger only: no protobuf message, SOAP XML parser, WS-Security signature or remote RPC has run.

WEB-17.S02 · Core · GraphQL, streaming and message authorization ↗
Overreading an open channel

The assumption to examine is that accepting a connection permits all later messages from that actor. It becomes a control failure only if the application reduces current session, operation and object decisions to the boolean recorded at channel admission. The ledger deliberately permits connectionAccepted=true and messageAllowed=false at the same time: at expiry no new read reaches the store. An admitted SSE subscription and permission to deliver its next event are also separate. This perspective does not label an open channel a vulnerability by itself. It asks where the handler applies current policy and what data is prepared before that gate. Without evidence about revocation propagation, the outcome is not a claim that revocation works or fails; that dependency is recorded as unknown. Previously delivered titles are not assumed to disappear from client memory.

WEB-17.S02 · Red · GraphQL, streaming and message authorization ↗
Jumping from schema success to business permission

The second assumption is that type validation and a reasonable query cost eliminate the need for resolver object and field policy. The consequence need not be a mutation: returning a title projection can also be a disclosure that requires permission. Although this note is a harmless public teaching object, its selected title gate is explicit. The field-denied branch may return a response skeleton and errors, but contains no protected title value. Here “no body” means no title projection, not the absence of every GraphQL response envelope. A typed gRPC request or a well-formed SOAP Envelope does not inherit that business decision either. Review the conjunction of fixed policy rows and retain separate evidence for operation, object, field and time conditions. Query execution, endpoint discovery and attempts to bypass permission are outside this example.

WEB-17.S02 · Red · GraphQL, streaming and message authorization ↗
One policy across different delivery forms

For the defensive design, readTitle is a decision over actor, tenant, note-A, action and property. A GraphQL resolver, WebSocket message handler, SSE event filter and gRPC method carry that decision into their own delivery format instead of leaving the only check at connection level. For SOAP, the parsed Body action is bound to an approved application handler. This need not become one global boolean: resource policy and field projection can remain separate, readable decisions. Cost and size limits form a budget independent of the permission gate. Document application-defined subscription expiry and revocation behavior rather than giving an open channel an unlimited identity lifetime. Cache keys and batch contexts preserve relevant policy inputs. Clients receive a safe, understandable failure while detailed decision reason, actor context and policy revision belong in access-controlled telemetry.

WEB-17.S02 · Blue · GraphQL, streaming and message authorization ↗
Check absence as well as successful results

The positive fixture checks that a permitted read produces the title projection. Negative fixtures additionally check store delivery=0, mutation=false and protectedBody=null. For GraphQL field denial, the selected null-plus-errors shape must agree with the nullable schema; an HTTP status is not automatically derived from it. A previously accepted WebSocket connection must not admit a new message at the time boundary, and a revoked SSE subscription must not deliver a new event to the client. Missing policy is different evidence from a known false decision: retain permissionUnknown and choose a safe deny outcome. That distinction helps explain whether failure came from a policy decision or lost context. The animation deterministically plays supplied ledger results. Actual browser Origin/cookie enforcement, stream backpressure, RPC servers and subscription adapters require separate integration evidence.

WEB-17.S02 · Blue · GraphQL, streaming and message authorization ↗
rows

Channel admission and current permission conjunction; null denotes absence of the protected title.

WEB-17.S02 · GraphQL, streaming and message authorization ↗
protocolLedger

Protocol form compared with its business decision; not a wire capture.

WEB-17.S02 · GraphQL, streaming and message authorization ↗
unknownEvidence

Missing context is separate unknown evidence with a safe deny result.

WEB-17.S02 · GraphQL, streaming and message authorization ↗
JSON produces data, not a choice of behavior

Deserialization turns an external representation into values that a program can read. For JSON these are objects, arrays, strings, numbers, booleans and null. A book object returned by JSON.parse is not an instance of the application’s Book class; its text does not automatically choose a caption method or approved constructor. Reconstruction is a separate design decision: the application chooses which validated fields enter a trusted domain type. Atlas Notes uses book-note/v1 with id, title and pageCount. Tea & Bread is only a plain title string. Successful parsing proves neither that pageCount is an appropriate integer, that the ID refers to the requested object, nor that an actor may use that data. This lesson creates only a fixed read-only caption; it derives no DOM, file or database action from the object.

WEB-17.S03 · Core · Deserialization and object reconstruction boundaries ↗
From a closed DTO to a trusted constructor

The selected profile accepts exactly three keys: pageCount is an integer from 1 to 1000, title is a string from 1 to 80 characters, and id must equal note-A. An unknown subtitle field is rejected in this profile; this is not a claim that every API must reject all unknown fields. A versioned contract can choose another compatibility policy, but silent field loss should be visible. An accepted DTO is built by explicit projection, and the constructor receives only those three values. Its name is not read from the input; external data selects no runtime module or method. ContextPresent and readAllowed are separate server-side inputs; no JSON field can open that gate. With missing context, even a correctly shaped object is not reconstructed for client delivery. Validation and authorization each retain their own decision.

WEB-17.S03 · Core · Deserialization and object reconstruction boundaries ↗
Revivers and format boundaries

The optional JSON.parse reviver is a function supplied by the application, not an executable instruction inside the text. A transformation hook introduces behavior that needs its own review; this profile uses no reviver. JSON is also not a universal, lossless snapshot of every runtime value. Class identity, methods and special runtime behavior are outside this three-field DTO. Numeric precision, nesting and text-size limits belong in the parser and contract profile. Unique object member names matter for interoperability; choose an explicit ingress parser policy rather than depending on duplicate-key behavior. This fixture produces no duplicate keys and runs no duplicate-preserving parser. A pure data format narrows the surface, but does not independently guarantee safe downstream business methods, output interpretation or permission.

WEB-17.S03 · Core · Deserialization and object reconstruction boundaries ↗
The assumption between data and runtime type

The failure class under review gives an external representation too much influence over runtime type or behavior selection. A parseable object is not sufficient evidence of a trusted domain object. The risk requires the application to connect external values to behavior-bearing objects, side effects or permission decisions without an approved DTO boundary. This example contains no class-selecting payload or dangerous loader; the finite Book constructor is fixed application code. The unknown subtitle branch demonstrates a contract mismatch, not an exploit result. Keep the states “parsed”, “shape valid”, “actor permitted” and “domain object constructed” separate. Asking where external data stops being a field projection and starts selecting behavior is a concrete review boundary. In this profile that transition occurs only through an approved constructor.

WEB-17.S03 · Red · Deserialization and object reconstruction boundaries ↗
Signatures, schemas and context provide different evidence

If integrity verification exists, it contributes evidence that particular bytes came with appropriate provenance; it does not independently authorize the business meaning of their fields or the recipient’s action. No actual signature exists in this lesson, and provenance is an external dependency rather than an assumed result. In the wrong-type branch pageCount arrives as a string. The parser correctly creates a string, while the contract expects an integer and denies it. The missing-context branch uses the same normal DTO but lacks context evidence; it does not prove that the actor is unauthorized. The safe result still withholds reconstruction delivery and its body. Distinguishing format mismatch, missing permission evidence and unsafe runtime reconstruction reduces both misplaced confidence and unnecessary alarms. The fixed example is applied to no organizational format or actual endpoint.

WEB-17.S03 · Red · Deserialization and object reconstruction boundaries ↗
Explicit projection and bounded reconstruction

The defensive pipeline is external text → JSON values → closed schema → authorization context → explicit DTO → fixed constructor → plain caption. Construction does not run before schema acceptance, and no caption is delivered without context. The success branch copies only id, title and pageCount. Freezing the object is a local choice that reduces mutation risk; it neither authenticates identity nor makes every nested graph automatically immutable. The method implementation is fixed application code, so input need not load behavior. Adding a field later requires a joint review of contract version, compatibility and constructor projection. Other formats requiring richer runtime serialization need separate parser, type-allowlist and behavior review. Pure JSON gives this small example a clear boundary; it does not certify every format or deserializer as secure.

WEB-17.S03 · Blue · Deserialization and object reconstruction boundaries ↗
Prove that reconstruction did not occur

The fixture checks more than whether a successful caption is correct. For unknown field, wrong type and missing context it requires constructed=false, delivered=false, body=null and mutation=false together. The native check uses fixed JSON.parse data to observe that a plain object is not a Book instance, that an approved constructor runs after validated projection, and that the caption is only a plain string. These are actual JSON and class observations; they establish neither a web endpoint’s authorization nor the safety of an unsafe serialization format. Parsing a denied row must not increment the constructor counter. Missing context remains unknownPermission, with a diagnostic selected by the application profile. The checks retain value as contracts change because they compare field, type and context boundaries alongside the normal input. Browser DOM, persistence and remote deserialization services remain outside the evidence.

WEB-17.S03 · Blue · Deserialization and object reconstruction boundaries ↗
profile

Local closed contract and trusted constructor selection; input selects no constructor.

WEB-17.S03 · Deserialization and object reconstruction boundaries ↗
rows

Only fixed normal and harmless field/type/context comparisons.

WEB-17.S03 · Deserialization and object reconstruction boundaries ↗
runtimeLedger

Differences between data, class behavior and authorization.

WEB-17.S03 · Deserialization and object reconstruction boundaries ↗
Why is a database separate from browser state?

A web application may need structured state shared across requests and users: a public book catalog, author information, or a saved note. A database owns queryable data and defined consistency boundaries. Browser preference cookies or a variable in one process do not provide the same ownership. Nor does choosing a database automatically make all storage durable: this relational SQLite example lives in a :memory: connection and makes no disk-durability claim.

WEB-18.01 · Core · Relational data and relationships ↗
Keys constrain relationships; joins produce results

books.author_id references authors.id through a foreign key. Multiple books under one author demonstrate one-to-many; each NOT NULL author_id connects a book to one parent in this fixture. The foreign key requires an existing parent key, not a copy of every parent attribute. A join matches books to authors and produces book title and author name in one result row. A constraint and a query are different mechanisms.

WEB-18.01 · Core · Relational data and relationships ↗
Declaration and enforcement are different evidence

Do not stop at FOREIGN KEY in CREATE TABLE when reviewing a controlled fixture. The selected SQLite connection foreign_keys value and an expected constraint result provide evidence together. Rejecting a benign catalog row without a parent demonstrates referential integrity for that boundary, not another connection or schema. The failure condition is mistaking an application comment for an enforced constraint.

WEB-18.01 · Red · Relational data and relationships ↗
Result multiplicity and identity boundaries

A many-to-many join can yield multiple rows for one logical book. Two tags on Tea book legitimately produce two rows; an application should not mistake them for duplicate books or independent objects. Possible effects include an incorrect aggregate or repeated presentation. Connect the result shape and association cardinality to the presentation mapping.

WEB-18.01 · Red · Relational data and relationships ↗
Connect the schema and result ledger

The artifact holds authors=[1,Duru] and books=[10,Tea book,1]/[11,Coffee book,1]. ORDER BY books.id produces two title/name join rows. book_tags has three unique pairs; two tags on Tea book mean grouped counts and raw join counts answer different questions. These tables/fields form a synthetic teaching schema, not product data or real users.

WEB-18.01 · Blue · Relational data and relationships ↗
Bind the relationship selector to one connection

XPath count(/audit/relation[@parentExists="false" and @insertAccepted="true"]) counts authored observations that accept an insert without its parent. Expected normal FK rejection gives 0; a deliberately inconsistent positive fixture gives 1. Multiple tags on one book are benign cardinality, not this violation. With no event, zero means insufficient evidence rather than proven enforcement.

WEB-18.01 · Blue · Relational data and relationships ↗
schema

Authored SQLite keys/nullability, not a product schema.

WEB-18.01 · Relational data and relationships ↗
join

Ordered read result, separate from a constraint.

WEB-18.01 · Relational data and relationships ↗
enforcement

Observed FK/duplicate-pair boundaries on the selected connection.

WEB-18.01 · Relational data and relationships ↗
Statements, bound data, and result shape

Query lifecycle begins when the application selects an operation. The driver supplies a statement and bound values, the engine executes a suitable plan, and a cursor returns rows. Our SELECT id, title FROM notes WHERE title=? is fixed; Tea note is a parameter value. Placeholders bind values, not table/column names or arbitrary SQL fragments. Dynamic identifiers need a separate controlled-selection contract.

WEB-18.02 · Core · Query lifecycle, transactions, and ORM ↗
Transaction decisions are broader than statement success

A transaction defines the boundary for several selected changes. Our writer executes BEGIN, updates a title, and inserts an audit row. After successful COMMIT, a fresh reader sees Updated note and one audit row. Writer-local uncommitted results differ from committed state visible to another connection. This reader finishes each SELECT and holds no long-lived read transaction; other isolation/journal choices have different visibility boundaries.

WEB-18.02 · Core · Query lifecycle, transactions, and ORM ↗
Different responsibilities of indexes, pools, and ORM

An index offers a lookup option to the planner, not a promise that every query uses it or gets faster. For selected WHERE title=?, SQLite shows a scan before idx_notes_title and an indexed search afterward. Result rows stay the same; no duration/throughput is measured. Indexes cost storage/write maintenance and replace neither integrity/authorization nor commit.

WEB-18.02 · Core · Query lifecycle, transactions, and ORM ↗
Execution success, commit, and access policy

Review benign fixed statements separately from parameters. Searching Tea note compares data rather than granting arbitrary query construction. Binding helps treat selected values as data instead of SQL structure, but it alone determines neither resource selection policy nor object permission. This lesson stays within a public fixture.

WEB-18.02 · Red · Query lifecycle, transactions, and ORM ↗
Abstractions do not erase boundaries

An ORM property containing Updated note is not a store-commit proof. Read flush/query/cache/identity-map behavior through framework/configuration scope. Likewise, a changed index plan proves neither result correctness nor production throughput. Limit claims to the exact operation and observed boundary; query counts or class names alone are insufficient.

WEB-18.02 · Red · Query lifecycle, transactions, and ORM ↗
Keep query and transaction ledgers separate

The query artifact records statement, parameters=[Tea note], and rows=[[1,Tea note]]. The normal transaction separates writerBefore=Tea note, writerDuring=Updated note, readerBeforeCommit=Tea note, and readerAfterCommit=Updated note. This is bounded fresh-read visibility because the reader consumes and finishes SELECTs, not a generalization to long-lived snapshots.

WEB-18.02 · Blue · Query lifecycle, transactions, and ORM ↗
Cleanup selectors, index plans, and ORM scope

XPath count(/audit/lease[@returned="true" and @transactionOpen="true"]) counts authored leases returned with an open transaction. Normal reset gives 0 and a deliberately inconsistent positive fixture gives 1. queryExecuted=false in the busy branch is benign and expected. With no observation, zero is insufficient evidence rather than a clean-connection proof.

WEB-18.02 · Blue · Query lifecycle, transactions, and ORM ↗
query

Bound data separate from fixed SQL structure.

WEB-18.02 · Query lifecycle, transactions, and ORM ↗
rollback

Statement ABORT separated from explicit transaction rollback.

WEB-18.02 · Query lifecycle, transactions, and ORM ↗
pool

Lease/reset at instructional capacity, not a framework pool.

WEB-18.02 · Query lifecycle, transactions, and ORM ↗
NoSQL is not one database behavior

NoSQL groups several data models outside relational tables; documents and key-value storage are our two examples. One product query language, validation, transactions, and consistency do not automatically apply to another. MongoDB collections can contain documents with different fields, yet the application still needs meaningful field contracts. MongoDB supports schema validation; embedding or referencing depends on access patterns and relationship ownership.

WEB-18.03 · Core · NoSQL and key-value stores ↗
Lifetime, revision, and availability differ

The fixture assigns expiresAt=50 in logical clock units. At 49 the value exists; at 50 it becomes missing at the expiry boundary. This is not a wall-clock timer test. Eviction removes keys before expiry according to memory pressure and policy. Redis maxmemory policies can evict keys, while noeviction can instead reject new writes; not every policy deletes data. A key might never have existed either. A plain missing result cannot establish its cause.

WEB-18.03 · Core · NoSQL and key-value stores ↗
A missing result does not explain ownership

When a controlled public-note lookup returns missing, identify the owner and the errors the adapter distinguishes. An expired cache entry and an authoritative record never written can require different product decisions. A memory-only cache miss may need a database fallback; collapsing an authoritative-store outage into missing can produce false default state. These scenarios use only authored logical lifetime and an injected unavailable event, not Redis telemetry.

WEB-18.03 · Red · NoSQL and key-value stores ↗
Attach atomicity to an operation boundary

A local expected-revision rejection proves only one serialized owner decision. Excluding a state change between separate read and write operations requires another assumption. Extending MongoDB single-document atomicity to a collection, or Redis serialized EXEC processing to SQL rollback, is likewise incorrect. The impact can be partially changed related data or a stale decision overwriting newer state. Our harmless version mismatch preserves the selected state.

WEB-18.03 · Red · NoSQL and key-value stores ↗
Connect adapter contracts to application decisions

Define found/value, missing, and unavailable/error outcomes at the application boundary. Validate the value schema after the store operation as a separate local step. The fixture returns a parsed copy so application mutation cannot silently change stored data. Key mapping is selected only for a public synthetic note. Real identity, authorization, namespace isolation, and presentation require separate design.

WEB-18.03 · Blue · NoSQL and key-value stores ↗
Verify lifecycle policy independently

Use a selected logical clock to check immediately before and at expiry; test explicit pre-expiry eviction separately for the same value. Record whether replacement preserves or clears lifetime. Production Redis policies depend on current documentation and workload; this lesson recommends no memory-limit or fsync tuning value. Do not report the native Python adapter as Redis or MongoDB execution.

WEB-18.03 · Blue · NoSQL and key-value stores ↗
selectedModel

Local adapter scope, not product runtime.

WEB-18.03 · NoSQL and key-value stores ↗
hit/expiry/eviction

Logical clock and different missing conditions.

WEB-18.03 · NoSQL and key-value stores ↗
stale

Expected revision and preserved current value.

WEB-18.03 · NoSQL and key-value stores ↗
unavailable/replacement

Error semantics and selected lifetime replacement contract.

WEB-18.03 · NoSQL and key-value stores ↗
selector

Inert XPath counting synthetic missing/error decisions.

WEB-18.03 · NoSQL and key-value stores ↗
Where are a note bytes and identity?

A public note has content bytes and metadata such as title, media type, and a storage reference. Object storage addresses an object by key in a selected namespace. In Amazon S3, bucket plus key identifies its name; with versioning, the selected version also matters. Slash prefixes need not be directories: S3 has a flat object model while its console can show logical folders. A filesystem path resolves in an operating-system directory/file namespace. Similar-looking strings do not imply the same mechanism.

WEB-18.04 · Core · Object storage, filesystem, and persistence flow ↗
Application, bytes, and database finish separately

In the normal flow the application encodes trusted public data, writes a buffered binary file, flushes its language-level buffer into the underlying stream, then calls os.fsync on the descriptor. Python write reports an accepted byte count; flush and fsync are separate stages. A successful system call is not an actual power-loss recovery test here. Durability depends on the operating system, filesystem, device, and directory metadata boundaries; no crash injection or universal platform guarantee is made.

WEB-18.04 · Core · Object storage, filesystem, and persistence flow ↗
One success field cannot describe every state

The controlled ledger records write success, fsync completion, and metadata commit separately. File bytes can exist while the reference transaction rolled back, leaving an orphan and an unavailable application result. Reading the file does not establish a committed reference; finding a row does not establish available bytes or the expected representation. Review checks both owners independently.

WEB-18.04 · Red · Object storage, filesystem, and persistence flow ↗
Keep recovery boundaries visible

Reading the same bytes after an orderly reopen proves a normal lifecycle outcome, not power-loss, hardware-cache, or filesystem recovery. Labeling fsync completion as durability across every deployment teaches the wrong boundary. S3 documentation likewise cannot turn a local file read into measured S3 durability.

WEB-18.04 · Red · Object storage, filesystem, and persistence flow ↗
Record reference and data contracts together

Select a mapping from note ID to fixed store identity, then independently verify that the database reference has the same key and byte length. The adapter returns bytes for content and explicit fields for metadata. This fixture uses text/plain and public synthetic data; validation and authorization remain separate application decisions. Its bounded mapping makes the namespace difference visible without arbitrarily joining object keys into local paths.

WEB-18.04 · Blue · Object storage, filesystem, and persistence flow ↗
Design partial completion as recoverable state

After file-store success and database failure, the application reports no false success. Reference rollback and retained bytes are distinct outcomes; the orphaned bytes can still be read. Cleanup or reconciliation needs clear key ownership. Removing the local example’s temporary directory does not establish production orphan scanning or an appropriate cleanup policy for user files.

WEB-18.04 · Blue · Object storage, filesystem, and persistence flow ↗
identity

Object keys and fixed owned files are separate namespaces.

WEB-18.04 · Object storage, filesystem, and persistence flow ↗
bytes

Independent UTF-8 byte/character counts.

WEB-18.04 · Object storage, filesystem, and persistence flow ↗
normal/orphan/dangling

Separate store/reference completion outcomes.

WEB-18.04 · Object storage, filesystem, and persistence flow ↗
selector

Synthetic false success across owners.

WEB-18.04 · Object storage, filesystem, and persistence flow ↗
Query structure and search values have different owners

Atlas public catalog offers exact title matching and two approved sort choices. The caller supplies a book title; the application chooses the table, fields, comparison, and projection. O'Reilly is an ordinary title. Its apostrophe does not make it invalid business input. In this example the SQL statement stays fixed while title and public visibility are separate bound values passed to the driver. The book name is never assembled as a piece of statement syntax.

WEB-18.S01 · Core · Query/data separation in SQL and NoSQL ↗
The SQL driver receives two distinct arguments

The artifact contains two prewritten SELECT statements, by-id and by-title. Both specify the id/title projection and equality conditions for title and visibility. Python sqlite3 execute receives the statement and the (title, public) tuple separately. The native check opens its own :memory: database, inserts three ordinary catalog rows, and reads only id=2 for O'Reilly. Input admission is not query execution; the view cannot show a result row before execute completes.

WEB-18.S01 · Core · Query/data separation in SQL and NoSQL ↗
Sorting is not a value slot

A title value and an ORDER BY column choice are different responsibilities. Putting title in a bound value slot does not turn it into a column identifier. The application maps id and title to its own two fixed statements. An unknown sort such as rating is rejected before executing a query. This profile admits no arbitrary identifier, raw SQL fragment, or direction string. Choosing a sort option does not delegate authorship of the query language.

WEB-18.S01 · Core · Query/data separation in SQL and NoSQL ↗
A document filter also belongs to a query language

The NoSQL label does not remove an interpretation boundary. The application validates a scalar title before constructing its own equality filter. Passing a client object through as the filter confuses application-owned query structure with client-owned data structure. Here the ordinary {display: Tea} object does not satisfy title:string and is rejected before any document lookup. Being a parsed object does not make it an admitted title value.

WEB-18.S01 · Core · Query/data separation in SQL and NoSQL ↗
A correct query still needs the right access decision

Binding preserves query structure; it does not decide which row may be disclosed to which caller. This catalog uses fixed teaching data selected for public visibility. Private resources, tenant membership, service account privileges, and field-level disclosure require separate policy in a real application. The public scope condition is application-owned; no new scope decision is inferred from the title field.

WEB-18.S01 · Core · Query/data separation in SQL and NoSQL ↗
The review question is when a value became structure

Begin a review with responsibility rather than the visual appearance of input: where does the application choose the statement/filter, which fields can the caller influence, and which typed values actually reach the driver? Ordinary O'Reilly shows that punctuation can remain business data. It is not an attack-string exercise. The fixed SELECT and separate tuple expose which code owns the query structure.

WEB-18.S01 · Red · Query/data separation in SQL and NoSQL ↗
Parsed objects and admitted filters are separate states

When title receives the ordinary display object, the transition from parsed JSON to business type stops. No query reaches the data owner and an earlier row list cannot masquerade as new success. This inert failure teaches the difference between parser acceptance and operation admission. Query count=0 together with a null result is the evidence; an error message by itself is insufficient.

WEB-18.S01 · Red · Query/data separation in SQL and NoSQL ↗
Keep the query factory small and explicit

The public catalog factory validates a closed field set, scalar title, and sort enum. Admitted id/title choices map only to two fixed SELECT statements. Values reach sqlite3 as a tuple; the document branch constructs a fresh application-owned equality filter. Copying a client object is not validation by itself. Type and allowed-field decisions complete before the builder emits its query contract.

WEB-18.S01 · Blue · Query/data separation in SQL and NoSQL ↗
Record failure, scope, and evidence separately

Admissible intent, selected statement/filter, query count, and projected result are distinct fields. Rejection produces a null result; an accepted lookup without a match produces []. Missing intent is NOT-COMPUTED. That small distinction matters during incident review: permission decisions, database connectivity failures, and genuinely absent resources should not become one indistinguishable record. Public visibility is the example’s fixed scope; it does not claim tenant authorization.

WEB-18.S01 · Blue · Query/data separation in SQL and NoSQL ↗
inputs

Ordinary typed intent; not client-authored query syntax.

WEB-18.S01 · Query/data separation in SQL and NoSQL ↗
statements / filter

Application-owned structure and fixed public scope.

WEB-18.S01 · Query/data separation in SQL and NoSQL ↗
queries

Completed lookup count; zero on rejection.

WEB-18.S01 · Query/data separation in SQL and NoSQL ↗
rows

Completed projection: no-result null differs from accepted-no-match [].

WEB-18.S01 · Query/data separation in SQL and NoSQL ↗
Which work does a cache avoid?

An application cache reuses computed results or data read from another owner to reduce repeated work. The first public Tea note read misses: the application reads version=1/title from the authoritative store, copies it into the cache, and uses it. A later hit returns the selected value without another store read. Our fixture observes this with a read counter, not latency measurements or a claim that every workload becomes faster. Query results, computed views, and raw objects are different caching units; we select one public note.

WEB-19.01 · Core · Application cache and invalidation ↗
Which revision does invalidation protect?

A cache-aside write commits the authoritative update before invalidating the corresponding entry. Invalidating before commit lets an intervening reader refill the previous committed value. Even the intended order does not guarantee consistency under every concurrent or topology condition. External writers, delayed reads, and other local caches can reintroduce old data. TTL can bound staleness, but does not guarantee the newest value before expiry.

WEB-19.01 · Core · Application cache and invalidation ↗
A hit and freshness are different claims

Do not review a controlled cache using hit ratio alone. The artifact separates cache and authoritative versions: a stale copy can still be a hit. Returning an older public title is a mechanism condition, not private-data or policy-bypass reproduction. Identify the caching unit and allowed staleness. TTL must not substitute for newest state or a permission refresh.

WEB-19.01 · Red · Application cache and invalidation ↗
Do not convert errors into database absence

An unavailable cache returns an error, not a miss. If the public-read fallback obtains an authoritative result, the application uses that owner and does not require successful cache population. If the authoritative owner is unavailable too, an error remains and no empty note is created. This selected policy does not prove all endpoints operate safely during outages; resource consumption and retry storms need different evidence.

WEB-19.01 · Red · Application cache and invalidation ↗
Make caching contracts observable

The evidence producers are the local cache adapter and note-store reads. error, returnedVersion and readCount are fields of this example, not predefined Redis log fields. Record which public representation and revision a cache key describes, and return a copy to the application. The first miss makes authoritative readCount=1; a later hit leaves it unchanged. These counts describe selected adapter operations, not latency or Redis statistics. Expiry, eviction, and missing retain the previous key-value lesson boundaries. The artifact makes clear that the cache does not own authoritative records.

WEB-19.01 · Blue · Application cache and invalidation ↗
Check commit, invalidation, and refill separately

The fixture commits version=2/title in the store, invalidation removes the entry, and the next read populates version=2. Each owner state is visible; successful invalidation is not an atomic cross-owner transaction. The same serialized guard rejects old pending candidate=1, leaving the cache empty until a fresh version=2 read. Observer reads verify this deterministic native sequence.

WEB-19.01 · Blue · Application cache and invalidation ↗
normal

Authoritative read counts for miss/hit.

WEB-19.01 · Application cache and invalidation ↗
update/lateFill

Commit/invalidate/refill and serialized revision guard.

WEB-19.01 · Application cache and invalidation ↗
error/bothUnavailable

Error fallback owner and absence of default state.

WEB-19.01 · Application cache and invalidation ↗
selector

Synthetic stale-fill acceptance decision.

WEB-19.01 · Application cache and invalidation ↗
When and for whom does a queue retain work?

A producer prepares a job description as a message: job-note-1 requests indexing for public note tea. The queue retains selected pending work; a consumer receives it and a worker executes application logic. These roles can share a process or use separate services. This worker is an application background-task component, not the browser Web Worker or Service Worker runtime API. Having a queue proves neither completion nor HTTP caller receipt.

WEB-19.02 · Core · Queues, producers, consumers, and workers ↗
Which boundaries do acknowledgements and commits cross?

Publisher confirms cover producer-to-broker publication; consumer acknowledgements cover a separate delivery boundary. Neither knows the other business result. With the selected manual-ack policy, the worker commits its result and processed-job marker in one SQLite transaction before acknowledging the local queue. The queue removes inflight state; it does not independently inspect the database commit. An early acknowledgement followed by failure before result storage leaves the selected queue unaware of pending work.

WEB-19.02 · Core · Queues, producers, consumers, and workers ↗
Queue state is not business state

The controlled ledger separates accepted jobs, delivered/inflight work, business commits, and acknowledgements. The early-ack case has an empty queue but resultRows0: empty transport state does not prove business completion. This is a harmless synthetic policy outcome, not intervention in a real broker. A counter or worker “done” message must identify its completion boundary.

WEB-19.02 · Red · Queues, producers, consumers, and workers ↗
Read the idempotency record scope

The selected jobId marker lives in the business database. Writing the marker and result in separate transactions creates another failure gap. This lesson writes both in one SQLite transaction and independently checks that rollback leaves neither. A unique marker covers the chosen job identity, not every operation purpose or external effect.

WEB-19.02 · Red · Queues, producers, consumers, and workers ↗
Make completion and retry policies explicit

The local queue adapter produces delivery counts; independent SQLite SELECTs produce result and processed-marker observations. Correlated by the same jobId, these fields are neither broker telemetry nor captured packets. Validate the known index-public-note kind and noteId=tea before invoking the selected service. Delivery stays inflight until business commit, then manual acknowledgement removes it from the chosen queue. Independent SELECTs compare the job identity with result and processed-marker rows. The worker does not execute message data as code and uses no network broker, credentials, or user content.

WEB-19.02 · Blue · Queues, producers, consumers, and workers ↗
Outbox and bounded work are separate controls

The producer commits its note update and outbox event in the same transaction; rolled-back work produces no event. A relay transfers only committed pending rows to the finite local queue. Delayed sent markers after publication can still duplicate work. Outbox reduces the dual-write intent gap without removing consumer idempotency. The test uses only own SQLite tables and a deterministic relay; external effects need another coordination scope.

WEB-19.02 · Blue · Queues, producers, consumers, and workers ↗
job

Known public-note job schema, inert data.

WEB-19.02 · Queues, producers, consumers, and workers ↗
normal/redelivery/earlyAck

Business results versus delivery/ack outcomes.

WEB-19.02 · Queues, producers, consumers, and workers ↗
outbox

Same-database intent commit and finite relay gap.

WEB-19.02 · Queues, producers, consumers, and workers ↗
selector

Synthetic early-acknowledgement boundary.

WEB-19.02 · Queues, producers, consumers, and workers ↗
A due time is a starting condition, not a result

A scheduled job expresses intent to start work for a schedule slot. Due time, scheduler observation, worker start, and committed business completion are separate fields. Our public-note indexing fixture uses due=10, observed=12, and finished=13 in logical units, not real cron or wall-clock measurements. Due does not mean a result exists, and started does not mean finished. The application must define units and lateness policy.

WEB-19.03 · Core · Scheduled jobs and async processing ↗
Async acceptance does not finish out-of-request work

Async processing lets a caller hand off work and receive admission before its final result. AWS Lambda asynchronous invocation queues an event and returns success without the function result as one selected service example; this site executes no Lambda. The local ledger keeps accepted, pending, running, and succeeded/failed separate. Admission success can coexist with later work failure. HTTP 202, if chosen, also means acceptance rather than a final result; no HTTP runtime or browser receipt is measured here.

WEB-19.03 · Core · Scheduled jobs and async processing ↗
Timer counts do not prove business completion

The controlled ledger separates due, observed, admitted, started, and resultRows. A timer tick or scheduler log entry may prove only a trigger boundary; committed data needs another owner observation. due=10 / observed=14 admits no work under the selected late policy. Accepted-but-failed instead has admission=true and resultRows=0. Labeling both simply as no work hides failure ownership.

WEB-19.03 · Red · Scheduled jobs and async processing ↗
Duplicate events need a chosen effect contract

Two triggers for one slot can occur under a product policy; even with the same job ID they are separate events. The worker commits its marker with the result, so the second event creates no second effect. Reusing that marker for a different purpose or slot is not the same operation identity. The native fixture handles an ordinary duplicate event without timing attacks or concurrent request floods.

WEB-19.03 · Red · Scheduled jobs and async processing ↗
Keep a lifecycle ledger through to results

Here the logical scheduler and dispatcher produce due/observed/admitted; an independent SQLite reader produces resultRows and processedRows. Records correlated by the same slot and jobId are not cloud-scheduler logs. Define the slot, original due, observed start, admitted status, and result owner. For maxStartAge=3 logical units, the native fixture admits observed=13 and skips observed=14; this is no Kubernetes default. A completed request may report only admission. Later status reads or notifications obtain meaning from the final-result owner; here that is only a SQLite observer read.

WEB-19.03 · Blue · Scheduled jobs and async processing ↗
Misses, failures, and retries are separate branches

The selected late skip creates no job row; an admitted failure keeps a failed lifecycle and rolls back its result/marker transaction. A duplicate admitted event finds the marker and preserves resultRows=1. Branches show different public outcomes. Compensation, retry budgets, and missed-schedule catch-up are service policy, not universal product behavior or production tuning values in this fixture.

WEB-19.03 · Blue · Scheduled jobs and async processing ↗
schedule

Selected logical clock slot and lateness policy.

WEB-19.03 · Scheduled jobs and async processing ↗
normal/late/failure

Admission and final results are distinct outcomes.

WEB-19.03 · Scheduled jobs and async processing ↗
duplicate

Selected effect count for one operation identity.

WEB-19.03 · Scheduled jobs and async processing ↗
selector

Synthetic accepted-but-failed false-success check.

WEB-19.03 · Scheduled jobs and async processing ↗
A read does not promise unchanged state at use

An application reads a public note at revision=1; the owner can change it before use. TOCTOU describes that knowledge gap between a check and use. Races are not all the same: order-dependent behavior, lost updates, and invariant violations can differ. This lesson races no vulnerable endpoint. It shows a guarded update rejecting old expectation=1 after an ordinary authored revision=2 transition.

WEB-19.S01 · Core · Races, transactions, and idempotency ↗
Retry identity includes result and purpose

If a caller receives no completion response, it cannot infer that nothing executed. Here note rename commits while response knowledge stays unknown; a retry with the same request alias reuses the committed result. The alias is no credential or bearer token. Application idempotency scope includes caller alias, operation purpose, and key, with normalized note ID/title parameters. The same scope/key with different parameters yields a selected conflict rather than another operation result.

WEB-19.S01 · Core · Races, transactions, and idempotency ↗
An earlier check has limited knowledge scope

The controlled ledger separates readVersion1 from currentVersion2 at use. The condition is treating stale knowledge as current state; a possible impact is an old decision overwriting a newer title. This lesson runs only the correct guarded condition, observing zero affected rows and preserved state. It provides no bypass, vulnerability reproduction, or race-winning timing instructions. Inspection finds the authoritative statement that evaluates expected revision.

WEB-19.S01 · Red · Races, transactions, and idempotency ↗
An unknown response is not a failed operation

Caller response loss and store rollback have different ledger states. Running committed work with a new alias can express another intent; using the same alias and parameters retrieves the stored result under the selected contract. Reusing an alias for another title or purpose needs a correctness decision. An idempotency key carries no browser identity or permission, so success is no authorization outcome.

WEB-19.S01 · Red · Races, transactions, and idempotency ↗
Evaluate the invariant in an authoritative statement

Before/after revisions and affectedRows come from a local SQLite statement and independent SELECT reads; caller UNKNOWN is a separately supplied scenario condition. The invariant is that a title changes only when current revision equals expected revision. Benign expected1/current2 mismatch yields rowcount0 and leaves current title/revision unchanged. Independent SELECTs compare before and after state without assuming the UI copy improved. Transaction visibility and operation condition are different controls, together supporting the selected outcome.

WEB-19.S01 · Blue · Races, transactions, and idempotency ↗
Commit mutation and saved result together

The scope tuple caller-demo / rename-public-note / request-a stores normalized tea +Updated note parameters. Normal response and same-parameter retry produce the same result with one business mutation. The key is an instructional alias, not entropy, production-retention, or authentication guidance. Native checks cover parameter conflict within a scope and a separate purpose namespace.

WEB-19.S01 · Blue · Races, transactions, and idempotency ↗
invariant

Fixed guarded SQL and observed stale rejection.

WEB-19.S01 · Races, transactions, and idempotency ↗
scope

Caller/purpose/key and normalized parameters.

WEB-19.S01 · Races, transactions, and idempotency ↗
retryUnknown/rollback

Preserved commit and rollback are distinct outcomes.

WEB-19.S01 · Races, transactions, and idempotency ↗
selector

Synthetic stale-mutation acceptance decision.

WEB-19.S01 · Races, transactions, and idempotency ↗
Deployment units and layers/tiers are different axes

A monolith groups core application behavior in one development/release deployment unit. This does not mean one file or binary: the unit can contain modules, projects, and artifacts, and horizontal replicas can run it in multiple processes or machines. Microsoft .NET examples describe instance core behavior in its own process, not a requirement that the whole topology has one process. Databases and other dependencies may be separate. No framework or deployment changes occur here.

WEB-20.01 · Core · Monoliths, three-tier architecture, and SPAs ↗
Initial HTML, later data, and DOM are separate states

In server rendering the server reads public Tea note through service/data owners and places content into h1; after HTML arrival the browser can parse/render the DOM. Our selected SPA startup instead returns a note container with Loading text. This is one client-rendered startup, not a rule that every SPA must send empty HTML; server rendering and hydration can coexist. JavaScript can update parts of the initial document without reloading it all.

WEB-20.01 · Core · Monoliths, three-tier architecture, and SPAs ↗
An architecture box proves no boundary by itself

Frontend/backend/data boxes do not prove server authorization or network isolation of a data tier. Logical class calls and remote requests differ. Server/service/data fixture calls are local and draw no packets. Browser/server request/response snapshots represent a conceptual HTTP boundary without a native capture claim.

WEB-20.01 · Red · Monoliths, three-tier architecture, and SPAs ↗
HTML success must not hide a later API failure

The SPA shell arrives with Loading. A selected API 404 preserves startup success while making the note result unavailable. A fulfilled promise counter is neither HTTP success nor a parsed note. Without an object matching the note schema, no successful title is projected into the DOM. This is ordinary missing-public-note behavior without real targets or malformed payloads.

WEB-20.01 · Red · Monoliths, three-tier architecture, and SPAs ↗
Keep topology and responsibility ledgers separate

A local HTML builder and HTMLParser read produce source-text observations; API status/body are the example’s separate representation. These fields are not live browser DOM observations or packet captures. Record browser presentation, server endpoints/rendering, application service logic, and data ownership separately. Server calls to service/data are local in one process; no network diagram implies deployment-unit counts. The monolith multiple-project example describes packaging while three-tier guidance addresses physical placement. This lesson performs no framework rewrite, cloud deployment, or performance comparison.

WEB-20.01 · Blue · Monoliths, three-tier architecture, and SPAs ↗
Separate arrival, parsing, and UI commit

The scene first prepares sender target intent, changing server target knowledge only at request ARRIVE. During prepared responses the browser keeps Loading or empty knowledge. Response ARRIVE and local status/body/schema steps precede projected DOM text changes. API404 arrives as an ordinary Response, and the local guard prevents note-success commit. Reduced motion preserves the same states and controls.

WEB-20.01 · Blue · Monoliths, three-tier architecture, and SPAs ↗
roles

Logical responsibilities and physical deployment differ.

WEB-20.01 · Monoliths, three-tier architecture, and SPAs ↗
ssr/spa

Initial source HTML and API representations are separate stages.

WEB-20.01 · Monoliths, three-tier architecture, and SPAs ↗
apiFailure

Startup success differs from data-result failure.

WEB-20.01 · Monoliths, three-tier architecture, and SPAs ↗
limits/selector

Native source-parser versus authored DOM/promise projection scope.

WEB-20.01 · Monoliths, three-tier architecture, and SPAs ↗
A service boundary is more than a URL

Microservices do not mean exposing every application function as another HTTP endpoint. A service carries a contract, release boundary, and data ownership around a business capability and bounded context. The notes service can own note representations while an index service owns a search summary. These are separate logical owners in the example. Their placement on machines, processes, or regions does not follow from that distinction. A route count cannot establish independent deployment.

WEB-20.02 · Core · Microservices, gateways, and intermediaries ↗
The different questions asked by gateway, load balancer, CDN, and WAF

An API gateway can route a public contract to a service, and a product may also provide authentication, quotas, or transformations. A load balancer distributes work among instances of the selected service. Layer 4 selection and Layer 7 selection using HTTP methods or paths have different visibility. A reverse proxy can act as a server outward and as a client on an inward connection. We still ask which resource owner produced the representation rather than treating every intermediary as the same origin.

WEB-20.02 · Core · Microservices, gateways, and intermediaries ↗
Extending one hop’s success to the whole flow

Finding a route at the gateway does not establish that the chosen replica will reply or that its index dependency will return a usable result. Treating these as equivalent can make ordinary dependency failure appear as a completed result with empty or stale data. Review where each decision was produced and what response the caller actually received. Ending the normal scene at the gateway makes the boundary explicit: undelivered browser results cannot be marked complete.

WEB-20.02 · Red · Microservices, gateways, and intermediaries ↗
Intermediary trust and domain permission

Edge allowance and recognition of a route are not domain authorization. A private service must bind caller identity, intended audience, operation, and object ownership in a trusted context. This fixture handles public reads only and does not claim to verify private permissions. A header or internal-looking service name alone is not identity evidence. If TLS termination points differ, each hop needs its own confidentiality and peer-trust boundary.

WEB-20.02 · Red · Microservices, gateways, and intermediaries ↗
Record roles and failure boundaries

The local routing adapter produces replica selection; the example’s service record produces originCalls and composed category. A JSON roundtrip rereads only those fields. Write the decision made by each box before its product name: can the edge reuse a representation, which service contract does the gateway select, which eligible replica does the balancing policy choose, and which data does notes own? Combining roles in an appliance does not merge their authority. Keep the method, target, and intended public-read purpose visible together. A trace identifier should not be treated as a secret or permission key.

WEB-20.02 · Blue · Microservices, gateways, and intermediaries ↗
Bind distinct evidence to distinct results

Check the public asset key and logical freshness input in the cache-hit branch, the explicit block decision in the policy branch, and absence of forwarding in the unavailable-origin branch. These cases explain different decisions rather than repeating one failure. Native checks run an own dictionary cache, routing adapter, and public index builder. An independent JSON roundtrip checks selected replica, origin calls, and category relationships; it is not a CloudFront or WAF request.

WEB-20.02 · Blue · Microservices, gateways, and intermediaries ↗
normal

Service composition ends at gateway arrival; browser completion is separate.

WEB-20.02 · Microservices, gateways, and intermediaries ↗
cacheHit/noOrigin

Reuse and eligibility decisions produce different origin call counts.

WEB-20.02 · Microservices, gateways, and intermediaries ↗
policyClosed/roles

Supplied maintenance predicate, not a real WAF rule or permission decision.

WEB-20.02 · Microservices, gateways, and intermediaries ↗
selector/limits

Own adapter/XML ledger; no real CDN, gateway, or network execution.

WEB-20.02 · Microservices, gateways, and intermediaries ↗
Image, instance, and durable state have different lifecycles

A container is an execution boundary for an application process with its dependencies and selected isolation mechanisms. The image, running instance, and durable application data are different objects. Linux containers typically share the host kernel; environments such as Docker Desktop can place that host inside a VM. Do not assign a separate kernel to every container. Isolation depends on runtime, privilege, and mount choices, and does not supply application authorization.

WEB-20.03 · Core · Containers, Kubernetes, serverless, and edge ↗
Serverless and edge retain ownership

Serverless does not mean an absence of servers. It means that provisioning and execution-environment lifecycle responsibilities are shared with a platform. AWS Lambda default-function environments have phases such as Init, Invoke, and Shutdown. They can be reused but should not be assumed to persist indefinitely. Product options such as Managed Instances and Durable Functions have different concurrency or persistence contracts. Transient-state discussion here is limited to the default-environment example.

WEB-20.03 · Core · Containers, Kubernetes, serverless, and edge ↗
Confusing running, ready, and completed

A replica process may have started while initial data loading is incomplete. Treating Running as ready can produce unusable responses during ordinary startup. Keep platform status distinct from the application readiness predicate and expose the selected traffic decision. In the replacement branch runtime-b exists and is running, but the native adapter does not select it while ready=false. After ready=true an own public read proceeds; this is not a measured kubelet probe.

WEB-20.03 · Red · Containers, Kubernetes, serverless, and edge ↗
Trusting transient state too broadly

State that can survive warm reuse conflicts with an assumption that every invocation starts clean. Conversely, treating memory as the durable source creates loss on replacement or disagreement across replicas. This lesson uses only a public Tea note and a counter. Without reading real secrets or user identities, it shows the purpose of the cache and how the application returns to its authoritative owner.

WEB-20.03 · Red · Containers, Kubernetes, serverless, and edge ↗
Build a lifecycle ownership table

Record image version, runtime instance identity, readiness, and durable-data reference separately. The table shows what changes on replacement. Choosing persistent data outside a container layer also requires retention, backup, access-control, and deletion ownership. Reading the public SQLite file after an orderly reopen is useful bounded evidence; it does not establish host-crash, replication, or volume durability guarantees.

WEB-20.03 · Blue · Containers, Kubernetes, serverless, and edge ↗
Separate request results from platform names

For function or edge handlers, distinguish invocation input, response status/body, and the owner of durable effects. Give each input a context-specific decision, and validate reused connections or public caches. Do not assign the same timeout, concurrency, or disk quota to every function type: bind claims to the selected product and version contract. There is no numeric production tuning advice here; counter changes are finite local observations.

WEB-20.03 · Blue · Containers, Kubernetes, serverless, and edge ↗
replacement

Memory replacement and a committed SQLite note have different lifetimes.

WEB-20.03 · Containers, Kubernetes, serverless, and edge ↗
warm

Own local environment counter is not a distributed durable sequence.

WEB-20.03 · Containers, Kubernetes, serverless, and edge ↗
edge

Public transform metadata proves neither location nor attestation.

WEB-20.03 · Containers, Kubernetes, serverless, and edge ↗
selector/limits

Ready-decision XML selector and real-platform execution boundary.

WEB-20.03 · Containers, Kubernetes, serverless, and edge ↗
Provider contract, local purpose, and ownership

A third-party service supplies an externally managed capability through an API, webhook, library, or browser integration. A SaaS dependency also binds operation, changes, availability, quotas, and retention to the provider contract. A provider name or a successful demo is not evidence of suitability for every application purpose. Record what data leaves, what result returns, and who treats that result as authoritative.

WEB-20.04 · Core · Third-party services and trust boundaries ↗
Arrival, validation, and commit are three distinct events

HTTP status and a provider error body belong to a contract; receiving an external response does not mean a local mutation happened. An adapter can parse a 200 application/json result before checking types, the intended object, or its purpose. The normal branch accepts idtea, titleTea note, and integer revision1, then uses a parameter-bound SQLite write and COMMIT. An independent connection reads the committed title afterward. Provider arrival, validation, and local commit have distinct scene snapshots.

WEB-20.04 · Core · Third-party services and trust boundaries ↗
A trusted channel is not unlimited trust in data

TLS trust supports peer identity and transit integrity; it does not establish that a title has the correct type, intended note, or local purpose. Removing the input gate because a SaaS provider is well known allows even ordinary version drift to break storage or UI invariants. This perspective connects condition, impact, and control: a numeric title fails the string contract before mutation. No vulnerable parser or exploit example is constructed.

WEB-20.04 · Red · Third-party services and trust boundaries ↗
Reading errors and unknown outcomes as success

Using status200 as schema validation differs from treating a provider-error body as a success body. An unknown response is neither: there is no status to classify. Each can leave the prior catalog title unchanged, but the reasons remain distinct. Diagnostic categories can differ even when a UI message is shared. The control binds contract mismatch, provider unavailability, and missing observation to a mutation gate without conflating them.

WEB-20.04 · Red · Third-party services and trust boundaries ↗
Put the integration contract in a boundary ledger

A fixed local provider adapter supplies status/body observations; an independent SQLite connection supplies commit visibility. These are not logs or network captures proving a remote provider ran. Record provider identity alias, intended capability, data classification, expected status and media type, schema version, and local authority together. When a contract changes, review ordinary schema drift and provider errors as well as success fixtures. The strict gate checks requested-id equality, a string title, and an integer revision; unused extra fields are not consumed. This selected policy is not a universal JSON-schema standard and does not automatically sanitize a title for every output context.

WEB-20.04 · Blue · Third-party services and trust boundaries ↗
Connect response categories to user effects

Do not present success for contract mismatch, map unavailability to a selected application error, and do not assert remote completion for an unknown outcome. If an old local title exists, retain provenance and freshness information; explicitly describe any chosen stale fallback. This fixture neither presents stale data as new success nor retries an external write. A generic user error can coexist with a distinct internal category without copying an entire provider object into logs or the browser.

WEB-20.04 · Blue · Third-party services and trust boundaries ↗
contract

Own public capability scope, contract version, and private-authority boundary.

WEB-20.04 · Third-party services and trust boundaries ↗
normal/schemaDrift

Response arrival, type gate, and committed local effect differ.

WEB-20.04 · Third-party services and trust boundaries ↗
providerError/unknown

Observed status errors and no-response knowledge have different categories.

WEB-20.04 · Third-party services and trust boundaries ↗
selector/limits

Local evidence gate; no SaaS, network, browser, or measured deadline.

WEB-20.04 · Third-party services and trust boundaries ↗
Whose authority does the HTTP client use?

A browser executes a page’s JavaScript request within its own origin and credential rules. Server-side fetch uses the application process’s network reachability. The same fetch name does not make these environments the same security boundary. In the public catalog example, the learner selects note-A; the server maps that business identifier to its registered catalog endpoint. The client selects neither an arbitrary URL nor credentials to forward.

WEB-20.S01 · Core · Server-side fetch, SSRF boundaries and egress policy ↗
URL, destination and connection form one decision chain

This profile fixes origin https://catalog.example.org, path /public-notes/note-A and method GET on the server. A URL parser separates protocol, hostname, port and pathname; an origin alone contains no path permission. The same origin’s /help is a valid URL but not this operation’s endpoint. Re-parsing the constructed URL must preserve the approved components; parser consistency is part of the design when strings cross service boundaries.

WEB-20.S01 · Core · Server-side fetch, SSRF boundaries and egress policy ↗
Egress and the response boundary

An application allowlist states which business operation should call which service. Network egress independently limits the process’s available routes. Collapsing both into one boolean hides the layer at which evidence was obtained. The artifact supplies separate destination and egress evidence; a correct URL with an approved destination still produces no dispatch when egress is denied.

WEB-20.S01 · Core · Server-side fetch, SSRF boundaries and egress policy ↗
Broken assumption: valid input means permitted destination

The Red perspective questions necessary conditions instead of sending attempts to a destination. note-A can satisfy its schema while the endpoint configuration must still match the approved origin and path. Unapproved docs.example.org is an ordinary documentation origin; being public does not make it the destination of this catalog operation. The unknown-origin branch produces neither a catalog message nor a title body.

WEB-20.S01 · Red · Server-side fetch, SSRF boundaries and egress policy ↗
Finding the layer where a control stops applying

The second question is whether a decision for one hop silently carries into another. The artifact does not follow redirects and records no new dispatch to an ordinary different documentation origin. This is not an executed redirect test. A system that needs redirects must separately demonstrate that every hop fits its approved profile and that forwarded context remains restricted.

WEB-20.S01 · Red · Server-side fetch, SSRF boundaries and egress policy ↗
Constructing the endpoint from a business identifier

The Blue design gives the client a narrow identifier such as note-A. A server-owned registry binds it to a profile with fixed scheme, origin, path and method. Known URL parsing separates the configured endpoint for comparison with approved components. Reading a public title needs no credential forwarding; copying a generic header collection into another service is outside this example’s contract.

WEB-20.S01 · Blue · Server-side fetch, SSRF boundaries and egress policy ↗
Checking negative evidence with a dispatch counter

The regression table accepts correct configuration; an unapproved origin, missing destination evidence and denied egress each leave catalog dispatch at zero. A denied read has no title body and performs no store write. A separate ordinary /help row on the correct origin demonstrates an endpoint boundary narrower than origin equality. The positive branch produces the fixed title projection.

WEB-20.S01 · Blue · Server-side fetch, SSRF boundaries and egress policy ↗
profile

Server-owned origin/path/method and native-test boundary.

WEB-20.S01 · Server-side fetch, SSRF boundaries and egress policy ↗
rows

Configuration, destination and egress evidence; dispatch/body/write outcomes.

WEB-20.S01 · Server-side fetch, SSRF boundaries and egress policy ↗
componentChecks

Approved endpoint versus an ordinary different path on the same origin.

WEB-20.S01 · Server-side fetch, SSRF boundaries and egress policy ↗
redirectLedger

Automatic following disabled; no new dispatch to a different ordinary origin.

WEB-20.S01 · Server-side fetch, SSRF boundaries and egress policy ↗
connectionEvidence

Validated/connected-set relationship is a declared alias only; no DNS is executed.

WEB-20.S01 · Server-side fetch, SSRF boundaries and egress policy ↗
budget

Example byte/deadline/hop budgets; no real runtime enforcement.

WEB-20.S01 · Server-side fetch, SSRF boundaries and egress policy ↗
boundaries

Boundaries where CORS, domain approval and parsing do not replace permission.

WEB-20.S01 · Server-side fetch, SSRF boundaries and egress policy ↗
SPA, BFF and SSR do different jobs

A SPA can manage client navigation and view state; a BFF is a server adapter tailored to that interface. SSR constructs the initial HTML on the server. These roles may share a deployment without being mandatory names for one another. In public notes, the BFF selects only a title from the catalog record; mobile and web interfaces can need different projections. Shared domain permission remains part of the relevant service contract.

WEB-20.S02 · Core · BFF, SSR, hydration and server actions ↗
When does server-produced data become public?

The server record contains title, internalReviewState and serverOnlyContextAlias. The latter two are not secrets in this example, but remain outside the public contract. An explicit public projection selects {title: Tea & Bread}. Serializing the complete record and hiding fields in the UI does not provide the same boundary: a field delivered to the browser has become browser data. Server-side computation does not make delivered props private again.

WEB-20.S02 · Core · BFF, SSR, hydration and server actions ↗
A server action is a new entry point

A previously rendered page is not evidence of current permission for a later operation. In modern frameworks, a client-invoked server function or action crosses the server boundary again with its own input and identity context. The Next.js guide makes this distinction through authentication and object permission inside the action. An action identifier, UI button or visibility in a client bundle is not a permission document.

WEB-20.S02 · Core · BFF, SSR, hydration and server actions ↗
Broken assumption: server production stays private

The Red review first asks what the record loses when projected. Displaying Tea & Bread needs neither an internal review field nor a service context alias. Including these fields in serialization crosses the data boundary even if the UI does not show them. Both compared objects are entirely harmless here; there is no extraction of real secrets or movement into another system.

WEB-20.S02 · Red · BFF, SSR, hydration and server actions ↗
Broken assumption: the entry point inherits an earlier gate

A page permission decision covers that render request at that moment. Action-read and entry-denied share pagePreviouslyRendered but have different current action permission. The second row sends no catalog message. Missing current context is not reconstructed by guessing identity from old page state; unknown evidence stays visibly null and delivery stops.

WEB-20.S02 · Red · BFF, SSR, hydration and server actions ↗
Minimal projection and matching initial state

This record is produced by the local JSON serializer, HTML-context encoder and initial-title comparison; action-gate fields are selected policy inputs. It measures no actual React hydration or server-framework logs. The Blue contract separates the server record from the public DTO. Build the public title projection with allowlisted fields rather than a generic spread or full-record serialization. Real systems using private projections need viewer-context cache partitioning; this public-title example implements no private cache. Finding a cached projection belonging to another actor does not replace current permission.

WEB-20.S02 · Blue · BFF, SSR, hydration and server actions ↗
A current decision record for each operation

Write the action contract as input schema, verified actor, action permission, object permission and domain conditions. An assumption that the actor already logged in during page rendering does not shorten this list. Missing context means no dispatch; denied permission means no dispatch; an accepted public read produces only a title body. Regression fixtures preserve separate reasons and evidence for these outcomes.

WEB-20.S02 · Blue · BFF, SSR, hydration and server actions ↗
profile

Public note operation and actual framework/browser scope.

WEB-20.S02 · BFF, SSR, hydration and server actions ↗
rows

Render/action mode, current actor/object/action evidence and no-write outcomes.

WEB-20.S02 · BFF, SSR, hydration and server actions ↗
serverRecord

Harmless server record; not every field belongs in the public DTO.

WEB-20.S02 · BFF, SSR, hydration and server actions ↗
publicProjection

The single title field selected for client delivery.

WEB-20.S02 · BFF, SSR, hydration and server actions ↗
serializedPublicJSON

Byte text of the narrow DTO in separate JSON format.

WEB-20.S02 · BFF, SSR, hydration and server actions ↗
publicHTML

HTML text-context representation of the fixed title.

WEB-20.S02 · BFF, SSR, hydration and server actions ↗
serializationBoundary

JSON and HTML encoder scopes; no inline script is used.

WEB-20.S02 · BFF, SSR, hydration and server actions ↗
hydrationLedger

Server/client initial-title match; not a real React hydration test.

WEB-20.S02 · BFF, SSR, hydration and server actions ↗
architecture

Separation of SPA/BFF/SSR/hydration/action roles.

WEB-20.S02 · BFF, SSR, hydration and server actions ↗
cacheBoundary

Viewer partition requirement for private projections; no actual cache.

WEB-20.S02 · BFF, SSR, hydration and server actions ↗
boundaries

Buttons/action IDs/old renders are not permission; delivered data is client data.

WEB-20.S02 · BFF, SSR, hydration and server actions ↗
A workload and an end user are different actors

A service’s identity is different from the actions it may perform for an end user. Accepting Notes API as a workload at the Queue does not permit it to read every tenant’s data for Duru. Service connection identity is verified against appropriate trust roots/issuers and recipient profiles; user delegation is separately bound to subject, tenant, purpose, audience, action and object. SPIFFE defines workload identity and the SVID used to prove it; permission for a particular SPIFFE ID to read notes remains application policy. This lesson contains no credential or SVID bytes. WorkloadVerifiedDeclared is an independent fixture input, not a claimed result of actual TLS or token verification. Recognizing the sender, trusting its user assertion and permitting the resource remain three distinct questions.

WEB-20.S03 · Core · Service identity and asynchronous context propagation ↗
Queue delay changes how context must be evaluated

An asynchronous job may be admitted when enqueued, yet execute later under a different clock value or policy revision. Its context must therefore travel with trusted provenance, and the worker must evaluate audience, purpose, time and action for its own operation. The artifact binds public-note-read to the notes-worker audience and note-A object. At validUntil=200, now=200 is invalid; this equality rule belongs to the selected profile. A different purpose with the correct user and tenant still cannot send a read to the store. Missing context is recorded as permissionUnknown and leads to a safe deny. A queue receipt or ACK is not business success; it records arrival. Retries and idempotency grant no permission either: controlling repeated processing is a different problem from validating actor and purpose.

WEB-20.S03 · Core · Service identity and asynchronous context propagation ↗
Correlation context is not identity

Trace context correlates the same work across components. W3C traceparent and tracestate fields serve correlation; sensitive user claims do not belong in them. The artifact uses trace-A only as a readable teaching alias, not actual traceparent syntax. A matching alias proves neither workload identity, subject nor permission. Authentication and tracing contexts need separate fields, provenance and retention rules. A local copy projects only approved job fields into a new object; retaining the original request object by reference can mix another job’s state. Runtime tools such as AsyncLocalStorage help retain context through asynchronous continuations within one process. They do not create an identity assertion across a network or queue boundary. A recipient must perform its own validation before considering deserialized context trustworthy.

WEB-20.S03 · Core · Service identity and asynchronous context propagation ↗
Serverless execution reuse and least privilege

Serverless does not mean that each invocation receives a new process. An execution environment may be reused, so reusable SDK clients or static resources must be separated from request-specific actor and context state. AWS Lambda’s function-code guidance recommends avoiding stored user data and security-sensitive event state across invocations. The local two-context check keeps Duru/job-A and Ece/job-B in separate async stores and copies; it is not an actual Lambda isolation test. A workload’s platform permissions also require a minimal service role; user delegation does not replace that role. Even a queue consumer with a readNotes role must not produce note-A’s body when current context is invalid. Deployment platforms, token exchange, actual clock synchronization and revocation propagation remain external dependencies without assumed evidence.

WEB-20.S03 · Core · Service identity and asynchronous context propagation ↗
Assuming an internal sender establishes user context

The assumption to inspect gives an internal connection or familiar service name authority over every user assertion. Such a failure requires loss of the sender’s assertion privileges or the recipient’s validation policy. Workload authentication concerns the sender; an assertion that it acts for Duru on public-note-read may need a different issuer and delegation trust decision. In the wrong-purpose branch the workload is recognized and user context is present, but purpose does not match the notes-worker profile. This is no token alteration or bypass attempt: a supplied policy row safely closes for the wrong purpose. Internal hostnames, queue names, trace aliases and successful receipts do not open that gate. Without inspection of actual connection identity, there is no claim of attack success; workload verification remains an explicit declared dependency.

WEB-20.S03 · Red · Service identity and asynchronous context propagation ↗
Distinguish delayed context from missing evidence

Context admitted into a queue may no longer be acceptable when the worker executes. The impact arises if execution uses an old admission result instead of current time or policy gates. The expired row contains a known time mismatch; the context-missing row contains insufficient evidence of actor delegation. Both safely yield resource delivery=0 and body=null, while keeping different diagnostic meanings. A continued trace does not imply continued identity. Sharing the same mutable object across jobs is also a runtime-state problem; this lesson observes positive isolation only for approved copied contexts. This perspective asks which supplied conditions are necessary. It performs no privilege operation or credential use on an actual queue. The finite model supplies no evidence of real distributed replay or retry behavior.

WEB-20.S03 · Red · Service identity and asynchronous context propagation ↗
Every recipient owns its gate

The local Node AsyncLocalStorage check measures separate jobId and subject values in two async scopes. Worker-policy rows are produced from purpose, audience and validUntil inputs; they are not queue logs, signature verification or IAM evidence. Separate service roles for Notes API, Queue and Worker: enqueue, dequeue and notes.read are not the same permission. User context travels as a minimal approved field projection; downstream recipients validate their own audience, purpose, lifetime and resource scope. Even a valid signature must be bound to an issuer authorized to assert that context; no signature is executed here. Where another recipient needs context, design a delegation or exchange profile appropriate to its purpose and audience rather than blindly copying ID tokens or user bearer material. The success scene brings the store’s read-only title projection to the worker; it claims no delivery to the API or final browser. Separate telemetry outcomes for service verification, user delegation and resource permission make failure causes visible.

WEB-20.S03 · Blue · Service identity and asynchronous context propagation ↗
Isolation and the consequences of failure

The local runtime check gives two Promise continuations separate AsyncLocalStorage.run scopes and observes each job ID and subject. That is actual context behavior within Node, not another process’s trust decision. Changing a copied job’s title or trace field must not alter its original request or a second job. Policy fixtures require no message to reach the store, no mutation and no protected title body for wrong-purpose, expiry and missing context. Unknown context is not merged into known-deny evidence. Production designs need separate integrations for retries, revocation, key rotation and current policy revision; an idempotency key is not a permission document. With serverless execution reuse, request state remains per invocation. The deterministic scene is not presented as a queue ACK, actual token validation or cloud IAM enforcement test.

WEB-20.S03 · Blue · Service identity and asynchronous context propagation ↗
rows

Declared workload/provenance inputs and current purpose/audience/time/resource gates.

WEB-20.S03 · Service identity and asynchronous context propagation ↗
copiedContextFields

Approved context projection only; no credential material is carried.

WEB-20.S03 · Service identity and asynchronous context propagation ↗
correlation

A trace alias is neither identity nor permission evidence.

WEB-20.S03 · Service identity and asynchronous context propagation ↗
deliveryBoundary

Success is only a read-only body from store to worker.

WEB-20.S03 · Service identity and asynchronous context propagation ↗
Source, build output, and environment carry different evidence

Development, test, staging, and production names are not quality results. Development produces changes, tests check selected behavior, staging can examine a release candidate with more representative configuration and dependencies, and production serves users. Identical names do not guarantee identical isolation or data policies across projects. Passing a staging check does not establish matching production secrets, network rules, load, or migration state.

WEB-21.01 · Core · From source to deployment ↗
At which stage do bundling, CI/CD, and configuration act?

Bundling processes an imported dependency graph around an entry point and connects it to outputs. It differs from concatenation and ZIP packaging. Minification affects representation size, while bundling changes code/dependency organization. esbuild Bundle is a named example of recursively inlining imports; external or unanalyzable imports can remain runtime dependencies. The native ZIP here packages static files and does not execute esbuild.

WEB-21.01 · Core · From source to deployment ↗
Mistaking a successful build for an approved release

Build exit0 only describes the selected command. Independent checks may not have run, the inspected artifact may differ, or release approval may be separate. Marking the candidate production-ready then misstates gate coverage. In the failed-check branch the builder produces valid HTML, but the verifier compares expectedCoffee with actualTea and refuses promotion. This differs from a source compilation failure.

WEB-21.01 · Red · From source to deployment ↗
Treating configuration as merely a byte boundary

Runtime configuration can change while a static package remains identical; equal bytes do not establish equal behavior. Conversely, embedding a secret in browser build-time config does not make it server-only. The fixture carries public values and uses a separate typed parser gate. Secret management retains the lifecycle boundaries of WEB-16.02; an environment name or .env syntax supplies neither a vault nor rotation.

WEB-21.01 · Red · From source to deployment ↗
Fix the identity of the tested candidate

These records come from the local static-file builder, HTML-title reader, hash calculation and typed config decoder. They observe no GitHub workflow, production environment or deployment logs. Bind the input manifest, selected builder identity, config influence, and output digest in one record. Missing required input must prevent a candidate; partial output must not appear as a ready release. The fixture uses a fixed file set rather than arbitrary paths. Repeat builds yield equal bytes, while an ordinary title change alters index and package digests. The parser title and hash answer different questions: content expectations and exact output identity.

WEB-21.01 · Blue · From source to deployment ↗
Separate gate results from publication state

Distinguish candidate passed, check failed, missing input, and config mismatch. Neither source review nor a local build is publication. The supplied READ_ONLY parsing gate makes false genuinely false and rejects unexpected text. That is not a Node process.env read or production-policy enforcement; the source string semantics and own typed-adapter result are recorded separately.

WEB-21.01 · Blue · From source to deployment ↗
inputs/outputs

Own public source bytes and generated HTML/CSS bytes.

WEB-21.01 · From source to deployment ↗
normal/gateFailed

Digest identity and independent content checks are distinct decisions.

WEB-21.01 · From source to deployment ↗
runtimeConfig/bundling

Runtime config separate; static ZIP packaging differs from JS bundling.

WEB-21.01 · From source to deployment ↗
selector/limits

Inert gate observation; no repo build, deployment, or secret read.

WEB-21.01 · From source to deployment ↗
A DNS answer is not an HTTP response

DNS helps resolve names to resource records. It is not a forwarding hop carrying an HTTP request body to the application. After a resolver obtains an address or related record data, the client makes a separate connection to the selected endpoint. DNS answers concern name authority and resolver-cache lifetime; they do not establish that the application can read a note now or authorize the caller. public.example.invalid and edge-demo are supplied aliases, with no queries or record changes.

WEB-21.02 · Core · Traffic routing, scaling, and availability ↗
Scale-out, ready capacity, and high availability

Horizontal scaling shares work across more instances or replicas, whereas vertical scaling adds resources to existing instances. Desired replica count is controller intent; created and ready counts may not reach it simultaneously. Kubernetes HPA is a named example of a periodic metric-driven control loop updating a workload scale target, while startup, dependency initialization, and readiness progress separately. desired3/ready2 are explicit finite fixture values, not production thresholds or HPA-formula output.

WEB-21.02 · Core · Traffic routing, scaling, and availability ↗
Mistaking resolution and box counts for availability

A successful DNS lookup does not establish completion of the selected public request across the whole chain. An edge miss, an empty eligible target pool, and an application dependency error are different boundaries. Review actual request/response knowledge instead of assigning every final status to an origin failure. Ending at edge arrival prevents counting an undelivered representation as a completed viewer flow.

WEB-21.02 · Red · Traffic routing, scaling, and availability ↗
Treating missing observations as healthy or authorized

Defaulting missing readiness to true can route traffic to an unknown target. Defaulting it to false and reporting confirmed failure invents different knowledge. The selected control admits only literal true and retains unknown as the missing reason. An empty eligible pool produces a selected unavailable result without sending a request to the application. That does not replace diagnostic evidence about why each instance is unready.

WEB-21.02 · Red · Traffic routing, scaling, and availability ↗
Separate intent, observation, and selected targets

Keep desired count, observed instances, and the ready set together but as separate fields. For the public read, expose route purpose, the balancer-selected instance, and response source. Artifact/version equality across ready instances requires configuration evidence, not a count. Deterministic first-ready selection is only fixture policy. The native checker independently filters explicit lists and checks distinctions among unknown, false, and true fields.

WEB-21.02 · Blue · Traffic routing, scaling, and availability ↗
Bind availability claims to the user flow

Define a successful result for the selected operation: correct public title, usable status, and the endpoint where delivery occurred. A result from b in the replica-down case differs from absence of forwarding in the no-ready case. An HA claim needs measured user-flow availability, remaining capacity, and failure-domain evidence; these finite cases produce no percentage or SLA. DNS TTL and CDN lifetime do not imply globally instantaneous propagation.

WEB-21.02 · Blue · Traffic routing, scaling, and availability ↗
topology/normal

Supplied resolution and bounded origin path carry different knowledge.

WEB-21.02 · Traffic routing, scaling, and availability ↗
scale

Desired/created/ready counts differ; no HPA or capacity measurement.

WEB-21.02 · Traffic routing, scaling, and availability ↗
unknownHealth/noReady

Missing observation is unknown; literal-true policy selects traffic.

WEB-21.02 · Traffic routing, scaling, and availability ↗
selector/limits

Inert health decision; no actual DNS, cloud, HA, or private permission.

WEB-21.02 · Traffic routing, scaling, and availability ↗
Observability is a question beyond instrumentation counts

Observability uses external signals to understand internal system behavior and why a selected outcome occurred. Many log lines or an attractive dashboard are not enough. Choose the question first: did a public note read finish, which dependency waited, where did an error occur, and did the observation pipeline receive data? Bind instrumentation, signal semantics, and correlation to that question. Telemetry outcomes do not become authoritative business state.

WEB-21.03 · Core · Logs, metrics, and traces ↗
An event need not appear in every signal

Instrumentation, sampling, local buffers, exporters, and collector/backend stages differ. A request can occur without a retained trace under selected sampling. Separate metric instrumentation can still count it. Head sampling decides early and does not guarantee selection of a later error; tail sampling can inspect more completed spans but has its own buffering and availability limits. The fixture uses a supplied sampled boolean, not an OpenTelemetry sampler or collector.

WEB-21.03 · Core · Logs, metrics, and traces ↗
Reading no signal as no event or healthy

An absent trace does not prove that an operation never occurred. Sampling false, missing context, export failure, or retention windows can explain the gap. The condition examined is an observation gap, not an attack workflow. In the unsampled branch the business response completes and metrics increment while trace records remain0. The control separates outcomes from recording decisions without fabricating another success or failure event.

WEB-21.03 · Red · Logs, metrics, and traces ↗
More collected data is not always better

Copying bodies, Authorization, session identifiers, or private attributes wholesale into logs can expose secrets and personal data. The fixture seeds only fake demo-token-alias and demo-session-alias values. Its output allowlist retains event, operation, and correlationAlias without mutating the source dictionary. This is not discovery of real secrets or a detector for every nested log format; independent reading checks only that known fixture fields do not reach the sink.

WEB-21.03 · Red · Logs, metrics, and traces ↗
Define what each signal counts and carries

Define log purpose, safe output fields, and correlation aliases rather than raw secrets or entire upstream objects. Record counter-reset scope and operation/status dimensions. Histogram or duration interpretation needs units, a window, and a source clock; authored logical ticks are not milliseconds or a benchmark. Show shared traceAlias and an exact parentAlias relationship for root/child spans. Equal names alone do not establish parent context.

WEB-21.03 · Blue · Logs, metrics, and traces ↗
Show visibility gaps beside business outcomes

Use separate branches for export errors, unsampled traces, and missing observations. A local successful public read can survive exporter failure while the signal store remains incomplete; record a diagnostic gap rather than health success. The unsampled branch has a declared explanation for trace0, whereas a missing observation may lack that verified explanation. Best-effort policy here concerns operational public reads; security-sensitive audit retention and access policy need separate design.

WEB-21.03 · Blue · Logs, metrics, and traces ↗
normal/schema

Own public output schema only; seeded fake aliases redacted.

WEB-21.03 · Logs, metrics, and traces ↗
window/spans

Finite counters and authored logical parent intervals have different scopes.

WEB-21.03 · Logs, metrics, and traces ↗
unsampled/exportFailure/missing

Recording decisions, sink errors, and no evidence carry different knowledge.

WEB-21.03 · Logs, metrics, and traces ↗
selector/limits

No production capture, SDK/backend, real secret, or latency claim.

WEB-21.03 · Logs, metrics, and traces ↗
What do encryption, MACs and signatures establish?

Encryption aims to keep plaintext unreadable without an appropriate key; not every encryption mode independently supplies integrity or data-origin authentication. Authenticated encryption combines these objectives under a suitable profile. A MAC provides integrity and key-holder origin evidence to parties sharing a secret, but cannot distinguish which of several holders generated it. A digital signature is produced with a private key and verified with a public key; it provides no confidentiality and does not independently prove a person’s business identity. Atlas Notes separates signature verification for Tea & Bread from trusted key provenance and accepted purpose. A hash uses no key: if the expected digest is untrusted, a correct match alone does not establish trustworthy origin. The ledger compares these objectives without claiming to execute encryption, a MAC or a complete identity protocol.

WEB-21.S01 · Core · Data, secrets and cryptographic key lifecycle ↗
The decisions in a key lifecycle

A key lifecycle includes generation, controlled distribution/storage, active use, rotation, retirement and, where needed, recovery and destruction. The ledger selects key-new as active and key-old as verify-only. The selected application policy prohibits creating a new signature with the old private key, while its public key may verify an accepted archived title within a selected verification period. Profile acceptance stops at now=verifyUntil even though the signature can remain mathematically valid. Rotation selects a new key version; it neither automatically reencrypts old ciphertext nor destroys every copy of a key. Destroying an encryption key too early can prevent a required restore. Archived verification with a signing key raises a different retention question. The native check observes only ordinary title signing/verification and local lifecycle gates with own ephemeral Ed25519 KeyObjects, not KMS, HSM, certificate-chain or secure-zeroization behavior.

WEB-21.S01 · Core · Data, secrets and cryptographic key lifecycle ↗
Secrecy does not survive delivery to a browser

A server credential, a signing private key and browser-visible public configuration belong to different classifications. Server secrets should not enter a source repository, build log, generated bundle or source map. A value substituted into browser JavaScript at build time becomes data delivered to the client; calling it an environment variable does not preserve secrecy. Obfuscation is not trusted secret storage either. A public endpoint name, public verification key or color setting need not be a secret; classification depends on its intended use rather than its appearance. The artifact contains only aliases and booleans, never actual secret values. Its source/build/browser ledger requires delivered=false for server-secret. Secret access is limited to the server workload’s minimum needs and an appropriate lifetime. Access to a secret manager does not permit forwarding that secret to every client.

WEB-21.S01 · Core · Data, secrets and cryptographic key lifecycle ↗
The data lifecycle continues in every copy

A data lifecycle begins with collection and purpose, then covers processing, storage, sharing, retention and deletion. Although Tea & Bread is a public teaching note, the same ledger makes copy purposes explicit: primary storage, cache, logs and backups are not interchangeable. A visible delete marker does not prove that every copy has disappeared. In particular, absent backup-deletion evidence stays unknown instead of becoming a claim of complete erasure. Retention follows real product needs and applicable obligations; the example’s 30-tick value is not a legal rule. W3C minimization and purpose principles reduce unnecessary data transfer, while OWASP’s log-disposal guidance includes log copies and retention bounds. Neither source proves that this note was actually deleted. The copy ledger is our own declared example.

WEB-21.S01 · Core · Data, secrets and cryptographic key lifecycle ↗
Mistaking primitive success for trust

The assumption under review is that a valid signature makes its key and purpose acceptable. An incorrect result requires the caller to skip key provenance, use/state or verification-window gates. A verify-only old public key validating ordinary archived data is not itself a problem; it is intended behavior within the selected policy. In the retired-key branch cryptoVerifiedDeclared can remain true while application acceptance is false. A mathematical operation and a resource-delivery decision therefore retain separate evidence. This perspective does not treat that row as key forgery or credential theft. The unknown-key branch has null cryptographic evidence, so an unperformed verification is not mislabeled an invalid signature. There is also no actual issuer or certificate evidence for binding business identity; reasoning uses only supplied aliases and an ordinary policy.

WEB-21.S01 · Red · Data, secrets and cryptographic key lifecycle ↗
Copy visibility and deletion claims

The second assumption is that removing a secret line from source, or marking a primary record deleted, ends the lifecycle. That claim depends on the scope of copies in build outputs, logs, caches and backups; one UI observation is insufficient. No secret is searched for or read in this lesson. The classification ledger closes browser delivery for server-only data while allowing the public title. The data-copy table does not turn unknown backup evidence into true merely because the primary copy is marked deleted. Different copy purposes and retention periods are not automatically errors, but storage or sharing outside a documented scope needs a separate control. Ask which evidence exists for each copy. Because no repository history, browser bundle or key store was examined, these fixtures establish neither actual exposure nor complete deletion.

WEB-21.S01 · Red · Data, secrets and cryptographic key lifecycle ↗
Purpose, state and copy inventory together

The defensive key inventory separates alias, algorithm, purpose, active/verify-only/retired state, originator-use period and recipient verification/decryption needs. A rotation profile documents which key creates new material, how long archived data can be verified and how acceptance closes after compromise. Sensitive-data classification remains distinct: an explicit delivery gate separates a server-only secret from a public note. Access-controlled audit records key metadata rather than key material. Where recovery is required, preserve the relationship between encrypted data and necessary key versions; do not assume successful destruction or recovery without evidence. These old/new aliases are not files or endpoints of an actual key manager. Native keypair generation certifies neither a validated cryptographic module nor an organizational rotation program.

WEB-21.S01 · Blue · Data, secrets and cryptographic key lifecycle ↗
Test denial and unknown evidence

The positive fixture checks accepted verification and public-title delivery. Retired-key, server-only and unknown-key rows must jointly produce delivered=false, write=false and body=null. The primitive test signs and verifies only ordinary Tea & Bread bytes with own generated Ed25519 keypairs; it serializes no token, certificate or credential. A verify-only policy blocks new signing with the old key while separately observing that its ordinary archived signature remains mathematically verifiable. Dropping KeyObject references does not guarantee secure zeroization in JavaScript memory, and no such claim is recorded. The data-deletion check keeps an unknown backup unknown in the all-copy conjunction. These are concrete, rerunnable local checks; actual KMS rotation, browser secrecy, storage restore or backup erasure require separate integration evidence.

WEB-21.S01 · Blue · Data, secrets and cryptographic key lifecycle ↗
cryptoPurpose

Different crypto objectives; not universal identity proof.

WEB-21.S01 · Data, secrets and cryptographic key lifecycle ↗
rows

Supplied lifecycle/classification gates and protected-title delivery result.

WEB-21.S01 · Data, secrets and cryptographic key lifecycle ↗
classificationLedger

Aliases only; no server-only value is included anywhere.

WEB-21.S01 · Data, secrets and cryptographic key lifecycle ↗
dataCopies

Copy-specific deletion evidence; null means unknown.

WEB-21.S01 · Data, secrets and cryptographic key lifecycle ↗
Environment configuration is also a release input

The same artifact can create different exposure under different runtime configuration. Document debug output, admin-access policy, accepted-host profile, secret injection and storage connections per environment. Atlas Notes selects a release-review profile requiring debug=false, owner-only admin policy and configured host rules. These are this fixture’s policy values. Django 5.2’s deployment checklist explains disabling production DEBUG, but this lesson runs no Django and does not claim that one flag secures a system. An obscure admin URL does not replace authentication/authorization; network isolation and application permission are different layers. Configuration review is separate from the build hash: correct bytes can still run with inappropriate exposure. No deployment happens here; the profile only selects candidates for an approved local review list.

WEB-21.S02 · Core · Dependencies, CI/CD integrity and safe deployment ↗
Dependencies extend beyond direct packages

A dependency inventory includes direct and transitive packages, build tooling and pipeline integrations/actions. A lockfile stabilizes selected resolution and integrity metadata; it does not certify every package as trustworthy or free of vulnerabilities. Consider pinning alongside acquisition provenance and maintained-version review. Third-party JavaScript running in a browser document’s context can also change data-access boundaries; CDN hosting does not make it isolated. SRI compares particular resource bytes against expected hashes. It proves neither the trustworthiness of the HTML selecting those hashes nor the business safety of the code. Cross-origin SRI depends on the browser’s CORS requirements. The artifact’s dep-A is only a synthetic inventory alias, not a registry package or installed dependency. No new package, action or remote script is fetched.

WEB-21.S02 · Core · Dependencies, CI/CD integrity and safe deployment ↗
Hashes and provenance answer complementary questions

Comparing an artifact’s SHA-256 is useful for byte equality; the trusted manifest supplying the expected digest is a separate question. Provenance connects an artifact to source revision, builder and build profile. SLSA v1.2 verification guidance distinguishes trusted builders/roots, provenance signatures and expected build types/parameters. This ledger is not a complete SLSA attestation: signature validation and builder trust are declared inputs only. The fixed public text’s digest is actually calculated locally. With missing provenance, even a correct digest leaves builder evidence unknown and closes review delivery. Build provenance does not replace code review or deployment authorization. If artifact and metadata come from the same untrusted source, their agreement creates no new trust. Record hash results and the approval gate’s reason separately.

WEB-21.S02 · Core · Dependencies, CI/CD integrity and safe deployment ↗
Which evidence supports promotion and rollback?

A safe deployment design aims to promote a reviewed artifact with the same identity/digest rather than rebuilding it, validate environment configuration and release permission, and define health and rollback conditions in advance. A tag resolving to different bytes or a rollback incompatible with a data migration raises separate concerns; possession of an old artifact does not guarantee recovery. Here source-rev-A and builder-A are descriptive aliases, not actual Git commits or runners. The scene follows source → builder → review gate → local candidate list. Its terminal state is eligible-for-review, never published or deployed. Even with declared review permission, actualDeployment remains false. This boundary states what actually completed: a finite gate was evaluated; infrastructure, a public endpoint and rollout were not verified.

WEB-21.S02 · Core · Dependencies, CI/CD integrity and safe deployment ↗
Mistaking a green build for a trusted release

The assumption is that a successful build or matching digest also settles provenance, configuration and release approval. Conflating those gates can give unreviewed source, a different builder or debug-on configuration the same promotion result. The hash-different row contains another harmless public title; it is no attack payload or package-substitution attempt. The gate only determines that expected bytes differ. In the provenance-missing row the bytes match but builder evidence is absent; labeling that a failed hash would also be wrong. Ask whether every gate is bound to its intended input. Passing a test grants neither deployment privileges to a builder nor permission to expose administration. No actual runner, registry or production configuration was examined, so these rows claim neither a supply-chain compromise nor successful safe deployment.

WEB-21.S02 · Red · Dependencies, CI/CD integrity and safe deployment ↗
The scope of dependency and browser trust

The second assumption treats a pinned dependency or SRI hash as proof that third-party code is harmless. Those controls concern selected resolution or expected bytes; data use, transitive behavior and publisher provenance still need review. A runtime script executing in a document’s context does not become origin-isolated simply because its network host differs. Integrity success does not change secret classification either. This lesson scans no source map, bundle or package contents; inventory fields are supplied teaching data. Relate dependency, revision, permission and build input questions to the same candidate. Missing review evidence remains unknown and closes review delivery. Package installation, remote script invocation or exploitation workflows against a vendor or organization are outside the example.

WEB-21.S02 · Red · Dependencies, CI/CD integrity and safe deployment ↗
Keep candidate identity stable across gates

The defensive pipeline binds source revision, dependency-resolution profile, trusted builder evidence, artifact digest and target configuration to the same candidate ID. Approval applies to the reviewed artifact rather than only a branch name or mutable tag. Give the builder minimal identity privileges and require separate authority at the release gate. The candidate list here accepts only local review delivery; it has no publication permission. Debug and admin-policy checks remain independent from the hash check. Review dependency changes like contracts, documenting direct/transitive scope and runtime browser-script access. If using SRI, protect the expected hash’s provenance and cross-origin CORS compatibility separately. Applying these profiles to an actual platform requires integration evidence for signed provenance and trusted roots; those fields are declarative here.

WEB-21.S02 · Blue · Dependencies, CI/CD integrity and safe deployment ↗
A negative gate must send no candidate

The native check only calculates SHA-256 for fixed Atlas Notes texts and evaluates the supplied gate conjunction. Hash-different, debug-on and missing-provenance rows require expectedReviewDelivery=false, write=false and approvedBody=null. Absent provenance is not hidden as a known false assertion; unknown evidence has its own field. The last actor in the normal branch receives a candidate for approved local review. No deployment, DNS change, public distribution or CI workflow is triggered. Debug flags and admin policy are configuration declarations in this model, not settings actually applied to a server. A fixture rejecting inappropriate configuration even for a matching digest separates two distinct questions. Local evidence covers artifact equality and finite policy. Actual supply-chain acquisition, browser SRI enforcement, reproducible builds and rollback health need separate execution.

WEB-21.S02 · Blue · Dependencies, CI/CD integrity and safe deployment ↗
rows

Local review gate: hash, declared provenance and configuration are distinct conditions.

WEB-21.S02 · Dependencies, CI/CD integrity and safe deployment ↗
dependencyInventory

Synthetic alias; not installed-package inventory or registry evidence.

WEB-21.S02 · Dependencies, CI/CD integrity and safe deployment ↗
browserBoundary

SRI integrity scope is neither code safety nor an actual browser result.

WEB-21.S02 · Dependencies, CI/CD integrity and safe deployment ↗
promotionBoundary

Review delivery is not publication or deployment.

WEB-21.S02 · Dependencies, CI/CD integrity and safe deployment ↗
Quotas and permission do not substitute for each other

Resource policies include separate bounds for request size, concurrency, work budget, deadlines and queues. A rate limit restricts frequency over a time window; it does not by itself bound one expensive operation’s memory use or fan-out. Atlas Notes selects maxConcurrent=2, maxBytes=64 and deadlineTick=10 for a public-title read. These are finite teaching values, not measured production capacity. PermissionKnown and permissionAllowed remain separate from quota admission. A permitted actor cannot start a read when quota is full, and spare capacity cannot open unknown permission. Cheap size/shape checks before expensive work provide a useful boundary, not proof of OS/container isolation. The scene dispatches nothing to the store before completing its gate. Success is a read-only title projection; no write operation or store mutation is modeled.

WEB-21.S03 · Core · Resource limits, errors and fail-open boundaries ↗
Deadlines, cancellation and partial failure

A deadline can mean that a caller stops waiting; it does not prove that downstream work stopped or that a side effect was undone. Checking the deadline before admission keeps this model’s expired branch from reaching the store. Losing a response after a write was dispatched is different: its result may be unknown, and a blind retry can repeat the action. The artifact keeps that general partial-failure situation in a separate ledger, without adding false certainty about prior writes to this lesson’s read-only negative cases. Cancellation propagation, transactional commits and idempotency scope need actual system integrations. A local quota reservation is released after either a normal result or an exception. That finally behavior is testable for a local counter; process crashes, distributed leases and autoscaling under load are not verified here.

WEB-21.S03 · Core · Resource limits, errors and fail-open boundaries ↗
Error format and the scope of evidence

Error handling gives clients a meaningful status and limited explanation while retaining access-controlled diagnostics on the server. Stack dumps, secrets and internal paths do not enter the client body. RFC9457 supplies bounded problem descriptions for troubleshooting and replaces RFC7807. This ledger uses typed decision codes, not actual HTTP responses. A 429 describes rate limiting, and Retry-After is optional; neither every concurrency rejection being 429 nor a future retry necessarily succeeding follows from that. Unknown permission, known denial, deadline and full quota remain different internal reasons. A simple client message does not require telemetry to collapse every outcome into one error. Track dispatched actions, resource delivery and available commit evidence separately.

WEB-21.S03 · Core · Resource limits, errors and fail-open boundaries ↗
The permission boundary of graceful degradation

Keeping part of a system available when a dependency fails can be useful. Turning an unreachable permission service into allow is a different decision. A fail-closed gate withholds the protected action; public help or an offline reference may be offered under another policy. That alternative action is not silently substituted for the original protected body. The missing-permission row retains evidence=null and allow=false. A cached decision requires an explicit actor/object/action scope, freshness and revocation profile; unlimited reuse of an old allow is not graceful degradation. Error boundaries do not convert every exception into uncontrolled success. A resource limit adds an independent admission layer above permission. This finite predicate guarantees neither actual fault tolerance, network availability nor resource isolation.

WEB-21.S03 · Core · Resource limits, errors and fail-open boundaries ↗
Assuming an error proves nothing happened

The assumption is that a caller error proves every downstream action did not happen. That conclusion requires evidence about dispatch and commit boundaries. Our full-quota and deadline branches close before dispatch, so an untouched store follows from their concrete state order. The separate general partial-failure ledger instead records “write dispatched, response lost, commit evidence unknown” and leaves the write outcome null. This is no actual write experiment or timeout reproduction. Ask where evidence was lost and which action the retry policy applies to. A client error does not also prove server rollback, cancellation reaching every worker or complete audit. Those independent claims need integration or transaction evidence; a green ordinary-read fixture cannot replace it.

WEB-21.S03 · Red · Resource limits, errors and fail-open boundaries ↗
Jumping from an unknown dependency to allow

The second assumption treats opening an action after an unavailable resource or permission dependency as only an availability choice. For a protected action, converting unknown into allow also changes authorization. The risk requires a fallback to deliver protected data without necessary actor/object/action evidence. The model keeps missing permission null and closes with no dispatch and no body. Known denial retains false evidence separately; matching safe outcomes do not make those evidence states identical. A full quota does not prove the actor lacks permission, only that the selected budget is exceeded. Review necessary conditions without merging these reasons. This example performs no stress traffic, allocation bomb, endpoint fault injection or fail-open bypass.

WEB-21.S03 · Red · Resource limits, errors and fail-open boundaries ↗
Ownership of admission and cleanup

The defensive profile applies request-size, permission-evidence, concurrency and deadline gates before an expensive resource action. It reserves a counter only for accepted work and releases it in finally after the selected local operation. In a distributed system the counter’s node/tenant scope, atomicity and crash recovery are separate design questions; comparing two integers does not solve them. A failed permission dependency leaves the protected title withheld. Any limited public fallback is explicit under a different operation ID and policy. Prepare server diagnostic reasons and safe client messages as separate projections; expose no plaintext secret, stack or internal filesystem path. An HTTP adapter chooses statuses appropriate to its profile. The lesson’s typed code is not a universal Event ID or HTTP code for every platform.

WEB-21.S03 · Blue · Resource limits, errors and fail-open boundaries ↗
Preserve no-dispatch and unknown-commit evidence

The independent fixture checks a successful title read and requires dispatch=0, delivery=0, write=false and body=null for full quota, missing permission and deadline expiry. A native counter test observes finally cleanup for one success and one fixed benign exception; it performs no allocation flood or real scheduler test. Unchanged data copies and request context are separate assertions. The partial-failure table never turns unknown commit into known false, particularly where retrying a mutation needs idempotency and transaction evidence. Safe error formatting limits client detail while retaining the internal reason. This scoped evidence makes the resource-protection design readable without claiming to verify real concurrency, cancellation, circuit breakers or overload capacity. Those belong to separate bounded integration tests.

WEB-21.S03 · Blue · Resource limits, errors and fail-open boundaries ↗
rows

Finite admission predicate; negatives have no dispatch/delivery/write.

WEB-21.S03 · Resource limits, errors and fail-open boundaries ↗
partialFailureLedger

After dispatch, commit can be unknown; no actual write is performed.

WEB-21.S03 · Resource limits, errors and fail-open boundaries ↗
errorProfile

Safe client projection; includes no sensitive internal details.

WEB-21.S03 · Resource limits, errors and fail-open boundaries ↗
unknownEvidence

Missing permission evidence differs from known denial.

WEB-21.S03 · Resource limits, errors and fail-open boundaries ↗
HTTP records and business decisions

A Tea note HTTP access record describes the server observing a request and its response status. Business audit describes actor Duru, action rename-note, object tea, tenant Atlas, decision deny and reason owner-policy. These events serve different purposes. A public explanatory response can be 200 while rename-note remains denied; the status alone is not a business commit receipt. An event generated near the application’s policy decision has different evidential authority from an actor label inferred from an external request header.

WEB-21.S04 · Core · Audit evidence, detection and incident scope ↗
Baselines, missing evidence and incident bounds

The finite detector searches for deny plus committed=true within a tenant, operationAlias and object tuple. Normal deny/committed=false yields zero and a deliberately synthetic contradiction yields one. This fixture does not establish a real policy violation; it identifies inconsistent records requiring review. If tenant Nova reuses req-demo, its record is not joined to Atlas. A missing commit record is not defaulted to committed=false: the result is unknown. Expected denial, contradictory evidence and missing evidence remain distinct outcomes. When a tuple contains several records, all are evaluated; ordering or an identical event repeat cannot change the outcome. Conflicting completed decisions remain ambiguous and missing fields unknown; neither is an automatic incident judgment.

WEB-21.S04 · Core · Audit evidence, detection and incident scope ↗
When correlation is mistaken for authority

Normal logging makes an application decision understandable later. Its trust assumption binds an event to the correct source, identity context and operation. Reused request labels or a missing tenant can make unrelated work appear to be one chain. The impact may be incorrect attribution or an unnecessarily broad incident scope; matching a label never proves a user’s authority over an object. Composite correlation, source context and unknown handling for missing fields block that mistaken inference. The branch is tested with fixed Atlas/Nova rows and generates no live requests.

WEB-21.S04 · Red · Audit evidence, detection and incident scope ↗
Logs are also data requiring protection

Copying an entire request into logs can include session values, tokens, personal information or note bodies alongside the few fields needed for correlation. The ordinary purpose is to explain an action’s result; that broad copy is unnecessary for this purpose. An allowlist and minimization provide the control. The source fixture contains fake Authorization, a fake sessionIdentifier and ordinary noteText, but audit output contains none of them. Review access is limited to needed event fields; using hashes or aliases does not automatically remove linkability risk.

WEB-21.S04 · Red · Audit evidence, detection and incident scope ↗
Selector results and evidence sufficiency

The detector schema requires eventId, tenant, operationAlias, object, decision and committed. The comparator inspects every business row in the same tuple rather than stopping at the first match. An identical repeated eventId with identical fields counts as one piece of evidence. Any unique deny/true row yields review-required. Differing completed outcomes in the tuple, or differing fields under the same eventId, also retain an ambiguity flag; without explicit deny/true the result is ambiguous. Missing commitment remains unknown. This finite Python comparison proves neither a real policy violation nor SIEM deployment. XPath separately selects deny/true business rows within one XML document: negative yields zero, positive one, and missing data zero; the last result is not a healthy baseline.

WEB-21.S04 · Blue · Audit evidence, detection and incident scope ↗
Bounding incident and recovery decisions

A review note first states the observation: the selected decision and commit records disagree for Atlas/op-demo/tea. It then adds confidence and provenance: fixed fixture, supplied producer context and clock uncertainty. Bound impact to that evidence; neither all tenants being affected nor Duru being malicious follows. NIST incident guidance emphasizes analysis, magnitude assessment and evidence provenance. This example neither blocks users automatically nor starts recovery operations; it presents the known and unknown fields to the decision owner.

WEB-21.S04 · Blue · Audit evidence, detection and incident scope ↗
ledger

Fixed source-context fields, not live logs.

WEB-21.S04 · Audit evidence, detection and incident scope ↗
correlationKeys

Tenant/operation/object relationship, not a credential.

WEB-21.S04 · Audit evidence, detection and incident scope ↗
excludedSeed

Fake sensitive fields are not copied to output.

WEB-21.S04 · Audit evidence, detection and incident scope ↗
scope/recovery

Known scope and a new checkpoint; no production restoration.

WEB-21.S04 · Audit evidence, detection and incident scope ↗
selector

Denial/commit disagreement within one XML document; missing is unknown.

WEB-21.S04 · Audit evidence, detection and incident scope ↗
Address components belong to different decisions

Consider https://public.example.invalid/notes/tea?view=compact#details. Scheme, hostname, port, path, query, and fragment are not one server instruction. A URL parser separates a record; the default HTTPS port can disappear from canonical serialization. /notes/tea?view=compact contributes to the HTTP target, while #details remains client-side selection. This capstone examines the record using a URL API from the same standards family without pretending to run an address bar, history, or document navigation.

WEB-22.01 · Core · From URL to a secure connection ↗
Separate transport selection from the trusted peer

An HTTPS request does not require a fresh TCP handshake every time. A suitable existing connection may be reused, and a cache or service worker may answer earlier. New HTTP/1.1 or HTTP/2 connections separate TCP from TLS. HTTP/3 uses QUIC; QUIC v1 combines transport and TLS cryptographic handshakes rather than adding a TCP handshake. Protocol selection, pooling, and resumption depend on implementation policy. One animation cannot impose a universal browser timeline.

WEB-22.01 · Core · From URL to a secure connection ↗
A resolved address is not a trusted service

The normal purpose is to reach the origin selected by the URL. The required trust relationship is validation for the intended service identity. Substituting a DNS answer or reachable transport for that relationship risks sending application data to an unintended peer. The broken assumption is that address discovery authenticates an endpoint. An ordinary other.example.invalid alias produces nameMatch=false here, without connecting to a real server or bypassing validation.

WEB-22.01 · Red · From URL to a secure connection ↗
Do not invent completion of an absent stage

The no-address branch has no usable answer for this fixture. It does not invent a real NXDOMAIN, timeout, or offline diagnosis; only missing observed address information exists. Route and TLS owners remain untouched. Rendering this as HTTP500 or application404 invents a server result before the request reaches a server. Connection failure and application responses carry different evidence.

WEB-22.01 · Red · From URL to a secure connection ↗
Track dependencies of a request plan

Keep raw input, parsed origin/target, reference hostname, address source, and transport mode separate. Show fragment exclusion using parser output. Compare an explicit :443 or an ordinary query value change to see exactly which record component changes. This check covers a URL API; it establishes neither document navigation policy nor certificate verification.

WEB-22.01 · Blue · From URL to a secure connection ↗
Record failure reasons and trust boundaries

The peer-failed example keeps trustPath=true beside nameMatch=false; an apparently acceptable chain cannot erase a name mismatch. In no-address, the peer check is not evaluated rather than failed. A reused context explains freshHandshake=false together with selectedSuitable=true. These outcomes need not share one retry or error category; the native predicate decides only over supplied ASCII names and booleans.

WEB-22.01 · Blue · From URL to a secure connection ↗
parsed

Origin, path, query, and client fragment examined with an actual URL API.

WEB-22.01 · From URL to a secure connection ↗
normal

Selected supplied dependency outcomes, not application authority.

WEB-22.01 · From URL to a secure connection ↗
peerFailed

Trust/path and name matching are separate predicates.

WEB-22.01 · From URL to a secure connection ↗
reuse

A suitable supplied context without a fresh handshake.

WEB-22.01 · From URL to a secure connection ↗
An HTTP request is not shared knowledge across boxes

Follow the prepared GET /notes/tea?view=compact plan from WEB-22.01. This selected read is public, has no body, and excludes #details from the server target. A request line and Host field form a readable HTTP/1.1 projection; HTTP/2 and HTTP/3 carry the same semantics using different frames and fields. A prepared client plan does not mean the edge has seen it. The first arrival changes edge knowledge only.

WEB-22.02 · Core · From HTTP to a handler ↗
The runtime hands a received request to application decisions

Node http.Server exposes request information such as IncomingMessage method, url, and headers; it does not automatically create a router or permission policy. The runtime represents request bytes at its parser/API boundary, while application routing maps method/path to an operation. /notes/tea and view=compact are separate path/query components. The selected route carries a public note identifier and presentation choice; an upstream header alone does not verify a principal.

WEB-22.02 · Core · From HTTP to a handler ↗
Edge acceptance is not object permission

The normal purpose is to carry a public request to a suitable upstream. The necessary control is a decision by the correct policy owner for that request purpose and application operation. Treating WAF allow as an authenticated principal or note-level authorization shifts a trust boundary. Every successful representation here is explicitly public; edge caching is not claimed to authorize private object access. Private policy stays with WEB-15 and the next capstone.

WEB-22.02 · Red · From HTTP to a handler ↗
Do not invent handler evidence before handoff

A cache hit has zero service reads. Adding a runtime log or database read anyway invents an event in the observation chain. Maintenance closure also stops at the edge; its selected403 is not the same evidence as an application authorization denial. An ordinary missing route reaches the runtime but does not call the service. Status alone cannot distinguish these branches for detection or debugging.

WEB-22.02 · Red · From HTTP to a handler ↗
Verify the operation chain through receiver knowledge

Carry method, target, and public purpose from the client plan to edge knowledge only on arrival. Record edge policy, cache source, selected application, and runtime route matching separately. A diagnostic correlation alias is not a credential; select output-safe operation fields instead of raw headers or session values. The ordinary baseline uses the same public note and bounded compact query, not arbitrary target or route discovery.

WEB-22.02 · Blue · From HTTP to a handler ↗
Zero calls differ from missing observations

An explicitly observed serviceCalls0 identifies a no-handler branch. Absence of a log record does not support the same conclusion. Preserve result source for selected403, cached200, and route404; WEB-21.02 supplies the related no-ready upstream case. Availability, edge policy, and application semantics then avoid one generic failure box. Unchanged application state is verified only for this selected ordinary read fixture.

WEB-22.02 · Blue · From HTTP to a handler ↗
request

H1 semantics projection, not an actual capture.

WEB-22.02 · From HTTP to a handler ↗
origin.callOrder

Observed ordinary control order in an owned adapter.

WEB-22.02 · From HTTP to a handler ↗
cacheHit

Public stored representation and selected freshness predicate.

WEB-22.02 · From HTTP to a handler ↗
closed / routeMiss

Edge policy and runtime routing have different failure owners.

WEB-22.02 · From HTTP to a handler ↗
Knowing a principal differs from permitting an operation

We reached the application boundary behind the public read. Duru now renames an owned synthetic reading note from Local draft to Tea note. The request context is assumed to have already arrived. sid-demo is an inert session alias: a store lookup, declared active flag, and supplied logical expiry yield principal Duru. The native example runs no login, cookie parsing, or cryptographic session verification; its question is how a recognized context remains bounded by later decisions.

WEB-22.03 · Core · From identity to persistence and jobs ↗
Connect commit, cache invalidation, and job acknowledgement

A cached Local draft at revision1 does not prove the database still has that state. A cache is derived state with an explicit version and invalidation owner. The normal fixture runs a parameterized UPDATE and outbox INSERT in one SQLite transaction. An independent reader sees Local draft/rev1 and outbox0 before COMMIT, then Tea note/rev2 and event1 afterward. This orderly local observation proves a selected atomic boundary without testing every crash, storage, or replication condition.

WEB-22.03 · Core · From identity to persistence and jobs ↗
Do not derive unlimited write rights from a session

The normal behavior is a recognized principal transitioning an owned note. Its trust relationship joins principal, object owner, and operation policy. Omitting the owner check merely because session lookup succeeded risks an unauthorized mutation of another synthetic object. The model uses an ordinary denied context, with no real object selection, endpoint probing, or permission-bypass instructions. Its scope is the selected owner policy, not every authorization model.

WEB-22.03 · Red · From identity to persistence and jobs ↗
Delivery and derived caches are not business commit

A prepared write, COMMIT, outbox publication, and worker acknowledgement are different facts. A selected rollback must leave both title and outbox at their prior state; pretending a notification was still published creates incorrect downstream knowledge. The normal branch invalidates cache after commit. A process stopping between these steps may leave stale cache, requiring a separate recovery/version policy. The finite orderly fixture measures no crash and claims no permanent freshness.

WEB-22.03 · Red · From identity to persistence and jobs ↗
Evidence from principal to authoritative version

An intent ledger joins operation, synthetic object id, principal decision, owner-policy result, and expected/actual revision. Expired authentication, denied authorization, failed business validation, and store rollback need separate reasons. Use safe synthetic fields rather than wholesale session tokens or user bodies. The ordinary baseline is owner Duru, existing rev1, and a Tea note title; no real credential or student data is present.

WEB-22.03 · Blue · From identity to persistence and jobs ↗
Keep outbox and consumer outcomes distinct

Committed outbox intent, relay delivery attempts, a processed effect marker, and selected queue acknowledgement have different meanings. Two deliveries with one projection effect can be an ordinary retry rather than an automatic security incident. Relate parent-note and event versions, and identify the operation/consumer owning dedupe scope. Job delay does not invalidate a note commit; downstream freshness needs separate observation.

WEB-22.03 · Blue · From identity to persistence and jobs ↗
session / policy

Inert alias validity and selected object/action relationship are separate.

WEB-22.03 · From identity to persistence and jobs ↗
query

Prepared shape and ordinary bound title/id/revision data.

WEB-22.03 · From identity to persistence and jobs ↗
normal

Pending writer, independent committed view, and derived cache.

WEB-22.03 · From identity to persistence and jobs ↗
event / redelivery

Outbox intent, effect-specific dedupe, and separate acknowledgement.

WEB-22.03 · From identity to persistence and jobs ↗
When a response reaches its next owner

WEB-22.01 followed URL and peer selection, WEB-22.02 the edge-to-service path, and WEB-22.03 the session, policy and commit boundary. Here public HTML prepared by the server reaches the browser. The same bytes now belong to a different component: the parser processes markup, application script asks for data, and rendering produces visible geometry. Preparing a result, receiving its response and seeing the current title are three distinct completion points. For Tea note, keep those points separate rather than collapsing them into one green success box.

WEB-22.04 · Core · From response to pixels and the trust map ↗
The API response and complete trust map

The module’s GET /api/public/notes/tea plan is a separate request from HTML navigation. A 200 JSON response does not guarantee a contract-compatible title: the body is consumed, JSON parsed and title checked as a string. In the ordinary schema-drift branch title is 7, Loading remains and the application reports a data error. A Fetch promise resolving with a response is distinct from HTTP success, body consumption and application validation. In the no-JS branch the shell is parsed but no API plan exists; service readiness cannot complete that dependency.

WEB-22.04 · Core · From response to pixels and the trust map ↗
From response correctness to the visible result

The normal branch uses contract-compatible application data as a title in its document context. Its trust assumption is that server content is interpreted with the intended schema and purpose. If that assumption fails, valid JSON and a 200 can coexist with an incorrect or stale heading. The numeric title fixture is an ordinary type mismatch, not an attack input: it shows that visible results are independent of transport status. The API contract and consuming validator own the control. Visible text requires a DOM data API or suitable text serialization; HTML, JavaScript and CSS are different interpreter contexts.

WEB-22.04 · Red · From response to pixels and the trust map ↗
What authority does vendor code receive?

A public stylesheet, API data and executable module are different risk objects. For executable third-party code accepted in the host document, a trust decision cannot rest only on the network destination name. The vendor, version, document context and granted runtime access matter. The relevant condition is actual loading and execution; a vendor name in a plan does not prove execution occurred. A working public title while the optional dependency is disabled establishes only this fixture’s dependency boundary.

WEB-22.04 · Red · From response to pixels and the trust map ↗
Separate evidence for bytes, DOM and pixels

In the Tea note chain the Network response body is one observation, the live Elements DOM a second, and rendering or a screenshot a third. Record the request target, initiator, response status, media type, consumed title and selected revision together. Network can expose a response without automatically knowing the application validator’s outcome; a changed Elements heading is not a server commit receipt. The local parser actually reads the heading and asset references, but browser repair rules, the script event loop, CSSOM, layout and paint are outside its scope.

WEB-22.04 · Blue · From response to pixels and the trust map ↗
Validating the dependency branch

The no-JS baseline expects shell title Loading and zero API calls. Schema drift has an API response but a false string-title predicate. With the optional vendor disabled, the title is Tea note and no vendor request is planned. These are benign baselines, not automatic incidents. Comparisons use the same public note and selected schema. If a new revision, browser policy or user context is introduced, record that change; a previous observation does not establish correctness under new conditions.

WEB-22.04 · Blue · From response to pixels and the trust map ↗
shell

Public initial markup and asset references.

WEB-22.04 · From response to pixels and the trust map ↗
normal/schemaDrift/noJs

Selected consumer outcomes, not browser captures.

WEB-22.04 · From response to pixels and the trust map ↗
trustMap

Decision ownership and prior lesson links for data edges.

WEB-22.04 · From response to pixels and the trust map ↗
selector

Fixed schema-rejection ledger selector; missing data is unknown.

WEB-22.04 · From response to pixels and the trust map ↗
Authorized purpose and controlled comparison

This assessment concerns the contract of an owned public-title fixture: tea should display the title Tea note and the optional vendor plan should remain disabled. The scope manifest states which fixed inputs, purposes and local operations are authorized. It does not authorize discovering another application’s endpoints, collecting real user records or sending requests to new targets. Application mapping connects known data and decision owners: the HTML serializer, title consumer, fixture source and evidence reviewer. The URL-to-pixels lesson chain explains observation points without claiming they have all been measured.

WEB-22.S01 · Core · Evidence-led assessment and regression review ↗
Tool vantage points and outcome language

DevTools can observe requests, initiators and the live DOM in one browser context. An HTTP client observes response status/body without automatically executing the browser DOM or its cookie/policy behavior. An intercepting proxy can observe one position in an authorized connection; that position is not the authority for a server business commit and its configuration may affect observations. None of these tools is run in this fixture. A source line can describe intent, a runtime observation a selected execution result, and resource-owner evidence a persistence or policy decision. These evidence types cannot be substituted for one another.

WEB-22.S01 · Core · Evidence-led assessment and regression review ↗
A test boundary expanding silently

Normal review compares candidate behavior against an authorized contract. Its trust assumption is that scope and measurements describe the same work. Expanding one public-title observation into all authorization, tenant isolation or persistence behavior creates assurance unsupported by evidence. Record the observation point and unknown fields on every matrix row. If pixels are expected but only HTML source is checked, the test can read the selected heading while leaving the actual appearance unknown. Increasing the passing-test count cannot fill that evidence gap.

WEB-22.S01 · Red · Evidence-led assessment and regression review ↗
Evidence files and their meaning

A HAR, log export or response capture can help a review, but its potential secrets and personal data require a separate decision. This lesson has no real captures: it uses ordinary public HTML and booleans. The scope manifest defines necessary fields, review purpose and retention bounds. A report can relate a test result to a source snippet without abandoning evidence minimization. A hash checks candidate-content identity; it is not a credential establishing a trusted vendor, authorized user or correct business state.

WEB-22.S01 · Red · Evidence-led assessment and regression review ↗
A reproducible review package

The package includes the manifest, fixture bytes, selected contract, runtime version, observation list and candidate hashes. It records the heading actually read by the parser, not just pass. The finite comparator returns unknown for observed=None, pass for an observed expected value, and fail for another measured value. The title fails before, passes after and fails again when the old heading regresses. The optional vendor plan is observed false in all three candidates. Database revision and pixels have no observations, so passing totals do not absorb those unknown rows.

WEB-22.S01 · Blue · Evidence-led assessment and regression review ↗
Retest, regression and closure decisions

A retest returns to the same defect with the same seed and contract. Regression review also checks the optional dependency behavior and a branch reverting to the old title. Behavior outside these finite rows remains outside coverage. If context changes, record comparable=false instead of success. A failing check records candidate bytes, expected/observed values and the relevant owner. A successful fix retains the earlier failing artifact’s identity; a final green screenshot or test count alone cannot explain the defect or the change.

WEB-22.S01 · Blue · Evidence-led assessment and regression review ↗
manifest

Authorized purpose, seed, expectation and local operation bounds.

WEB-22.S01 · Evidence-led assessment and regression review ↗
candidates

Before/after/regression public HTML bytes.

WEB-22.S01 · Evidence-led assessment and regression review ↗
matrix

Measured pass/fail and unknown remain distinct.

WEB-22.S01 · Evidence-led assessment and regression review ↗
contextChanged

A changed seed is not the same controlled comparison.

WEB-22.S01 · Evidence-led assessment and regression review ↗
finding

Selected title root cause/impact; other layers unknown.

WEB-22.S01 · Evidence-led assessment and regression review ↗
selector

Finite failure selection; missing ledgers provide no assurance.

WEB-22.S01 · Evidence-led assessment and regression review ↗

Cookie and session

Compare the responsibilities of two mechanisms
DimensionCookieSession
State ownerBrowser cookie jarApplication and session store
Carried informationName/value pairs in a requestAuthoritative record referenced by an opaque handle
TerminationCookie expiry or removal from the browserServer expiry or revocation decision

Origin and site

Compare the responsibilities of two mechanisms
DimensionOriginSite
HTTP(S) boundaryScheme + hostname + effective portScheme + registrable domain
Port effectA different effective port can make a different originSchemeful site is not separated by port
InterpretationSame-origin is an input to access decisionsSame-site is an input to cookie policy

Response sharing and object permission

Compare the responsibilities of two mechanisms
DimensionCORSObject authorization
Decision ownerBrowser applying the CORS contractServer applying subject/action/object policy
QuestionMay script at this origin read the response?May this subject perform this action on this object?
Required evidenceFinal response CORS gate resultAuthoritative authorization decision