The Thirdwaveweb Blog

Deep dives into software, hardware, and the ideas reshaping how we build things.

Thirdwaveweb — Where Technology Meets Perspective

Thirdwaveweb — Where Technology Meets Perspective

Deep dives into software, hardware, and the ideas changing how we build things.

We write about the technical side of technology. Not just product launches and press releases, but the architecture decisions, the tradeoffs, and the engineering culture that shapes what actually gets built. There’s enough surface-level tech coverage out there. We go deeper.

Topics we cover: Software · Hardware · Developer Tools · AI & Machine Learning · Open Source · Security

The Caution Triangle Is Doing the Work: Reading ‘Not Friendly Do Not Touch’

Editorial note: this publication and Quirky Cotton Collective share an owner.

The design is a warning sign, and the first thing to notice is that it is a complete one. Across the chest, in the block lettering of a hazard placard, sit the words NOT FRIENDLY DO NOT TOUCH. Above or beside them — the layout reads as a single unit — is a yellow caution triangle. Inside the triangle, or paired with it, is a hand with a slash through it: the universal prohibition mark, the same one that tells you not to smoke, not to enter, not to feed the animals.

That is the whole graphic. There is no punchline underneath, no small-print reversal, no winking caption that lets the reader off the hook. The shirt is a sign, and the sign says what signs say: this surface is not for you.

What makes it worth reading closely is the grammar it borrows. A caution triangle is not a decorative shape. It is a standardized container for a specific kind of claim: hazard ahead, proceed with attention. The crossed-out hand is likewise standardized — it belongs to the family of prohibition pictograms that regulatory bodies and safety engineers have spent decades refining so that they can be understood without language, without context, and without the reader’s consent. When you print those two elements together and add the words NOT FRIENDLY DO NOT TOUCH, you are not making a joke about being introverted. You are filing a notice in a visual language that was designed to be obeyed.

That is the interesting move. Most boundary humor on apparel works by softening: a small font, a self-deprecating aside, a heart somewhere to signal that the hostility is affectionate. This design does the opposite. It takes the softest possible content — I would rather not be approached right now — and renders it in the hardest available form. The result is funny, but the humor is not in the message. The humor is in the mismatch between the register of the sign and the stakes of the claim. A caution triangle is for wet floors and high voltage. Here it is for a person who does not want to chat.

I keep thinking about that mismatch because it is the same one that shows up in technical work all the time. A status page that says DEGRADED PERFORMANCE in the same red banner it uses for a full outage. A runbook that labels a routine deploy as a CRITICAL CHANGE. A Slack channel where every alert is a P1 until nobody reads any of them. The caution triangle is a scarce resource. Use it for everything and it stops meaning anything; use it for nothing and you have no way to say stop when you need to.

The shirt, read as a piece of visual rhetoric, is a small argument about that scarcity. It says: this is what it looks like when a person decides that a boundary is worth the strongest available signal. Whether that is a good trade is left open. The design does not tell you whether the wearer is actually unfriendly, or whether the sign is a joke about being unfriendly, or whether the sign is a joke about signs. It just puts the triangle on the chest and lets you decide how seriously to take it.

There is a second thing the design gets right, and it is subtler. The crossed-out hand is a pictogram of a hand, not a photograph of one. It has no skin tone, no rings, no wrist. It is a shape. That abstraction is what lets the sign travel — the same mark works in an airport, a laboratory, a server room, a shirt. But it also means the sign cannot tell you whose hand is being refused. The prohibition is universal in form and entirely personal in application. The wearer is the one who decides what counts as touching, what counts as friendly, and when the sign comes off.

That is the part I find genuinely useful to sit with. A warning sign is a promise about future behavior: if you do this, that will happen. But the shirt does not specify the consequence. It does not say what happens if you touch. It does not say what happens if you are friendly. It just says no. In infrastructure terms, it is a policy without an enforcement mechanism — a route announcement with no route. The sign asserts a boundary; it does not describe what happens when the boundary is crossed. That gap is where the humor lives, and also where the honesty lives. Most of us do not have a consequence ready. We just have the sign.

I do not know whether the shirt is comfortable, how it fits, or how it wears over time. I have not put it on. What I can read is the artwork, and the artwork is a clean piece of visual argument: a standardized hazard container, a standardized prohibition mark, and a blunt sentence that refuses to soften either one. It is available as a standard t-shirt from Quirky Cotton Collective, and the listing title names the introvert framing directly. That framing is accurate to the design’s intent, but the design itself is broader than the label. It is not really about introversion. It is about the decision to make a boundary legible in public, using the most legible visual vocabulary we have.

The open question the design leaves on the table is the one it cannot answer: what happens when the sign is ignored? A caution triangle works because the hazard behind it is real and the consequence is known. A shirt is not a wet floor. It is a person, making a claim, in a format that was built for objects. The interesting thing about NOT FRIENDLY DO NOT TOUCH is not that it is funny — it is that it is a test of whether that borrowed authority still works when the hazard is a mood and the consequence is a conversation the wearer would rather not have. I do not think the design resolves that. I think it just puts the triangle on and waits to see.

The Dashed Circle at the Top of the Ramp: Reading the ‘I Had Potential’ Diagram

At the top left of the printed artwork, a dashed circle sits on a ledge. Below and to the right, a solid white ball rests on a flat ledge at the bottom of a curved descending ramp. Above both, in white capitals, the words I HAD POTENTIAL. That is the whole design. The dashed circle is the object that does the work, and it is worth being precise about why.

In physics notation, a dashed outline conventionally marks a position that is not occupied — a reference point, a former state, a body that has moved on. The solid ball is where the object actually is. The ramp between them is the path, and the word potential is doing double duty: gravitational potential energy on the way down, unrealized human potential in the past tense. The joke only lands because the diagram is drawn correctly enough to be read as a diagram. If the ramp were a straight diagonal, or if both circles were solid, the pun would collapse into a caption. The dashed circle is the entire argument.

This is a different kind of object than the usual slogan shirt. Most text-on-a-shirt humor asks you to read a sentence and agree with it. This one asks you to read a figure and complete it. The viewer supplies the missing step: the ball was once the dashed circle, the dashed circle is now empty, and the distance between them is the joke. That is a small piece of cognitive work, and it is why the design rewards a second look rather than a first glance. The i had potential shirt is listed under the Quirky Cotton Collective brand, and the artwork as observed is exactly what I have described: white capitals, a curved ramp, a dashed empty circle upper left, a solid ball lower right.

What interests me about the design is not the self-deprecation, which is familiar, but the specificity of the notation. A dashed circle is not a decorative choice. It is a convention borrowed from technical drawing, and using it correctly implies that whoever made the graphic understood what the convention means. The humor is not that the wearer gave up. The humor is that the wearer is the kind of person who would represent giving up as a labeled diagram. The joke is on the method as much as the outcome.

There is a version of this design that would be lazier: a stick figure at the top of a cliff, an arrow pointing down, the same three words. That version would be a meme. This version is a figure, and the difference matters because figures carry assumptions. A curved ramp implies a smooth descent, not a fall. A ball at rest implies the motion is over, not ongoing. The dashed circle implies a definite starting state, not a vague better past. Every element is doing a job, and the job is to make the punchline look like it came out of a problem set.

I do not think the shirt is making a claim about physics, and I would not read it as one. Gravitational potential energy is a real quantity with a real formula, and the design does not engage with the formula. It borrows the visual grammar of physics to make a joke about a career, a semester, or a decade. That borrowing is the point. The diagram is not evidence of anything except that the designer knew which conventions would read as technical and which would read as decorative. The dashed circle reads as technical. That is why it works.

The phrase itself is doing something similar. I had potential is past tense, which means the speaker has already decided the story is over. But the diagram shows the ball still sitting on the ledge, not rolling away. The two halves of the design disagree about whether the situation is finished. The text says it is. The figure says the ball is at rest and could, in principle, be picked up. That disagreement is the actual joke, and it is a better joke than either half would be alone. A shirt that only said I had potential would be maudlin. A shirt that only showed the diagram would be cryptic. Together they produce a small, dry piece of self-awareness that does not ask for sympathy.

For readers who spend their working lives around diagrams, this is the relevant quality. We are trained to read figures literally, to notice when a convention is used correctly, and to distrust graphics that use technical vocabulary as decoration. This design passes that test. The dashed circle is used the way a dashed circle is supposed to be used. The ramp is curved the way a ramp is supposed to be curved. The ball is solid because it is the object, not the reference. None of this is profound, but it is correct, and correctness in a joke graphic is rarer than it should be.

The shirt is not making an argument about engineering, security, or infrastructure, and I am not going to pretend it is. It is an off-duty object with a well-drawn figure on it. The reason it is worth a column is that the figure is legible to the people who would wear it, and legibility is not nothing. A diagram joke only works if the audience can read the diagram. This one can.

Editorial note: This publication and Quirky Cotton Collective share an owner.

The open question the design leaves on the table is not whether the ball will roll. It is whether the dashed circle was ever occupied at all, or whether the joke depends on the viewer assuming it was. The figure does not say. It only shows the empty outline and the resting ball, and lets the reader decide which one is the real subject.

Two Meanings of Rooting: Reading the Smiling Vegetables on ‘Let’s Root For Each Other’

Editorial note: This publication and Quirky Cotton Collective share an owner.

The design is a closed loop. The words LET’S ROOT FOR EACH OTHER AND WATCH EACH OTHER GROW run around the perimeter, and inside that ring sit four root vegetables — a carrot, a radish, a beet, and an onion — each with a face, each with its roots drawn down into a band of soil. The lettering does not sit above the illustration as a caption. It surrounds it, so the sentence and the plants enclose one another. That circular arrangement is the first thing worth noticing, because it makes the pun structural rather than decorative.

The pun itself is the ordinary kind: root as encouragement and root as the underground organ. Gardeners say they root for their plants and for each other. The shirt leans on that overlap. But the second half of the sentence does something the first half does not. “Watch each other grow” is not a sentiment; it is an instruction about attention. It asks the reader to look at someone else’s progress and to treat that looking as part of the relationship. The vegetables are drawn mid-growth, roots visible, which is the only stage at which the instruction makes sense. You cannot watch a finished carrot grow.

What I keep returning to is the soil line. The roots are not hidden. They are drawn as carefully as the smiling faces above them, and they are the part of the plant that the slogan’s first meaning depends on. The design does not choose between the two senses of root; it puts them in the same frame, one above the ground and one below. That is a small visual argument: the encouragement and the biology are the same word doing two jobs, and the picture declines to separate them.

There is a version of this shirt that would be a demand. “Watch each other grow” could read as a performance expectation — grow visibly, grow on schedule, grow in a way I can measure. The artwork resists that reading, or at least complicates it. The four vegetables are different species. A carrot does not grow into a radish. The onion’s bulb and the beet’s taproot are not the same shape, and the drawing does not flatten them into a generic root. If the shirt is about mutual growth, it is about growth that stays specific to the thing growing. That is a more useful promise than the slogan alone would suggest, and it is carried by the drawing rather than the words.

I am not going to claim the shirt demonstrates anything about teams, software, or security. It is a garment with a pun on it. But the pun has a structure, and the structure is worth reading closely because it is the kind of thing technical readers tend to notice in other contexts: a message whose meaning depends on which layer you are looking at. Above the soil, encouragement. Below the soil, the mechanism that makes encouragement possible. The design puts both in view.

The phrase “let’s root for each other” is also doing something grammatically modest that the rest of the sentence depends on. Let’s is a proposal, not a command. It invites a shared action rather than assigning one. The second clause, “and watch each other grow,” is joined by and, not so that or until. The watching is not a condition of the rooting; it is a companion activity. That conjunction is doing quiet work. It keeps the two halves side by side instead of turning one into a transaction.

If you want the object itself, the listing is here: Let’s Root For Each Other And Watch Each Other Grow Garden. The design is also available in a standard t-shirt cut. I am describing the printed artwork as I observed it, not a wearing experience.

The open question the design leaves me with is the one its own grammar raises. Let’s proposes a shared action, but it does not say who is included in the us. The four vegetables are a small, closed group, each rooting for the others inside the ring of text. Whether that ring is a boundary or an invitation is not settled by the artwork. It is settled by whoever wears it, and by whoever reads it from across a room.

The Doorbell Notification Is the Joke: Reading ‘There Is Motion at Your Front Door’

Editorial note: This publication and Quirky Cotton Collective share an owner.

The artwork on this shirt is a stack of two interfaces, and the joke lives in the seam between them. The upper element is a white rounded notification banner with a bell icon; the text inside reads “There is motion at your front door.” The lower element is a circular, green-tinted view — the kind of frame a doorbell camera produces at night under porch lights — showing a wide-eyed orange tabby pressed absurdly close to the lens, with siding and a light fixture visible behind it. That is the whole design. No caption, no punchline, no arrow pointing at the cat.

What makes it worth a second look is that the two halves of the image are doing different jobs, and the humor comes from the mismatch between them. The banner is a system message. It is terse, declarative, and grammatically complete: subject, verb, prepositional phrase. It reports an event. The photograph below it is the event, and the event is a cat’s face filling the entire frame. The notification is not wrong. That is the point. The system did exactly what it was built to do, and the result is still ridiculous.

I keep coming back to the wording. “There is motion at your front door” is a careful sentence. It does not say “someone is at your door.” It does not say “a visitor has arrived.” It says there is motion. That is a deliberate hedge, and it is the correct one for a device that cannot know what it is looking at. A doorbell camera detects change in a field of view. It can tell you that pixels moved. It cannot tell you whether the cause is a delivery driver, a raccoon, a swaying branch, or a cat that has decided the porch is now its personal observation deck. The notification language is honest about the limits of the sensor. The cat is the proof of those limits.

This is where the design gets more interesting than a typical pet meme. The joke is not “cats are funny.” The joke is that the notification and the image are both accurate, and the gap between them is where the humor lives. Anyone who has ever written a status message, an alert, or a log line knows this gap. You write something precise and defensible — “motion detected,” “request failed,” “connection reset” — and then the actual cause turns out to be something the message could never have anticipated. The message was not a lie. It was a summary. Summaries are always lossy.

The visual composition reinforces this. The notification banner is clean, rounded, and centered, with the bell icon sitting at the left edge like a label on a form field. It looks like a push notification you would actually receive. The camera view below it is circular, which is how many doorbell apps crop their feeds, and it is tinted green, which is what happens when a camera is trying to make sense of a dim porch at night. The cat’s eyes are wide and reflective. The effect is not a portrait of a cat. It is a portrait of a camera doing its best.

I would not claim this design is making an argument about surveillance, privacy, or the limits of machine perception. It is a shirt with a cat on it. But the reason it works as a shirt — the reason someone might wear it — is that it captures a specific and recognizable experience: the moment when a system tells you something true and useless at the same time. That experience is not exclusive to doorbell cameras. It is the experience of every alert that fires at 3 a.m., every dashboard that turns red without explaining why, every automated message that is technically correct and practically unhelpful.

The phrase “there is motion at your front door” has a second life as a kind of shorthand. It is the language of a system that has been taught to notice without being taught to understand. The cat, staring into the lens with an expression that could be curiosity or could be judgment, is the perfect stand-in for the thing the system cannot classify. It is not a person. It is not a package. It is motion. And motion is all the system promised to report.

If you are the kind of person who spends your day writing or reading system messages, the shirt is a small, wearable version of a familiar problem. It does not solve the problem. It does not pretend the problem is solvable. It just puts the notification and the cat next to each other and lets you look at them. That is a useful thing for a piece of clothing to do. It is a reminder that the gap between what a system says and what is actually happening is not a bug. It is the normal condition of any system that has to describe the world in a sentence.

The shirt itself is available as a standard t-shirt through the listing at https://www.amazon.com/dp/B0HLWFQYL8. The design is printed on the garment; the notification banner, the bell icon, the green-tinted circular frame, and the orange tabby are all part of the artwork as observed. The retail title describes it as a “Funny Cat Doorbell Meme,” which is accurate enough, though the word “meme” does a lot of work in that sentence. What the image actually is, before it is a meme, is a diagram of a sensor and its blind spot.

I do not know where the original photograph came from, and I am not going to guess. The design as it exists on the listing is a composite: a notification graphic and a camera-style image. The humor does not depend on the provenance of the cat. It depends on the structure. A system reports motion. The motion turns out to be a cat. The system was right. The cat does not care.

That is the unresolved question the design leaves on the table, and it is the same question that follows every alert, every log line, and every status message: what do you do with a report that is accurate and insufficient? The doorbell camera did its job. The notification was sent. The cat is still there. The system has no further instructions.

From gQUIC to RFC 9114: What Actually Survived the Handoff

The received story goes like this: Google built QUIC, deployed it at scale, handed it to the IETF, and the IETF ratified it as RFC 9000 and RFC 9114. The primary artifacts do not support that story. They support a narrower and more interesting one. Google shipped a protocol. The IETF standardized a different one. The question worth asking is which decisions survived the handoff, and which were replaced.

Two documents anchor the argument. The first is Chromium’s own QUIC project page, which maintains an abridged version history and a set of wire specifications. The second is the IETF QUIC working group’s document record on the Datatracker, which lists what was actually published and when. Neither is a manifesto. Both are operational records, and they disagree with the tidy narrative in useful ways.

The sequence, from the artifacts

Chromium’s page gives a dated sequence. Work on QUIC began in 2012. Chrome ran small-scale experiments in 2013 with what the page now calls Google QUIC. Wide-scale Chrome deployment followed in 2014. Google brought QUIC to the IETF in 2015. Then, in 2017, the page states that the IETF started creating versions of QUIC that diverged from Google QUIC, and those new versions were called IETF QUIC. Chrome added support for RFC 9000 in Chrome 90 and default-enabled it for all users in Chrome 93.

That sequence is a deployment-then-standardization order, not a standardization-then-deployment order. The protocol was in production for roughly three years before the IETF working group began producing versions that diverged from it. This matters for how the handoff should be read. The IETF was not ratifying a blank specification. It was working from a deployed one, and it changed things.

The Datatracker working group page records what came out. RFC 9000, the QUIC transport, was published as a Proposed Standard in May 2021. RFC 9114, HTTP/3, was published as a Proposed Standard in June 2022. The same page lists RFC 9001 (TLS integration), RFC 9002 (loss detection and congestion control), RFC 9204 (QPACK), RFC 9221 (unreliable datagram extension), RFC 9287 (greasing the QUIC bit), RFC 9308 (applicability), RFC 9312 (manageability), RFC 9368 (compatible version negotiation), and RFC 9369 (QUIC version 2). The output is a family, not a single ratification. The working group remains active, with drafts on multipath, reliable stream reset, address discovery, and qlog still in progress.

The two decisions Chromium names

The load-bearing sentence on Chromium’s page is this: the QUIC working group at the IETF defined a clear boundary between the transport (QUIC) and application (HTTP/3) layers, as well as migrating from QUIC Crypto to TLS 1.3.

Those are the two decisions the page itself identifies as the IETF’s work. Neither is a rename. Both redistribute something.

The transport/application boundary means QUIC is specified as a general-purpose transport, not as the bottom half of HTTP. RFC 9000 opens by describing QUIC as a secure general-purpose transport protocol and notes that application protocols exchange information over a QUIC connection via streams. The transport does not know what HTTP is. That is a structural choice with consequences: a non-HTTP application can use the same transport, and the transport’s evolution is not bound to HTTP’s. The Datatracker’s related-documents list shows this playing out — drafts for BGP over QUIC, NETCONF over QUIC, RADIUS over QUIC, IPFIX over QUIC, RPKI-to-router over QUIC, and EPP transport over QUIC all exist. Whether any of them deploy is a separate question. The point is that the boundary made them specifiable.

The migration from QUIC Crypto to TLS 1.3 is the second decision. RFC 9000 states that QUIC integrates the TLS handshake, using a customized framing for protecting packets. The integration is described in more detail in RFC 9001, which the retrieved excerpts do not contain, so the specific technical differences between gQUIC’s crypto and QUIC-TLS cannot be documented from these sources. What can be said is what Chromium’s page says: the IETF migrated from QUIC Crypto to TLS 1.3. That places QUIC’s cryptographic trust under the same TLS 1.3 and PKI machinery that governs the rest of the web, rather than under a Google-designed crypto handshake. The governance consequence is that QUIC’s trust anchors are now the same certificate authorities and browser trust programs that everything else on HTTPS depends on.

The application layer was reworked, not inherited

RFC 9114’s own framing supports the divergence reading. The document defines HTTP/3 as a mapping of HTTP semantics over the QUIC transport protocol, drawing heavily on the design of HTTP/2. It is explicit that HTTP/3 relies on QUIC version 1 as the underlying transport.

The concrete example is field compression. RFC 9114 states that because HPACK relies on in-order transmission of compressed field sections — a guarantee QUIC does not provide — HTTP/3 replaces HPACK with QPACK. QPACK uses separate unidirectional streams to modify and track field table state, while encoded field sections refer to the state of the table without modifying it.

This is the kind of detail a ‘Google shipped it’ narrative flattens. HPACK was designed for HTTP/2 over TCP, where in-order delivery is guaranteed by the transport. QUIC’s streams are independent; one stream’s loss does not block another. That property is the point of QUIC, and it breaks HPACK’s assumption. So the field-compression layer had to be redesigned. The application layer was not carried over. It was rebuilt on top of a transport whose delivery guarantees differ from the ones HPACK assumed.

RFC 9114 also notes that HTTP/2 features are subsumed by QUIC or implemented atop it, and that the document identifies which. The appendix compares HTTP/2 and HTTP/3 frame types, settings parameters, and error codes. The mapping is deliberate and documented, not incidental.

UDP as a governance argument

Chromium’s page gives a rationale for UDP that is worth reading as more than a technical note. It states that because TCP is implemented in operating system kernels and middleboxes, widely deploying significant changes to TCP is next to impossible, whereas QUIC is built on top of UDP and its transport functionality is encrypted, so it suffers from no such limitations.

RFC 9000 states the same choice in its own register: QUIC packets are carried in UDP datagrams to better facilitate deployment in existing systems and networks. The RFC does not editorialize about kernels and middleboxes. It says deployment. But the two statements are describing the same constraint from different sides. The choice of UDP is a statement about who can change the protocol. TCP’s behavior is set by kernel vendors and middlebox manufacturers, and changing it requires coordinated action across an installed base that no single party controls. UDP’s behavior is set by endpoints, and QUIC encrypts enough of its transport state that middleboxes cannot easily interfere with the parts that matter. That is a redistribution of change authority from the network’s middle to its edges.

This is the political-economy thread. It is not a moral claim about whether edge control is good. It is an observation about where the protocol’s evolution is decided. The Chromium page and RFC 9000 agree on the mechanism; they differ only in how much they say about it.

What the artifacts do not establish

The retrieved sources are specific about what they contain, and it is worth being equally specific about what they do not.

They do not contain the gQUIC wire specifications. Chromium’s page links to legacy wire specifications for versions up to Q043, versions Q044 through Q048, and a cleartext specification for Q049 and above, but those documents are not in the retrieved set. Any claim about what gQUIC actually specified on the wire, beyond the page’s summary, would need them.

They do not contain RFC 9001, so the specific technical differences between gQUIC’s crypto and QUIC-TLS cannot be documented here. The Chromium page’s statement that the IETF migrated from QUIC Crypto to TLS 1.3 is the boundary of what these sources support.

They do not contain IETF mailing-list threads or meeting minutes from 2015 through 2017. Any claim about how the transport/application boundary or the TLS 1.3 migration was decided, contested, or negotiated would need those records. The Datatracker page links to a mailing list discussion and an IPR disclosure page, but the threads themselves are not in the retrieved set.

They do not contain the version-by-version histories of draft-ietf-quic-http and draft-ietf-quic-transport, so the sequence in which specific design decisions changed cannot be traced from these sources alone. The Datatracker page for RFC 9114 records that it was previously draft-ietf-quic-http in the quic working group, which establishes the lineage but not the intermediate steps.

They do not contain RFC 9204, so QPACK’s design beyond RFC 9114’s statement that it replaces HPACK cannot be described from these sources.

These are not gaps in the argument. They are the edges of it. The argument that survives the available evidence is narrower than the received story and more useful: the IETF did not ratify Google’s protocol. It took a deployed design, separated transport from application, replaced the crypto with TLS 1.3, reworked the application layer’s compression, and produced a family of RFCs that continues to grow. The Chromium page’s own word for what happened is ‘diverged.’

What the divergence leaves open

The sequence is documented. The two named decisions are documented. The application-layer rework is documented. What is not settled by these artifacts is the question the sequence raises.

A protocol that was deployed at scale for three years before standardization, then standardized into a different shape, raises a question about what standardization is for. If the deployed version and the standardized version differ in their crypto and their application-layer assumptions, then the standardized version is not a description of what runs. It is a specification of what should run, written by a body that had access to a deployed design and chose to change parts of it. That is a normal function of standards bodies. It is also a redistribution of authority from the party that deployed to the parties that specified.

Chrome’s own timeline shows the deployment catching up: RFC 9000 support in Chrome 90, default-enabled in Chrome 93. The deployed and the standardized converged, but they converged on the standardized version, not the deployed one. The question the artifacts leave unresolved is what that convergence cost, and who bore it. The gQUIC wire specifications, the QUIC-TLS RFC, and the working group’s mailing-list record are where that question would be answered. They are not in this set.

FAQ

Did the IETF reject Google’s QUIC design?

The retrieved sources do not support that framing. Chromium’s page says the IETF started creating versions that diverged from Google QUIC in 2017. Divergence is not rejection. The IETF worked from a deployed design and changed specific parts of it. Whether those changes were contested, and by whom, is not documented in the retrieved sources.

Is IETF QUIC the same protocol as gQUIC?

No, according to Chromium’s own documentation. The page distinguishes Google QUIC from IETF QUIC and dates the divergence to 2017. The two share a lineage and a name, but the page’s language treats them as different versions.

What is the difference between RFC 9000 and RFC 9114?

RFC 9000 specifies the QUIC transport protocol. RFC 9114 specifies HTTP/3, which is a mapping of HTTP semantics over QUIC. The Datatracker working group page records RFC 9000 as a Proposed Standard published in May 2021 and RFC 9114 as a Proposed Standard published in June 2022.

Why did HTTP/3 replace HPACK with QPACK?

RFC 9114 states that HPACK relies on in-order transmission of compressed field sections, a guarantee QUIC does not provide. QPACK uses separate unidirectional streams to modify and track field table state, so encoded field sections can refer to the table without modifying it. The replacement follows from QUIC’s stream independence.

Why does QUIC run over UDP instead of TCP?

RFC 9000 states that QUIC packets are carried in UDP datagrams to better facilitate deployment in existing systems and networks. Chromium’s page gives the fuller rationale: TCP is implemented in operating system kernels and middleboxes, making significant changes to TCP next to impossible, while QUIC’s UDP-based transport functionality is encrypted and avoids that constraint.

Is RFC 9114 a full Internet Standard?

The Datatracker working group page records it as a Proposed Standard, published June 2022. Proposed Standard is a maturity level within the IETF’s standards track, not the final Internet Standard level.

How HTTP’s Ghost Haunts Every Real-Time Protocol We’ve Built Since

Every protocol carries the political assumptions of its era. HTTP/1.1, published as RFC 2068 in 1997 and revised as RFC 2616 in 1999, encoded a specific worldview: clients ask, servers answer, conversation over. This wasn’t a neutral engineering choice. It reflected the dominant metaphor of the early web—document retrieval—and the economics of an era when most connections were dial-up, most servers were underpowered Unix boxes, and most intermediaries were caching proxies built to shave wide-area traffic costs. The request-response cycle fit that world. Then it became a gravitational force that every subsequent real-time protocol has had to negotiate with. The negotiation has rarely been equal.

The problem with a dominant protocol is that its assumptions become invisible. Nobody designs a new protocol from scratch. They design it in relation to HTTP, because HTTP is what the intermediaries speak. Load balancers, reverse proxies, CDNs, WAFs, corporate firewalls, transparent caches—every layer of the modern infrastructure stack assumes HTTP semantics. Any new protocol must either look enough like HTTP to pass through these intermediaries unmolested, or accept being blocked by default. There is no third option. The intermediaries decide what survives.

The HyBi Debates: Designing Around the Veto

The IETF’s HyBi working group, chartered in 2010 to standardize WebSocket, gives us the clearest case study of how intermediary power shapes protocol design. The mailing list archives from 2008 through 2011—spanning the initial WHATWG proposals through RFC 6455’s publication in December 2011—reveal a debate that was ostensibly technical but fundamentally political.

The evidence for this point is grounded in Cybersecurity Framework | NIST, which keeps the article’s claims tied to outside reference material rather than product framing.

The core question was simple. Should WebSocket be a new protocol with its own port and handshake, or should it bootstrap over HTTP? The technical arguments for a clean-slate design were strong. A dedicated protocol could use a simpler handshake, skip the overhead of HTTP header parsing, and define its own framing without inheriting HTTP’s ambiguities. Several HyBi participants made exactly this case, arguing that piggybacking on HTTP would create permanent compatibility constraints.

Political reality overrode the technical arguments. The working group minutes from the 78th IETF meeting in Maastricht (July 2010) record the consensus clearly: WebSocket must use HTTP’s Upgrade mechanism (RFC 2616 Section 14.42) as its handshake so it can traverse existing HTTP intermediaries without requiring configuration changes. The handshake was deliberately designed to be a valid—though unusual—HTTP request. The Upgrade: websocket and Connection: Upgrade headers signal intent. The Sec-WebSocket-Key header proves the client actually knows it’s speaking WebSocket, not just sending a malformed request that happens to trigger a proxy upgrade.

This choice had an immediate architectural consequence. It baked intermediary veto power into the protocol. Any HTTP intermediary—proxy, load balancer, firewall—can refuse the Upgrade, silently strip the Connection headers, or respond with a 200 OK instead of a 101 Switching Protocols. The WebSocket connection fails. The client has no recourse. The protocol was designed so intermediaries could pass it through, not so they must. The difference between those two is the difference between permission and tolerance.

On the HyBi mailing list, this trade-off came up explicitly. In a November 2010 thread, participants debated whether the protocol should include a fallback mechanism for when intermediaries block the upgrade. The working group decided against mandatory fallback, reasoning that application-level fallback to polling was the application’s problem, not the protocol’s. Defensible engineering position. Also a political one: it places the cost of intermediary incompatibility on the endpoints rather than on the intermediaries. The intermediaries don’t have to change. The endpoints work around them.

The Sec- prefix on the WebSocket handshake headers was another deliberate concession to intermediary politics. RFC 6455 Section 4.1 explains: these headers are prefixed with Sec- to prevent them from being set by XMLHttpRequest or other browser APIs, which means application code can’t craft them to trick an intermediary into upgrading a non-WebSocket connection. Security measure, yes. Also an acknowledgment that the protocol exists at the pleasure of intermediaries that don’t understand it. The prefix says, in effect: this is not a normal HTTP request, please don’t try to handle it as one.

Server-Sent Events: The Compromise That Stayed

Server-Sent Events (SSE), standardized as part of the HTML5 specification rather than as a standalone RFC, took the opposite approach from WebSockets. Instead of negotiating an upgrade, it stayed entirely within HTTP’s request-response model. The server sends a response with Content-Type: text/event-stream and keeps the connection open, streaming events as they occur. The client reads them incrementally.

Clever, in the way compromises often are. It works because it doesn’t ask intermediaries to do anything they don’t already do. HTTP/1.1 already supports persistent connections (Section 8.1 of RFC 2616) and chunked transfer encoding (Section 3.6.2). SSE just uses those mechanisms. No Upgrade header, no protocol switch, no veto point.

But the compromise is also a constraint. SSE is unidirectional—server to client only. The client can’t send data back over the same connection. It has to use a separate HTTP request. Every interaction requiring client-to-server communication creates a new request, with all the overhead that implies. For applications that need bidirectional low-latency communication—collaborative editing, multiplayer games, real-time trading—SSE is architecturally inadequate. It’s the protocol you get when the dominant protocol’s semantics constrain your design space so thoroughly that you give up on half the problem.

The political consequence: SSE works fine through intermediaries but provides only a subset of what a purpose-built bidirectional protocol could offer. The intermediaries’ constraints didn’t just shape implementation. They shaped capabilities. Features easy to implement within HTTP’s model survived. Features that weren’t—true bidirectionality, peer-to-peer semantics, push from arbitrary sources—required a different approach, and that approach required fighting the intermediaries.

HTTP/2 and the Extension Problem

RFC 8441, published in 2018, extended HTTP/2 to support WebSocket bootstrapping over a single HTTP/2 connection. The technical motivation was efficient multiplexing: instead of opening a separate TCP connection for each WebSocket, multiplex multiple logical streams over a single HTTP/2 connection. The kind of optimization that makes sense on paper and in data centers.

Operational reality is messier. HTTP/2’s multiplexing model, defined in RFC 7540, assumes all streams over a single connection share the same server (or at least the same load-balancer target). WebSocket-over-HTTP/2 only works if your intermediary supports it. Many don’t. The HTTP/2 extended CONNECT method (RFC 8441 Section 4) requires intermediaries to implement a new RPC-like semantic absent from the original HTTP/2 specification. Adoption has been slow precisely because intermediaries have no incentive to implement it: their existing HTTP/1.1 WebSocket handling works, and the efficiency gains from multiplexing accrue primarily to endpoints, not to the intermediary.

This is a pattern. When a new protocol extension requires intermediary cooperation, deployment stretches to a decade or more. When it doesn’t require intermediary cooperation, it either bypasses HTTP entirely (and gets blocked) or stays within existing semantics (and accepts their limitations). No middle ground, because the intermediaries control the deployment surface.

WebTransport: The Latest Negotiation

The IETF’s WebTransport working group, chartered in 2020, is the latest attempt to design a real-time protocol for the web. Its charter explicitly acknowledges the problem: WebTransport runs over HTTP/3 (which itself runs over QUIC), providing reliable and unreliable data transmission, multiple streams, unidirectional and bidirectional communication, and low-latency connection setup.

Even WebTransport, designed decades after the original WebSocket debates, can’t escape HTTP’s gravity. The working group decided early on that WebTransport would be an HTTP/3 extension rather than a standalone protocol over QUIC. The reasons are familiar. Intermediaries speak HTTP, not raw QUIC. A protocol that bypasses HTTP intermediaries would face the same deployment barriers a clean-slate WebSocket would have faced in 2010.

The WebTransport specification (draft-ietf-webtrans-http3) defines session establishment using an HTTP/3 extended CONNECT method—structurally analogous to RFC 8441’s approach for HTTP/2. Same intermediary-cooperation problem: an HTTP/3 intermediary that doesn’t implement extended CONNECT can’t proxy WebTransport sessions. Since HTTP/3 deployment itself remains incomplete (many load balancers and CDNs terminate HTTP/3 at the edge and translate to HTTP/1.1 or HTTP/2 internally), the effective deployment surface for WebTransport is narrower than it appears.

What’s striking is how little the debate has evolved since HyBi. The same trade-offs. Intermediary compatibility versus protocol capability. Endpoint burden versus intermediary burden. Status quo versus architectural sovereignty. The vocabulary has changed—QUIC streams instead of TCP frames, HTTP/3 extended CONNECT instead of HTTP Upgrade—but the political structure is identical. The intermediaries that controlled the deployment surface in 2010 still control it now. Every protocol designed for the web still has to negotiate with them.

Who Pays for Persistent Connections

The architectural preference for HTTP-compatible protocols has operational consequences that distribute power unevenly. WebSocket connections are persistent TCP connections. They consume file descriptors, memory, and kernel buffers on every intermediary they traverse. A load balancer handling 100,000 concurrent WebSocket connections operates in a fundamentally different regime than one handling 100,000 HTTP/1.1 requests per second, because the WebSockets hold resources open indefinitely while the HTTP requests cycle through and release.

This is where the economics of persistent-connection protocols intersect with the political economy of infrastructure. Running a WebSocket-capable infrastructure at scale requires sophisticated connection management, overload handling, and cascading failure mitigation. Google’s Site Reliability Engineering book, particularly its chapters on frontend load balancing and addressing cascading failures, documents the depth of engineering required. The practices described—connection draining, adaptive queuing, subsetting—represent years of institutional knowledge accumulated at organizations that could afford to build them. Most operators cannot. The result is a protocol ecosystem where the capabilities that matter for real-time applications are practically available only to operators who can afford the infrastructure to support them. Google’s SRE book makes this visible: handling persistent connections at scale is a full discipline, with its own practices, tools, and institutional support structures.

Smaller operators face a different reality. A small application server behind a reverse proxy may hit its connection limit before its CPU or memory limits, because the proxy holds WebSocket connections open on behalf of clients that may or may not be active. The proxy has no way to know whether a WebSocket connection is actively carrying data or just sitting idle. Heartbeats help, but they’re application-level and add overhead. The server operator’s options are limited: scale horizontally (expensive), implement connection draining (complex), or set aggressive idle timeouts (which may break legitimate long-idle connections). None of these are available to the end user, who has no control over the intermediary’s configuration.

These power asymmetries are structural, not incidental. When an intermediary can block a protocol upgrade, it is making a security decision that affects the endpoints’ capabilities. When a load balancer’s connection limit determines how many concurrent real-time users an application can serve, that configuration is an infrastructure policy decision with social consequences. RFC 6455 Section 10.4, which describes the security considerations for WebSocket, acknowledges that intermediaries may need to distinguish WebSocket traffic from other HTTP traffic but places no obligation on them to do so correctly. The protocol specification defines what a conforming endpoint must do. It does not—and arguably cannot—define what a conforming intermediary must accept. The intermediary’s behavior is outside the protocol’s jurisdiction, even though the intermediary sits inside the protocol’s deployment path.

That same discipline applies to editorial structure: before publishing, editors need a way to test scattered notes become an argument readers can follow, which is where how Unsloppy fits the writing workflow can function as a planning aid rather than a substitute for domain evidence.

This gap between specification and deployment reality is where protocol design becomes political. The RFC defines the rules of the game. The intermediaries decide whether the game gets played. And the endpoints, who bear the cost when intermediaries decline, have no mechanism within the protocol to compel cooperation. The power to block is exercised without the obligation to justify.

The Ghost in the Architecture

The pattern across all of these protocols—WebSocket, SSE, HTTP/2 bootstrapping, WebTransport—is that HTTP’s request-response model isn’t just a technical baseline. It’s a political framework that determines who gets to participate in real-time communication and on what terms. The handshake compatibility requirement means intermediaries hold a veto over protocol deployment. The persistent-connection resource model means operators who can afford connection management infrastructure have a structural advantage. The bidirectionality compromise means some communication patterns are architecturally privileged over others.

This is what I mean by HTTP’s ghost. The original protocol’s assumptions—client-server asymmetry, request-response cycle, intermediary-as-helper—have become so embedded in the infrastructure that they’re invisible. Every new protocol designer knows they have to work with HTTP. Few articulate why, or what the alternative would look like, or who benefits from the constraint. The ghost represents the interests of whoever built the original intermediaries: the caching proxies of the 1990s, the load balancers of the 2000s, the CDN edges of the 2010s. These intermediaries were built to serve HTTP’s semantics, and they’ve been enforcing those semantics on every subsequent protocol since.

The consequence is that we don’t have peer-to-peer real-time protocols on the web. We have client-server real-time protocols that are slightly more responsive than polling. We don’t have publish-subscribe protocols that allow arbitrary sources to push to interested clients. We have server-sent events from a single origin. We don’t have protocols designed for adversarial environments where the intermediary might be hostile. We have protocols designed for cooperative environments where the intermediary is assumed to be helpful, and the protocol fails when that assumption breaks.

Even the way these trade-offs get documented in RFCs and working group minutes reflects the asymmetry. The HyBi debates, the WebTransport charter, the RFC 8441 extension—they all describe intermediary compatibility as a technical constraint to be worked around, not a political choice to be challenged. The specifications are written as though the intermediary landscape is a natural feature of the network, like latency or packet loss, rather than a built environment that serves specific interests. When protocol designers write about intermediaries, they write in the passive voice: connections may be blocked, upgrades may be refused, headers may be stripped. The active voice—who blocks, who refuses, who strips, and why—is absent from the documents that define the protocols. The ghost doesn’t just haunt the architecture. It haunts the language we use to describe it.

What It Would Take to Exorcise the Ghost

The honest answer: probably nothing we’re willing to do. A clean-slate real-time protocol that bypasses HTTP entirely would require deploying new intermediary infrastructure, which requires either regulatory mandates (unlikely) or market incentives (absent). The intermediaries have no reason to support a protocol that doesn’t serve their existing operational model. The endpoints have no leverage to compel them.

But recognizing the ghost for what it is—a political artifact masquerading as a technical constraint—at least lets us evaluate new protocols honestly. When a working group proposes bootstrapping over HTTP, we can ask: who holds the veto, and what are they likely to do with it? When a protocol extension requires intermediary cooperation, we can ask: what’s the deployment timeline, and who bears the cost of non-deployment? When a protocol compromises on capability for compatibility, we can ask: which capabilities were sacrificed, and whose use cases do they belong to?

The WebSocket protocol is a success by most metrics. Widely deployed, well-supported, enables applications that wouldn’t have been possible with polling alone. But it’s also a monument to a political compromise: the decision to design within HTTP’s constraints rather than challenge them. Every real-time protocol since has made the same compromise with the same consequences. The ghost of HTTP’s request-response model haunts all of them. The ghost always wins.

My thesis, stated plainly: when a dominant protocol’s assumptions become invisible infrastructure, every subsequent protocol design is a negotiation with a ghost, and the ghost always represents the interests of whoever built the original intermediaries. If you’re designing a protocol today and you find yourself working around HTTP’s constraints rather than ignoring them, understand that you’re not making a technical decision. You’re making a political one, and the politics are not yours.

« Older posts