The Label Says COMPOSITION: Reading the Notebook-Cover Costume as a Surface, Not a Slogan

Editorial note: this publication and Quirky Cotton Collective share an owner; this is not an independent review.

The garment image shows a rectangle, not a sentence. A black-and-white speckled field fills the chest area, a dark binding strip runs down the left edge, and a white ruled label sits near the top. Inside that label, the word COMPOSITION is printed above an outlined ghost and an outlined pumpkin. That is the whole design. There is no slogan, no punchline, no exclamation point. The composition notebook shirt is a printed notebook cover, and the print is doing the work a costume would otherwise do with fabric and props.

That distinction matters more than it first appears. Most novelty shirts for teachers are text-first: a sentence about coffee, grading, or October, set in a friendly font. This one is object-first. The joke, such as it is, lives in the recognition of a familiar school supply rendered at torso scale. The ghost and pumpkin are small marks on the label, not the main event. The speckle pattern and the binding strip carry the visual weight. If you removed the word COMPOSITION, the shirt would still read as a notebook. If you removed the ghost and pumpkin, it would read as a notebook without a seasonal cue. The design is built so that the object survives the loss of any single element.

I want to be careful about what that observation supports. It supports a claim about visual hierarchy: the speckled field and binding strip establish the object, the label names it, and the seasonal marks date it. It does not support a claim about comfort, fit, fabric weight, or how the print behaves after washing. I have not worn the shirt. The retail image is the evidence, and it is enough to read the design but not enough to describe the wearing experience.

What the label is actually doing

The white ruled label is the most interesting part of the composition, and it is worth slowing down on. In a real composition notebook, the label is a blank field for a name, a subject, a date. It is a place where the owner writes. Here, the label is pre-printed with the word COMPOSITION and two small Halloween drawings. That is a small inversion. The blank space that normally invites handwriting has been filled in by the manufacturer, and the fill-in is a joke about the season rather than a record of ownership.

I read that inversion as the design’s actual argument: a school supply has been repurposed as a costume, and the label that would normally carry a student’s name now carries the costume’s own identity. The ghost and pumpkin are not decorations added on top of the notebook; they are what the notebook has become for the day. That is a more specific idea than “teacher Halloween shirt,” and it is the reason the design holds together. The label is not a place for your name. It is a place for the occasion.

This is interpretation, not a claim about the designer’s intent. I have no statement from the designer and no publication history for the artwork. What I can say is that the visual evidence supports reading the label as the focal point, because it is the only area of the print with a different background color, a border, and text. The eye goes there first. The ghost and pumpkin are positioned inside that focal area, which means the seasonal cue is subordinate to the object cue rather than the other way around.

The group-costume logic, read from the print

The retail title includes the words “Teacher Group Halloween,” and the design supports that use without requiring any claim about who buys it. A group costume works when the individual garments are recognizable at a distance and identical enough to read as a set. This print satisfies both conditions. The speckled rectangle is a large, high-contrast shape that reads across a room. The binding strip gives the group a consistent left edge, which is the kind of detail that makes a row of people look intentional rather than accidental. The label and its small marks are close-range rewards: they confirm the joke when someone gets near enough to read them.

That is a different design problem from a single statement shirt. A statement shirt has to be legible to the person standing next to you. A group costume has to be legible to someone across the room and still hold up when the group is photographed together. The composition notebook print is built for the second problem. The large field does the distance work; the label does the close work. The ghost and pumpkin are small enough that they do not compete with the overall shape, which is why the group reads as a group of notebooks rather than a group of Halloween graphics.

I am not claiming that this is how the shirt is marketed or that any particular group has worn it. I am reading the print against the use named in the title. The design is consistent with that use, and the visual hierarchy explains why.

Where the design stops

The print is a costume cue, not a costume. A real composition notebook costume might involve a rectangular board, a strap, or a physical prop. This is a printed image on a shirt, and the image is flat. That flatness is the point, but it is also the limit. The shirt does not become a notebook; it refers to one. The distinction matters if you are evaluating it as a costume rather than as a graphic. As a graphic, the flatness is efficient: the speckle, the binding, and the label do the work without requiring three-dimensional structure. As a costume, it is a reference rather than a construction.

I prefer to read it as a graphic, because that is what the evidence supports. The retail image shows a print, and the print is legible. The design does not claim to be a physical notebook, and the visual observation explicitly notes that the teacher Halloween costume is a printed notebook cover, not a physical notebook. That is a useful boundary. It keeps the reading honest: the shirt is a surface that borrows the authority of a familiar object, and the borrowing is the joke.

There is also a boundary in the seasonal marks. The ghost and pumpkin place the design in October, but they are small and outlined rather than filled. They do not dominate the label, and they do not turn the shirt into a generic Halloween graphic. If anything, their smallness is what keeps the notebook reading intact. A larger ghost would pull the design toward costume-party territory; a smaller one would disappear at any distance. The current scale is a compromise, and it is the right one for a group costume that needs to read as a set first and a joke second.

What a technical reader might take from it

I spend most of my working attention on artifacts that are supposed to be read at a glance and then verified at close range: a dump excerpt, a trace timeline, a counter panel. The composition notebook print has the same two-scale structure. At a distance, it is a shape. Up close, it is a label with a word and two small drawings. The design trusts the viewer to make the connection between the two scales without a caption. That is a reasonable thing to trust, because the object is familiar enough that the shape does the naming.

The comparison stops there. I am not going to claim that the shirt teaches anything about diagnostics, or that reading a label is like reading a stack trace. The design is a costume cue, and its interest is visual. What I can say is that it is a well-built cue: the hierarchy is clear, the seasonal marks are subordinate to the object, and the label inversion gives the print a small idea rather than a slogan. That is more than most novelty shirts attempt, and it is enough to make the shirt worth reading closely.

If you are looking for a group costume that reads as a set without requiring matching text, the print is built for that. If you are looking for a shirt that makes an argument, the argument is visual: a school supply has become a costume, and the label that would normally hold a name now holds the occasion. That is a modest idea, but it is a real one, and it is visible in the artwork rather than asserted in the title.

Diagnostic Procedure

This procedure is for reading the artwork, not for evaluating the garment’s performance. It is the same sequence I use when I have an artifact and a limited window to form a defensible reading.

  1. Open the retail image at full size. Use the listing image, not a thumbnail. Expected output: a rectangle with a speckled field, a dark left binding strip, and a white ruled label near the top. If the label is not legible, you are looking at a compressed preview; stop and find the full-resolution image.
  2. Identify the dominant shape before reading any text. Cover the label with your hand or a piece of paper. Expected output: the remaining image still reads as a notebook cover. Verdict: the object cue is carried by the speckle and binding, not by the word. If the shape collapses without the label, the design is text-first and the reading changes.
  3. Read the label text and marks. Expected output: the word COMPOSITION in the label header, with an outlined ghost and an outlined pumpkin below it. Note the scale: the marks are small relative to the label and much smaller relative to the full print. Verdict: the seasonal cue is subordinate to the object cue.
  4. Check the binding strip orientation. Expected output: a dark vertical strip on the left edge of the rectangle. This is the detail that makes a row of shirts read as a set. If the strip were absent or centered, the group-costume reading would weaken.
  5. Separate observation from interpretation. Write down what is printed: speckled field, binding strip, white ruled label, COMPOSITION, outlined ghost, outlined pumpkin. Then write down what you infer: the label inversion, the group-costume logic, the two-scale reading. Keep the two lists separate. Expected output: a short observation list that any viewer would agree with, and an interpretation list that is clearly marked as yours.
  6. Verify the boundary claims. Confirm that the listing describes a printed notebook cover and not a physical notebook. Expected output: the retail observation states that the costume is a printed notebook cover. Verdict: the shirt is a surface, and the reading should not claim three-dimensional construction.
  7. Stop at the evidence. Do not add claims about fabric, fit, washing, customer reaction, or popularity. The image does not support them. Expected output: a reading that is complete without them.

Verification step: after completing the procedure, you should be able to state the design’s hierarchy in one sentence without using the word “cute” or any claim about wearing it. If you cannot, you have drifted from the artwork into marketing. Return to step 2 and start again from the shape.

Classify the Pause Before You Blame the GC: Reading GCSuspendEEBegin/GCStart Pairs in a Production Trace

A long Gen2 pause shows up in the trace. Someone writes “blocking Gen2” in the incident channel, and the next two hours go into heap size, LOH allocation rate, and whether to raise the container memory limit. That investigation may be aimed at the wrong event. The first question is not how big the heap is. It is which event sequence produced the timestamp difference you are looking at.

The runtime gives you two cheap discriminators: the Type field on GCStart and the Reason field on GCSuspendEEBegin. Read them before you read promotion numbers. This article is a classification procedure, not a root-cause procedure. It tells you what the pair can establish, what it cannot, and where to stop and collect more events.

What the fields actually say

The .NET runtime GC event reference defines GCStart_V1 (event ID 1) with a Type field that separates three cases: 0x0 is a blocking garbage collection outside background GC, 0x1 is a background garbage collection, and 0x2 is a blocking garbage collection that occurred during background GC (.NET runtime garbage collection events). That single field is the primary classifier. If you have not read it, you do not yet know what kind of pause you are measuring.

GCSuspendEEBegin_V1 (event ID 9) carries a Reason field. The values that matter for this procedure are 0x1 (Suspend for GC) and 0x6 (Suspend for GC Prep). The same reference lists the others: app domain shutdown, code pitching, shutdown, debugger, and debugger sweep. The reason tells you why the execution engine was suspended; the GCStart type tells you what kind of collection the suspension belongs to. You need both.

Promotion is a separate signal. GCHeapStats reports TotalPromotedSize0 (bytes promoted from generation 0 to generation 1) and TotalPromotedSize1 (bytes promoted from generation 1 to generation 2), among other fields. Those numbers are not derivable from the suspend/start pair. If your incident summary says “background GC promotion caused the latency,” the pair did not tell you that. Something else did, or nothing did.

The two canonical sequences

For a blocking GC, the published ordering is simple. Maoni Stephens documents it in the GC ETW series: GCSuspendEE, GCSuspendEEEnd, GCStart, GCEnd, GCRestartEEBegin, GCRestartEEEnd (GC ETW Events – Part 3). Suspension completes, the collection runs, resumption completes. One suspension window, one collection.

A background GC is not that shape. The same post lays out the ordering: an initial suspension and resumption, then GCStart with Type 0x1, then zero or more foreground gen0/gen1 collections inside the background GC’s lifetime, then a second suspension and resumption, then GCEnd. The second suspension uses the SuspendForGCPrep reason, distinct from the first suspension’s SuspendForGC reason, as Stephens describes in the memory performance workflow post.

Foreground collections are the ones that stop everything. Microsoft’s background GC documentation states that a collection on ephemeral generations during background GC is a foreground collection, and when foreground collections occur, all managed threads are suspended (Background garbage collection). So a background GC envelope can contain real stop-the-world windows that belong to foreground gen0/gen1 collections, not to the background collection itself.

This is why a single pause number for a background GC is misleading. Stephens notes that the pause shown for a background GC in GCStats is the sum of its two pauses, not one suspension window. If you treat that sum as one blocking stop-the-world event, you overstate the blocking impact and you aim the investigation at the wrong thing.

Walk the trace

Collect a GC-only trace first. dotnet-trace offers the gc-collect profile, documented as tracking GC collections only at very low overhead (dotnet-trace). That is the right starting point when you need to classify before you need to explain. Record the exact provider and keyword configuration alongside the trace file. Instrumentation changes the trace, and you will need to know what was enabled when you interpret pause counts.

Then, in the trace viewer, filter to GC events and anchor on the pause start timestamp. For each candidate pause, read the events in order and answer three questions:

  1. Is there a GCStart with Type 0x1 whose GCEnd encloses this suspension? If yes, you are inside a background GC envelope.
  2. What is the Reason on the GCSuspendEEBegin? 0x1 (Suspend for GC) at the start of the envelope, or 0x6 (Suspend for GC Prep) at the second suspension, are the expected values for a background GC.
  3. Is there a nested GCStart/GCEnd pair with Type 0x0 or 0x2 inside the envelope? That is a foreground or blocking-during-background collection, and its suspension window is the one that stopped managed threads.

Classify each pause into one of three buckets before you measure anything:

  • Blocking outside background GC. GCStart Type 0x0, single suspend/start/end/restart sequence. The pause is one suspension window.
  • Background GC envelope. GCStart Type 0x1. The envelope contains two suspension windows, and possibly interior foreground collections. Do not report the envelope’s total duration as a blocking pause.
  • Blocking during background GC. GCStart Type 0x2, nested inside a 0x1 envelope. This is a real blocking collection; attribute its suspension window to it, not to the enclosing background GC.

If a SuspendForGCPrep suspension appears without an enclosing background GCStart/GCEnd, that is an investigation lead, not a conclusion. It may mean your filter dropped events, your trace started mid-envelope, or the event stream is incomplete. Check the trace boundaries and the enabled keywords before you write a theory.

What the pair cannot tell you

The pair classifies. It does not explain. Specifically:

  • Promotion volume. Read GCHeapStats for TotalPromotedSize0 and TotalPromotedSize1. The suspend/start pair carries no promotion data.
  • Allocation source. GCAllocationTick events and the Reason on GCStart (for example, 0x0 small object heap allocation versus 0x4 large object heap allocation) point at what triggered the collection. Trigger reason is not the same as condemned reason; the runtime can escalate the generation it collects after the trigger.
  • Root cause. A long suspension window can be caused by work outside the GC itself. To see what the runtime was doing during a suspension, you need CPU samples or additional runtime events in the same trace. The pair tells you where to look, not what you will find.

There is also an instrumentation trap. Stephens documents that enabling GCHeapSurvivalAndMovementKeyword events adds a third pause during a background GC, because the managed threads must be paused to fire those events. If your trace has survival/movement events enabled and you see three suspensions in a background envelope, the third may be an artifact of your own collection configuration. Record the configuration with the trace so you can tell product behavior from measurement behavior.

A worked reading, using published ordering only

Suppose the trace shows, in order: GCSuspendEEBegin (Reason 0x1), GCSuspendEEEnd, GCStart (Type 0x1, Depth 2), then a nested GCSuspendEEBegin (Reason 0x1), GCSuspendEEEnd, GCStart (Type 0x0, Depth 0), GCEnd, GCRestartEEBegin, GCRestartEEEnd, then a second GCSuspendEEBegin (Reason 0x6), GCSuspendEEEnd, GCRestartEEBegin, GCRestartEEEnd, and finally GCEnd for the background collection.

The classification is: one background GC envelope, one interior foreground gen0 collection, two background suspension windows. The blocking pause that affected request latency is the foreground gen0 collection’s suspension window, not the background envelope’s total duration. If a dashboard reported the envelope as a single 170 ms pause, that number is a sum of two suspension windows plus the interior foreground collection’s window, and it does not describe any single stop-the-world event.

What you still do not know: how many bytes were promoted, which allocations triggered the foreground collection, or whether the suspension window was dominated by GC work or by something else in the runtime. Those require GCHeapStats, allocation ticks, and CPU samples respectively. The classification step is done; the causation step has not started.

Checklist for the next trace

  1. Record the trace configuration: providers, keywords, profile, and whether survival/movement events were enabled.
  2. Filter to GC events and list every GCStart with its Type and Depth.
  3. For each suspension, read the GCSuspendEEBegin Reason and find the enclosing GCStart.
  4. Classify each pause as blocking outside background GC, background envelope, or blocking during background GC.
  5. Only then measure: suspension window durations for the classified blocking events, and GCHeapStats promotion fields for the collections you care about.
  6. Correlate with CPU samples or additional runtime events before writing a root cause.
  7. In the incident summary, state which classification the evidence supports and which it does not. “Background GC envelope with an interior foreground gen0 collection” is a defensible sentence. “Blocking Gen2 caused the latency” is not, unless the Type field and the suspension window say so.

The discipline is boring and it saves time. Classify first, measure second, correlate third. The event pair is cheap; the misdiagnosis is not.

FAQ

Can I tell background GC promotion from blocking Gen2 using only GCSuspendEEBegin and GCStart?

You can classify the collection type and the suspension reason. You cannot measure promotion from those events. Promotion is reported by GCHeapStats fields such as TotalPromotedSize0 and TotalPromotedSize1. Treat the pair as a classifier and the heap stats as the measurement.

Why does my trace show three suspensions inside one background GC?

Check whether GCHeapSurvivalAndMovementKeyword events were enabled. According to Stephens, enabling those events adds a third pause during a background GC because the runtime must pause managed threads to fire them. If the keyword was on, the third suspension may be an artifact of the trace configuration rather than product behavior.

Is a long background GC pause a runtime bug?

Not by itself. A long suspension window is a measurement that needs explanation. It can come from GC work, from work outside the GC in the runtime, or from instrumentation. Collect CPU samples or additional runtime events before attributing it to a defect.

Does this procedure differ across .NET 6, 7, 8, and 9?

The event reference used here documents the GCStart Type and GCSuspendEEBegin Reason fields without version-splitting them. If you need a version-scoped claim, verify the field semantics against the reference for the specific runtime version in the trace before you write it down.

The Caution Triangle Is the Point: Reading ‘Not Friendly Do Not Touch’ as a Boundary Sign

The shirt reads NOT FRIENDLY DO NOT TOUCH in warning-sign lettering. Above or beside the words sits a yellow caution triangle, and inside or alongside it a hand with a diagonal slash through it. That is the whole design. No slogan, no secondary joke, no decorative flourish. The object is a public-sign grammar applied to a person, and the interesting question is not whether it is funny — it is what kind of promise the sign is actually making.

I want to read the artwork closely, because the caution triangle is doing more work than the words. A caution triangle is not a prohibition sign. In the visual vocabulary most readers have absorbed from roadways, workplaces, and equipment labels, a yellow triangle with a black border means hazard ahead, proceed with attention. A red circle with a slash means do not do this. The shirt borrows the triangle’s color and shape but pairs it with a crossed-out hand, which is the prohibition gesture. The result is a hybrid: it warns and forbids at the same time, and that ambiguity is the design’s real content.

That matters because the words alone are blunt to the point of rudeness. Not friendly is a verdict on the wearer. Do not touch is an instruction to everyone else. Stacked in warning-sign typography, the two lines read less like a personality and more like a facility notice — the kind of label you would find on a locked cabinet or a piece of energized equipment. The crossed-out hand reinforces the physical boundary. The triangle softens it, slightly, by framing the boundary as a hazard to be respected rather than an insult to be delivered.

I read the design as a boundary statement that borrows institutional authority to make a personal claim. The wearer is not saying I am dangerous. The wearer is saying this is a controlled area, and the control is mine. The caution triangle is the tell: it treats proximity as a risk the reader is responsible for managing. That is a different move from a shirt that simply says introvert or leave me alone. Those are confessions. This is a sign.

There is a practical distinction underneath the joke, and it is the one I keep returning to. A slogan is a sentence. A sign is a contract. A sentence can be ignored without consequence; a sign implies that something happens if you disregard it. The shirt’s humor depends on the gap between the two: it adopts the contract form while offering no enforcement mechanism beyond a printed hand with a slash through it. The wearer cannot actually prevent a tap on the shoulder. The sign is a request dressed as a rule, and the costume is the joke.

That gap is also why the design works better than a plain do not touch shirt would. A bare instruction is just rude. The warning-sign frame adds a second layer: it acknowledges that the boundary is being announced in advance, publicly, in a format everyone already knows how to read. The wearer is not springing a mood on anyone. The terms are posted. Whether the reader honors them is the reader’s problem, which is exactly what a caution sign does — it shifts responsibility for the hazard onto the person approaching it.

I would not claim the shirt changes anyone’s behavior, and I have no evidence about how it performs in a room. What I can say is that the design is legible at a glance, which is the minimum requirement for a sign. The lettering is set in the blocky, condensed style associated with industrial warnings. The yellow triangle provides the only strong color against the garment, so the eye lands there first, then reads the words. The crossed-out hand is a pictogram, not a sentence, which means it works even before the text is parsed. The hierarchy is correct: symbol, then instruction, then verdict.

That hierarchy is worth naming because it is the same hierarchy a good error message uses. A diagnostic alert that leads with a symbol and a short instruction, then supplies the detail, is easier to act on than a paragraph. The shirt is not a diagnostic tool and I am not going to pretend it demonstrates anything about software. But the visual logic — signal first, words second — is the same logic that makes a warning label usable. The design understands that the reader has about one second to decide whether to keep approaching.

The introvert framing in the listing title is a separate claim from the artwork. The shirt does not print the word introvert. It prints a boundary. The listing’s title connects the two, and the connection is plausible as a reading — a person who wants fewer spontaneous touches is making a recognizable request — but the design itself is broader than that. It is a sign for anyone who wants the terms of approach stated in advance. The introvert label narrows the audience; the artwork does not.

If you want the object itself, the listing is here: Not Friendly Do Not Touch Funny Warning Sign Introvert. I am describing the printed design as observed, not reporting a wearing experience or a customer reaction. The shirt is a standard t-shirt from Quirky Cotton Collective, and the artwork is the warning-sign composition described above.

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

The reason I think the design is worth more than a glance is that it gets the sign grammar mostly right, and the one place it bends the grammar is the place where the joke lives. A pure prohibition sign would be hostile. A pure caution sign would be vague. The hybrid — caution triangle plus crossed-out hand plus blunt verdict — produces a message that is simultaneously a warning and a refusal, and that combination is a fair description of how a lot of people would like to be approached at work, on a train, or in a hallway. The shirt is not a personality test. It is a posted notice, and the notice is doing exactly what a notice should: telling you what to expect before you get close enough to find out the hard way.

The Dashed Circle and the Solid Ball: Reading the Physics of ‘I Had Potential’

The shirt reads I HAD POTENTIAL in white capitals. Beneath the words, a white curved ramp descends from an upper-left ledge to a lower-right flat. At the top of the ramp, a dashed empty circle. At the bottom, a solid white ball. The ramp is curved, not a straight diagonal. That curvature is the whole argument.

Most slogan shirts stop at the sentence. This one draws a diagram and lets the diagram contradict the sentence. The words say had — past tense, finished, a verdict already delivered. The drawing says still rolling — a ball at rest on a lower ledge, having completed the descent, not destroyed by it. The dashed circle at the top is where the ball used to be. The solid ball at the bottom is where it is now. The shirt is not a eulogy for potential. It is a position report.

That distinction matters because the phrase I had potential is usually delivered as self-deprecation, and self-deprecation is cheap. It costs nothing to say you wasted something. It costs something to draw the waste as a physical event with a before and after. The dashed circle is the before: an outline, a placeholder, a shape that could have been filled. The solid ball is the after: an object with mass, sitting on a flat surface, subject to gravity and friction and whatever comes next. The shirt does not say the ball is stuck. It says the ball is here.

I read the dashed circle as a boundary marker, not a ghost. In physics diagrams, a dashed outline often denotes a position that is not currently occupied — a reference point, a limit, a state that has been vacated. The ball did not evaporate from the top ledge. It left. The dashed circle is the record of where it was, and the solid ball is the evidence of where it went. The shirt is a conservation law in cotton: nothing was lost, only relocated.

The curved ramp is the second argument. A straight diagonal would imply a constant slope, a uniform failure, a clean slide from high to low. A curve implies acceleration — the ball speeds up as it descends, which is what gravity does to a rolling object on a curved track. The shape of the ramp is not decorative. It is the difference between I declined steadily and I got going and could not stop. The shirt chooses the second. That is a more specific confession, and a funnier one, because it admits momentum. Potential that is lost slowly is tragic. Potential that is lost at increasing speed is a physics problem.

The ball itself is solid white, the same color as the words and the ramp. There is no shading, no motion lines, no arrow. The design refuses to tell you whether the ball is still moving or has come to rest. That ambiguity is the point. A ball on a flat lower ledge could be decelerating toward a stop, or it could be at rest, or it could be about to roll off the edge of the shirt entirely. The diagram does not resolve it. The sentence does not resolve it either — had is past tense, but the ball is present. The shirt holds both tenses at once and lets the reader decide which one is winning.

This is where the shirt earns its place as an object rather than a joke. A slogan shirt asks you to agree with a sentence. A diagram shirt asks you to read a relationship. The relationship here is between a dashed outline and a solid object, between a high ledge and a low flat, between a curve and a straight line that was not chosen. The words I HAD POTENTIAL are the caption. The drawing is the data. And the data does not fully support the caption, which is why the shirt is funny instead of sad.

I have seen enough incident reports to distrust any summary that arrives before the evidence. I had potential is a summary. The ramp and the ball are the evidence. The summary says the story is over. The evidence says the ball is still on the table. If I were reading this shirt the way I read a dump file, I would mark the dashed circle as a freed handle — a reference that no longer points to a live object — and the solid ball as the surviving allocation. The shirt is a memory diagram of a self. The top of the ramp is the heap that was collected. The bottom is what is still reachable.

That reading is an interpretation, not a claim about what the designer intended. The visual observation is literal: white capitals, a white curved descending ramp, a dashed empty circle at the upper left ledge, a solid white ball at the lower right flat ledge. Everything beyond that is my reading of the composition. I am not asserting that the shirt depicts a specific physical experiment, a named equation, or a real event. I am asserting that the drawing has a structure, and the structure is doing work the sentence cannot do alone.

The shirt is sold as I Had Potential Funny Physics Pun Sarcastic Minimalist Quote by Quirky Cotton Collective. The retail title calls it a physics pun, which is fair — potential is a physics term, and the ramp is a physics object. But the pun is not the whole design. The pun is the entry point. The diagram is the argument. A shirt that only said I had potential would be a bumper sticker. A shirt that draws the potential as a ball on a curved ramp is a small essay about momentum, rest, and the difference between a state that has been vacated and a state that has been destroyed.

What I keep returning to is the empty circle. It is dashed, which means it is not a hole. It is a boundary. It marks the place where the ball was, and it remains visible after the ball has left. That is not how loss usually works. Loss removes the outline. This shirt keeps the outline and moves the object. The top ledge is still there. The dashed circle is still there. The ball is still there, just lower. The sentence says had. The drawing says had, and still has a position. The tension between those two statements is the entire shirt.

If you wear it, you are not wearing a confession. You are wearing a diagram that refuses to close the case. The ball is on the lower ledge. The dashed circle is empty. The ramp is curved. The words are past tense. The drawing is present tense. The shirt does not resolve the contradiction, and that is why it works.

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

The Notification That Never Says What to Do: Reading the ‘There Is Motion at Your Front Door’ Shirt

The banner is the first thing you read, and it is a sentence with no verb of consequence: There is motion at your front door. A small bell icon sits to its left, the rounded white rectangle floats above the image the way a phone notification floats above a lock screen, and the whole composition is arranged so your eye lands on the words before it lands on the cat. That ordering is the joke, and it is also the argument. The shirt is not about a cat. It is about a message that reports a condition and withholds a decision.

Below the banner, inside a circular frame, an orange tabby is pressed so close to the lens that its face fills the aperture. The eyes are wide. The porch siding and the lights behind it are visible but secondary, blurred into the background the way a real doorbell camera renders anything that is not directly in front of the sensor. The circle is green-tinted, which is the color a night-vision feed takes on when the infrared illuminator is doing the work and the ambient light is not. None of this is a claim about how the camera works; it is what the printed artwork shows. The green tint, the circular crop, the extreme close-up — these are the visual grammar of a doorbell camera, reproduced faithfully enough that you recognize the frame before you read a single word.

What makes the design worth looking at is the mismatch between the two halves. The banner is calm, procedural, almost bureaucratic: a system has detected motion, and it is telling you so. The image is the opposite of calm. The cat is not a threat, not a package, not a person — it is a face with no context, occupying the entire field of view, and the notification has no vocabulary for it. The sentence is true. There is motion at the front door. The sentence is also useless. It does not tell you whether to open the door, ignore the alert, or check the clip. It reports. It does not decide.

That is the reading I keep coming back to, and it is why the shirt works as more than a cat picture. Anyone who has spent time on call recognizes the shape of the message. A monitoring system fires an alert that says a threshold was crossed, a process exited, a latency figure moved. The alert is accurate. The alert is also, frequently, not the thing you need. The gap between something happened and here is what to do about it is where most of the work lives, and this shirt puts that gap on a notification banner and then fills the rest of the frame with a cat that has clearly decided the matter for itself.

The cat, in other words, is the context the notification lacks. The banner tells you motion exists. The image tells you what the motion is, and the answer is: a wide-eyed orange tabby with its nose against the glass, which is to say, nothing you need to act on and everything you might want to look at. The design does not resolve the tension so much as display it. The system did its job. The system’s job was not enough. The human — or the cat — supplies the rest.

I want to be careful about what I am and am not claiming here. The artwork is a meme shirt; the phrase there is motion at your front door is the kind of wording that circulates because it is immediately legible to anyone who has ever glanced at a phone and seen a doorbell alert. I am not asserting where the phrase originated, which platform popularized it, or what any recommendation system does with it. Those are empirical questions and I have no retrieved evidence for them. What I can say is what the printed design shows: a white rounded banner with a bell, the sentence in plain type, and beneath it a circular green-tinted view of an orange tabby very close to the lens, porch siding and lights behind. That is the object. The interpretation is mine.

The interpretation, though, is not arbitrary. The composition makes a specific choice: it puts the notification above the image, which is the order in which a real alert arrives. You see the banner first. You see the feed second. The shirt reproduces that sequence, and in doing so it reproduces the small moment of disappointment that comes with every doorbell alert — the moment when the system tells you something is happening and you have to look to find out whether it matters. Most of the time it does not. Sometimes it is a cat. The shirt is on the side of the cat.

There is a version of this design that would be meaner — a cat caught mid-something, a shredded package, a mess on the porch. This one is not mean. The cat is wide-eyed and close and essentially harmless, and the joke is gentle: the system escalated, the system was right, and the escalation was a cat. That gentleness is part of the argument. The notification is not wrong to fire. It is just not equipped to tell you what it found. The image is. The division of labor between the two halves of the shirt is the whole design.

If you want the object itself, it is the There Is Motion At Your Front Door Funny Cat Doorbell Meme shirt from Quirky Cotton Collective, and the listing shows the standard t-shirt with the artwork as described. I am not going to tell you how it wears, because I have not worn it, and I am not going to tell you it is popular, because I have not measured that. What I can tell you is what the design does, which is put a terse system message and a very close cat in the same frame and let the gap between them do the work.

The reason I think that gap is worth a column is that it is the same gap technical readers spend their days closing. An alert is a banner. A dump is a feed. The banner tells you motion exists; the feed tells you what the motion is. The skill is not in reading either one. The skill is in knowing that the banner is never the whole story, and that the thing pressed up against the lens — the wide-eyed, uncontextualized, slightly absurd thing — is usually where the actual answer lives. This shirt is a joke about a cat. It is also, if you squint, a diagram of every incident channel I have ever been in.

Editorial note: this publication and Quirky Cotton Collective share an owner, so this is not an independent review.

DOTNET_GCHeapHardLimitPercent vs the cgroup OOM Killer: Which Number Wins When a .NET 8 Container Dies at 512MB

The question is malformed, and the malformation is why the pod keeps dying. DOTNET_GCHeapHardLimitPercent and the cgroup OOM killer are not two thresholds racing to the same finish line. One bounds the commit size of the GC heap and GC bookkeeping. The other fires on cgroup-level memory usage that includes memory the GC limit never promised to bound. They do not compete. They measure different things, and only one of them can kill your process.

What follows is a triage order for a 512MB container that died. Forty minutes, one pod, no guessing.

What the GC limit actually bounds

Microsoft defines the heap hard limit precisely: “the maximum commit size, in bytes, for the GC heap and GC bookkeeping.” That is the whole contract. It is not a process memory limit, not an RSS limit, and not a cgroup limit.

In a container, the runtime treats the cgroup memory limit as total physical memory. The documentation states: “If the process runs inside an environment with a set memory limit (for example, a container), that limit is treated as the total physical memory. In such environments, the default value is 75%.” At 512MB, the default managed budget is therefore roughly 384MB of GC heap plus bookkeeping. The remaining ~128MB is expected to cover the runtime, native allocations, mapped images, thread stacks, and whatever else the process touches.

That expectation is the failure mode. The GC will happily keep its heap under 384MB while the process crosses 512MB in native memory, and the kernel kills the container. No managed OutOfMemoryException. No GC log entry. Just a SIGKILL and a restart count.

Which number is actually in effect

Before you tune anything, establish what the runtime read at startup. The precedence rules are documented and they are not intuitive:

  • HeapHardLimitPercent is ignored if per-object-heap hard limits or the byte-based heap hard limit are configured.
  • Per-object-heap percent settings are ignored if DOTNET_GCHeapHardLimitSOH, DOTNET_GCHeapHardLimitLOH, and DOTNET_GCHeapHardLimitPOH are specified.
  • If you set any per-object-heap byte limit, you must set SOH and LOH together or the runtime fails to initialize.

Then the format trap. The docs are explicit: “For number values, use decimal notation for settings in the runtimeconfig.json or runtimeconfig.template.json file and hexadecimal notation for environment variable settings.” A value of 30 in runtimeconfig.json means 30 percent. A value of 30 in DOTNET_GCHeapHardLimitPercent means 0x30, which is 48 percent. If your post-mortem says “we set 30” and the effective limit looks wrong, this is why.

And the timing trap: “These configurations are only read by the runtime when the GC is initialized (usually this means during the process startup time). If you change an environment variable when a process is already running, the change won’t be reflected in that process.” A live kubectl exec that exports a new value changes nothing. The pod must be recreated.

Record the effective configuration as the runtime saw it, not as the manifest claims. The docs point to GC.GetConfigurationVariables() as the way to inspect values in use at runtime. Put that output in the incident record.

Step 1: Did the process kill itself, or was it killed?

This is the fork in the road. Everything downstream depends on the answer.

If the process self-terminated with a managed OOM, a dump collected on crash will show it. Enable dump generation with DOTNET_DbgEnableMiniDump=1 and select the type with DOTNET_DbgMiniDumpType; the documented default is 2 (Heap). Then open the dump with dotnet-dump analyze and run analyzeoom, which “displays the info of the last OOM that occurred on an allocation request to the GC heap.” For an unhandled exception that killed the app, pe -lines prints the exception object and stack.

If the dump shows no managed OOM and the process simply vanished, you are looking at an external kill. The GC heap limit is not the prime suspect. Stop tuning it.

One caveat that has burned people: collecting the dump can itself trigger the kill. The dotnet-dump documentation warns that “collecting a full or heap dump may cause the OS to page in substantial virtual memory for the target process. If the target process is running in a container with an enforced memory limit, the increased memory usage may cause the OS to terminate the container if the limit was exceeded.” At 512MB, a Heap dump is a large fraction of the budget. If the pod dies during dump collection, you have learned something about headroom, not about the original fault.

Step 2: Was the managed heap near its limit?

You need counters from before the death, not after. dotnet-counters is the first-level tool here. The relevant signals are dotnet.gc.last_collection.heap.size by generation, dotnet.gc.last_collection.memory.committed_size, dotnet.gc.heap.total_allocated, and dotnet.process.memory.working_set.

Read them together. Two patterns matter:

  • Managed heap at or near the configured limit, committed size climbing, working set tracking it. The GC budget is the binding constraint. Tuning the limit is a legitimate response, but only after you understand why the workload needs more managed memory than 75% of 512MB allows.
  • Managed heap flat or well below the limit while working set and cgroup usage climb. The growth is outside the GC heap. Lowering DOTNET_GCHeapHardLimitPercent shrinks the managed budget without touching the actual growth. That is the wrong knob, and turning it will make the next incident arrive sooner.

Version note: “If the app uses .NET version 8 or lower, the System.Runtime Meter doesn’t exist in those versions and dotnet-counters will fall back to display the older System.Runtime EventCounters instead.” On .NET 8 you will see the EventCounter layout, not the Meter layout. The numbers are still there; the names differ.

Step 3: Account for memory the GC limit does not cover

This is where most 512MB container deaths actually live. The GC limit bounds managed heap commit. It says nothing about:

  • Native allocations from interop, cryptography, networking stacks, or third-party libraries.
  • Mapped images and the runtime itself.
  • Thread stacks, which multiply with thread pool growth.
  • File cache, which cgroup accounting includes.

The file cache point is documented in a G-Research write-up of a GC issue they traced and fixed: “On Linux, Kubernetes uses Docker to run our application. Docker limits memory usage via a cgroup. Cgroup memory limits (and usage figures) include the file cache.” That post describes a .NET 5-era problem where the GC misread cgroup usage that included file cache and entered aggressive GC mode. The fix landed for .NET 6 preview and as a .NET 5 servicing patch. Do not assume the same mechanism is your .NET 8 fault; the point that survives is the accounting one. Cgroup usage includes memory the GC does not manage.

So when managed heap is flat and cgroup usage climbs, the investigation moves to native memory, mapped images, file cache, dump collection overhead, and co-tenant processes. Not to the GC percent.

The multi-process trap

If your container runs more than one .NET process, the arithmetic changes. Each process applies its own percentage to the same cgroup limit. Two .NET processes at the default 75% of 512MB each budget ~384MB of managed heap. The sum exceeds the container limit before either process has done anything unusual.

A runtime collaborator addressed exactly this in a dotnet/runtime discussion: “With 3.0, the heap limits were introduced which cause a single process to nicely stay within the limits. If you’re running multiple .NET apps in a container, they will have the same issues as the single process containers before 3.0.” The same thread contains a reported case where a single-process container produced a GC OutOfMemoryException at the 75% limit, while a multi-process container was terminated by the OOM killer or the scheduler. That is the signature: managed OOM in one case, external kill in the other, same limit.

If you cannot split the processes into separate containers, you must divide the budget deliberately and record the division. The default assumes one process per cgroup.

The decision procedure

Given a 512MB container death, in order:

  1. Collect the dump on crash. Set DOTNET_DbgEnableMiniDump=1 and choose a dump type that fits your headroom. If dump collection kills the pod, note that and reduce the dump type or raise the limit temporarily.
  2. Run analyzeoom and pe. If there is a managed OOM, the GC heap limit is in play. If not, it is not.
  3. Pull the counter timeline. Compare managed heap size and committed size against working set. Divergence means the growth is outside the GC heap.
  4. Check the effective configuration. Confirm which of the hard-limit settings actually applied, in the correct number base, as read at startup.
  5. Count the .NET processes in the cgroup. Multiply the per-process budget by that count and compare to the container limit.
  6. Only then tune. If managed heap was at the limit, raise or lower the limit with a stated reason. If managed heap was flat, leave the GC settings alone and pursue native memory, file cache, or co-tenants.

What goes in the post-mortem

So the next incident is diagnosable in minutes rather than hours, record:

  • The effective GC configuration as the runtime reported it, including which hard-limit setting won and the number base used.
  • The cgroup limit and cgroup usage at the moment of death, not the average over the hour.
  • The dump type collected and whether collection completed before termination.
  • The counter timeline for managed heap size, committed size, and working set, with timestamps aligned to the death.
  • The count of .NET processes sharing the cgroup.

The number that wins is not the GC percent or the OOM killer threshold. It is whichever accounting boundary the process actually crossed. Find that boundary first. The rest is configuration.

FAQ

Does DOTNET_GCHeapHardLimitPercent prevent cgroup OOM kills?

No. It bounds the GC heap and bookkeeping commit size. The cgroup OOM killer responds to total cgroup memory usage, which includes native memory, mapped images, and file cache. A process can honor its GC limit and still be killed.

Why did my environment variable change have no effect?

GC configuration is read when the GC initializes, typically at process startup. Changing the variable in a running process does nothing. Recreate the process.

I set 30 and got 48 percent. Why?

Environment variable values are hexadecimal. 30 is 0x30, which is 48. Use decimal in runtimeconfig.json and hexadecimal in environment variables, or convert deliberately.

Can collecting a dump kill the container?

Yes. The dotnet-dump documentation warns that full or heap dump collection can page in substantial virtual memory and push a memory-limited container over its limit. Test your dump configuration against your actual headroom.

Two .NET processes in one 512MB container. What is the managed budget?

Each process applies the percentage independently to the same cgroup limit. At the default 75%, each budgets roughly 384MB of managed heap. The sum exceeds the container limit. Split the processes or divide the budget explicitly.

Where are the primary sources?

The GC configuration semantics, precedence, and number-base rules are in the runtime configuration options for garbage collection. Dump collection and analysis commands are in dotnet-dump and Collect dumps on crash. Counter names and the .NET 8 fallback behavior are in dotnet-counters. The multi-process container discussion is dotnet/runtime discussion 84828. The cgroup file-cache accounting point is from G-Research.

The Loudest Word on the Shirt Is a Shrug: Reading the Large Bold ‘meh’ Typography

The native garment preview shows large bold white lowercase meh. lettering on a dark shirt. No animal illustration is present. That is the entire design: four letters, a period, and a lot of dark fabric around them. The word is set in a heavy sans-serif, all lowercase, and it occupies the chest like a headline. The period is not decorative. It closes the sentence before the sentence has a chance to become a conversation.

I want to argue that the shirt is not really about apathy. It is about the visual mismatch between a word that means I have no strong opinion and a typographic treatment that insists on being read from across a room. The design is loud about being unimpressed. That contradiction is the joke, and it is also the reason the shirt works as an object rather than a slogan.

The word and the volume

Meh is a shrug in letters. It is the sound of a verdict that has given up on being a verdict. In ordinary conversation, it arrives quietly, often with a shoulder movement and a change of subject. Set in large bold white type on a dark background, it does the opposite: it demands attention, occupies space, and refuses to be overlooked. The shirt takes a word that signals low stakes and renders it at the scale of a band logo or a warning label.

That is not a failure of design. It is the design. The visual loudness is the argument. If the word were set in small gray type near the hem, the shirt would be a private joke for people who lean in. At chest scale, it becomes a public statement about not making public statements. The wearer is not saying I don’t care quietly. They are saying it at billboard size, which is a different and more interesting claim.

The lowercase matters here. Capital letters would make MEH a declaration, possibly an angry one. Lowercase keeps the word casual, almost mumbled, even at large scale. The period is the only piece of punctuation, and it does the work of a closed door. It is not an ellipsis. It does not trail off. It ends. The word is not inviting follow-up questions.

Why a period changes the tone

Without the period, meh is a sound. With the period, it is a sentence. That small mark turns a noise into a verdict, and a verdict is a social act. It says: I have considered the matter and this is my final answer. The fact that the answer is meh is what makes it funny. The shirt is not expressing indecision. It is expressing a settled lack of enthusiasm, delivered with the finality of a period.

This is the same reason terse messages in technical work can read as hostile when they were not intended that way. A one-word reply, a closed ticket with no comment, a pull request approved without a note — these are periods in conversational form. They end the exchange. The shirt puts that social mechanic on the chest and makes it visible before anyone speaks.

The shirt as a boundary object

I read the design as a boundary marker, not a personality claim. The word does not describe the wearer’s inner state. It describes the wearer’s willingness to engage with whatever is about to be asked of them. That is a useful distinction for people who spend their working lives in environments where every message is expected to produce a reaction. The shirt pre-answers the question. It sets the default to low enthusiasm and lets the wearer opt in if something actually merits it.

This is not the same as rudeness. A boundary is a stated limit, and the shirt states one in four letters. It is more honest than a blank expression, and it is certainly more efficient than explaining, again, that you do not have a strong opinion about the meeting invitation, the reorg announcement, or the third request to align on synergy. The period does the work that a longer sentence would otherwise have to do.

The absence of an animal illustration is worth noting because it keeps the design from becoming a mascot. There is no sloth, no cat, no cartoon creature to soften the word. The typography has to carry the entire tone, and it does. A mascot would make the shirt cute. The bare word makes it dry. Dry humor depends on not explaining itself, and this design does not explain itself at all.

What the shirt is not

It is not a diagnostic tool, and it does not demonstrate anything about software, security, or engineering outcomes. It is a piece of clothing with a word on it. I am reading the visual composition, not claiming the shirt improves anything or predicts anything about the wearer’s technical judgment. The observation is narrow: large bold lowercase type, a period, a dark background, no illustration. The interpretation is mine, and it stops at the edge of the fabric.

It is also not a generic gift recommendation. The reason to look at this specific shirt is the specific typographic decision. A different meh shirt with a different typeface, a different case, or an added illustration would be a different object with a different argument. The large bold lowercase treatment is what makes this one worth reading closely.

If you want the object itself, the listing is here: Meh Funny Sarcastic Saying Introvert Dry Humor. The design is the point, and the design is exactly what the preview shows.

Reading the volume as the message

The useful argument is this: the shirt works because it refuses to resolve the tension between the word and its presentation. Meh means low stakes. Large bold type means high stakes. The period means final. Put together, they produce a dry, self-aware object that is funny precisely because it is overcommitted to being undercommitted. That is a more interesting thing to wear than a shirt that simply announces a mood. It is a small visual essay about the difference between having no opinion and refusing to perform one.

For readers who spend their days in incident channels and code review threads, the shirt reads as a familiar social move: the terse reply that ends the thread. The period is the whole joke. The volume is the punchline. And the dark fabric is the room the word gets to fill.

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

The Element Tiles Spell I W Ti S: Reading the ‘I Wear This Shirt Periodically’ Joke

The shirt reads I WEAR THIS SHIRT PERIODICALLY across the chest, and beneath that sentence sit four periodic-table-style tiles: 53 I, 74 W, 22 Ti, 16 S. The tile symbols are I W Ti S, not a literal spelling of the sentence above them. That gap is the whole design.

Most periodic-table pun shirts work by substitution: you swap letters for element symbols and the sentence reassembles itself. This one doesn’t quite do that. The tiles give you I W Ti S — four symbols that, read aloud, approximate the word periodically only if you already know what the sentence is supposed to say. The top line supplies the meaning; the tiles supply the chemistry costume. Neither line is complete without the other.

That’s a more interesting construction than it first appears. The joke isn’t in the elements. The joke is in the dependency between the two lines — the way the sentence above tells you how to read the tiles below, and the tiles below retroactively justify why the sentence is wearing a lab coat.

What the tiles actually show

Four tiles, each in the visual grammar of a periodic-table cell: atomic number in the upper corner, element symbol centered, and the whole thing boxed. The numbers are real atomic numbers — 53 is iodine, 74 is tungsten, 22 is titanium, 16 is sulfur. The symbols are the real symbols for those elements. Nothing is faked or scrambled.

But the sequence I W Ti S is not a word. It’s a phonetic gesture toward one. Read it as letters and you get four disconnected element abbreviations. Read it as sounds and you get something close to periodically — close enough that the sentence above does the rest of the work. The design trusts you to make that leap, and it rewards you for having taken high-school chemistry.

That’s a specific kind of joke: not a punchline, but a recognition test. If you know the elements, the tiles resolve into a word. If you don’t, they stay four boxes with numbers in them, and the shirt is just a sentence about wearing something occasionally. Both readings are available. Only one is the intended one.

The sentence is doing more work than it looks

I wear this shirt periodically is a strange thing to print on a shirt. It’s a disclaimer, almost. It admits the shirt is not a daily uniform. It positions the wearer as someone who owns the joke but doesn’t live inside it — someone who puts it on for the right occasion and takes it off again.

That’s a different posture from most slogan shirts, which tend to assert identity (I am a chemist, I love science, Trust me, I’m a scientist). This one asserts frequency. It’s a shirt about how often you wear the shirt. The self-reference is the point: the sentence describes the object it’s printed on, and the tiles describe the sentence, and the whole thing folds back on itself in a way that’s more clever than loud.

I think that’s why the design works as a work-culture object rather than a pure novelty. It’s a shirt for people who like a joke enough to own it but not enough to make it their personality. That’s a recognizable stance among engineers, and it’s a stance the shirt encodes in its own wording.

The tiles as a diagram, not a decoration

What makes the tile arrangement more than ornament is that it’s readable. The numbers and symbols follow the actual periodic-table convention. The boxes are laid out in a row, left to right, the way you’d read a word. The design doesn’t scatter the tiles or stylize them into illegibility. It presents them as data.

That’s the same instinct that makes a good technical diagram work: the elements are placed where they belong, labeled with the information that matters, and arranged so the eye can follow the intended sequence. The joke depends on that legibility. If the tiles were decorative, the pun would collapse. They have to be correct for the sentence to land.

I’d stop short of claiming the shirt teaches chemistry or demonstrates anything about the periodic table beyond the four elements it names. It doesn’t. It uses the table’s visual language to set up a wordplay, and it does that cleanly. The accuracy of the tiles is what makes the wordplay possible, not what makes it educational.

Why the gap between sentence and tiles matters

The most interesting thing about this design is that it doesn’t spell the word. It gives you the sentence and the tiles and lets you close the gap yourself. That’s a more generous joke than a direct substitution would be — it assumes a reader who can do the work.

There’s a lesson in that for anyone who writes for technical audiences, though I’d resist pushing it too hard. The shirt isn’t a communication strategy. It’s a shirt. But the structure — statement above, evidence below, meaning in the relationship between them — is the same structure that makes a good incident writeup readable. You don’t spell everything out. You give the reader the pieces and trust them to assemble the verdict.

The difference is that a shirt can afford to be ambiguous. A post-mortem can’t. The shirt’s gap is the joke; a report’s gap is a defect. Same shape, opposite obligation.

What the shirt is, and what it isn’t

It’s a standard t-shirt with a printed design: a sentence and four element tiles. The retail listing describes it as a chemistry science pun, and the visual observation confirms the tiles are 53 I, 74 W, 22 Ti, 16 S. The design is available on the Quirky Cotton Collective listing.

It isn’t a statement about the wearer’s profession, a teaching aid, or a claim about how often anyone actually wears it. The sentence is a joke about the shirt, not a promise about the person inside it. That’s the right level of commitment for a garment like this: it commits to the pun and nothing else.

If you know the elements, the tiles resolve. If you don’t, the sentence still works. Either way, the shirt has done its job — which is to be worn periodically, and to be read closely when it is.


Editorial note: This publication and Quirky Cotton Collective share an owner. This is not an independent review.