10 interesting stories served every morning and every evening.




1 2,831 shares, 118 trendiness

Google will require developer verification to install Android apps, including sideloading

To com­bat mal­ware and fi­nan­cial scams, Google an­nounced to­day that only apps from de­vel­op­ers that have un­der­gone ver­i­fi­ca­tion can be in­stalled on cer­ti­fied Android de­vices start­ing in 2026.

This re­quire­ment ap­plies to certified Android de­vices” that have Play Protect and are pre­loaded with Google apps. The Play Store im­ple­mented sim­i­lar re­quire­ments in 2023, but Google is now man­dat­ing this for all in­stall meth­ods, in­clud­ing third-party app stores and side­load­ing where you down­load an APK file from a third-party source.

Think of it like an ID check at the air­port, which con­firms a trav­el­er’s iden­tity but is sep­a­rate from the se­cu­rity screen­ing of their bags; we will be con­firm­ing who the de­vel­oper is, not re­view­ing the con­tent of their app or where it came from.

Google wants to com­bat convincing fake apps” and make it harder for re­peat malicious ac­tors to quickly dis­trib­ute an­other harm­ful app af­ter we take the first one down.” A re­cent analy­sis by the com­pany found that there are over 50 times more mal­ware from in­ter­net-side­loaded sources than on apps avail­able through Google Play.”

Google is ex­plicit to­day about how developers will have the same free­dom to dis­trib­ute their apps di­rectly to users through side­load­ing or to use any app store they pre­fer.”

This new re­quire­ment sees Google cre­ate a new Android Developer Console for those that only dis­trib­ute out­side of Google Play. Students and hob­by­ists will get a sep­a­rate work­flow that dif­fers from com­mer­cial de­vel­op­ers.

Those that dis­trib­ute via Google Play likely al­ready met these ver­i­fi­ca­tion re­quire­ments through the ex­ist­ing Play Console process,” with a D-U-N-S num­ber for or­ga­ni­za­tions needed.

The first Android app de­vel­op­ers will get ac­cess to ver­i­fi­ca­tion this October, with the process open­ing to all in March 2026.

The re­quire­ment will go into ef­fect in September 2026 for users in Brazil, Indonesia, Singapore, and Thailand. Google notes how these coun­tries have been specifically im­pacted by these forms of fraud­u­lent app scams.” Verification will then ap­ply glob­ally from 2027 on­wards.

At this point, any app in­stalled on a cer­ti­fied Android de­vice in these re­gions must be reg­is­tered by a ver­i­fied de­vel­oper.

Google notes supportive ini­tial feed­back” from gov­ern­ment au­thor­i­ties and other par­ties:

* …with Indonesia’s Ministry of Communications and Digital Affairs prais­ing it for pro­vid­ing a balanced ap­proach” that pro­tects users while keep­ing Android open.

* …Thailand’s Ministry of Digital Economy and Society sees it as a positive and proac­tive mea­sure” that aligns with their na­tional dig­i­tal safety poli­cies.

* In Brazil, the Brazilian Federation of Banks (FEBRABAN) sees it as a significant ad­vance­ment in pro­tect­ing users and en­cour­ag­ing ac­count­abil­ity.”

...

Read the original on 9to5google.com »

2 1,003 shares, 39 trendiness

Introducing Gemini 2.5 Flash Image, our state-of-the-art image model- Google Developers Blog

Today, we’re ex­cited to in­tro­duce Gemini 2.5 Flash Image (aka nano-ba­nana), our state-of-the-art im­age gen­er­a­tion and edit­ing model. This up­date en­ables you to blend mul­ti­ple im­ages into a sin­gle im­age, main­tain char­ac­ter con­sis­tency for rich sto­ry­telling, make tar­geted trans­for­ma­tions us­ing nat­ural lan­guage, and use Gemini’s world knowl­edge to gen­er­ate and edit im­ages. When we first launched na­tive im­age gen­er­a­tion in Gemini 2.0 Flash ear­lier this year, you told us you loved its low la­tency, cost-ef­fec­tive­ness, and ease of use. But you also gave us feed­back that you needed higher-qual­ity im­ages and more pow­er­ful cre­ative con­trol.This model is avail­able right now via the Gemini API and Google AI Studio for de­vel­op­ers and Vertex AI for en­ter­prise. Gemini 2.5 Flash Image is priced at $30.00 per 1 mil­lion out­put to­kens with each im­age be­ing 1290 out­put to­kens ($0.039 per im­age). All other modal­i­ties on in­put and out­put fol­low Gemini 2.5 Flash pric­ing.

To make build­ing with Gemini 2.5 Flash Image even eas­ier, we have made sig­nif­i­cant up­dates to Google AI Studio’s build mode” (with more up­dates to come). In the ex­am­ples be­low, not only can you quickly test the mod­el’s ca­pa­bil­i­ties with cus­tom AI pow­ered apps, but you can remix them or bring ideas to life with just a sin­gle prompt. When you are ready to share an app you built, you can de­ploy right from Google AI Studio or save the code to GitHub. Try a prompt like Build me an im­age edit­ing app that lets a user up­load an im­age and ap­ply dif­fer­ent fil­ters” or choose one of the pre­set tem­plates and remix it, all for free!A fun­da­men­tal chal­lenge in im­age gen­er­a­tion is main­tain­ing the ap­pear­ance of a char­ac­ter or ob­ject across mul­ti­ple prompts and ed­its. You can now place the same char­ac­ter into dif­fer­ent en­vi­ron­ments, show­case a sin­gle prod­uct from mul­ti­ple an­gles in new set­tings, or gen­er­ate con­sis­tent brand as­sets, all while pre­serv­ing the sub­ject.We built a tem­plate app in Google AI Studio (that you can eas­ily cus­tomize and vibe code on top of) to demon­strate the mod­el’s char­ac­ter con­sis­tency ca­pa­bil­i­ties.

Gemini 2.5 Flash Image en­ables tar­geted trans­for­ma­tion and pre­cise lo­cal ed­its with nat­ural lan­guage. For ex­am­ple, the model can blur the back­ground of an im­age, re­move a stain in a t-shirt, re­move an en­tire per­son from a photo, al­ter a sub­jec­t’s pose, add color to a black and white photo, or what­ever else you can con­jure up with a sim­ple prompt. To show these ca­pa­bil­i­ties in ac­tion, we built a photo edit­ing tem­plate app in AI Studio, with both UI and prompt-based con­trols.

Historically, im­age gen­er­a­tion mod­els have ex­celled at aes­thetic im­ages, but lacked a deep, se­man­tic un­der­stand­ing of the real world. With Gemini 2.5 Flash Image, the model ben­e­fits from Gemini’s world knowl­edge, which un­locks new use cases. To demon­strate this, we built a tem­plate app in Google AI Studio that turns a sim­ple can­vas into an in­ter­ac­tive ed­u­ca­tion tu­tor. It show­cases the mod­el’s abil­ity to read and un­der­stand hand-drawn di­a­grams, help with real world ques­tions, and fol­low com­plex edit­ing in­struc­tions in a sin­gle step.

Gemini 2.5 Flash Image can un­der­stand and merge mul­ti­ple in­put im­ages. You can put an ob­ject into a scene, restyle a room with a color scheme or tex­ture, and fuse im­ages with a sin­gle prompt. To show­case multi-im­age fu­sion, we built a tem­plate app in Google AI Studio which lets you drag prod­ucts into a new scene to quickly cre­ate a new pho­to­re­al­is­tic fused im­age.

Check out our de­vel­oper docs to start build­ing with Gemini 2.5 Flash Image. The model is in pre­view to­day via the Gemini API and Google AI Studio but will be sta­ble in the com­ing weeks. All of the demo apps we high­lighted here were vibe coded in Google AI Studio so they can be remixed and cus­tomized with just a prompt. OpenRouter.ai has part­nered with us to help bring Gemini 2.5 Flash Image to their 3M+ de­vel­op­ers every­where, to­day. This is the first model on OpenRouter — of the 480+ live to­day –that can gen­er­ate im­ages.We’re also ex­cited to part­ner with fal.ai, a lead­ing de­vel­oper plat­form for gen­er­a­tive me­dia, to make Gemini 2.5 Flash Image avail­able to the broader de­vel­oper com­mu­nity.All im­ages cre­ated or edited with Gemini 2.5 Flash Image will in­clude an in­vis­i­ble SynthID dig­i­tal wa­ter­mark, so they can be iden­ti­fied as AI-generated or edited.

...

Read the original on developers.googleblog.com »

3 1,003 shares, 35 trendiness

Create and edit images with Gemini 2.5 Flash Image

Generate, trans­form and edit im­ages with sim­ple text prompts, or com­bine mul­ti­ple im­ages to cre­ate some­thing new. All in Gemini.

Reuse the same char­ac­ters while chang­ing their out­fits, poses, the light­ing, or the scene. Or reimag­ine your­self — across decades, in dif­fer­ent places, or in your child­hood dream job.

Prompt 1: Remove the door mir­ror. Prompt 2: Make the land­scape snowy and moun­tain­ous. Prompt 3: Make her hair dyed cool blond at the top and ma­genta at the bot­tom. Prompt 4: She is wear­ing a yel­low and dark blue flan­nel shirt

Prompt: A clas­sic, faded pho­to­graph cap­tur­ing a scene from a 1960s record­ing stu­dio, fea­tur­ing these two blue char­ac­ters. They are de­picted in the con­trol room, sur­rounded by the warm glow of vac­uum tubes and the com­plex ar­ray of a large-for­mat mix­ing con­sole. The larger of the two blue fig­ures has a pair of bulky head­phones placed slightly askew on its head and gazes peace­fully through the sound­proof glass at a mu­si­cian in the live room. The smaller char­ac­ter, perched on a stool, wears a tiny pair of round, 1960s-style glasses and is turned slightly to ad­just a knob on a reel-to-reel tape ma­chine. The en­tire im­age has the aes­thetic of an aged pho­to­graph, with a grainy tex­ture, soft fo­cus, and a de­sat­u­rated, warm color palette.

Prompt: Change head piece to some­thing made from red flow­ers

Prompt: Create 5 head­shot po­laroid prints, laid out on a clean table, all of which show me in var­i­ous sit­u­a­tions from the 1980′s

Prompt: Make woman un­der­wa­ter, and re­move the couch and wall­pa­per

Prompt: A close-up shot of a ro­man­tic mo­ment hold­ing each other while it snows

Prompt 1: Show this man as a teacher. Prompt 2: Show this man as a sculp­tor. Prompt 3: Show this man as a nurse. Prompt 4: Show this man as a baker

Prompt: Recreate this dog as a 16-Bit Video Game char­ac­ter, and place the char­ac­ter in a level of a 2d 16-bit plat­form video game

Prompt 1: The t-rex is in a hal­loween cos­tume. Prompt 2: Now try a more fun cos­tume. Prompt 3: Fun. Now let’s try a cute cos­tume. Prompt 4: How about a pi­rate cos­tume?

Merge up to three im­ages to cre­ate some­thing new. Generate sur­re­al­ist art, com­bine dis­parate photo el­e­ments, or seam­lessly blend ob­jects, col­ors, and tex­tures.

Prompt: A hy­per-de­tailed, high-fash­ion pho­to­graph cap­tur­ing a woman float­ing within a mas­sive, amor­phous bub­ble of translu­cent, glass-like liq­uid on light blue back­ground.

Prompt: Replace the as­tro­naut on the right with the women and re­move the hel­met on the as­tro­naut on the left to show the man’s face. The two are look­ing at each other.

Prompt: Combine these pho­tos so that the syn­chro­nized swim­mers are in­side the lo­tus flower

Prompt: The man cud­dles with his dog

Create and edit im­ages with pow­er­ful con­trol. Replace the back­ground, re­store faded im­ages, and change char­ac­ters’ out­fits. Keep tweak­ing un­til you’re happy, all with nat­ural lan­guage.

Prompt: Change the pose, bal­le­rina is rais­ing her arms

Prompt: Make this en­vi­ron­ment com­pletely brand new and clean, no de­cay

Prompt 1: The house painted white. Prompt 2: Add flower beds with vi­brant bloom­ing flow­ers in front of the house. Prompt 3: Transformed into a fall set­ting. Prompt 4: Transform this im­age into a win­ter set­ting and dec­o­rate the houses

Prompt: Recreate this bird as red with hints of emer­ald green

Prompt: Change time of day to day with bright sun

Prompt: Fix the sign, make it say GAS

Experiment with cre­ative di­rec­tions, or bring them into dif­fer­ent con­texts. Apply spe­cific pat­terns to vis­i­ble sur­faces, or test out col­ors for fash­ion, de­sign, and in­te­rior dec­o­ra­tion.

Prompt: Turn this into a stun­ning out­fit of a woman walk­ing through a lus­cious botan­i­cal gar­den

Prompt: Restyle this liv­ing room in a fresh dreamy style mix­ing wo­ven ma­te­ri­als and tex­tures us­ing the colour swatches

Prompt: Turn me into a car­toon like char­ac­ter on the front of a 1960′s ce­real packet of Adventure O’s’ along with other text you would find on a ce­real box from the 1960′s. the packet sits in a break­fast table in a photo rem­i­nis­cent of the 1970′s

Prompt: Show me what you can build with this blue­print

Prompt: A bed­room restyled in an over the top, max­i­mal­ism style of The Cassette-Futurist Room’: A 1980s vi­sion of the fu­ture. Think clunky, beige plas­tic com­put­ers built into the walls, fur­ni­ture with un­nec­es­sary vents and chunky but­tons, and a colour palette of grey, or­ange, and brown. It’s the tech aes­thetic seen in clas­sic sci-fi films of that era.

Prompt: Fashion shot of a woman in a huge dress in origami pa­per red and white geo­met­ric pat­tern style

Prompt: Create an­other post stamp in the same se­ries with a dif­fer­ent mush­room

Prompt: Make this feath­ered tex­ture into a stun­ning dress on a woman stand­ing by a glac­ier lake

Prompt: Restyle this liv­ing room in nou­veau an­tique art deco style us­ing the colour swatches

Prompt: Woman walks in the dress with pat­tern from im­age 2 in the room with walls and floor from im­age 1

Generate mul­ti­ple im­ages us­ing just one prompt to ex­plore dif­fer­ent cre­ative av­enues. Or cre­ate sev­eral im­ages that work to­gether to tell a com­plete story.

Prompt: Create a beau­ti­fully en­ter­tain­ing 8 part story with 8 im­ages with two blue char­ac­ters and their ad­ven­tures in the 1960s mu­sic scene. The story is thrilling through­out with emo­tional highs and lows and end­ing on a great twist and high note. Do not in­clude any words or text on the im­ages but tell the story purely through the im­agery it­self.

Prompt: Create an ad­dic­tively in­trigu­ing 12 part story with 12 im­ages with these two char­ac­ters in a clas­sic black and white film noir de­tec­tive story. Make it about miss­ing trea­sure that they get clues for through­out and then fi­nally dis­cover. The story is thrilling through­out with emo­tional highs and lows and end­ing on a great twist and high note. Do not in­clude any words or text on the im­ages but tell the story purely through the im­agery it­self.

Prompt: Create a riv­et­ing epic 9 part story with 9 im­ages with these two pro­tag­o­nists and their ad­ven­tures as se­cret su­per heros. The story is thrilling through­out with emo­tional highs and lows and end­ing on a great twist and high note. Do not in­clude any words or text on the im­ages but tell the story purely through the im­agery it­self.

Upload im­ages and share text in­struc­tions with Gemini to cre­ate com­plex and de­tailed im­ages.

Use every­day lan­guage while cre­at­ing im­ages, and keep the con­ver­sa­tion go­ing to re­fine what the model gen­er­ates.

Generate im­ages that fol­low real-world logic, thanks to Gemini’s ad­vanced rea­son­ing ca­pa­bil­i­ties.

Gemini 2.5 Flash Image is a state-of-the-art im­age gen­er­a­tion and edit­ing model, with lower la­tency com­pared to other lead­ing mod­els.

Gemini 2.5 Flash Image was tested on LMArena as nano-ba­nana.

While Gemini can now cre­ate a wide range of im­ages, we’re still work­ing on im­prov­ing key ca­pa­bil­i­ties.

Not every im­age Gemini gen­er­ates will be per­fect – it can still strug­gle with small faces, ac­cu­rate spelling, and fine de­tails in im­ages.

The model ex­cels at char­ac­ter con­sis­tency, but it may not al­ways get it right. We’re work­ing to make this con­sis­tency even more re­li­able.

We use ex­ten­sive fil­ter­ing and data la­bel­ing to min­i­mize harm­ful con­tent in datasets and re­duce the like­li­hood of harm­ful out­puts. We also con­duct red team­ing and eval­u­a­tions on con­tent safety, in­clud­ing child safety, and rep­re­sen­ta­tion. Image gen­er­a­tion in Gemini has all our lat­est pri­vacy and safety fea­tures. This in­cludes SynthID, our tool that em­beds an in­vis­i­ble dig­i­tal wa­ter­mark di­rectly into an im­age, al­low­ing it to be iden­ti­fied as AI gen­er­ated.

...

Read the original on deepmind.google »

4 922 shares, 39 trendiness

Do the simplest thing that could possibly work

When de­sign­ing soft­ware sys­tems, do the sim­plest thing that could pos­si­bly work.

It’s sur­pris­ing how far you can take this piece of ad­vice. I gen­uinely think you can do this all the time. You can fol­low this ap­proach for fix­ing bugs, for main­tain­ing ex­ist­ing sys­tems, and for ar­chi­tect­ing new ones.

A lot of en­gi­neers de­sign by try­ing to think of the ideal” sys­tem: some­thing well-fac­tored, near-in­fi­nitely scal­able, el­e­gantly dis­trib­uted, and so on. I think this is en­tirely the wrong way to go about soft­ware de­sign. Instead, spend that time un­der­stand­ing the cur­rent sys­tem deeply, then do the sim­plest thing that could pos­si­bly work.

System de­sign re­quires com­pe­tence with a lot of dif­fer­ent tools: app servers, prox­ies, data­bases, caches, queues, and so on. As they gain fa­mil­iar­ity with these tools, ju­nior en­gi­neers nat­u­rally want to use them. It’s fun to con­struct sys­tems out of many dif­fer­ent com­po­nents! And it feels very sat­is­fy­ing to draw boxes and ar­rows on a white­board - like you’re do­ing real en­gi­neer­ing.

However, as with many skills, real mas­tery of­ten in­volves learn­ing when to do less, not more. The fight be­tween an am­bi­tious novice and an old mas­ter is a well-worn cliche in mar­tial arts movies: the novice is a blur of mo­tion, flip­ping and spin­ning. The mas­ter is mostly still. But some­how the novice’s at­tacks never seem to quite con­nect, and the mas­ter’s even­tual at­tack is de­ci­sive.

In soft­ware, this means that great soft­ware de­sign looks un­der­whelm­ing. It does­n’t look like any­thing much is hap­pen­ing at all. You can tell you’re in the pres­ence of great soft­ware de­sign be­cause you start hav­ing thoughts like oh, I did­n’t re­alise the prob­lem was that easy” or oh nice, you don’t ac­tu­ally have to do any­thing dif­fi­cult”.

Unicorn is great soft­ware de­sign, be­cause it de­liv­ers all the most im­por­tant guar­an­tees in a web server (request iso­la­tion, hor­i­zon­tal scal­ing, crash re­cov­ery) by lean­ing on Unix prim­i­tives. The in­dus­try-stan­dard Rails REST API is great soft­ware de­sign, be­cause it gives you ex­actly what you need for a CRUD app in the most bor­ing way pos­si­ble. I don’t think any of these are im­pres­sive soft­ware. But they’re im­pres­sive feats of de­sign, be­cause they do the sim­plest thing that could pos­si­bly work.

You should do that too! Suppose you’ve got a Golang ap­pli­ca­tion that you want to add some kind of rate lim­it­ing to. What’s the sim­plest thing that could pos­si­bly work? Your first idea might be to add some kind of per­sis­tent stor­age (say, Redis) to track per-user re­quest counts with a leaky-bucket al­go­rithm. That would work! But do you need a whole new piece of in­fra­struc­ture? What if in­stead you kept those per-user re­quest counts in-mem­ory? Sure, you’d lose some rate lim­it­ing data when the ap­pli­ca­tion is restarted, but does that mat­ter? Actually, are you sure your edge proxy does­n’t sup­port rate lim­it­ing al­ready? Could you just write a cou­ple of lines in a con­fig file in­stead of im­ple­ment­ing the fea­ture at all?

Maybe your edge proxy does­n’t sup­port rate lim­it­ing. Maybe you can’t track it in-mem­ory be­cause you have too many server in­stances run­ning in par­al­lel, so the tight­est rate limit you could en­force that way is too wide. Maybe it’s a deal­breaker if you ever lose rate lim­it­ing data, be­cause peo­ple are ham­mer­ing your ser­vice that hard. In that case, the sim­plest thing that could pos­si­bly work is adding per­sis­tent stor­age, so you should go and do that. But if you could do one of the eas­ier ap­proaches, would­n’t you want to?

You re­ally can build a whole ap­pli­ca­tion from scratch this way: start with the ab­solute sim­plest thing, and then only ex­tend it when you have new re­quire­ments that force you to. It sounds silly, but it works. Think of it as tak­ing YAGNI as the ul­ti­mate de­sign prin­ci­ple: above sin­gle-re­spon­si­bil­ity, above choos­ing the best tool for the job, and above good de­sign”.

Of course, there are three big prob­lems with al­ways do­ing the sim­plest thing that could pos­si­bly work. The first is that, by not an­tic­i­pat­ing fu­ture re­quire­ments, you end up with an in­flex­i­ble sys­tem or a big ball of mud. The sec­ond is that it’s not clear what simplest” means, so at worst I’m say­ing to de­sign well, al­ways do good de­sign”. The third is that you ought to be build­ing sys­tems that can scale, not sys­tems that just work right now. Let’s take those ob­jec­tions in or­der.

To some en­gi­neers, do the sim­plest thing that could pos­si­bly work” sounds like I’m telling them to stop do­ing en­gi­neer­ing. If the sim­plest thing is usu­ally a quick kludge, does that mean this ad­vice will in­evitably lead to a com­plete mess? We’ve all seen code­bases with hacks stacked on top of hacks, and they def­i­nitely don’t look like good de­sign.

But are hacks sim­ple? I ac­tu­ally don’t think so. The prob­lem with a hack or a kludge is pre­cisely that it is­n’t sim­ple: that it adds com­plex­ity to the code­base by in­tro­duc­ing an­other thing you have to al­ways re­mem­ber. Hacks are just eas­ier to think of. Figuring out the proper fix is hard be­cause it re­quires hav­ing to un­der­stand the en­tire code­base (or large sec­tions of it). In fact, the proper fix is al­most al­ways much sim­pler than the hack.

It is not easy to do the sim­plest thing that could pos­si­bly work. When you’re look­ing at a prob­lem, the first few so­lu­tions that come to mind are un­likely to be the sim­plest ones. Figuring out the sim­plest so­lu­tion re­quires con­sid­er­ing many dif­fer­ent ap­proaches. In other words, it re­quires do­ing en­gi­neer­ing.

Engineers dis­agree a lot about what con­sti­tutes sim­ple code. If simplest” al­ready means with good de­sign”, is it just a tau­tol­ogy to say you should do the sim­plest thing that could pos­si­bly work?” In other words, is Unicorn re­ally sim­pler than Puma? Is adding in-mem­ory rate lim­it­ing re­ally sim­pler than us­ing Redis? Here’s a rough, in­tu­itive de­f­i­n­i­tion of sim­plic­ity:

Simple sys­tems have fewer moving pieces”: fewer things you have to think about when you’re work­ing with them

Simple sys­tems are less in­ter­nally-con­nected. They are com­posed from com­po­nents with clear, straight­for­ward in­ter­faces

Unix processes are sim­pler than threads (and thus Unicorn is sim­pler than Puma) be­cause processes are less con­nected: they do not share mem­ory. This makes a lot of sense to me! But I don’t think it gives you the tools to fig­ure out what’s sim­pler in every case.

What about in-mem­ory rate lim­it­ing vs Redis? On the one hand, in-mem­ory is sim­pler be­cause you don’t have to think about all the things in­volved in stand­ing up a sep­a­rate ser­vice with per­sis­tent mem­ory. On the other hand, Redis is sim­pler be­cause the rate lim­it­ing guar­an­tees it of­fers are more straight­for­ward - you don’t have to worry about the case where one server in­stance thinks a user is rate lim­ited and an­other one does­n’t.

When I’m not sure what seems” sim­pler to me, I like to use this tiebreaker: sim­ple sys­tems are sta­ble. If you’re com­par­ing two states of a soft­ware sys­tem, and one will re­quire more on­go­ing work if no re­quire­ments change, the other one is sim­pler. Redis must be de­ployed and main­tained, it can have its own in­ci­dents, it re­quires its own mon­i­tor­ing, it re­quires a sep­a­rate de­ploy­ment in any new en­vi­ron­ments the ser­vice finds it­self in, and so on. Thus in-mem­ory rate lim­it­ing is sim­pler than Redis.

A cer­tain type of en­gi­neer is now scream­ing to them­selves but in-mem­ory rate lim­it­ing won’t scale!” Doing the sim­plest thing that could pos­si­bly work will em­phat­i­cally not de­liver the most web-scale sys­tem. It will de­liver a sys­tem that works well at the cur­rent scale. Is this ir­re­spon­si­ble en­gi­neer­ing?

No. In my view, the car­di­nal sin of big tech SaaS en­gi­neer­ing is an ob­ses­sion with scale. I’ve seen so much un­avoid­able pain caused by over-en­gi­neer­ing sys­tems to pre­pare for sev­eral or­ders of mag­ni­tude more than the cur­rent scale.

The main rea­son to not try this is that it does­n’t work. In my ex­pe­ri­ence, for any non-triv­ial code­base, you can’t an­tic­i­pate how it will be­have at sev­eral or­ders of mag­ni­tude more traf­fic, be­cause you don’t know ahead of time where all the bot­tle­necks are go­ing to be. At most you can try to make sure you’re ready for 2x or 5x the cur­rent traf­fic, and then stand by to deal with prob­lems as they come in.

The other rea­son not to try this is that it makes your code­base in­flex­i­ble. It’s fun to de­cou­ple your ser­vice into two pieces so they can be scaled in­de­pen­dently (I have seen this hap­pen maybe ten times, and I have seen them ac­tu­ally be use­fully scaled in­de­pen­dently maybe once). But that makes cer­tain fea­tures very hard to im­ple­ment, be­cause they now re­quire co­or­di­na­tion over the wire. In the worst case, they re­quire trans­ac­tions over the wire, which is a gen­uinely hard en­gi­neer­ing prob­lem. Most of the time you just don’t have to do any of this!

The longer I spend work­ing in tech, the less op­ti­mistic I be­come about our col­lec­tive abil­ity to pre­dict where a sys­tem is go­ing. It’s hard enough to get your head around where a sys­tem cur­rently is. And in fact, that’s the main prac­ti­cal dif­fi­culty in do­ing good de­sign: get­ting an ac­cu­rate big-pic­ture un­der­stand­ing of the sys­tem. Most de­sign is done with­out that un­der­stand­ing, and most de­sign is thus pretty bad.

There are, broadly speak­ing, two ways to de­velop soft­ware. The first is to pre­dict what your re­quire­ments might look like six months or a year from now, and then de­sign the best sys­tem for that pur­pose. The sec­ond is to de­sign the best sys­tem for what your re­quire­ments ac­tu­ally look like right now: in other words, to do the sim­plest thing that could pos­si­bly work.

edit: this ar­ti­cle has got­ten some com­ments on Hacker News.

One in­ter­est­ing com­ment thread says that sim­plic­ity of ar­chi­tec­ture does­n’t mat­ter at scale, be­cause the com­plex­ity of state space ex­plo­ration in im­ple­men­ta­tion” (I think that means some­thing like what I wrote about here) dom­i­nates any other com­plex­ity. I dis­agree - the more com­plex your fea­ture in­ter­ac­tions be­come, the more im­por­tant a sim­ple ar­chi­tec­ture be­comes, be­cause your complexity bud­get” is al­most ex­hausted.

I also want to credit Ward Cunningham and Kent Beck for in­vent­ing the ex­pres­sion - I gen­uinely thought I’d just come up with the word­ing my­self, but I al­most cer­tainly just re­mem­bered it. Oops! Thanks to the HN user ternary­op­er­a­tor for point­ing this out.

...

Read the original on www.seangoedecke.com »

5 800 shares, 62 trendiness

zakirullin/cognitive-load: 🧠 Cognitive Load is what matters

It is a liv­ing doc­u­ment, last up­date: August 2025. Your con­tri­bu­tions are wel­come!

There are so many buzz­words and best prac­tices out there, but most of them have failed. We need some­thing more fun­da­men­tal, some­thing that can’t be wrong.

Sometimes we feel con­fu­sion go­ing through the code. Confusion costs time and money. Confusion is caused by high cog­ni­tive load. It’s not some fancy ab­stract con­cept, but rather a fun­da­men­tal hu­man con­straint. It’s not imag­ined, it’s there and we can feel it.

Since we spend far more time read­ing and un­der­stand­ing code than writ­ing it, we should con­stantly ask our­selves whether we are em­bed­ding ex­ces­sive cog­ni­tive load into our code.

Cognitive load is how much a de­vel­oper needs to think in or­der to com­plete a task.

When read­ing code, you put things like val­ues of vari­ables, con­trol flow logic and call se­quences into your head. The av­er­age per­son can hold roughly four such chunks in work­ing mem­ory. Once the cog­ni­tive load reaches this thresh­old, it be­comes much harder to un­der­stand things.

Let’s say we have been asked to make some fixes to a com­pletely un­fa­mil­iar pro­ject. We were told that a re­ally smart de­vel­oper had con­tributed to it. Lots of cool ar­chi­tec­tures, fancy li­braries and trendy tech­nolo­gies were used. In other words, the au­thor had cre­ated a high cog­ni­tive load for us.

We should re­duce the cog­ni­tive load in our pro­jects as much as pos­si­ble.

Intrinsic - caused by the in­her­ent dif­fi­culty of a task. It can’t be re­duced, it’s at the very heart of soft­ware de­vel­op­ment.

Extraneous - cre­ated by the way the in­for­ma­tion is pre­sented. Caused by fac­tors not di­rectly rel­e­vant to the task, such as smart au­thor’s quirks. Can be greatly re­duced. We will fo­cus on this type of cog­ni­tive load.

Let’s jump straight to the con­crete prac­ti­cal ex­am­ples of ex­tra­ne­ous cog­ni­tive load.

We will re­fer to the level cog­ni­tive load as fol­lows:

🧠: fresh work­ing mem­ory, zero cog­ni­tive load

🧠++: two facts in our work­ing mem­ory, cog­ni­tive load in­creased

🤯: cog­ni­tive over­load, more than 4 facts

Our brain is much more com­plex and un­ex­plored, but we can go with this sim­plis­tic model.

if val > some­Con­stant // 🧠+

&& (condition2 || con­di­tion3) // 🧠+++, prev cond should be true, one of c2 or c3 has be true

&& (condition4 && !condition5) { // 🤯, we are messed up by this point

is­Valid = val > some­Con­stant

isAl­lowed = con­di­tion2 || con­di­tion3

is­Se­cure = con­di­tion4 && !condition5

// 🧠, we don’t need to re­mem­ber the con­di­tions, there are de­scrip­tive vari­ables

if is­Valid && isAl­lowed && is­Se­cure {

if is­Valid { // 🧠+, okay nested code ap­plies to valid in­put only

if is­Se­cure { // 🧠++, we do stuff for valid and se­cure in­put only

stuff // 🧠+++

Compare it with the early re­turns:

if !isValid

re­turn

if !isSecure

re­turn

// 🧠, we don’t re­ally care about ear­lier re­turns, if we are here then all good

stuff // 🧠+

We can fo­cus on the happy path only, thus free­ing our work­ing mem­ory from all sorts of pre­con­di­tions.

We are asked to change a few things for our ad­min users: 🧠

Ohh, part of the func­tion­al­ity is in BaseController, let’s have a look: 🧠+

Basic role me­chan­ics got in­tro­duced in GuestController: 🧠++

Things got par­tially al­tered in UserController: 🧠+++

Finally we are here, AdminController, let’s code stuff! 🧠++++

Oh, wait, there’s SuperuserController which ex­tends AdminController. By mod­i­fy­ing AdminController we can break things in the in­her­ited class, so let’s dive in SuperuserController first: 🤯

Prefer com­po­si­tion over in­her­i­tance. We won’t go into de­tail - there’s plenty of ma­te­r­ial out there.

Method, class and mod­ule are in­ter­change­able in this con­text

Mantras like methods should be shorter than 15 lines of code” or classes should be small” turned out to be some­what wrong.

Deep mod­ule - sim­ple in­ter­face, com­plex func­tion­al­ity

Shallow mod­ule - in­ter­face is rel­a­tively com­plex to the small func­tion­al­ity it pro­vides

Having too many shal­low mod­ules can make it dif­fi­cult to un­der­stand the pro­ject. Not only do we have to keep in mind each mod­ule re­spon­si­bil­i­ties, but also all their in­ter­ac­tions. To un­der­stand the pur­pose of a shal­low mod­ule, we first need to look at the func­tion­al­ity of all the re­lated mod­ules. Jumping be­tween such shal­low com­po­nents is men­tally ex­haust­ing, lin­ear think­ing is more nat­ural to us hu­mans.

Information hid­ing is para­mount, and we don’t hide as much com­plex­ity in shal­low mod­ules.

I have two pet pro­jects, both of them are some­what 5K lines of code. The first one has 80 shal­low classes, whereas the sec­ond one has only 7 deep classes. I haven’t been main­tain­ing any of these pro­jects for one year and a half.

Once I came back, I re­alised that it was ex­tremely dif­fi­cult to un­tan­gle all the in­ter­ac­tions be­tween those 80 classes in the first pro­ject. I would have to re­build an enor­mous amount of cog­ni­tive load be­fore I could start cod­ing. On the other hand, I was able to grasp the sec­ond pro­ject quickly, be­cause it had only a few deep classes with a sim­ple in­ter­face.

The best com­po­nents are those that pro­vide pow­er­ful func­tion­al­ity yet have a sim­ple in­ter­face.

John K. Ousterhout

The in­ter­face of the UNIX I/O is very sim­ple. It has only five ba­sic calls:

open(path, flags, per­mis­sions)

read(fd, buffer, count)

write(fd, buffer, count)

lseek(fd, off­set, ref­er­en­ce­Po­si­tion)

close(fd)

A mod­ern im­ple­men­ta­tion of this in­ter­face has hun­dreds of thou­sands of lines of code. Lots of com­plex­ity is hid­den un­der the hood. Yet it is easy to use due to its sim­ple in­ter­face.

P. S. If you think we are root­ing for bloated God ob­jects with too many re­spon­si­bil­i­ties, you got it wrong.

All too of­ten, we end up cre­at­ing lots of shal­low mod­ules, fol­low­ing some vague a mod­ule should be re­spon­si­ble for one, and only one, thing” prin­ci­ple. What is this blurry one thing? Instantiating an ob­ject is one thing, right? So MetricsProviderFactoryFactory seems to be just fine. The names and in­ter­faces of such classes tend to be more men­tally tax­ing than their en­tire im­ple­men­ta­tions, what kind of ab­strac­tion is that? Something went wrong.

We make changes to our sys­tems to sat­isfy our users and stake­hold­ers. We are re­spon­si­ble to them.

A mod­ule should be re­spon­si­ble to one, and only one, user or stake­holder.

This is what this Single Responsibility Principle is all about. Simply put, if we in­tro­duce a bug in one place, and then two dif­fer­ent busi­ness peo­ple come to com­plain, we’ve vi­o­lated the prin­ci­ple. It has noth­ing to do with the num­ber of things we do in our mod­ule.

But even now, this rule can do more harm than good. This prin­ci­ple can be un­der­stood in as many dif­fer­ent ways as there are in­di­vid­u­als. A bet­ter ap­proach would be to look at how much cog­ni­tive load it all cre­ates. It’s men­tally de­mand­ing to re­mem­ber that change in one place can trig­ger a chain of re­ac­tions across dif­fer­ent busi­ness streams. And that’s about it, no fancy terms to learn.

This shal­low-deep mod­ule prin­ci­ple is scale-ag­nos­tic, and we can ap­ply it to mi­croser­vices ar­chi­tec­ture. Too many shal­low mi­croser­vices won’t do any good - the in­dus­try is head­ing to­wards some­what macroservices”, i.e., ser­vices that are not so shal­low (=deep). One of the worst and hard­est to fix phe­nom­ena is so-called dis­trib­uted mono­lith, which is of­ten the re­sult of this overly gran­u­lar shal­low sep­a­ra­tion.

I once con­sulted a startup where a team of five de­vel­op­ers in­tro­duced 17(!) mi­croser­vices. They were 10 months be­hind sched­ule and ap­peared nowhere close to the pub­lic re­lease. Every new re­quire­ment led to changes in 4+ mi­croser­vices. It took an enor­mous amount of time to re­pro­duce and de­bug an is­sue in such a dis­trib­uted sys­tem. Both time to mar­ket and cog­ni­tive load were un­ac­cept­ably high. 🤯

Is this the right way to ap­proach the un­cer­tainty of a new sys­tem? It’s enor­mously dif­fi­cult to elicit the right log­i­cal bound­aries in the be­gin­ning. The key is to make de­ci­sions as late as you can re­spon­si­bly wait, be­cause that is when you have the most in­for­ma­tion at hand. By in­tro­duc­ing a net­work layer up front, we make our de­sign de­ci­sions hard to re­vert right from the start. The team’s only jus­ti­fi­ca­tion was: The FAANG com­pa­nies proved mi­croser­vices ar­chi­tec­ture to be ef­fec­tive”. Hello, you got to stop dream­ing big.

The Tanenbaum-Torvalds de­bate ar­gued that Linux’s mono­lithic de­sign was flawed and ob­so­lete, and that a mi­cro­ker­nel ar­chi­tec­ture should be used in­stead. Indeed, the mi­cro­ker­nel de­sign seemed to be su­pe­rior from a the­o­ret­i­cal and aes­thet­i­cal” point of view. On the prac­ti­cal side of things - three decades on, mi­cro­ker­nel-based GNU Hurd is still in de­vel­op­ment, and mono­lithic Linux is every­where. This page is pow­ered by Linux, your smart teapot is pow­ered by Linux. By mono­lithic Linux.

A well-crafted mono­lith with truly iso­lated mod­ules is of­ten much more flex­i­ble than a bunch of mi­croser­vices. It also re­quires far less cog­ni­tive ef­fort to main­tain. It’s only when the need for sep­a­rate de­ploy­ments be­comes cru­cial, such as scal­ing the de­vel­op­ment team, that you should con­sider adding a net­work layer be­tween the mod­ules, fu­ture mi­croser­vices.

We feel ex­cited when new fea­tures got re­leased in our favourite lan­guage. We spend some time learn­ing these fea­tures, we build code upon them.

If there are lots of fea­tures, we may spend half an hour play­ing with a few lines of code, to use one or an­other fea­ture. And it’s kind of a waste of time. But what’s worse, when you come back later, you would have to recre­ate that thought process!

You not only have to un­der­stand this com­pli­cated pro­gram, you have to un­der­stand why a pro­gram­mer de­cided this was the way to ap­proach a prob­lem from the fea­tures that are avail­able. 🤯

These state­ments are made by none other than Rob Pike.

Reduce cog­ni­tive load by lim­it­ing the num­ber of choices.

Language fea­tures are OK, as long as they are or­thog­o­nal to each other.

On the back­end we re­turn:

401 for ex­pired jwt to­ken

403 for not enough ac­cess

418 for banned users

The en­gi­neers on the fron­tend use back­end API to im­ple­ment lo­gin func­tion­al­ity. They would have to tem­porar­ily cre­ate the fol­low­ing cog­ni­tive load in their brains:

401 is for ex­pired jwt to­ken // 🧠+, ok just tem­po­rary re­mem­ber it

403 is for not enough ac­cess // 🧠++

418 is for banned users // 🧠+++

Frontend de­vel­op­ers would (hopefully) in­tro­duce some kind nu­meric sta­tus -> mean­ing dic­tio­nary on their side, so that sub­se­quent gen­er­a­tions of con­trib­u­tors would­n’t have to recre­ate this map­ping in their brains.

Then QA en­gi­neers come into play: Hey, I got 403 sta­tus, is that ex­pired to­ken or not enough ac­cess?”

QA en­gi­neers can’t jump straight to test­ing, be­cause first they have to recre­ate the cog­ni­tive load that the en­gi­neers on the back­end once cre­ated.

Why hold this cus­tom map­ping in our work­ing mem­ory? It’s bet­ter to ab­stract away your busi­ness de­tails from the HTTP trans­fer pro­to­col, and re­turn self-de­scrip­tive codes di­rectly in the re­sponse body:

code”: jwt_has_expired”

Cognitive load on the fron­tend side: 🧠 (fresh, no facts are held in mind)

Cognitive load on the QA side: 🧠

The same rule ap­plies to all sorts of nu­meric sta­tuses (in the data­base or wher­ever) - pre­fer self-de­scrib­ing strings. We are not in the era of 640K com­put­ers to op­ti­mise for mem­ory.

People spend time ar­gu­ing be­tween 401 and 403, mak­ing de­ci­sions based on their own men­tal mod­els. New de­vel­op­ers are com­ing in, and they need to recre­ate that thought process. You may have doc­u­mented the whys” (ADRs) for your code, help­ing new­com­ers to un­der­stand the de­ci­sions made. But in the end it just does­n’t make any sense. We can sep­a­rate er­rors into ei­ther user-re­lated or server-re­lated, but apart from that, things are kind of blurry.

P. S. It’s of­ten men­tally tax­ing to dis­tin­guish be­tween authentication” and authorization”. We can use sim­pler terms like login” and permissions” to re­duce the cog­ni­tive load.

Do not re­peat your­self - that is one of the first prin­ci­ples you are taught as a soft­ware en­gi­neer. It is so deeply em­bed­ded in our­selves that we can not stand the fact of a few ex­tra lines of code. Although in gen­eral a good and fun­da­men­tal rule, when overused it leads to the cog­ni­tive load we can not han­dle.

Nowadays, every­one builds soft­ware based on log­i­cally sep­a­rated com­po­nents. Often those are dis­trib­uted among mul­ti­ple code­bases rep­re­sent­ing sep­a­rate ser­vices. When you strive to elim­i­nate any rep­e­ti­tion, you might end up cre­at­ing tight cou­pling be­tween un­re­lated com­po­nents. As a re­sult changes in one part may have un­in­tended con­se­quences in other seem­ingly un­re­lated ar­eas. It can also hin­der the abil­ity to re­place or mod­ify in­di­vid­ual com­po­nents with­out im­pact­ing the en­tire sys­tem. 🤯

In fact, the same prob­lem arises even within a sin­gle mod­ule. You might ex­tract com­mon func­tion­al­ity too early, based on per­ceived sim­i­lar­i­ties that might not ac­tu­ally ex­ist in the long run. This can re­sult in un­nec­es­sary ab­strac­tions that are dif­fi­cult to mod­ify or ex­tend.

A lit­tle copy­ing is bet­ter than a lit­tle de­pen­dency.

We are tempted to not rein­vent the wheel so strong that we are ready to im­port large, heavy li­braries to use a small func­tion that we could eas­ily write by our­selves.

All your de­pen­den­cies are your code. Going through 10+ lev­els of stack trace of some im­ported li­brary and fig­ur­ing out what went wrong (because things go wrong) is painful.

...

Read the original on github.com »

6 782 shares, 30 trendiness

Dissecting the Apple M1 GPU, the end

In 2020, Apple re­leased the M1 with a cus­tom GPU. We got to work re­verse-en­gi­neer­ing the hard­ware and port­ing Linux. Today, you can run Linux on a range of M1 and M2 Macs, with al­most all hard­ware work­ing: wire­less, au­dio, and full graph­ics ac­cel­er­a­tion.

Our story be­gins in December 2020, when Hector Martin kicked off Asahi Linux. I was work­ing for Collabora work­ing on Panfrost, the open source Mesa3D dri­ver for Arm Mali GPUs. Hector put out a pub­lic call for guid­ance from up­stream open source main­tain­ers, and I bit. I just in­tended to give some quick point­ers. Instead, I bought my­self a Christmas pre­sent and got to work. In be­tween my uni­ver­sity course­work and Collabora work, I poked at the shader

in­struc­tion set.

One thing led to an­other. Within a few weeks, I drew a

tri­an­gle.

In 3D graph­ics, once you can draw a tri­an­gle, you can do any­thing.

Pretty soon, I started work on a shader

com­piler. After my fi­nal ex­ams that se­mes­ter, I took a few days off from Collabora to bring up an OpenGL

dri­ver ca­pa­ble of spin­ning gears with my new com­piler.

Over the next year, I kept re­verse-en­gi­neer­ing

and im­prov­ing the dri­ver un­til it could run 3D

games on ma­cOS.

Meanwhile, Asahi Lina wrote a ker­nel dri­ver for the Apple GPU. My user­space OpenGL dri­ver ran on ma­cOS, leav­ing her ker­nel dri­ver as the miss­ing piece for an open source graph­ics stack. In December 2022, we shipped graph­ics

ac­cel­er­a­tion in Asahi Linux.

In January 2023, I started my fi­nal se­mes­ter in my Computer Science pro­gram at the University of

Toronto. For years I jug­gled my courses with my part-time job and my hobby dri­ver. I faced the same ques­tion as my peers: what will I do af­ter grad­u­a­tion?

Maybe Panfrost? I started re­verse-en­gi­neer­ing of the Mali Midgard GPU back in 2017, when I was still in high school. That led to an in­tern­ship at Collabora in 2019 once I grad­u­ated, turn­ing into my job through­out four years of uni­ver­sity. During that time, Panfrost grew from a kid’s pet pro­ject based on black­box re­verse-en­gi­neer­ing, to a pro­fes­sional dri­ver en­gi­neered by a team with Arm’s back­ing and hard­ware doc­u­men­ta­tion. I did what I set out to do, and the pro­ject suc­ceeded be­yond my dreams. It was

time to move on.

What did I want to do next?

* Finish what I started with the M1. Ship a great dri­ver.

* Bring full, con­for­mant OpenGL dri­vers to the M1. Apple’s dri­vers are

not con­for­mant, but we should strive for the in­dus­try stan­dard.

* Bring full, con­for­mant Vulkan to Apple plat­forms, dis­prov­ing the

myth that Vulkan is­n’t suit­able for Apple hard­ware.

* Bring Proton gam­ing to Asahi Linux. Thanks to Valve’s work for the

Steam Deck, Windows games can run bet­ter on Linux than even on Windows.

Why not reap those ben­e­fits on the M1?

Panfrost was my chal­lenge un­til we won”. My next chal­lenge? Gaming on Linux on M1.

Once I fin­ished my course­work, I started full-time on gam­ing on Linux. Within a month, we shipped OpenGL 3.1

on Asahi Linux. A few weeks later, we passed of­fi­cial

con­for­mance for OpenGL ES 3.1. That put us at fea­ture par­ity with Panfrost. I wanted to go fur­ther.

OpenGL (ES) 3.2 re­quires geom­e­try shaders, a legacy fea­ture not sup­ported by ei­ther Arm or Apple hard­ware. The pro­pri­etary OpenGL dri­vers em­u­late geom­e­try shaders with com­pute, but there was no open source prior art to bor­row. Even though mul­ti­ple Mesa dri­vers need geom­e­try/​tes­sel­la­tion em­u­la­tion, no­body did the work to get there.

My early progress on OpenGL was fast thanks to the ma­ture com­mon code in Mesa. It was time to pay it for­ward. Over the rest of the year, I im­ple­mented geom­e­try/​tes­sel­la­tion shader em­u­la­tion. And also the rest of the owl. In January 2024, I passed con­for­mance for the full OpenGL

4.6 spec­i­fi­ca­tion, fin­ish­ing up OpenGL.

Vulkan was­n’t too bad, ei­ther. I pol­ished the OpenGL dri­ver for a few months, but once I started typ­ing a Vulkan dri­ver, I passed 1.3

con­for­mance in a few weeks.

What re­mained was wiring up the geom­e­try/​tes­sel­la­tion em­u­la­tion to my shiny new Vulkan dri­ver, since those are re­quired for Direct3D. Et voilà, Proton

games.

Along the way, Karol

Herbst passed OpenCL 3.0 con­for­mance on the M1, run­ning my com­piler atop his rusticl” fron­tend.

Meanwhile, when the Vulkan 1.4 spec­i­fi­ca­tion was pub­lished, we were ready and shipped

a con­for­mant im­ple­men­ta­tion on the same day.

After that, I im­ple­mented sparse tex­ture sup­port, un­lock­ing Direct3D 12 via Proton.

We’ve suc­ceeded be­yond my dreams. The chal­lenges I chased, I have tack­led. The dri­vers are fully up­stream in Mesa. Performance is­n’t too bad. With the Vulkan on Apple myth busted, con­for­mant Vulkan is now com­ing to ma­cOS via LunarG’s

KosmicKrisp pro­ject build­ing on my work.

Satisfied, I am now step­ping away from the Apple ecosys­tem. My friends in the Asahi Linux or­bit will carry the torch from here. As for me?

...

Read the original on rosenzweig.io »

7 778 shares, 31 trendiness

What are OKLCH colors?

OKLCH is a newer color model that is de­signed to be per­cep­tu­ally uni­form. This means that col­ors are much more ac­cu­rate in terms of how hu­mans per­ceive them and it makes work­ing with them much eas­ier.

Before be­ing able to un­der­stand how OKLCH dif­fers from the other color mod­els, it is im­por­tant to un­der­stand some of the ba­sic color con­cepts.

Color mod­els are sys­tems to de­scribe col­ors. These in­clude RGB, HSL, LCH, OKLCH and more. The model de­ter­mines how easy it is to ma­nip­u­late or think about a color.

Gamut is a play­ing field where the model lives and de­fines what col­ors are pos­si­ble. Common gamuts in­clude sRGB (the web de­fault) and Display-P3 (used on mod­ern de­vices).

There is a lot more nu­ance when you get into color spaces. They don’t just de­fine a gamut, but also things like the white point and trans­fer func­tion. I de­cided to leave those out for the sake of keep­ing the ar­ti­cle sim­ple.

OKLCH, same as LCH, con­sists of three val­ues: Lightness, Chroma and Hue. The dif­fer­ence be­tween the two is the un­der­ly­ing color space that the color model uses, which in case of OKLCH, is OKLab.

Lightness - Equal steps feel like equal changes in bright­ness. Ranges from value be­tween 0 and 1 or per­cent­age rang­ing from 0% to 100%.

Chroma - Controls in­ten­sity of the color, sim­i­lar to sat­u­ra­tion.

Hue - Controls the hue, mea­sured in de­grees rang­ing from 0 to 360.

Let’s say you want to cre­ate a cou­ple of pill but­tons and you want each one to have a dif­fer­ent color. The usual work­flow with sRGB col­ors would be defin­ing the first color and then hand­pick­ing oth­ers to match it.

With OKLCH, you can use the same value for all of them and only change hue. That way you cre­ate col­ors that look and feel the same.

You can do the same thing with color mod­els like HSL, but as you can see above, the col­ors don’t look uni­form. Some are lighter, some darker, some pop more and some less.

This is one of the ma­jor ad­van­tages of OKLCH over other color mod­els. Creating per­cep­tu­ally uni­form color palettes and work­ing with them is very easy.

It also works the other way around, where you can change the light­ness value to cre­ate var­i­ous color shades and there is no hue or sat­u­ra­tion drift un­like in other color modes.

In the ex­am­ple above, you can see that the OKLCH col­ors main­tain con­sis­tent blue­ness across all of the shades, while in the HSL ex­am­ple, the lighter shades drift to pur­ple and the darker ones muddy out to­wards gray­ish.

The way gra­di­ents work in OKLCH is pretty dif­fer­ent com­pared to sRGB. In sRGB, gra­di­ents are cal­cu­lated in red, green, and blue val­ues, which of­ten leads to muddy mid­points and un­even bright­ness.

In OKLCH, the math fol­lows light­ness, chroma, and hue. In the ex­am­ple above you can see that the start­ing and end­ing points are the same but the col­ors the gra­di­ent passes through are quite dif­fer­ent.

This can be a dou­ble edged sword. While some gra­di­ents might look smoother, you might also see col­ors that you’ve never de­fined. This is be­cause hue in OKLCH is cir­cu­lar and gra­di­ents can take un­ex­pected de­tours.

To avoid this, many tools use OKLAB for gra­di­ents, which in­ter­po­lates in a straight line and gives more con­sis­tent re­sults.

sRGB can’t reach a lot of col­ors that mod­ern screens can show. In OKLCH you can write col­ors that are only pos­si­ble to ren­der on a screen that sup­ports Display-P3 col­ors.

If you are on a dis­play that sup­ports Display-P3, you will see the right col­ors more vivid than the left ones. If you are on a dis­play that only sup­ports sRGB, the col­ors should look nearly iden­ti­cal, as the browser maps the out of gamut color back in­side the sRGB gamut.

Keep in mind that grays are iden­ti­cal in sRGB and Display-P3, so there would be no dif­fer­ence there.

OKLCH can also de­fine more col­ors than any real screen can show. It can spec­ify val­ues that don’t fit in­side any ac­tual gamut like sRGB or Display-P3.

Let’s take this color as an ex­am­ple color: oklch(0.7 0.4 40). It has a very high chroma value and it could math­e­mat­i­cally ex­ist but in prac­tice it lies out­side of any real dis­play’s gamut. When this color is used, it will get clipped or mapped to the near­est rep­re­sentable color in­side the gamut.

@layer base {

:root {

color: oklch(0.7 0.4 40);

Generally you don’t want this to hap­pen, as the clipped color can of­ten look very dif­fer­ent from the de­fined one.

Therefore, there is a con­cept of a max­i­mum chroma value, which cal­cu­lates the max­i­mum chroma that a dis­play can show based on the light­ness, hue and the se­lected gamut like sRGB or Display-P3.

OKLCH col­ors were in­tro­duced in CSS Color Module Level 4 and they are well sup­ported across all mod­ern browsers.

However, there are still some sur­faces where OKLCH col­ors are not sup­ported such as out­dated browsers. In case you are wor­ried about this, you can add fall­backs and use the @supports di­rec­tive in CSS.

@layer base {

:root {

/* sRGB hex */

–color-gray-100: #fcfcfc;

–color-gray-200: #fafafa;

–color-gray-300: #f4f4f4;

@supports (color: oklch(0 0 0)) {

/* OKLCH */

–color-gray-100: oklch(0.991 0 0);

–color-gray-200: oklch(0.982 0 0);

–color-gray-300: oklch(0.955 0 0);

This way the browser uses OKLCH col­ors if the syn­tax is sup­ported, oth­er­wise it falls back to sRGB.

Keep in mind that this does­n’t mag­i­cally change how the col­ors look. If an OKLCH color fits in­side the sRGB gamut, it will look the same as the equiv­a­lent hex color. The dif­fer­ence is that OKLCH can also de­fine col­ors out­side of sRGB, like the Display-P3 gamut, which hex val­ues can’t reach.

I built a small tool ded­i­cated to OKLCH col­ors called oklch.fyi. It helps gen­er­ate OKLCH col­ors palettes, it can take your ex­ist­ing CSS vari­ables and con­vert them to OKLCH and more.

Try it out!

In case you have any ques­tions reach me at jakub@kbo.sk or see more of my work on Twitter.

...

Read the original on jakub.kr »

8 770 shares, 26 trendiness

Piloting Claude for Chrome

We’ve spent re­cent months con­nect­ing Claude to your cal­en­dar, doc­u­ments, and many other pieces of soft­ware. The next log­i­cal step is let­ting Claude work di­rectly in your browser.

We view browser-us­ing AI as in­evitable: so much work hap­pens in browsers that giv­ing Claude the abil­ity to see what you’re look­ing at, click but­tons, and fill forms will make it sub­stan­tially more use­ful.

But browser-us­ing AI brings safety and se­cu­rity chal­lenges that need stronger safe­guards. Getting real-world feed­back from trusted part­ners on uses, short­com­ings, and safety is­sues lets us build ro­bust clas­si­fiers and teach fu­ture mod­els to avoid un­de­sir­able be­hav­iors. This en­sures that as ca­pa­bil­i­ties ad­vance, browser safety keeps pace.

Browser-using agents pow­ered by fron­tier mod­els are al­ready emerg­ing, mak­ing this work es­pe­cially ur­gent. By solv­ing safety chal­lenges, we can bet­ter pro­tect Claude users and share what we learn with any­one build­ing a browser-us­ing agent on our API.

We’re start­ing with con­trolled test­ing: a Claude ex­ten­sion for Chrome where trusted users can in­struct Claude to take ac­tions on their be­half within the browser. We’re pi­lot­ing with 1,000 Max plan users—join the wait­list—to learn as much as we can. We’ll grad­u­ally ex­pand ac­cess as we de­velop stronger safety mea­sures and build con­fi­dence through this lim­ited pre­view.

Within Anthropic, we’ve seen ap­pre­cia­ble im­prove­ments us­ing early ver­sions of Claude for Chrome to man­age cal­en­dars, sched­ule meet­ings, draft email re­sponses, han­dle rou­tine ex­pense re­ports, and test new web­site fea­tures.

However, some vul­ner­a­bil­i­ties re­main to be fixed be­fore we can make Claude for Chrome gen­er­ally avail­able. Just as peo­ple en­counter phish­ing at­tempts in their in­boxes, browser-us­ing AIs face prompt in­jec­tion at­tacks—where ma­li­cious ac­tors hide in­struc­tions in web­sites, emails, or doc­u­ments to trick AIs into harm­ful ac­tions with­out users’ knowl­edge (like hid­den text say­ing disregard pre­vi­ous in­struc­tions and do [malicious ac­tion] in­stead”).

Prompt in­jec­tion at­tacks can cause AIs to delete files, steal data, or make fi­nan­cial trans­ac­tions. This is­n’t spec­u­la­tion: we’ve run red-teaming” ex­per­i­ments to test Claude for Chrome and, with­out mit­i­ga­tions, we’ve found some con­cern­ing re­sults.

We con­ducted ex­ten­sive ad­ver­sar­ial prompt in­jec­tion test­ing, eval­u­at­ing 123 test cases rep­re­sent­ing 29 dif­fer­ent at­tack sce­nar­ios. Browser use with­out our safety mit­i­ga­tions showed a 23.6% at­tack suc­cess rate when de­lib­er­ately tar­geted by ma­li­cious ac­tors.

One ex­am­ple of a suc­cess­ful at­tack—be­fore our new de­fenses were ap­plied—was a ma­li­cious email claim­ing that, for se­cu­rity rea­sons, emails needed to be deleted. When pro­cess­ing the in­box, Claude fol­lowed these in­struc­tions to delete the user’s emails with­out con­fir­ma­tion.

As we’ll ex­plain in the next sec­tion, we’ve al­ready im­ple­mented sev­eral de­fenses that sig­nif­i­cantly re­duce the at­tack suc­cess rate—though there’s still work to do in un­cov­er­ing novel at­tack vec­tors.

The first line of de­fense against prompt in­jec­tion at­tacks is per­mis­sions. Users main­tain con­trol over what Claude for Chrome can ac­cess and do:

* Site-level per­mis­sions: Users can grant or re­voke Claude’s ac­cess to spe­cific web­sites at any time in the Settings.

* Action con­fir­ma­tions: Claude asks users be­fore tak­ing high-risk ac­tions like pub­lish­ing, pur­chas­ing, or shar­ing per­sonal data. Even when users opt into our ex­per­i­men­tal autonomous mode,” Claude still main­tains cer­tain safe­guards for highly sen­si­tive ac­tions (Note: all red-team­ing and safety eval­u­a­tions were con­ducted in au­tonomous mode).

We’ve also built ad­di­tional safe­guards in line with Anthropic’s trust­wor­thy agents prin­ci­ples. First, we’ve im­proved our sys­tem prompts—the gen­eral in­struc­tions Claude re­ceives be­fore spe­cific in­struc­tions from users—to di­rect Claude on how to han­dle sen­si­tive data and re­spond to re­quests to take sen­si­tive ac­tions.

Additionally, we’ve blocked Claude from us­ing web­sites from cer­tain high-risk cat­e­gories such as fi­nan­cial ser­vices, adult con­tent, and pi­rated con­tent. And we’ve be­gun to build and test ad­vanced clas­si­fiers to de­tect sus­pi­cious in­struc­tion pat­terns and un­usual data ac­cess re­quests—even when they arise in seem­ingly le­git­i­mate con­texts.

When we added safety mit­i­ga­tions to au­tonomous mode, we re­duced the at­tack suc­cess rate of 23.6% to 11.2%, which rep­re­sents a mean­ing­ful im­prove­ment over our ex­ist­ing Computer Use ca­pa­bil­ity (where Claude could see the user’s screen but with­out the browser in­ter­face that we’re in­tro­duc­ing to­day).

We also con­ducted spe­cial red-team­ing and mit­i­ga­tions fo­cused on new at­tacks spe­cific to the browser, such as hid­den ma­li­cious form fields in a web­page’s Document Object Model (DOM) in­vis­i­ble to hu­mans, and other hard-to-catch in­jec­tions such as through the URL text and tab ti­tle that only an agent might see. On a challenge” set of four browser-spe­cific at­tack types, our new mit­i­ga­tions were able to re­duce at­tack suc­cess rate from 35.7% to 0%.

Before we make Claude for Chrome more widely avail­able, we want to ex­pand the uni­verse of at­tacks we’re think­ing about and learn how to get these per­cent­ages much closer to zero, by un­der­stand­ing more about the cur­rent threats as well as those that might ap­pear in the fu­ture.

Internal test­ing can’t repli­cate the full com­plex­ity of how peo­ple browse in the real world: the spe­cific re­quests they make, the web­sites they visit, and how ma­li­cious con­tent ap­pears in prac­tice. New forms of prompt in­jec­tion at­tacks are also con­stantly be­ing de­vel­oped by ma­li­cious ac­tors. This re­search pre­view al­lows us to part­ner with trusted users in au­then­tic con­di­tions, re­veal­ing which of our cur­rent pro­tec­tions work, and which need work.

We’ll use in­sights from the pi­lot to re­fine our prompt in­jec­tion clas­si­fiers and our un­der­ly­ing mod­els. By un­cov­er­ing real-world ex­am­ples of un­safe be­hav­ior and new at­tack pat­terns that aren’t pre­sent in con­trolled tests, we’ll teach our mod­els to rec­og­nize the at­tacks and ac­count for the re­lated be­hav­iors, and en­sure that safety clas­si­fiers will pick up any­thing that the model it­self misses. We’ll also de­velop more so­phis­ti­cated per­mis­sion con­trols based on what we learn about how users want to work with Claude in their browsers.

For the pi­lot, we’re look­ing for trusted testers who are com­fort­able with Claude tak­ing ac­tions in Chrome on their be­half, and who don’t have se­tups that are safety-crit­i­cal or oth­er­wise sen­si­tive.

If you’d like to take part, you can join the Claude for Chrome re­search pre­view wait­list at claude.ai/​chrome. Once you have ac­cess, you can in­stall the ex­ten­sion from the Chrome Web Store and au­then­ti­cate with your Claude cre­den­tials.

We rec­om­mend start­ing with trusted sites—al­ways be mind­ful of the data that’s vis­i­ble to Claude—and avoid­ing use of Claude for Chrome for sites that in­volve fi­nan­cial, le­gal, med­ical, or other types of sen­si­tive in­for­ma­tion. You can find a de­tailed safety guide in our Help Center.

We hope that you’ll share your feed­back to help us con­tinue to im­prove both the ca­pa­bil­i­ties and safe­guards for Claude for Chrome—and help us take an im­por­tant step to­wards a fun­da­men­tally new way to in­te­grate AI into our lives.

...

Read the original on www.anthropic.com »

9 746 shares, 27 trendiness

A German ISP tampered with their DNS

In Germany, we have the Clearingstelle Urheberrecht im Internet (CUII) - lit­er­ally Copyright Clearinghouse for the Internet’, a pri­vate or­ga­ni­za­tion that de­cides what web­sites to block, cor­po­rate in­ter­ests rewrit­ing our free in­ter­net. No judges, no trans­parency, just a bunch of ISPs and ma­jor copy­right hold­ers de­cid­ing what your eyes can see.

I de­cided to cre­ate a web­site, cui­iliste.de, to find blocked do­mains, as the CUII re­fuses to pub­lish such a list. To read more about the CUII, check out one of my pre­vi­ous blog posts. Germany’s four biggest ISPs (Telekom, Vodafone, 1&1 and Telefonica (o2)) are all part of the CUII.

This week, Netzpolitik.org pub­lished an ar­ti­cle about the CUIIs lat­est blun­der, based on in­for­ma­tion I gath­ered. They man­aged to block do­mains that no longer even ex­isted: web­sites that had al­ready been seized and taken of­fline when they were blocked. It’s not the first time the CUII has tripped over its own feet, and this mis­take likely did­n’t sit well with them. In the past, it was re­ally easy to find out if a do­main was blocked by the CUII. If you asked an ISPs DNS server (basically the in­ter­net’s phone book) for a site and got a CNAME to no­tice.cuii.info, you knew it was blocked.

What this ba­si­cally means in case you’re not a tech nerd:

You can check the phone book of an ISP (the DNS server”) where to find a web­site, and you’d re­ceive a note say­ing This site is blocked by the CUII if the page is blocked. Automating this was sim­ple, I could ba­si­cally just ask Hey, where can I find this site?” and im­me­di­ately knew if it was blocked. The CUII ap­par­ently did not like the fact that it was so easy for me to check if a do­main was blocked. They want to keep their list se­cret.

ISPs like Telekom, 1&1 and Vodafone ac­tu­ally all stopped us­ing this re­sponse a few months ago, af­ter older ar­ti­cles about the CUIIs past fail­ures were pub­lished. Instead, they started pre­tend­ing that blocked sites did­n’t ex­ist at all. Straight up eras­ing en­tries from the phone book. You could not tell if a site was blocked or just did­n’t ex­ist. Telefonica (the par­ent com­pany of for ex­am­ple o2, Germany’s fourth-biggest ISP), ap­par­ently did­n’t get this memo, and they still used no­tice.cuii.info in their DNS re­sponses.

On cui­iliste.de, any­one can en­ter a do­main, and see if it is blocked by the CUII, and which ISPs block it specif­i­cally.

Telefonica mod­i­fied their DNS servers, specif­i­cally say­ing that blau-sicher­heit.info was blocked by the CUII. At 11:06 AM last Friday, some­one from Telefonica’s net­work checked if blau-sicher­heit.info was blocked on my site. The twist? Telefonica seems to own this do­main. Blau is one of their brands, and blau-sicher­heit.info was­n’t some piracy hub - it ap­pears to be a test do­main of theirs. My tool flagged it as blocked be­cause Telefonica’s DNS servers said so. Why would they block their own do­main?

* Someone from Telefonica vis­its my web­site to check if I de­tect this

* I do in fact de­tect this

Two hours af­ter this sus­pi­cious query, I was bom­barded with Notifications. My pro­gram thought that the CUII had sud­denly un­blocked hun­dreds of do­mains.

The rea­son: Telefonica had al­tered their DNS servers to stop redi­rect­ing blocked do­mains to no­tice.cuii.info. Now they pre­tend that the do­main does­n’t ex­ist at all, af­ter they specif­i­cally blocked their own do­main, likely to find out how my web­site works.

I had to spend my en­tire Friday af­ter­noon fix­ing this mess, and now every­thing is fully op­er­a­tional again.

The fix worked, but there’s a catch: with­out the no­tice.cuii.info redi­rect, it’s harder to con­firm if a block is ac­tu­ally the CUIIs do­ing. Sometimes ISPs block sites for other rea­sons, like ter­ror­ism con­tent (I wrote about that too). I try to com­pen­sate this by cross-check­ing do­mains against a list of known non-CUII-blocks.

The tim­ing is more than sus­pi­cious. Right af­ter Netzpolitik’s ar­ti­cle ex­posed the CUII for block­ing non-ex­is­tent do­mains, they make it harder to track their mis­takes. Coincidence? Or a move to bury fu­ture slip-ups? We can only spec­u­late. Regardless of in­tent, the re­sult is the same: less trans­parency and harder over­sight. And that ben­e­fits the CUII, not the pub­lic.

In this con­text, Netzpolitik.org re­leased an­other ar­ti­cle (German):

Netzpolitik.org: Provider ver­stecken, welche Domains sie sper­ren

...

Read the original on lina.sh »

10 645 shares, 25 trendiness

SQLite editor for macOS

Create and mod­ify ta­bles with ease us­ing Base’s vi­sual table ed­i­tor. No need to write com­plex CREATE or ALTER state­ments.

Add and or­ga­nize columns and de­fine con­straints through a clean in­ter­face. The table ed­i­tor makes data­base de­sign ac­ces­si­ble to every­one.

...

Read the original on menial.co.uk »

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.

If you like 10HN please leave feedback and share

Visit pancik.com for more.