10 interesting stories served every morning and every evening.

How Europe is killing makers and micro-entrepreneurs

lectronz.com

Lectronz is a mar­ket­place for open-source hard­ware mak­ers and DIY elec­tron­ics. Most of our sell­ers are not fac­to­ries or well-funded start-ups. They are en­gi­neers, in­de­pen­dent de­sign­ers, and hard­ware en­thu­si­asts work­ing from spare rooms, garages, and tiny work­shops.

Some earn a liv­ing from their prod­ucts. Some sell only a hand­ful of boards each year. Others build ten units sim­ply be­cause they cre­ated some­thing use­ful and want to share it with the com­mu­nity. Occasionally, one of those ex­per­i­ments grows into a real busi­ness. Every Arduino be­gins some­where.

But the European Union’s new pack­ag­ing rules now threaten to kill the world of mak­ers and mi­cro-en­tre­pre­neurs, putting jobs, liveli­hoods and an en­tire ecosys­tem of in­no­va­tion at risk.

And this threat is not just lim­ited to mak­ers and en­gi­neers. It af­fects artists, crafts­peo­ple and other mi­cro-en­tre­pre­neurs sell­ing their work across the EU.

A good idea, a ter­ri­ble im­ple­men­ta­tion

The EU has re­quired pro­duc­ers to take re­spon­si­bil­ity for pack­ag­ing waste for many years through Extended Producer Responsibility (EPR) schemes. The new Packaging and Packaging Waste Regulation (PPWR), which gen­er­ally ap­plies from 12 August 2026, aims to har­monise pack­ag­ing rules across the European Union and re­duce waste.

The main idea of EPR is sen­si­ble: busi­nesses that place pack­ag­ing on the mar­ket should help fi­nance its col­lec­tion and re­cy­cling.

For mak­ers, this means tak­ing re­spon­si­bil­ity for the boxes, en­velopes, plas­tic bags and other pack­ag­ing used to de­liver their prod­ucts. This is an idea we can all get be­hind.

Unfortunately, in­stead of cre­at­ing a sin­gle European sys­tem, the PPWR pre­serves a frag­mented na­tional model. A busi­ness sell­ing di­rectly to cus­tomers across the EU must reg­is­ter and ful­fil its oblig­a­tions sep­a­rately in every Member State where its pack­ag­ing be­comes waste. For large com­pa­nies, this is part of the cost of do­ing busi­ness; for mi­cro-busi­nesses sell­ing only a hand­ful of prod­ucts into each coun­try, the cost and ad­min­is­tra­tive bur­den can be wildly dis­pro­por­tion­ate to the amount of pack­ag­ing in­volved.

Imagine an en­gi­neer in Greece who de­signs a €25 open-source sen­sor board…

During the first year, he sells five to Germany, two to France, two to Austria and one to Belgium. Each ships in a small an­ti­sta­tic bag and a padded en­ve­lope. The amount of pack­ag­ing gen­er­ated for each sale is prob­a­bly around 50 grams.

He has just be­come a pack­ag­ing waste pro­ducer in four coun­tries.

Based on in­dica­tive prices cur­rently quoted by na­tional schemes and com­pli­ance providers, the an­nual cost for France alone can look like this:

Registering for a pack­ag­ing scheme, to­talling €110 in fees per year.

Using the ser­vices of an Authorised rep­re­sen­ta­tive, adding €190 to €300 in costs per year.

Spending time reg­is­ter­ing, doc­u­ment­ing, and re­port­ing waste cre­ated.

These in­dica­tive costs con­tinue to add up for each coun­try:

Belgium: €50 to €100 ad­min­is­tra­tive fees per year, plus the ser­vices of an au­tho­rised rep­re­sen­ta­tive (approx. €250 to €450).

Germany: reg­is­tra­tion is free, but pack­ag­ing-scheme par­tic­i­pa­tion starts at ap­prox­i­mately €10 per year, plus an au­tho­rised rep­re­sen­ta­tive cost­ing around €190 per year.

Austria: €250 ad­min­is­tra­tive fees per year, plus the ser­vices of an au­tho­rised rep­re­sen­ta­tive (approx. €100).

In short, the bar­rier to en­try for these four coun­tries to­tals €1150 per year in an op­ti­mistic sce­nario.

The weight-based en­vi­ron­men­tal con­tri­bu­tion as­so­ci­ated with half a kilo­gram of pack­ag­ing should be mea­sured in cents. The bu­reau­cracy re­quired to ac­count for it is mea­sured in thou­sands of eu­ros.

Now imag­ine you want to sell to all 27 Member States! To make it worth­while, our Greek en­gi­neer needs to sell not 10 boards, not 100, but lit­er­ally thou­sands of boards every year from the very start.

It sim­ply is­n’t worth it any­more.

Killing in­no­va­tion softly

Often, in­no­va­tion does­n’t come from large es­tab­lished cor­po­ra­tions, but from small busi­nesses that start from scratch with new ideas and lit­tle money. Before be­com­ing suc­cess­ful and sell­ing mil­lions of prod­ucts, many com­pa­nies started sell­ing 10, then 100, then 1000. Most busi­nesses never make it there. But there has to be space where ideas can be tested. This is one of the rea­sons Lectronz ex­ists.

In the past year, while some sell­ers on Lectronz sold hun­dreds of prod­ucts, half of our reg­is­tered sell­ers got fewer than 10 or­ders. This is not a bug, but the na­ture of a mar­ket­place like Lectronz where mak­ers are free to ex­per­i­ment with prod­uct ideas. Some ideas don’t work. Some cre­ators on Lectronz only build 10 units and share them with the com­mu­nity with­out mak­ing a profit. But even prod­ucts that fail” have a value. When hard­ware cre­ators share them with the com­mu­nity, they help oth­ers grow as well. One piece of hard­ware may un­lock the cre­ation of an­other, lead­ing to new prod­uct ideas and in­no­va­tion.

The EPR reg­u­la­tions threaten the ex­is­tence of this in­no­v­a­tive space in the EU.

EU pol­i­cy­mak­ers keep sound­ing the alarm about Europe’s lack of in­no­va­tion, but seem hell-bent on mak­ing it as hard as pos­si­ble for in­no­va­tion to emerge at all, with reg­u­la­tions that cre­ate a dis­pro­por­tion­ate bar­rier to en­try for mi­cro-en­ter­prises and SMEs. It’s an en­vi­ron­ment where only big play­ers like Amazon, Temu, or eBay can ex­ist.

Lectronz is also a mi­cro-en­ter­prise

Lectronz col­lects a 5% fee on every trans­ac­tion it processes. We waive this fee on the first five sales to en­cour­age sell­ers to test our plat­form. After years of work, and with the re­cent surge of new sell­ers join­ing our plat­form in 2026, Lectronz now gen­er­ates roughly the equiv­a­lent of one mod­est salary.

I did not build it to be­come the next Amazon. I built it be­cause in­de­pen­dent hard­ware cre­ators de­serve a mar­ket­place de­signed for them.

If these rules force many of our sell­ers to with­draw from the European mar­ket, they could also make Lectronz it­self un­vi­able. After every­thing we have built to­gether, that would be per­son­ally heart­break­ing.

For now, Lectronz sell­ers should not ex­pect any im­me­di­ate dis­rup­tion. It re­mains un­clear how na­tional au­thor­i­ties will en­force these rules against mak­ers and mi­cro-en­ter­prises, and we will con­tinue mon­i­tor­ing the sit­u­a­tion closely.

What are the so­lu­tions?

If these reg­u­la­tions are ap­plied strictly, the short-term so­lu­tion for mak­ers is sim­ple: stop sell­ing in the EU and ship ex­clu­sively to non-EU mar­kets.

Yes, you read that right. For a French mi­cro-en­tre­pre­neur, it makes more sense to ship prod­ucts to the US than to ship to neigh­bour­ing Germany or Belgium, for ex­am­ple. This is true even with any US tar­iffs in place.

Of course, lim­it­ing sales to the US is not a vi­able so­lu­tion for some sell­ers. It’s also a loss for the European econ­omy it­self. I still hope that we can work out re­al­is­tic so­lu­tions that can help re­store the EU sin­gle mar­ket for mi­cro-en­ter­prises. Here are some ideas.

Solution #1: Introduce an EU-wide de min­imis thresh­old.

Exempt small-vol­ume sell­ers and mi­cro-en­ter­prises from cross-bor­der pack­ag­ing oblig­a­tions. The thresh­old would ap­ply only to pro­duc­ers that are be­low a spe­cific vol­ume of waste and/​or a spe­cific yearly turnover.

Solution #2: Create an EU EPR One Stop Shop.

Create a cen­tralised EU por­tal where sell­ers can reg­is­ter, re­port waste, and pay truly rea­son­able fees at once, for all Member States where they ship prod­ucts. This could mimic the mech­a­nism that al­ready ex­ists for VAT with the One Stop Shop (OSS).

Ideally, since we are in 2026, most of this work should be done through a mod­ern open RESTful API (not web forms) and open-source soft­ware, to be as au­to­mated as pos­si­ble.

Solution #3: Allow mar­ket­places to rep­re­sent and man­age mi­cro-en­ter­prises col­lec­tively as if it were a sin­gle pro­ducer.

A mech­a­nism should al­low mar­ket­places like Lectronz or Tindie to reg­is­ter, re­port waste, and pay rea­son­able fees on be­half of all their sell­ers as if they were col­lec­tively one pro­ducer of waste.

This means that the mar­ket­place would pay ad­min­is­tra­tive fees and other EPR costs cor­re­spond­ing to a sin­gle pro­ducer, that would col­lec­tively rep­re­sent all its sell­ers. For Lectronz, this would have a non-triv­ial im­pact in terms of cost and ad­min­is­tra­tive work, but it might be achiev­able un­der the right con­di­tions.

As stated above, us­ing a com­mon API stan­dard for all coun­tries would help au­to­mate things.

Make your voice heard

Again, to re­it­er­ate, we sup­port the idea of re­duc­ing waste and pro­mot­ing sus­tain­abil­ity. But there’s got to be a bet­ter, sim­pler, and fairer way to do it.

This reg­u­la­tion is hav­ing a mas­sive ef­fect on the en­tire ecosys­tem of mi­cro-busi­nesses, not just mak­ers. It af­fects artists who sell their cre­ations on­line. Local tra­di­tional food pro­duc­ers who ex­port their prod­ucts across the EU. It also af­fects crafts­peo­ple who sell their work on­line through their own web­site or ded­i­cated plat­forms like Etsy. Beyond the small world of mak­ers and DIY elec­tron­ics, this will have an im­pact on the liveli­hood of po­ten­tially hun­dreds of thou­sands of peo­ple in the EU.

And to be clear: these rules af­fect not only busi­nesses in the EU, but any busi­ness that sells to buy­ers in the EU.

Jeanette Koňarčíková, an in­de­pen­dent artist and mi­cro-en­tre­pre­neur from Slovakia, launched an on­line pe­ti­tion to draw the at­ten­tion of pol­i­cy­mak­ers to this is­sue:

https://​www.change.org/​p/​stop-de­stroy­ing-eu-mi­cro-busi­nesses-im­me­di­ate-mora­to­rium-on-cross-bor­der-epr-fees

The pe­ti­tion is thought­ful and well-writ­ten. I en­cour­age you to read and sign it!

The European Commission also has an open pub­lic feed­back page for this is­sue here:

https://​ec.eu­ropa.eu/​info/​law/​bet­ter-reg­u­la­tion/​have-your-say/​ini­tia­tives/​15352-Pack­ag­ing-and-pack­ag­ing-waste-rules-on-na­tional-reg­is­ters-of-pro­duc­er­s_en

Consider leav­ing feed­back there as well.

Recently, the European Commission has be­gun to recog­nise part of the prob­lem and has pro­posed sus­pend­ing the re­quire­ment to ap­point an au­tho­rised rep­re­sen­ta­tive in every des­ti­na­tion coun­try un­til 2035. But this pro­posal has not yet been adopted. Unfortunately, this pro­posal may take time to be voted on and en­ter into force. By then, many small busi­nesses may have closed. More im­por­tantly, re­mov­ing the au­tho­rised-rep­re­sen­ta­tive re­quire­ment would ad­dress only part of the prob­lem. Rules like this risk un­der­min­ing trust in the European pro­ject it­self. What’s the point of the EU if the sin­gle mar­ket no longer ex­ists for mi­cro-en­ter­prises?

Here at Lectronz, we will con­tinue to move for­ward and hope for the best.

But make your voice heard now to make sure pol­i­cy­mak­ers un­der­stand the ur­gency of this is­sue!

Microsoft Paint and Photos Embed Server-Issued GUIDs as Invisible Watermarks in Locally-Generated Images

xusheng.dev

Reverse en­gi­neer­ing re­veals how Paint and Photos em­bed a server-is­sued GUID into the pix­els of lo­cally gen­er­ated AI im­ages.

TL;DR

Microsoft Paint sup­ports both lo­cal and cloud im­age gen­er­a­tion

Paint and Photos also ship lo­cal AI mod­els

The two apps send the prompt to a re­mote server for mod­er­a­tion

The server re­turns a GUID along with the mod­er­ated prompt

The GUID is em­bed­ded into the lo­cally gen­er­ated im­age as an in­vis­i­ble wa­ter­mark

A sep­a­rate vis­i­ble-wa­ter­mark set­ting does not con­trol this in­vis­i­ble wa­ter­mark

On Copilot+ PCs, im­age gen­er­a­tion is lo­cal but prompt mod­er­a­tion re­mains re­mote

Microsoft dis­closes that Paint adds C2PA meta­data to AI-generated im­ages

AI-generated im­age saves lim­ited to C2PA-preserving for­mats: PNG, JPEG, GIF, and .paint

A cu­ri­ous look at Microsoft Paint

This re­search started with my cu­rios­ity about Paint. I re­cently had some suc­cess look­ing into less-ex­plored Windows fea­tures like UCPD, WHESCVC, and I have long known that Microsoft added a bunch of AI fea­tures into the Paint app. I do not know if any­one ac­tu­ally uses Paint + AI to gen­er­ate im­ages, but I wanted to see how ex­actly the im­age gen­er­a­tion works.

Before I started, I ex­pected that it sim­ply called a re­mote API to do the im­age gen­er­a­tion. However, af­ter I set up Binary Ninja MCP with Codex and started the analy­sis, I soon re­al­ized that Microsoft ac­tu­ally shipped lo­cal mod­els in Windows as part of Copilot.

The Paint App is sit­ting in the fol­low­ing path (yes, they are all Windows Apps now):

C:\Program Files\WindowsApps\Microsoft.Paint_11.2605.71.0_x64__8wekyb3d8bbwe\PaintApp\

And there are four ap­par­ent model files with the .onnxe ex­ten­sion:

seg.on­nxe 23.1 MB in­seg_enc.on­nxe 28.0 MB in­seg_dec.on­nxe 16.5 MB mager.on­nxe 302.4 MB

The for­mat of seg.on­nxe was pre­vi­ously known, i.e., when it is XORed with the string Microsoft_2023, it be­comes a nor­mal ONNX file. However, the for­mat of the other three .onnxe files ini­tially looked dif­fer­ent.

It turned out that Microsoft had not changed the al­go­rithm, only the key. segapi.dll con­tains a small key reg­istry:

ps_enc_key.1.0.80-main -> Microsoft_2023” ps_enc_key.1.0.81-main -> a 4,096-byte al­phanu­meric string

After de­cryp­tion, onnx.checker.check­_­model() works on all of them:

A vis­i­ble wa­ter­mark

While walk­ing through these files, I found a Watermarker.dll:

This is not su­per sur­pris­ing to me, be­cause while I in­ter­acted with the Paint app, I al­ready dis­cov­ered that it has a set­ting to em­bed a vis­i­ble wa­ter­mark to the im­age that it pro­duces:

The vis­i­ble wa­ter­mark is just a small Copilot logo at the bot­tom right of the im­age, which is to­tally nor­mal.

Then, out of nowhere, I de­cided to ask AI to an­a­lyze the DLL and see if it could also be em­bed­ding an in­vis­i­ble wa­ter­mark. This is part of my in­tu­ition as a re­verse en­gi­neer, be­cause the file is 1.67 MB in size, which is un­usu­ally large for such triv­ial func­tion­al­ity (arguably, the vis­i­ble wa­ter­mark does not even re­quire a sep­a­rate DLL). Apparently, the re­cent Claude Code text-wa­ter­mark an­nounce­ment also played a role in prompt­ing me to think about this pos­si­bil­ity.

An in­vis­i­ble wa­ter­mark

To be­gin with, the vis­i­ble wa­ter­mark is added by AddPerceptibleWatermark:

CPBDoc::Save(…) | `– per­cep­ti­ble-wa­ter­mark save helper(bitmap, WatermarkSetting) | +– WatermarkSetting::Never | `– re­turn the orig­i­nal bitmap | +– WatermarkSetting::AskEveryTime | `– show the Yes / No con­fir­ma­tion popup | +– No: re­turn the orig­i­nal bitmap | `– Yes: con­tinue | `– Always or con­firmed Yes +– Paint::AI::GetPerceptibleWatermarkSvg() `– Paint::AI::AddPerceptibleWatermark(bitmap, SVG stream) `– com­pos­ite the vis­i­ble Copilot logo

Then there is also a dif­fer­ent WmkWriteWatermark func­tion:

Watermarker.dll!WmkWriteWatermark( out­put_pix­els, pay­load, pay­load­_length, width, height, stride, in­put_pix­els, pix­el_­for­mat);

Tracing the call tree, we can see WmkWriteWatermark is called af­ter a lo­cal Stable Diffusion im­age gen­er­a­tion. And if WmkWriteWatermark fails, Paint con­verts the en­tire gen­er­a­tion into an er­ror rather than re­turn­ing the im­age with­out it:

CocreatorViewModel::GenerateImageAsync(…) | `– Paint::AI::StableDiffusionHelpers::GenerateAsync(…, wa­ter­markId, …) | `– Microsoft.ImageCreation.ImageGenerator | `– NPU-generated im­age re­sult | +– out­put safety/​mod­er­a­tion checks | +– Paint::AI::AddWatermark(bitmap, wa­ter­markId) | | | `– Watermarker.dll!WmkWriteWatermark(…) | | | +– suc­cess: re­turn the wa­ter­marked bitmap | `– fail­ure: turn gen­er­a­tion into an er­ror | `– con­struct suc­cess­ful StableDiffusionResult

Then it is nat­ural to ask what the in­com­ing pay­load ac­tu­ally is. It quickly be­comes ap­par­ent that it must be 16 bytes:

if (payload_length < 16) re­turn -6;

if (payload_length > 16) re­turn -5;

It is funny to me that the code is us­ing two dif­fer­ent er­ror codes when the pay­load is too short or too long. The func­tion then ig­nores the length pa­ra­me­ter and uses a hard-coded loop bound when it copies the pay­load:

for (size_t i = 0; i < 16; i++) mes­sage.push_back(pay­load[i]);

We do not yet know what the 16-byte pay­load is, but as we will see later, it is a GUID! WmkWriteWatermark does not em­bed the GUID di­rectly. Its wrap­per con­structs the fol­low­ing 18-byte (144-bit) mes­sage:

0x4c || GUID[0..15] || (sum of the 16 GUID bytes mod­ulo 256)

The core en­coder rounds the us­able im­age di­men­sions down to mul­ti­ples of eight and keeps 144 coun­ters, one for each bit. It re­quires every bit to be placed at least three times.

The en­coder it­self can be sum­ma­rized as:

WmkWriteWatermark(output, guid, 16, width, height, stride, in­put, for­mat) | +– val­i­date point­ers, for­mat, stride, and pay­load length +– re­quire width >= 192 and height >= 192 +– con­struct pay­load | `– 0x4c || GUID || byte-sum check­sum +– ex­pand 18 bytes into 144 in­di­vid­ual bits +– round us­able di­men­sions down to 8-pixel bound­aries +– scan/​se­lect suit­able im­age blocks +– quan­tize se­lected block/​ma­trix val­ues ac­cord­ing to each bit +– re­quire at least three suc­cess­ful place­ments per bit | | | `– in­suf­fi­cient ca­pac­ity -> re­turn -8 `– re­con­struct RGB pix­els into the out­put buffer

The em­bed­ding loop per­forms small quan­tized changes over se­lected im­age blocks. It con­tains 3-by-5 ma­trix op­er­a­tions and a ma­trix-de­com­po­si­tion rou­tine, and it uses con­stants in­clud­ing 24.0, 0.25, 0.5, and 0.2. This looks like a con­tent-adap­tive block-do­main, SVD-style wa­ter­mark.

I am not an ex­pert in im­age wa­ter­mark­ing, but one thing should be clear — this is an in­vis­i­ble wa­ter­mark! AI even wrote some code to call this func­tion di­rectly and tested it with a syn­thetic 512-by-512 BGRA im­age — 193,376 of the 262,144 pix­els changed af­ter adding the wa­ter­mark.

That led to the next ques­tion. Where does the in­put of the wa­ter­mark come from?

a GUID from re­mote prompt mod­er­a­tion

At the WmkWriteWatermark bound­ary, the pay­load is only a pointer and a length. Knowing that it must be 16 bytes was a clue, but many things can be 16 bytes. I there­fore started walk­ing back­ward through its callers. The im­me­di­ate wrap­per in PaintAIManager.dll has this sym­bol­ized sig­na­ture:

Paint::AI::AddWatermark( Gdiplus::Bitmap& im­age, winrt::guid const& wa­ter­markId);

winrt::guid, yikes! Now we know that the 16-byte wa­ter­mark pay­load is in­deed a GUID.

Further track­ing the source, we find that the GUID ac­tu­ally comes from a net­work re­quest. Before Paint runs the lo­cal im­age model, AIServices.dll sends the prompt and style to:

https://​ap­sais­er­vices-a0fqcjc6bzb­hgdcd.b02.azurefd.net/ v1/​paint-cocre­ator/​mod­er­ate-prompt

The re­quest is JSON and con­tains at least these fields:

{ prompt”: …”, style”: …”, lastPromptGenerationId”: …” }

The re­sponse parser ex­pects:

{ revisedPrompt”: …”, promptGenerationId”: …”, watermarkId”: …”, containsHumanReference”: false }

Static analy­sis is nice, but at this point I wanted to see a real re­sponse from the server. I reused Paint’s own au­then­ti­cated ses­sion and sent the fol­low­ing prompt through the mod­er­a­tion end­point:

a cobalt blue cir­cle above a tiny or­ange square

The server re­turned HTTP 200:

{ revisedPrompt”: a cobalt blue cir­cle above a tiny or­ange square”, promptGenerationId”: 74d9e06b-adea-43ce-85fe-186a26e2e34a”, watermarkId”: 83424621 – 03cb-40e3 – 9808-a9fae837156d”, containsHumanReference”: false }

I also tried the prompt a por­trait of a smil­ing per­son wear­ing a blue hat. This time the re­sponse con­tained a dif­fer­ent pair of GUIDs and con­tain­sHu­man­Ref­er­ence was true. The field is there­fore a server-side clas­si­fi­ca­tion of whether the prompt refers to a hu­man. Paint parses and stores it along­side the IDs, al­though I found no ev­i­dence that it con­trols the wa­ter­mark­ing step it­self.

ParseModerateResponse parses both ID strings as GUIDs and re­jects zero val­ues with InvalidPromptGenerationId or InvalidWatermarkId. The server’s wa­ter­markId is what be­comes part of the gen­er­ated im­age:

PaintUI.dll `– IPromptModerationService `– PaintAIManager.dll `– AIServices.dll!ModerateAsync(…) | +– build JSON | +– prompt | +– style | `– last­Prompt­Gen­er­a­tionId | +– HTTPS POST /v1/paint-cocreator/moderate-prompt | `– AIServices.dll!ParseModerateResponse(response) +– re­vised­Prompt +– prompt­Gen­er­a­tionId -> parse as GUID +– wa­ter­markId -> parse as GUID `– con­tain­sHu­man­Ref­er­ence | `– PaintUI stores WatermarkId `– StableDiffusionHelpers::GenerateAsync(…, wa­ter­markId, …) `– lo­cal Stable Diffusion re­sult `– Paint::AI::AddWatermark(bitmap, winrt::guid const&) `– WmkWriteWatermark(…, guid, 16, …) `– mod­i­fied RGB pix­els

In other words, generated lo­cally” does not mean that the com­plete op­er­a­tion is lo­cal. Microsoft re­ceives and mod­er­ates the prompt, then is­sues the unique GUID that Paint em­beds into the lo­cally gen­er­ated im­age. Paint also sends the pre­vi­ous prompt­Gen­er­a­tionId as last­Prompt­Gen­er­a­tionId with its next mod­er­a­tion re­quest, al­low­ing suc­ces­sive re­quests to be linked ex­plic­itly.

There is an­other piece to this story. Paint does more than al­ter the pix­els. It also at­taches C2PA Content Credentials to the saved file. The code re­spon­si­ble for this lives in ProvenanceHelper.dll, backed by prove­nancesdk.dll.

For the lo­cal Stable Diffusion path, the flow looks like this:

lo­cal Stable Diffusion re­sult | +– Paint::AI::AddWatermark(bitmap, wa­ter­markId) | `– Watermarker.dll!WmkWriteWatermark(…, wa­ter­markId, 16, …) | `– AIServices.dll!SignIngredientOnlineAsync(…, prompt­Gen­er­a­tionId, im­age, …) | +– POST /v1/paint-cocreator/image-sign | +– im­ageMeta­data | | +– PromptGenerationId | | +– GenerationSeed | | +– CreativityLevel | | +– AIFVersion | | `– mod­er­a­tion scores | `– im­age­ToSign.jpg | `– ParseProvenanceResponse(…) `– server-sup­plied C2PA man­i­fest `– ProvenanceHelper::InsertManifestIngredient(…) `– AuthoringFinalizeOutputToBufferAsync(…) `– fi­nal im­age with C2PA meta­data

Notice that the sign­ing re­quest sends PromptGenerationId, while the im­age al­ready con­tains the sep­a­rately re­turned wa­ter­markId. The server as­signed both val­ues dur­ing mod­er­a­tion, so it can as­so­ci­ate the sign­ing re­quest with the wa­ter­mark al­ready pre­sent in the sub­mit­ted pix­els.

I then saved a real im­age di­rectly from Paint’s Image Creator and in­spected its PNG chunks. Immediately af­ter IHDR was an 18,979-byte caBX chunk con­tain­ing a signed C2PA man­i­fest. The in­ter­est­ing part was this:

{ c2pa.soft-binding”: { alg”: com.microsoft.invismark.1”, blocks”: [ { scope”: the en­tire im­age”, value”: 83424621 – 03cb-40e3 – 9808-a9fae837156d” } ] }, c2pa.actions.v2”: { actions”: [ { action”: c2pa.watermarked”, description”: Content wa­ter­marked by Microsoft Responsible AI } ] } }

Decoded into some­thing more read­able, the man­i­fest says:

Generator: Microsoft Responsible AI Provenance

AI sys­tem: Azure OpenAI ImageGen

Action: c2pa.wa­ter­marked

Algorithm: com.mi­crosoft.in­vis­mark.1

Watermark value: 83424621 – 03cb-40e3 – 9808-a9fae837156d

Description: Content wa­ter­marked by Microsoft Responsible AI

The server’s wa­ter­markId, the iden­ti­fier em­bed­ded into the pix­els, and the C2PA c2pa.soft-bind­ing.value are the same per-gen­er­a­tion value.

That re­la­tion­ship is im­por­tant. C2PA calls this a soft bind­ing: a value de­rived from, or em­bed­ded into, the con­tent so that the con­tent can still be matched with its prove­nance record af­ter the file-level man­i­fest has been re­moved. For a wa­ter­mark soft bind­ing, the value is the wa­ter­mark’s con­tent iden­ti­fier. Microsoft cryp­to­graph­i­cally signed this as­ser­tion.

Why does Paint wa­ter­mark lo­cally?

At this point, the ex­is­tence of Watermarker.dll started to make more sense. Paint ac­tu­ally has two rather dif­fer­ent gen­er­a­tion paths.

The Image Creator fea­ture I tested above uses Azure OpenAI ImageGen. Generation, wa­ter­mark­ing, and prove­nance pack­ag­ing can all hap­pen in Microsoft’s cloud, and Paint can sim­ply re­ceive a fin­ished im­age that al­ready con­tains both the in­vis­i­ble wa­ter­mark and C2PA man­i­fest:

Image Creator `– Microsoft cloud +– con­tent fil­ter­ing +– Azure OpenAI ImageGen +– in­vis­i­ble wa­ter­mark +– C2PA man­i­fest `– com­pleted im­age re­turned to Paint

Cocreator is dif­fer­ent. On a sup­ported Copilot+ PC, Microsoft says that the NPU gen­er­ates the im­age lo­cally, while Azure on­line ser­vices still per­form the safety checks. The fea­ture there­fore re­quires both a Microsoft ac­count and an in­ter­net con­nec­tion even though the ac­tual Stable Diffusion in­fer­ence runs on the de­vice:

Cocreator on a Copilot+ PC | +– prompt -> Microsoft mod­er­a­tion ser­vice | +– re­vised­Prompt | +– prompt­Gen­er­a­tionId | `– wa­ter­markId | +– re­vised­Prompt + sketch -> lo­cal NPU gen­er­a­tion | +– Watermarker.dll -> em­bed wa­ter­markId lo­cally | `– on­line prove­nance sign­ing -> fi­nal C2PA man­i­fest

This is prob­a­bly the rea­son Paint needs a lo­cal wa­ter­mark im­ple­men­ta­tion at all. A cloud gen­er­a­tor can wa­ter­mark its out­put be­fore re­turn­ing it. A lo­cal gen­er­a­tor can­not rely on that, so Paint has to al­ter the lo­cally gen­er­ated pix­els it­self. It also ex­plains why Paint treats a fail­ure from WmkWriteWatermark as a fail­ure of the en­tire gen­er­a­tion in­stead of qui­etly re­turn­ing an un­marked im­age.

There is an­other sur­pris­ingly vis­i­ble sign that Microsoft de­signed the save path around prove­nance. When I save a gen­er­ated re­sult di­rectly from the Image Creator pane, Paint of­fers ex­actly one for­mat: PNG.

After an AI re­sult is ap­plied to the Paint can­vas, the avail­able for­mats are still re­stricted to PNG, JPEG, GIF, and Paint’s own .paint for­mat. BMP—the clas­sic Paint for­mat—is con­spic­u­ously ab­sent.

This lines up with the for­mats sup­ported by C2PA. PNG stores its man­i­fest in a caBX chunk, JPEG uses one or more APP11 marker seg­ments, and GIF has its own C2PA ap­pli­ca­tion-ex­ten­sion rep­re­sen­ta­tion. The .paint for­mat is con­trolled by Microsoft and can pre­serve what­ever prove­nance state Paint re­quires. By con­trast, the C2PA spec­i­fi­ca­tion ex­plic­itly calls out BMP as a clas­sic for­mat that can­not em­bed ar­bi­trary man­i­fest data with­out us­ing an ex­ter­nal man­i­fest. If Paint al­lowed the im­age to be ex­ported di­rectly as BMP, the file-level C2PA man­i­fest would there­fore dis­ap­pear.

The split also raises an in­ter­est­ing se­cu­rity ques­tion about the cloud path. If the un­der­ly­ing re­mote im­age-gen­er­a­tion end­point can be made to re­turn the gen­er­ated im­age be­fore wa­ter­mark­ing and prove­nance pack­ag­ing—or has an in­ter­nal op­tion that sup­presses those stages—it might be pos­si­ble to ob­tain a cloud-gen­er­ated im­age with nei­ther sig­nal at­tached.

How to clas­sify such a path would de­pend en­tirely on Microsoft’s de­sign goal. It could be in­tended be­hav­ior if the un­der­ly­ing ser­vice is al­lowed to re­turn raw gen­er­a­tions and Paint is merely re­spon­si­ble for ap­ply­ing the prove­nance lay­ers. It could be a prod­uct bug if Microsoft over­looked the pos­si­bil­ity of some­one call­ing the API di­rectly and by­pass­ing Paint’s wa­ter­mark­ing step. Or it could be a se­cu­rity vul­ner­a­bil­ity if Microsoft treats wa­ter­mark­ing as a manda­tory abuse-pre­ven­tion or prove­nance con­trol and the end­point can be made to by­pass it. Without know­ing the in­tended trust bound­ary, all three pos­si­bil­i­ties re­main open.

Photos app does the same thing

While I was try­ing to lo­cate the Watermarker.dll on disk, I hap­pened to no­tice that Microsoft Photos con­tains a DLL with the same name:

C:\Program Files\WindowsApps\ Microsoft.Windows.Photos_2026.11060.2004.0_x64__8wekyb3d8bbwe\Watermarker.dll

There are also lo­cal Stable Diffusion op­er­a­tions be­hind Photos’ Image Creator and Restyle Image fea­tures. Both lead to the same wa­ter­mark wrap­per:

Photos Image Creator `– PerformSDTextToImageAndWatermarkAsync(…, prompt­Gen­er­a­tionId, …) +– run the lo­cal text-to-im­age model `– ApplyWatermark(image, prompt­Gen­er­a­tionId) +– parse prompt­Gen­er­a­tionId as a GUID +– ConvertGUIDtoContiguousByteArray() +– con­vert RGBA to ARGB +– Watermarker.dll!WmkWriteWatermark(…, guid, 16, …) `– con­vert ARGB back to RGBA

Restyle Image takes the par­al­lel path:

Photos Restyle Image `– PerformSDSketchToImageAndWatermarkAsync(…, prompt­Gen­er­a­tionId, …) `– ApplyWatermark(image, prompt­Gen­er­a­tionId) `– Watermarker.dll!WmkWriteWatermark(…, guid, 16, …)

A sub­tle dif­fer­ence be­tween Photos and Paint is fail­ure be­hav­ior. If the wa­ter­mark en­coder re­turns an er­ror, its code logs:

World's oceans hit highest temperature on record as El Niño grows

www.bbc.com

17 hours ago

Mark PoyntingClimate re­porter

Getty Images

The world’s oceans are hot­ter than ever recorded, new data sug­gests, as they suf­fer from hu­man-caused cli­mate change and the grow­ing El Niño weather phe­nom­e­non.

The av­er­age sur­face tem­per­a­ture of the plan­et’s seas out­side the po­lar re­gions hit 21.1C (70F) on Saturday, ac­cord­ing to fig­ures from the European Copernicus cli­mate change ser­vice.

That edges past the 21.09C recorded on three sep­a­rate days in March 2024, and is far above av­er­age for the time of year.

Warmer oceans can have wide-reach­ing con­se­quences, in­clud­ing su­per­charg­ing ex­treme weather, rais­ing sea lev­els and harm­ing ma­rine life.

This record is an­other clear sig­nal of an ocean un­der grow­ing stress,” said Dr Samantha Burgess, deputy di­rec­tor of Copernicus.

El Niño is adding heat to the sys­tem, but it is do­ing so on top of decades of hu­man-dri­ven warm­ing,” she added.

The data is based on sea tem­per­a­tures 10m (32ft 10in) be­low the sur­face, us­ing mea­sure­ments from buoys, ships and satel­lites, which are com­bined to pro­duce a global es­ti­mate.

While the mar­gin of record is cur­rently very small and any global es­ti­mate comes with un­cer­tain­ties, sci­en­tists say its tim­ing is par­tic­u­larly no­table.

Average world­wide sea tem­per­a­tures tend to reach their yearly peak in March or April, which cor­re­sponds to the end of sum­mer in the south­ern hemi­sphere - and not in August.

The south­ern hemi­sphere con­tains more of the plan­et’s ocean sur­face than the north­ern hemi­sphere and so ex­erts a big­ger in­flu­ence on av­er­age sea tem­per­a­tures.

What is es­pe­cially con­cern­ing to sci­en­tists is that the oceans are al­ready so hot when the nat­ural El Niño weather phe­nom­e­non is still some way off its ex­pected peak.

This could see ocean tem­per­a­tures climb yet fur­ther.

The fact that we are al­ready break­ing records is an early in­di­ca­tor of how strong the El Niño is be­com­ing,” said Dr Jeremy Grist, se­nior re­search fel­low at the National Oceanography Centre in Southampton.

All things be­ing equal we might ex­pect the ocean tem­per­a­ture record to be bro­ken again in March [or] April 2027,” he added.

The wa­ters far away from El Niño’s Pacific hunt­ing ground are also ex­tremely warm, in­clud­ing around the UK and Europe.

The west­ern English Channel has seen al­most con­tin­u­ous ma­rine heat­wave con­di­tions for more than three years, peak­ing at 7C above nor­mal in July, ac­cord­ing to Prof Tim Smyth, di­rec­tor of sci­ence at Plymouth Marine Laboratory.

This is un­prece­dented,” he added.

Scientists say such wide­spread warmth around the planet is a clear sign of the grow­ing ef­fect that hu­man-caused cli­mate change is hav­ing on the world’s seas.

The lat­est Copernicus data re­in­force the trou­bling up­ward trend in ocean tem­per­a­tures,” said Smyth.

Warmer seas help to fuel more ex­treme weather. They can pro­vide storms with ex­tra mois­ture and en­ergy, and can in­ten­sify heat­waves on land in some coastal re­gions by re­duc­ing the cool­ing ef­fect of sea breezes.

Warmer wa­ter also takes up more space, rais­ing sea lev­els and bring­ing a greater risk of coastal flood­ing - while in­tense ocean heat can be dev­as­tat­ing for sea habi­tats, such as coral reefs.

The in­creas­ing fre­quency of ma­rine heat­waves is al­ready putting in­creas­ing pres­sure on ma­rine ecosys­tems and the com­mu­ni­ties that de­pend on them”, Burgess said.

AI Coding will Prevent Expertise | Lars Faye

larsfaye.com

We see a fu­ture where in­tel­li­gence is a util­ity like elec­tric­ity or wa­ter and peo­ple buy it from us on a me­ter and use it for what­ever they want to use it for” - Sam Altman of OpenAI

We see a fu­ture where in­tel­li­gence is a util­ity like elec­tric­ity or wa­ter and peo­ple buy it from us on a me­ter and use it for what­ever they want to use it for” - Sam Altman of OpenAI

In my pre­vi­ous ar­ti­cle, Agentic Coding is a Trap, I dis­cussed the skilled or­ches­tra­tor para­dox”, where the skills re­quired to man­age AI agents for cod­ing are the same ones that can be di­min­ished through the con­tin­ued use of said AI agents. Expertise was largely the dif­fer­en­tia­tor; the more ex­pe­ri­enced a de­vel­oper is, the less likely it is that they might ex­pe­ri­ence skill at­ro­phy, as the knowl­edge has had a chance to os­sify af­ter years of ex­pe­ri­ence.

If you look around right now, you’ll find the vast ma­jor­ity of those that are see­ing the most ben­e­fits from these mod­els are those that have had years, if not decades, of ex­pe­ri­ence in the field (which pre­dates AI tool­ing, of course). And any in­dus­try vet­eran will tell you the same: the bedrock of this knowl­edge comes from do­ing the work.

Developers who’ve en­tered the field around the time of LLMs are placed in a po­si­tion where they don’t have the ben­e­fit of longevity, but they are be­ing guided (and some­times man­dated) to ac­cel­er­ate their ef­forts us­ing cod­ing as­sis­tants that re­quire a his­tory of ex­per­tise to wield ef­fec­tively and re­spon­si­bly.

It’s an awk­ward place to be for that de­mo­graphic, as it cre­ates a sce­nario where a novice needs ex­pert-level skills to lever­age the tools and keep pace in the in­dus­try.

The Expert Novice”

We’re cur­rently send­ing very mixed sig­nals to peo­ple across the in­dus­try. We’re ham­mer­ing in that if you’re not us­ing AI tools, you will be left be­hind” by your peers who are us­ing them. AI won’t re­place you, some­one us­ing AI will” has been on re­peat since 2023.

And in the same breath, it’s also said that the way to get the best re­sults from these mod­els is to ap­ply higher-or­der think­ing; vibe cod­ing” is a dead end; you need to move up the stack” and cre­ate ro­bust specs, ar­chi­tect with good de­sign pat­terns, and al­ways re­view the out­puts dili­gently so you never ship some­thing you don’t un­der­stand.

The skills to do so, how­ever, are a func­tion of some­one who has ex­pe­ri­enced the fric­tion and chal­lenges over time that cul­mi­nate in good taste”.

This leads to an­other sit­u­a­tional para­dox: If these tools de­mand ex­per­tise, yet the tools can ac­tively cir­cum­vent the fric­tion that cul­ti­vates ex­per­tise, then what is the path for one to be­come an ex­pert so they can ef­fec­tively use these tools?

Confidence with­out Comprehension

One hope is that these mod­els will end up ac­cel­er­at­ing learn­ing as they are used for code gen­er­a­tion. Junior de­vel­op­ers can work with the same grav­i­tas and con­fi­dence as in­dus­try vet­er­ans with their personal AI tu­tor”. Knowing syn­tax is in­creas­ingly less im­por­tant, and any knowl­edge or am­bi­gu­ity gaps are filled by the AI tool. The deeper me­chan­ics of the code stay ab­stracted away, since the de­vel­oper sits higher in the stack.

JetBrains, a ma­jor player in de­vel­oper tools, re­cently cited a study ti­tled The Widening Gap: The Benefits and Harms of Generative AI for Novice Programmers”, which painstak­ingly an­a­lyzed in­di­vid­ual be­hav­iors in live cod­ing ses­sions, and tested their abil­ity to learn cod­ing with vary­ing de­grees of AI as­sis­tance. Their main take­away was stark and coun­ter­in­tu­itive:

Participants thought it was like hav­ing a per­sonal tu­tor. From the data in our study … we ob­served that they did not, in fact, use GenAI tools like a per­sonal tu­tor. In fact, it was quite the op­po­site.”

Participants thought it was like hav­ing a per­sonal tu­tor. From the data in our study … we ob­served that they did not, in fact, use GenAI tools like a per­sonal tu­tor. In fact, it was quite the op­po­site.”

The par­tic­i­pants that leaned into heav­ier AI as­sis­tance:

Often skipped cru­cial plan­ning stages, find­ing that be­cause they had­n’t rea­soned them­selves into this po­si­tion, Copilot had.”

Finished with an illusion of com­pe­tence’ rather than true un­der­stand­ing.”

Counter to that, the par­tic­i­pants that mit­i­gated their us­age of AI:

Succeeded be­cause they had de­vel­oped negative ex­per­tise’—which is the abil­ity to ig­nore in­cor­rect or un­help­ful GenAI sug­ges­tions’—al­low­ing them to fo­cus on writ­ing their own so­lu­tions rather than be­ing led astray.”

Were able to use GenAI to ac­cel­er­ate, cre­at­ing code they al­ready in­tended to make.”

The novice de­vel­op­ers who were the most un­re­stricted and con­fi­dent in their AI us­age had skipped cru­cial steps in the pro­gram­ming prob­lem-solv­ing process, and were now lost.”

Perhaps un­sur­pris­ingly, the novice de­vel­op­ers who per­formed the best were the ones that greatly mit­i­gated or out­right ig­nored the AI cod­ing as­sis­tance.

Inverted Learning

Due to the self-di­rected na­ture of LLMs, the more ex­pe­ri­ence you have, the more ben­e­fit they pro­vide since you can ac­cu­rately steer, au­dit, and ver­ify the out­puts. The less knowl­edge you have, the more they can mis­lead you. Interacting with LLMs for learn­ing new skills takes the shape of an inverted learn­ing” model, a role re­ver­sal where the stu­dent is ini­tially guid­ing the men­tor, the men­tor re­sponds, and then the stu­dent, again, steers the men­tor.

The process is pre­car­i­ous; LLMs are in­cred­i­bly sen­si­tive to the shape of the prompt. When you’re ex­plor­ing new do­mains, you don’t know what you don’t know, and the mal­leable and ac­com­mo­dat­ing de­sign of an LLM can lead you to be­lieve you know more than you ac­tu­ally do.

If you’re ex­plor­ing ter­ri­tory that is even some­what un­fa­mil­iar, you of­ten don’t even know the ques­tions that you need to ask that could prop­erly guide the model to pro­vid­ing the best an­swers. It be­gins to feel like a com­pass that al­ways points north, wher­ever you sug­gest north might be.

From the same study that JetBrains high­lights, even the most pre­pared stu­dents were de­railed by the AI as­sis­tance due to this type of learn­ing model: One par­tic­i­pant demon­strated good fun­da­men­tal plan­ning and habits, but sud­denly skipped cru­cial prob­lem-solv­ing plan­ning stages, jump­ing di­rectly to cod­ing and was en­ticed by Copilot into quickly pro­duc­ing code” and had to rely on the LLM to fix the er­ror that the LLM in­tro­duced in the first place.

AI mod­els lack judg­ment, em­pa­thy, and ped­a­gog­i­cal in­tent, and the so­lu­tions pro­vided are not rooted in ex­pe­ri­ence but rather in pat­terns in the train­ing data (LLMs are, at their core, in­cred­i­bly com­plex pat­tern in­ter­po­la­tors).

The in­fi­nite an­swer ma­chine is tempt­ing, and known to be ad­dic­tive. It can un­wind rather quickly, es­pe­cially for in­ex­pe­ri­enced de­vel­op­ers. Once you get deep enough into a gen­er­ated so­lu­tion, you are of­ten be­holden to the AI tool to also fin­ish the job, cir­cum­vent­ing the prob­lem-solv­ing fric­tion that is re­quired for the for­ma­tion of a men­tal model (and to be fair, se­nior de­vel­op­ers are prone to this phe­nom­e­non, as well).

The Friction is a Feature

Expertise and mas­tery don’t hap­pen purely through ob­ser­va­tion and di­a­logue, but through ex­pe­ri­ence, rep­e­ti­tion, and trial and er­ror; you have to fail to suc­ceed. If I wanted to learn how to cook, I could watch a Master Chef work and make end­less in­quiries. After a month, I would be able to de­scribe the per­fectly medium-rare rib­eye but never know what it’s like to cook one, and I’d al­most cer­tainly over­cook it on my first at­tempt.

Coding has end­less mo­ments of trac­ing ob­scure er­rors with no log file to help, ex­pe­ri­enc­ing the sub­tle per­for­mance dif­fer­ences of cer­tain meth­ods, or hav­ing to rewrite an ap­proach when it’s clear it won’t go­ing to scale.

This ap­plied fric­tion is di­rectly what builds developer in­tu­ition” (or taste”). The Germans have a great word for this: Fingerspitzengefühl (fingertip feel­ing). It’s the mus­cle mem­ory that trig­gers when a de­vel­oper looks at some­thing and thinks, yeah…this is prob­a­bly go­ing to cause prob­lems.” By avoid­ing the me­chan­ics of the strug­gle, this in­tu­ition is never built.

In UPenn’s large-scale 2025 study Generative AI with­out guardrails can harm learn­ing, they fol­lowed 1,000 stu­dents us­ing an LLM to learn math­e­mat­ics and found stu­dents used AI as a crutch and ended up per­form­ing 17% worse than stu­dents with just a text­book (and just as with the pre­vi­ous study, the stu­dents us­ing the AI as­sis­tance thought they were ex­celling).

LLMs don’t just have to gen­er­ate code, though.

If lever­aged as Socratic spar­ring part­ners in­stead of an­swer gen­er­a­tors, stud­ies have shown that dialogic AI sys­tems can mean­ing­fully stim­u­late re­flec­tive, crit­i­cal and in­de­pen­dent think­ing”.

In that same UPenn study, they also tested a Tutor” ver­sion by hav­ing stu­dents ask for help and then in­de­pen­dently solve the prob­lem. The GPT Tutor group per­formed an as­ton­ish­ing 127% bet­ter in the AI-assisted prac­tice ses­sion (although, in­ter­est­ingly, they scored about the same on the test as the text­book group).

This is ef­fec­tive be­cause the model is no longer be­ing uti­lized as a means of pro­duc­tion, and it shifts the cog­ni­tive work back onto the in­di­vid­ual. It’s when the fric­tion is still pre­sent that it cre­ates a last­ing im­print that leads to ex­per­tise.

Anthropic’s 2026 study How AI as­sis­tance im­pacts the for­ma­tion of cod­ing skills” came to sim­i­lar con­clu­sions:

For novice work­ers in soft­ware en­gi­neer­ing or any other in­dus­try, our study can be viewed as a small piece of ev­i­dence to­ward the value of in­ten­tional skill de­vel­op­ment with AI tools. Cognitive ef­fort—and even get­ting painfully stuck—is likely im­por­tant for fos­ter­ing mas­tery.

For novice work­ers in soft­ware en­gi­neer­ing or any other in­dus­try, our study can be viewed as a small piece of ev­i­dence to­ward the value of in­ten­tional skill de­vel­op­ment with AI tools. Cognitive ef­fort—and even get­ting painfully stuck—is likely im­por­tant for fos­ter­ing mas­tery.

There’s a cer­tain sense of irony here: the most pro­duc­tive learn­ing that can hap­pen with an AI cod­ing tool is when it is­n’t used to gen­er­ate much of any code at all.

Pipeline Collapse

If LLMs can write code and de­bug code, and agen­tic work­flows can per­form sys­tem de­sign from the abun­dance of pat­terns in the train­ing data, then what is the pur­pose of this knowl­edge in the first place? Programming will be done en­tirely in nat­ural lan­guage, and we can dis­pense with the need to en­gage with the code be­cause the mod­els con­tinue to im­prove and fill in any knowl­edge or am­bi­gu­ity gaps. They will de­bug any is­sues that arise and man­age any com­plex­ity that they in­tro­duce.

The tril­lion-dol­lar bet that is be­ing made is: this knowl­edge won’t mat­ter, be­cause LLMs will take up the slack and ef­fec­tively be­come the new gen­er­a­tion of developers”. It starts give off an aire of hubris that drove past no-code move­ments, and the fever dreams of CEOs, rather than the re­al­ity on the ground.

Coding/programming/software is a unique in­ter­sec­tion of logic, math, prob­lem-solv­ing, crit­i­cal think­ing, plan­ning, com­mu­ni­ca­tion, and cre­ativ­ity. LLMs can de­tect pat­terns at a scale that no hu­man ever could, but pat­terns only get you so far.

David Cramer, co-founder at Sentry (a per­for­mance and er­ror track­ing plat­form), put it suc­cinctly in a re­cent in­ter­view:

I think there’s a type of per­son … that in­her­ently be­lieves that LLM will get bet­ter enough that they will go back and fix this stuff, that it will be able to clean up all the junk that’s been stacked up along the way. I don’t think that’s true. I think it’s a sci­ence ex­per­i­ment. You want to flex that you can gen­er­ate all of your code and have hun­dreds of things go­ing in par­al­lel, I will flex and show you how bro­ken the code is 100% of the time.

I think there’s a type of per­son … that in­her­ently be­lieves that LLM will get bet­ter enough that they will go back and fix this stuff, that it will be able to clean up all the junk that’s been stacked up along the way. I don’t think that’s true. I think it’s a sci­ence ex­per­i­ment.

You want to flex that you can gen­er­ate all of your code and have hun­dreds of things go­ing in par­al­lel, I will flex and show you how bro­ken the code is 100% of the time.

Will the pipeline col­lapse, or just change?

It re­ally de­pends on whether we make the needed shift to a more ped­a­gog­i­cal us­age of these sys­tems.

By con­tin­u­ing to fo­cus on and pro­mote AI cod­ing work­flows that pri­or­i­tize code gen­er­a­tion above deep un­der­stand­ing, we are not cul­ti­vat­ing the next gen­er­a­tion of ex­per­tise who will in­herit the code that is be­ing cre­ated to­day.

My Approach: Friction First

Joel Spolsky pre­sciently writes (in 2002, no less) in his Law of Leaky Abstractions:

Code gen­er­a­tion tools which pre­tend to ab­stract out some­thing, like all ab­strac­tions, leak. And the only way to deal with the leaks com­pe­tently is to learn about how the ab­strac­tions work … the ab­strac­tions save us time work­ing, but they don’t save us time learn­ing.

Code gen­er­a­tion tools which pre­tend to ab­stract out some­thing, like all ab­strac­tions, leak. And the only way to deal with the leaks com­pe­tently is to learn about how the ab­strac­tions work … the ab­strac­tions save us time work­ing, but they don’t save us time learn­ing.

If a de­vel­oper wants to learn Java, they should prob­a­bly not start with Spring Boot. If they want to learn JavaScript fun­da­men­tals, they should not start with React. If they want to be­come highly adept at CSS, they should not start with Tailwind. LLMs could be con­sid­ered the ul­ti­mate leaky ab­strac­tion.

My ad­vice here is very sim­i­lar to my pre­vi­ous pre­scrip­tion.

If a de­vel­oper wants to be­come an ex­pert in pro­gram­ming, they should largely dis­re­gard the pure code gen­er­a­tion ca­pa­bil­i­ties of these mod­els, and in­stead use them for in­ter­ac­tive doc­u­men­ta­tion, dy­namic tu­to­r­ial gen­er­a­tors, and Socratic ex­er­cises.

It’s not a panacea, of course: Using an AI tool as a tu­tor car­ries its own risks since it is sus­cep­ti­ble to the same hal­lu­ci­na­tions as any other in­ter­ac­tions, and it can­not be re­lied upon solely as a learn­ing source. If you can’t prop­erly au­dit the ac­cu­racy of the gen­er­ated code, they you can’t au­dit the ac­cu­racy of the gen­er­ated con­cept. If you use AI as a men­tor, you must still ver­ify its out­puts against of­fi­cial doc­u­men­ta­tion, hu­man peers, and ac­tual trial and er­ror.

Coding’s ac­tu­ally a great way to ce­ment un­der­stand­ing. The more you pro­gram, the more you un­der­stand the do­main that you’re work­ing in.” — Kent Beck, cre­ator of Test-Driven Development

Coding’s ac­tu­ally a great way to ce­ment un­der­stand­ing. The more you pro­gram, the more you un­der­stand the do­main that you’re work­ing in.”

— Kent Beck, cre­ator of Test-Driven Development

Choosing this slower, more de­lib­er­ate path is the best way to grow ex­per­tise, but I’m aware of how hard that is when the sur­round­ing ecosys­tem is ac­tively work­ing against it. AI is be­ing man­dated (often reck­lessly) across com­pa­nies, and baked into most soft­ware de­vel­op­ment tools and IDEs as they cater largely to se­nior en­gi­neers (even with some tools like Cursor tuck­ing away the code view un­less the user specif­i­cally seeks it out). Some com­pa­nies are even forc­ing de­vel­op­ers to only use AI for all cod­ing tasks, re­gard­less of ex­pe­ri­ence level, and these com­pa­nies will have to learn their own lessons.

However, for every­one else who is look­ing to strike a bal­ance be­tween deep learn­ing (no pun) and pro­duc­tiv­ity, there are qual­i­fy­ing ques­tions you can ask to en­sure your us­age of these tools yields long-term ben­e­fits.

My AI-assistance check­list:

If I did not have ac­cess to an AI tool, could I still ac­com­plish this task?

Am I us­ing the model to deepen my un­der­stand­ing, or ex­pe­dite the an­swer?

If I had to au­dit and ver­ify the gen­er­ated out­put, could I ad­e­quately ex­plain what was hap­pen­ing?

If I’m learn­ing a new con­cept, have I done proper re­search to know the right ques­tions to ask?

Have I cross-ref­er­enced and ver­i­fied the ap­proach through other meth­ods (reading doc­u­men­ta­tion, stan­dard search tools, StackOverflow, Reddit)?

Is this a truly rote task that’s been done 100 times be­fore, or a task that re­quires ex­ec­u­tive de­ci­sion-mak­ing some­where in the process?

Even as a de­vel­oper with decades of ex­pe­ri­ence un­der my belt, I am still con­stantly re­fer­ring to them through­out my daily work, es­pe­cially when I am at­tempt­ing to learn some­thing new (which in this field, is nev­erend­ing).

The key is to de­tect the dif­fer­ence be­tween cog­ni­tive debt and cog­ni­tive of­fload­ing: Cognitive debt is ab­di­cat­ing your judg­ment and de­ci­sions, whereas cog­ni­tive of­fload­ing is del­e­gat­ing the me­chan­i­cal or te­dious.

As the Anthropic study men­tioned, get­ting painfully stuck” is a good thing. It takes dis­ci­pline and ef­fort to not drift back to­wards just gen­er­at­ing an­swers, which might not even be ac­cu­rate in the first place. LLMs did­n’t sud­denly rewrite the fun­da­men­tals of how we learn, but they did give us a new way to do so.

Intelligence is­n’t a Commodity

The re­align­ment I hope to see over the years is the un­der­stand­ing that skills don’t de­velop with­out ac­tive par­tic­i­pa­tion. You must en­gage di­rectly and con­ti­nously to ex­pe­ri­ence the es­sen­tial fric­tion that cul­mi­nates in ex­per­tise (even if it means mov­ing more slowly).

If we stay fix­ated on lines of code and to­kens burned while the ex­per­tise pipeline dries up over the years, Sam Altman’s vi­sion of sell­ing in­tel­li­gence back to us on a me­ter could be­come re­al­ity. Domain knowl­edge could be­come very hard to come by, and when one sits down to do any type of de­vel­op­ment work, there will be a pang of paral­y­sis if that per­son does not have an ac­tive AI tool sub­scrip­tion at their side.

LLMs are a sta­tic data­base of skills. They are in­ter­po­la­tion en­gines. Software en­gi­neer­ing, how­ever, is an ex­er­cise in adap­ta­tion and novel prob­lem-solv­ing. You can­not in­ter­po­late your way through a com­pletely unique sys­tem fail­ure. — François Chollet, cre­ator of ARC-AGI Benchmark

LLMs are a sta­tic data­base of skills. They are in­ter­po­la­tion en­gines. Software en­gi­neer­ing, how­ever, is an ex­er­cise in adap­ta­tion and novel prob­lem-solv­ing. You can­not in­ter­po­late your way through a com­pletely unique sys­tem fail­ure.

— François Chollet, cre­ator of ARC-AGI Benchmark

San Francisco -- The Game

sf.thijs.gg

CHAT

NO MESSAGES YET

SAN FRANCISCO — THE GAMECITY ONLINEREADY TO EXPLORE

CLICK TO TELEPORT

G · TILE STREAMIDLE

CENTER · WAITING FOR TILE STATE

FILL = CURRENT OWNER Z20 Z17 Z16 Z15GROUND FILE FULL COLUMN READY VISIBLE CORNERS LOADING

L RANGE 470 m

SAN FRANCISCOL · DETAIL MODE

SAN FRANCISCO

NEIGHBORHOOD READY100%

The streets around you are ready.

WASD move · mouse look · Space jump · Shift run · C cam­era · H glider

WASD

CCAMERAHGLIDER−+SPEED↑↓ZOOMSHIFTSPRINT / EXITVVEHICLE

Loading

Welcome to San Francisco

Update: New domain for Sign in with Apple - Latest News - Apple Developer

developer.apple.com

August 24, 2026

Starting later this year, new Sign in with Apple ad­dresses, pre­vi­ously is­sued on pri­vatere­lay.ap­pleid.com, will be is­sued on pri­vate.icloud.com. Existing ad­dresses on pri­vatere­lay.ap­pleid.com will con­tinue to work and for­ward mail to users with­out in­ter­rup­tion.

After fur­ther con­sid­er­a­tion and re­view­ing com­mu­nity feed­back, iCloud+ Hide My Email ad­dresses will re­main on icloud.com.

What you need to do

Developers with apps or web­sites that use Sign in with Apple should en­sure that their ac­count sys­tems, email val­i­da­tion logic, and al­lowlists ac­cept ad­dresses on the new pri­vate.icloud.com do­main in ad­di­tion to the ex­ist­ing pri­vatere­lay.ap­pleid.com do­main.

Learn more about Sign in with Apple

Communicating us­ing the Private Email Relay Service

The end of IPFS at Shipyard

ipshipyard.com

We have some dif­fi­cult news to share with the IPFS and wider peer-to-peer com­mu­nity.

Protocol Labs has in­formed us that it will not be re­new­ing Shipyard’s fund­ing. While we’re grate­ful for the sup­port and trust they have placed in us over the past two-plus years, we’re nat­u­rally dis­ap­pointed by this out­come. As a di­rect re­sult, Shipyard will be wind­ing down its IPFS-related en­gi­neer­ing, main­te­nance, and in­fra­struc­ture op­er­a­tions. Our fi­nal day of our IPFS re­lated work will be September 30, 2026.

Over the past three years, it has been our priv­i­lege to help shape the mod­ern IPFS ecosys­tem and em­power users with more re­silient, self-sov­er­eign tech­nol­ogy. You can read more about the im­pact­ful work that we shipped in a fol­low-up post we’ll be shar­ing in the com­ing days, but some high­lights in­clude:

Delivering ver­i­fi­able web­sites and down­loads di­rectly in the browser through in­browser.link.

Re-architecting IPFS gate­way in­fra­struc­ture to han­dle ap­prox­i­mately more traf­fic while re­duc­ing op­er­at­ing and main­te­nance costs by around 80%.

Advancing HTTP-native ap­proaches to IPFS that dra­mat­i­cally sim­plify de­ploy­ment, de­vel­op­ment, and op­er­at­ing costs com­pared with tra­di­tional libp2p-based host­ing.

Maintaining and im­prov­ing many of the core im­ple­men­ta­tions, li­braries, and pub­lic in­fra­struc­ture re­lied upon by the IPFS ecosys­tem every day.

We were ex­cited about de­liv­er­ing the next chap­ter for IPFS: dra­mat­i­cally sim­pler HTTP-native im­ple­men­ta­tions, re­silient and sus­tain­able con­tent rout­ing, sup­port for large na­tive SHA-256 ob­jects, pseu­do­ny­mous host­ing and re­trieval through Tor and onion ser­vices, and many other ideas we be­lieved would make IPFS sig­nif­i­cantly eas­ier to adopt. Unfortunately, we won’t have the op­por­tu­nity to see those ef­forts through our­selves.

The prac­ti­cal im­pli­ca­tions ex­tend well be­yond Shipyard. Among other things:

Projects main­tained by Shipyard will no longer have ded­i­cated main­tain­ers re­spon­si­ble for new fea­tures, bug fixes, re­leases, or long-term stew­ard­ship. These in­clude: Kubo, Helia, Boxo, Rainbow, IPFS Desktop, IPFS Companion, Someguy, Service Worker Gateway, IPFS Check, and oth­ers.

Contributions from Shipyard to up­stream pro­jects such as go-libp2p and js-libp2p will cease.

Our work on IPFS spec­i­fi­ca­tions, stan­dards, and broader ecosys­tem co­or­di­na­tion will come to an end.

Shipyard will cease op­er­at­ing the pub­lic in­fra­struc­ture it cur­rently man­ages, in­clud­ing ipfs.io, dweb.link, check.ipfs.net­work, del­e­gated-ipfs.dev, the IPFS boot­strap nodes, col­lab­o­ra­tive clus­ter in­fra­struc­ture such as Wikipedia-on-IPFS, and re­lated ser­vices. Protocol Labs, as the owner of the as­so­ci­ated do­mains and in­fra­struc­ture, will de­ter­mine their fu­ture.

Our goal over the com­ing weeks is to leave the IPFS ecosys­tem in the best pos­si­ble po­si­tion for what­ever comes next.

We’ll re­main avail­able through the end of September to help with that tran­si­tion. If you main­tain soft­ware, op­er­ate in­fra­struc­ture, or rely on any of the work Shipyard has been re­spon­si­ble for, please don’t hes­i­tate to reach out. We’ll do every­thing we rea­son­ably can to an­swer ques­tions, pro­vide con­text, and help make the tran­si­tion as smooth as pos­si­ble.

If you have a favourite mem­ory of work­ing with Shipyard, or an idea you al­ways hoped IPFS would even­tu­ally achieve, we’d love to hear it. Google Form

Finally, we want to say thank you.

To every­one who con­tributed code, re­viewed pull re­quests, filed is­sues, tested ex­per­i­men­tal fea­tures, ran in­fra­struc­ture, par­tic­i­pated in stan­dards dis­cus­sions, or sim­ply be­lieved in the idea that con­tent should be ad­dressed by what it is rather than where it lives: thank you.

It’s been an ho­n­our to build along­side this com­mu­nity. While this chap­ter of IPFS at Shipyard is com­ing to a close, we re­main proud of what we’ve ac­com­plished to­gether, and we hope the work we’ve done helps pro­vide a strong foun­da­tion for what­ever comes next.

Pricing | OpenAI API

developers.openai.com

Standard

Regional pro­cess­ing (data res­i­dency) end­points are charged a 10% up­lift for mod­els re­leased on or af­ter March 5, 2026, that are el­i­gi­ble for data res­i­dency. See our Your data guide for sup­ported re­gions and pro­cess­ing de­tails. OpenAI mod­els in Amazon Bedrock are billed through AWS and may dif­fer from di­rect OpenAI pric­ing.

Priority pro­cess­ing was re­named Fast mode on July 30, 2026. You can use ei­ther ser­vice_tier: priority” or ser­vice_tier: fast” in your API re­quests. Learn more about Fast mode.

GPT-5.6 Sol’s pro­mo­tional pric­ing is avail­able at least through November 21, 2026.

Cyber mod­els

Cyber mod­els

Our lat­est Daybreak mod­els.

Prices per 1M to­kens.

day­break-blue-lat­est and day­break-red-lat­est are aliases that cur­rently point to gpt-5.6-sol and gpt-5.6-cy­ber, re­spec­tively. As new fron­tier mod­els are re­leased through the Daybreak pro­gram, these aliases will be up­dated to point to the lat­est mod­els, with pric­ing ad­justed to match each un­der­ly­ing model.

Realtime and au­dio gen­er­a­tion mod­els

Realtime and au­dio gen­er­a­tion mod­els

Prices per 1M to­kens un­less noted.

Standard

For im­age gen­er­a­tion cost es­ti­mates, use the cal­cu­la­tor in the im­age gen­er­a­tion guide.

Standard

Transcription mod­els

Transcription mod­els

Prices per 1M to­kens un­less noted.

Tools

Tools

Tokens used for built-in tools are billed at the cho­sen mod­el’s per-to­ken rates. GB refers to bi­nary gi­ga­bytes (also known as gibibytes), where 1 GB is 2^30 bytes. Web search con­tent to­kens are to­kens re­trieved from the search in­dex and fed to the model along­side your prompt to gen­er­ate an an­swer. For gpt-4o-mini and gpt-4.1-mini with the non-pre­view web search tool, search con­tent to­kens are billed as a fixed block of 8,000 in­put to­kens per call. File search tool call pric­ing ap­plies to the Responses API only. Container pric­ing in­cludes Hosted Shell and Code Interpreter. Eligible con­tainer ses­sions will be billed by the minute, with a 5-minute min­i­mum per ses­sion. Responses API, Chat Completions API, Realtime API, Batch API, and Assistants API are not priced sep­a­rately. Tokens are billed at the cho­sen mod­el’s in­put and out­put rates.

Standard

OpenAI is wind­ing down the fine-tun­ing plat­form. The plat­form is no longer ac­ces­si­ble to new users, but ex­ist­ing users of the fine-tun­ing plat­form will be able to cre­ate train­ing jobs for the com­ing months.

All fine-tuned mod­els will re­main avail­able for in­fer­ence un­til their base mod­els are dep­re­cated. The full time­line is here.

Standard

Tokens used for model grad­ing in re­in­force­ment fine-tun­ing are billed at that mod­el’s per-to­ken rate. Inference dis­counts are avail­able if you en­able data shar­ing when cre­at­ing the fine-tune job. Learn more.

Anna’s Archive Owes $340 Million, Lost Several Domains, but It’s Still Online

torrentfreak.com

Home > Piracy >

When Anna’s Archive suf­fered wide­spread down­time ear­lier this month, many users feared a le­gal crack­down. Instead, the site was re­port­edly tar­geted by a co­or­di­nated as­sault on its net­work in­fra­struc­ture. Just as it did af­ter fac­ing $340 mil­lion in dam­ages and los­ing sev­eral do­mains ear­lier this year, the Archive quickly bounced back.

Mid August, shadow li­brary Anna’s Archive faced ex­tended down­time, which had many reg­u­lar vis­i­tors con­cerned.

These wor­ries did­n’t come out of nowhere as the site has been un­der quite a bit of le­gal pres­sure in re­cent months.

Lawsuit Takes Domains Offline

In January, the site lost its flag­ship .org do­main. Initially it was­n’t clear what was be­hind this ac­tion but un­sealed court records even­tu­ally con­nected it to a law­suit filed by mu­sic com­pa­nies. This case was a di­rect re­sponse to a Spotify scrape Anna’s Archive an­nounced a few weeks ear­lier.

The mu­sic com­pa­nies ob­tained an in­junc­tion from a U.S. fed­eral court to go af­ter the site’s do­main names. This took out not only the .ORG do­main but also the .SE do­main, as well as the .PM and .VG do­mains that were put in place as back­ups.

Anna’s Archive even­tu­ally landed on .GL, .PK, and .GD do­mains, which re­main ac­tive to­day. These are con­nected to reg­is­trars and reg­istries based out­side the United States that, ap­par­ently, do not com­ply with U.S. court or­ders.

Two Lawsuits, $340 Million

The mu­sic in­dus­try in­junc­tion also came with a sub­stan­tial de­fault judg­ment that was handed down in April. This in­cludes a $322 mil­lion de­fault judg­ment against the un­known op­er­a­tors of Anna’s Archive, who failed to show up in court.

This judg­ment was soon fol­lowed by a sim­i­lar re­quest from a group of ma­jor book pub­lish­ers, in­clud­ing Penguin Random House, Elsevier, and HarperCollins, who sued the shadow li­brary at a New York fed­eral court.

That case also re­sulted in a de­fault judg­ment, with a dam­ages award that is smaller, but still sub­stan­tial at $19.5 mil­lion. In ad­di­tion, the court also is­sued an in­junc­tion tar­get­ing Anna’s Archive’s do­main reg­is­trars and reg­istries.

Coordinated Attack’

With this back­drop, it is no sur­prise that le­gal trou­bles came to mind when the site be­came un­reach­able ear­lier this month. However, this time around, the threat ap­pears to have come from else­where.

After the site came back on­line, the of­fi­cial AnnaArchivist ac­count at­trib­uted it to a co­or­di­nated at­tack by an un­named party.

Apologies for the is­sues. We sus­pect a co­or­di­nated at­tack. We’ve mit­i­gated the at­tack vec­tors…” the mes­sage read, while not­ing that mem­ber­ships al­ready in­clude one to two ex­tra days per month to ac­count for down­time.

Theoretically, an at­tack can also come from a rogue anti-piracy group, but there’s no ev­i­dence for that. A scam or phish­ing op­er­a­tion, which tries to cash in on Anna’s Archive search traf­fic, is an­other op­tion. Neither is con­firmed.

What Options Are Left?

Looking more broadly at the en­force­ment ac­tion that has taken place over the past months, we see that U.S. courts have run into their ju­ris­dic­tional bor­ders on the Internet.

This likely comes as a dis­ap­point­ment for right­sh­old­ers, but it also of­fers a clear take­away.

U.S. courts can’t reach do­mains reg­is­tered be­yond their ju­ris­dic­tion. That’s likely to in­crease calls for site-block­ing leg­is­la­tion, a mea­sure the in­dus­try has long fa­vored and that re­mains high on the po­lit­i­cal agenda in the United States.

Where Did All the Public Bathrooms Go?

daily.jstor.org

The icon in­di­cates free ac­cess to the linked re­search on JSTOR.

Here’s a pop quiz for you: What pur­pose did this lit­tle kiosk serve?

It’s quite a pretty lit­tle build­ing—note the del­i­cate grilles, the or­nately etched glass, and the lit­tle bou­quet of metal flow­ers burst­ing from the roof.

But of course, there is one key clue miss­ing from the pho­to­graph: the smell. Or rather, the stench. This was one of Paris’s in­fa­mous pub­lic uri­nals—a pis­soir (or ves­pasi­enne, if you’re in­clined to be po­lite).

There was a mo­ment around the mid-1800s in Paris when pub­lic uri­na­tion be­gan to be treated as a pub­lic health is­sue. A se­ries of dev­as­tat­ing cholera out­breaks led peo­ple to be­gin re­gard­ing hu­man waste as a dan­ger rather than a mere nui­sance. Something had to be done.

Before that point, au­thor­i­ties had in­stalled em­peche pipi here and there—a kind of hos­tile ar­chi­tec­ture meant to pre­vent rogue pee­ing. This might take the form of a row of iron spikes block­ing an en­tic­ing cor­ner, or a piece of bull­nose ma­sonry meant to send the stream shoot­ing back onto the of­fend­er’s shoes.

The most these in­ter­ven­tions could do was shunt prospec­tive pee-ers from one spot to an­other. But, in 1850, pub­lic uri­na­tion was ac­tu­ally banned. People were go­ing to need some­where to go.

Enter the pis­soir. When you can’t smell them, it’s easy to wish they were still around. Nowadays, pub­lic re­strooms are util­i­tar­ian at best, but these looked like lit­tle palaces, crusted with iron flow­ers, shells, and scrolls—even, in some cases, tiny li­ons’ heads, glar­ing out as if to guard your back while you’re in the booth. On the other hand, the great­est con­ces­sion most of them made to pri­vacy was a lit­tle iron screen sep­a­rat­ing the user from the street.

Enclosed six-stall uri­nal, Jardin de la Bourse, Place de la Bourse, 2nd ar­rondisse­ment, Paris, circa 1865, via Wikimedia Commons

Single stall uri­nal with raised mod­esty screen, Square des Batignolles, Paris, circa 1865, via Wikimedia Commons

Slate cu­bi­cle with two stalls and doors, on curb of foot­path, Place du Louvre, Paris, circa 1865, via Wikimedia Commons

Single stall ma­sonry uri­nal mounted with globe and ad­ver­tis­ing on sides, circa 1865, via Wikimedia Commons

Eight-stall uri­nal, cast iron and slate with shrub­bery screen, Champs-Élysées Gardens, in front of the Palais de l’In­dus­trie, 8th ar­rondisse­ment, Paris, circa 1873, via Wikimedia Commons

Cast iron uri­nal on curb of street, ad­ver­tis­ing on pan­els of uri­nal walls, Paris, circa 1865, via Wikimedia Commons

Some were sur­mounted by glow­ing street­lamps, which served the joint pur­pose of mak­ing them easy to find and il­lu­mi­nat­ing the ad­ver­tise­ments with which they were lib­er­ally pasted. (Apparently, the per­fumers and wine­mak­ers weren’t wor­ried about un­sa­vory as­so­ci­a­tions with their prod­uct.)

Notably, they were only in­tended for use by men. The as­sump­tion was that women weren’t re­ally much of a part of pub­lic life, and so would­n’t need a way to re­lieve them­selves while out on the street—kind of a self-ful­fill­ing prophecy, if you think about it.

There was an­other use for the pis­soir, which took their de­sign­ers quite by sur­prise. Almost im­me­di­ately, they be­came the fa­vored meet­ing spot for men seek­ing ren­dezvous with one an­other. They were rel­a­tively pri­vate, se­cluded, and per­fect for com­mu­ni­cat­ing anony­mously with graf­fiti—the ideal re­lease valve for a pop­u­la­tion that was pro­hib­ited from meet­ing pub­licly.

Early Doctors Diagnosed Disease by Looking at Urine

March 24, 2023

When uroscopy be­came trendy, it caused a mi­nor scan­dal within the early med­ical pro­fes­sion.

In Dirty Desire: The Uses and Misuses of Public Urinals in Nineteenth-Century Paris” so­ci­ol­o­gist Andrew Israel Ross tracks the con­tested ter­rain of the uri­nal, writ­ing:

[T]he case of the pub­lic uri­nals ul­ti­mately shows that the mean­ing of mod­ern ur­ban life emerged in a con­stantly shift­ing di­a­logue be­tween those who con­ceived and built the city and those who ul­ti­mately used it. The ten­dency of the built en­vi­ron­ment to ex­ceed the con­trol of those who con­ceived it … is a dis­tin­guish­ing fea­ture of mod­ern ur­ban life.

[T]he case of the pub­lic uri­nals ul­ti­mately shows that the mean­ing of mod­ern ur­ban life emerged in a con­stantly shift­ing di­a­logue be­tween those who con­ceived and built the city and those who ul­ti­mately used it. The ten­dency of the built en­vi­ron­ment to ex­ceed the con­trol of those who con­ceived it … is a dis­tin­guish­ing fea­ture of mod­ern ur­ban life.

The crack­down fol­lowed swiftly. The po­lice started pa­trolling par­tic­u­larly pop­u­lar uri­nals. So did black­mail­ers, for whom merely step­ping into a uri­nal was enough to launch a ha­rass­ment cam­paign.

Meanwhile, in the United States, toi­lets were be­com­ing a cen­ter­piece in yet an­other hot-but­ton is­sue: tem­per­ance. In the ab­sence of other op­tions, sa­loons had be­come the de facto pub­lic bath­room net­work for most ma­jor cities—which meant that any­one who needed to empty their blad­der was reg­u­larly ex­posed to the en­tice­ments of drink.

Weekly Newsletter

*” in­di­cates re­quired fields

As his­to­rian Peter C. Baldwin doc­u­ments in Public Privacy: Restrooms in American Cities, 1869 – 1932,” tem­per­ance ad­vo­cates made fight­ing for pub­lic bath­rooms one of their pri­or­i­ties. After all, once the sa­loons were shut down, peo­ple would still need some­where to go. Baldwin quotes a 1913 Chicago Tribune ar­ti­cle:

Why are we com­pelled to run the gaunt­let past the beer bar, the bar­tender, and sub­ject to the search­ing glance of this white-aproned gen­tle­man, un­til in shame we start to spend money for booze?

Why are we com­pelled to run the gaunt­let past the beer bar, the bar­tender, and sub­ject to the search­ing glance of this white-aproned gen­tle­man, un­til in shame we start to spend money for booze?

Rather than small, min­i­mally pri­vate pub­lic uri­nals, tem­per­ance ac­tivists ad­vo­cated for large, many-stalled comfort sta­tions.” But there was a sur­pris­ing side ef­fect: the pri­vately owned re­strooms started to close their gates. (After all, there were pub­lic bath­rooms avail­able now, so why should­n’t they only al­low in pay­ing cus­tomers?)

Meanwhile, as Prohibition played out, the pro­ject of con­struct­ing pub­lic bath­rooms slowed to a trickle, and the few that had been built be­gan to fall into dis­re­pair.

The large, un­der­ground com­fort sta­tions of the early twen­ti­eth cen­tury are

al­most all gone now through­out the United States. City pedes­tri­ans are usu­ally forced to rely on fa­cil­i­ties in semi-pri­vate build­ings such as ho­tels, stores, restau­rants, and cof­fee shops. Instead of a right con­ferred by gov­ern­ment on all cit­i­zens, bod­ily pri­vacy is a pur­chasable com­mod­ity. Even if pro­vided free of charge, the use of the toi­let is un­der­stood to be the re­sult of an agree­ment be­tween an in­di­vid­ual and a busi­ness. It is an awk­ward, grudg­ing agree­ment, in­flected by judg­ments of the in­di­vid­u­al’s so­cial sta­tus.

al­most all gone now through­out the United States. City pedes­tri­ans are usu­ally forced to rely on fa­cil­i­ties in semi-pri­vate build­ings such as ho­tels, stores, restau­rants, and cof­fee shops. Instead of a right con­ferred by gov­ern­ment on all cit­i­zens, bod­ily pri­vacy is a pur­chasable com­mod­ity. Even if pro­vided free of charge, the use of the toi­let is un­der­stood to be the re­sult of an agree­ment be­tween an in­di­vid­ual and a busi­ness. It is an awk­ward, grudg­ing agree­ment, in­flected by judg­ments of the in­di­vid­u­al’s so­cial sta­tus.

If you’ve ever been wan­der­ing the streets of Chicago or New York, won­der­ing why there’s no place to pee, this his­tory is part of the an­swer.

Men seek­ing same-sex en­coun­ters trans­formed the pis­soir into some­thing its plan­ners never in­tended. Who ul­ti­mately de­ter­mines the mean­ing of a pub­lic space: its de­sign­ers, au­thor­i­ties, or the peo­ple who use it?

The ar­ti­cle de­scribes em­peche pipi as an early form of hos­tile ar­chi­tec­ture. What as­sump­tions about hu­man be­hav­ior dis­tin­guish ar­chi­tec­ture de­signed to pre­vent an ac­tiv­ity from in­fra­struc­ture de­signed to ac­com­mo­date it?

What kinds of his­tor­i­cal sources would al­low us to re­con­struct the ex­pe­ri­ences of peo­ple who ac­tu­ally used nine­teenth-cen­tury pub­lic toi­lets, rather than the in­ten­tions of of­fi­cials who de­signed and reg­u­lated them?

Why did tem­per­ance ad­vo­cates in the United States view pub­lic re­strooms as part of the cam­paign against al­co­hol? What does that con­nec­tion re­veal about the un­ex­pected ways in­fra­struc­ture can in­flu­ence so­cial be­hav­ior?

The ar­ti­cle ends by de­scrib­ing bod­ily pri­vacy as a purchasable com­mod­ity” in many American cities. How does the his­tory of pub­lic toi­lets com­pli­cate the dis­tinc­tion be­tween pub­lic rights and pri­vate ser­vices?

Explore more class­room re­sources from JSTOR Daily.

To add this web app to your iOS home screen tap the share button and select "Add to the Home Screen".

10HN is also available as an iOS App

If you visit 10HN only rarely, check out the the best articles from the past week.

Visit pancik.com for more.