10 interesting stories served every morning and every evening.

Ghosted After a Job Interview? Report the Company

didtheyghostyou.com

The new rules of context engineering for Claude 5 generation models

claude.com

Then and now

There were a num­ber of pre­vi­ous con­text en­gi­neer­ing best prac­tices that had be­come myths. Including:.

Then: Give Claude rules

Now: Let Claude use judge­ment

When we first rolled out Claude Code, we needed to be sure that Claude avoided worst case sce­nar­ios, such as delet­ing files. This meant we would give par­tic­u­larly strong guid­ance that might not al­ways be true, For ex­am­ple, in the sys­tem prompt we used to say:

In code: de­fault to writ­ing no com­ments. Never write multi-para­graph doc­strings or multi-line com­ment blocks — one short line max. Don’t cre­ate plan­ning, de­ci­sion, or analy­sis doc­u­ments un­less the user asks for them — work from con­ver­sa­tion con­text, not in­ter­me­di­ate files.

But for a cer­tain sub­set of prompts, this guid­ance would be wrong. In the case of doc­u­men­ta­tion, the user may have their own pref­er­ences, or spe­cific parts of very com­plex code might need multi-line com­ment blocks.

Still, with­out these guardrails for older mod­els, the com­ments Claude wrote would be in­cor­rect in many cases and we had to ac­cept this trade­off. But newer mod­els have bet­ter judge­ment and can han­dle these de­ci­sions well with­out ex­plicit rules.

In the new sys­tem prompt we say: Write code that reads like the sur­round­ing code: match its com­ment den­sity, nam­ing, and id­iom.

Then: Give Claude ex­am­ples

Now: Design in­ter­faces

The num­ber one rule for tool us­age was to give Claude ex­am­ples on how to use them. With our newest mod­els, we’ve found that giv­ing ex­am­ples ac­tu­ally con­strains them to a cer­tain ex­plo­ration space.

Instead of us­ing ex­am­ples, think more about the de­sign of your tools, scripts and files- what pa­ra­me­ters does Claude have and how can they be more ex­pres­sive?

For ex­am­ple, in the Todo tool ex­am­ple, just list­ing sta­tus as an enu­mer­a­tion be­tween pend­ing, in­_progress, and com­pleted, hints to Claude about how to use it. The in­struc­tion on keep­ing one item in­_progress helps de­fine our re­quested be­hav­ior.

Then: Put it all up­front

Now: Use pro­gres­sive dis­clo­sure

Because Claude Code was fo­cused on cod­ing, our sys­tem prompt in­cluded de­tailed in­for­ma­tion on how to do code re­view and ver­i­fi­ca­tion. These were not al­ways needed, but when they were, it was cru­cial in­for­ma­tion.

Since then, Claude Code has got­ten very com­pe­tent at us­ing pro­gres­sive dis­clo­sure- load­ing the right con­text at the right times. For ex­am­ple, we moved ver­i­fi­ca­tion and code re­view into their own skills that Claude Code could se­lec­tively call.

But pro­gres­sive dis­clo­sure is not just for skills, we also use it for tools. Some of our tools are deferred load­ing,’ which means the agent must search for their full de­f­i­n­i­tions us­ing ToolSearch be­fore us­ing them. This al­lows us to have more tools (such as our Task tools) that don’t take up con­text un­til they’re needed.

The same can be ap­plied to your own CLAUDE.md and Skill.md files. A com­mon myth is that you want to make these a cen­tral repos­i­tory for every known prac­tice that you might run into, be­cause Claude would not find it oth­er­wise. Instead, con­sider hav­ing a tree of files that can be loaded at the right time.

Then: Repeat your­self

Now: Simple tool de­scrip­tions

Earlier Claude mod­els could some­times need re­peated in­struc­tions or be more likely to lis­ten to in­struc­tions at the end of their con­text win­dow than at the start. This meant our sys­tem prompt would some­times have ref­er­ences to tools in the main sys­tem prompt as well as in­struc­tions in the tool de­scrip­tion.

We found we could delete these re­peat ex­am­ples and put in­struc­tions on how to use tools in the tool de­scrip­tions rather than the sys­tem prompt.

Then: Memory in CLAUDE.md files

Now: Auto-memory

We used to en­cour­age users to save things to Claude’s mem­ory, by us­ing the # hotkey to write to their CLAUDE.md au­to­mat­i­cally. Instead, Claude now au­to­mat­i­cally saves mem­o­ries that are rel­e­vant to the work and to you.

Then: Simple specs

Now: Rich ref­er­ences

In plan mode, Claude Code has heav­ily re­lied on mark­down files with plans. Storing these files as plans helped Claude re­fer to them when needed. Another sim­i­lar best prac­tice was to store specs in the code­base for Claude to re­fer to while work­ing across longer pro­jects.

But we’ve found that Claude can han­dle in­creas­ingly more com­pli­cated ref­er­ences. Instead of sim­ple mark­down files, Claude can ref­er­ence HTML ar­ti­facts cre­ated by our new ar­ti­facts fea­ture.

You may also give Claude ref­er­ences in the form of code. A spec may also be a de­tailed test suite, or a func­tion in a dif­fer­ent code­base that Claude might port.

Rubrics are an­other form of ref­er­ences. Rubrics al­low Claude to try and ver­ify your taste in a par­tic­u­lar field (e.g. what does a good API de­sign look like) by us­ing dy­namic work­flows and spin­ning up ver­i­fier agents with those rubrics.

Applying this to your con­text

Pulling this all to­gether, what does this look like when you as­sem­ble your con­text?

System Prompt

A sys­tem prompt is heav­ily tied to the prod­uct con­text. It tells Claude what prod­uct it’s op­er­at­ing in and what it’s do­ing. For Claude Code, you will likely never mod­ify this, but if you are build­ing your own agent har­ness, this is where you should spend a lot of time.

CLAUDE.md

Keep your CLAUDE.md light­weight and briefly de­scribe what your repo is for, but spend most of the to­kens on gotchas in­side of the code­base. For ex­am­ple, you may or­ga­nize your code to keep types in one mono­lithic file and nowhere else. Avoid stat­ing the ob­vi­ous’ things Claude should know by look­ing at your file sys­tem or your repo.

Use pro­gres­sive dis­clo­sure heav­ily, for ex­am­ple if you have sev­eral unique in­struc­tions on how to ver­ify your work, cre­ate a ver­i­fi­ca­tion skill and ref­er­ence it from your CLAUDE.md.

Skills

Think of skills as light­weight guides to let Claude find in­for­ma­tion when needed. Avoid mak­ing them over­con­strained, ex­cept in highly im­por­tant ar­eas.

For long skills, try and use pro­gres­sive dis­clo­sure as much as pos­si­ble- di­vide it into many files and split them out.

It’s best when skills en­code par­tic­u­lar opin­ions, knowl­edge, or best prac­tices that are par­tic­u­lar to you, your team, or prod­uct.

References

You can @ men­tion files to in­clude them as ref­er­ences. References al­low Claude to re­fer to in-depth in­for­ma­tion about the cur­rent plan.

This might be in specs files, mock­ups, or even en­tire code­bases. Generally you should pre­fer files that are in code as it pro­vides clear, high-fi­delity in­struc­tions to Claude in a lan­guage it knows very well. For ex­am­ple, a HTML mockup of a de­sign will gen­er­ally pro­duce bet­ter re­sults than a de­scrip­tion of the de­sign or a screen­shot.

Try sim­pli­fy­ing

Across your sys­tem prompt, skills, and CLAUDE.md files, you may need to sim­plify just like we did. We rolled out a new com­mand called `claude doc­tor,` which will help you do this au­to­mat­i­cally as well. For more de­tails on prompt­ing more ad­vanced mod­els specif­i­cally, check out our Fable field guide.

This ar­ti­cle was writ­ten by Thariq Shihipar, mem­ber of tech­ni­cal staff, Anthropic.

A shell colon does nothing. Use it anyway.

refp.se

I’ve writ­ten more shell scripts than I can count, but I still stum­ble upon tricks that hon­estly blow my mind far too of­ten than I care to ad­mit. Latest thing that blew my head clean off? The shell colon.

#shell

#posix

#unix

In a land far-far away..

… there was once a far too cold cup of cof­fee next to a freshly brewed far-too-hot one. Four dif­fer­ent ter­mi­nals where three could have been closed an hour ago, and a shell script which I re­ally (really) did not want to write.

Who would have thought a sin­gle colon would be the one to save the day night?

Note: Want your mind blown straight away? See more colons in the lime­light.

Note: Want your mind blown straight away? See more colons in the lime­light.

Checking for re­quired ar­gu­ments

This is a fa­mil­iar dance, it’s pretty much mus­cle mem­ory by this point. You have a script, it takes a few ar­gu­ments, and some of them are manda­tory; al­right, an if-state­ment like so many times be­fore:

if [ -z $1” ]; then echo missing ar­gu­ment, abort­ing.” 1>&2 exit 1 fi

echo Hello $1!”

Though.. what if I told you the above four lines could be re­placed by just… one?

: ${1:?missing ar­gu­ment, abort­ing.}” echo Hello $1!”

$ bash ex­am­ple.sh ex­am­ple.sh: line 1: 1: miss­ing ar­gu­ment, abort­ing.

$ bash ex­am­ple.sh refp Hello refp!

And look what hap­pens if we re­fer to a vari­able with a proper name — it’s the same be­hav­ior as pre­vi­ously but eas­ier to spot; the di­ag­nos­tic in­cludes the name of our vari­able!

: ${GREET_NAME:?missing ar­gu­ment, abort­ing.}” echo Hello $GREET_NAME!”

$ bash greet.sh greet.sh: line 1: GREET_NAME: miss­ing ar­gu­ment, abort­ing.

Parameter ex­pan­sion and the story of :?

There are two things go­ing on in the pre­vi­ous snip­pet, and you are cor­rect in iden­ti­fy­ing that one part is us­ing pa­ra­me­ter ex­pan­sion:

The syn­tax ${name:?diagnostic} checks whether $name is un­set or empty — if it is, the di­ag­nos­tic is printed to stderr and the shell ex­its with a non-zero sta­tus, oth­er­wise;

The syn­tax ${name:?diagnostic} checks whether $name is un­set or empty — if it is, the di­ag­nos­tic is printed to stderr and the shell ex­its with a non-zero sta­tus, oth­er­wise;

if the vari­able is set, it is equiv­a­lent to $name.

if the vari­able is set, it is equiv­a­lent to $name.

That.. other colon

So that’s one colon, but what about that other one, the one who sits alone at the be­gin­ning of the line?

: is the null-com­mand — a builtin that does noth­ing but eval­u­ate its ar­gu­ments and dis­card the re­sult.

: is the null-com­mand — a builtin that does noth­ing but eval­u­ate its ar­gu­ments and dis­card the re­sult.

: is old — it goes all the way back to the 1971 Thompson shell where it dou­bled as a la­bel and Unix’s very first com­ment marker.

: is old — it goes all the way back to the 1971 Thompson shell where it dou­bled as a la­bel and Unix’s very first com­ment marker.

: two eyes star­ing at you in the dark, with love.

: two eyes star­ing at you in the dark, with love.

More colons in the lime­light

Perhaps we have al­ready es­tab­lished that there is more to : than meets the eye, but to prove the real magic of the null-com­mand — here are a few us­ages that blew my mind.

: ${DATA_DIR:=/var/data}” # set de­faults, : swal­lows the re­sult : ${RETRIES:=3}” # in­stead of run­ning it as a com­mand

: > er­ror.log # trun­cate er­ror.log : > er­ror.log > ac­cess.log # trun­cate both er­ror.log and ac­cess.log

( : < dataset.json ) && echo YES # is dataset.json read­able? ( : >> re­sult.json ) && echo YES # is re­sult.json writable?

trap : INT # trap re­quires a com­mand sleep 60 # sleep is in­ter­rupt­ible

set -u # er­ror on un­set vari­ables : $DEPLOY_ENV” $HOST # check DEPLOY_ENV and HOST

if some-com­mand; then : # com­mand re­quired else echo command failed” fi

Con-colon-sion

So, if you are like me and pre­fer less typ­ing (gotta go fast) — the null-com­mand and pa­ra­me­ter ex­pan­sion are a pair worth study­ing be­fore your cof­fee goes cold.

And also.. is­n’t this — magic?

set  : : : : : : : : : : : : : : : : : : : : :

while : colons are more than ${1:?magic}”; do echo $*” && shift done

Note: The above ex­am­ple is safe to run lo­cally, try it!

Note: The above ex­am­ple is safe to run lo­cally, try it!

Frequently Asked Questions

After read­ing a few com­ments on­line, it seems I skipped over some things worth ex­plain­ing. I will keep this sec­tion up­dated as ques­tions come up.

Why do I need the null-com­mand? Doesn’t the ex­pan­sion hap­pen with­out the colon? The pa­ra­me­ter ex­pan­sion will hap­pen re­gard­less, but with­out a null-com­mand or sim­i­lar us­age the shell will treat the re­sult­ing string as a com­mand to run. % ${HELLO:=123} zsh: com­mand not found: 123

If we pre­fix our pa­ra­me­ter-ex­pan­sion with the null-com­mand, the re­sult is dis­carded, but the ex­pres­sion is still eval­u­ated (setting HELLO to 123). % : ${HELLO:=123} % echo $HELLO 123

Why do I need the null-com­mand? Doesn’t the ex­pan­sion hap­pen with­out the colon?

The pa­ra­me­ter ex­pan­sion will hap­pen re­gard­less, but with­out a null-com­mand or sim­i­lar us­age the shell will treat the re­sult­ing string as a com­mand to run.

% ${HELLO:=123} zsh: com­mand not found: 123

If we pre­fix our pa­ra­me­ter-ex­pan­sion with the null-com­mand, the re­sult is dis­carded, but the ex­pres­sion is still eval­u­ated (setting HELLO to 123).

% : ${HELLO:=123} % echo $HELLO 123

Why use the null-com­mand when I could do VAR=${VAR:-default-value}? This at its core boils down to per­sonal pref­er­ence, but us­ing our beloved colon we can shrink the num­ber of po­ten­tial ty­pos to one (rather than two): : ${DATA_DIR:=/var/data}” # <- DATA_DIR men­tioned once (1) DATA_DIR=“${DATA_DRI:-/var/data}” # <- oops (2)

Why use the null-com­mand when I could do VAR=${VAR:-default-value}?

This at its core boils down to per­sonal pref­er­ence, but us­ing our beloved colon we can shrink the num­ber of po­ten­tial ty­pos to one (rather than two):

: ${DATA_DIR:=/var/data}” # <- DATA_DIR men­tioned once (1) DATA_DIR=“${DATA_DRI:-/var/data}” # <- oops (2)

Why would I do any of these when it hurts read­abil­ity? There are a few com­mon mis­con­cep­tions about the — very con­trived — ex­am­ples pre­sented in this ar­ti­cle, ques­tions re­gard­ing their use­ful­ness, or if one should ever-ever use these things at all. Let’s take the be­low as an ex­am­ple. if some-com­mand; then : # com­mand re­quired else echo command failed” fi

Of course you can use if ! some-com­mand and get rid of the branch­ing, but that is­n’t the point of the snip­pet — the point is to show that the null-com­mand can be used in places where a com­mand is re­quired, but noth­ing is de­sired. It was never meant to be read as oh, if I have an if-state­ment I should use null-com­mand”, it is in­tended to be read as oh, if I am in a con­text which re­quires a com­mand, I can use the null-com­mand to no-op it”.

Clever real-world us­age of : in the wild User if­philipe posted what fol­lows as a com­ment on news.ycombi­na­tor.com, which is the di­rect equiv­a­lent of need­ing a com­mand which does ab­solutely noth­ing.

I use the colon as EDITOR with Git when I want to do an in­ter­ac­tive re­base com­bined with auto squash with­out hav­ing to edit the todo list. I have an alias[1] for that which I call a quick in­ter­ac­tive re­base: riq = -c se­quence.ed­i­tor=: re­base –interactive

Could this ar­ti­cle have used the above rather than the so much de­bated if-state­ment? If I was clever enough to come up with it — yes.. but would it be as com­pre­hen­si­ble in terms of un­der­stand­ing what : re­ally is? I strongly sus­pect not.

Why would I do any of these when it hurts read­abil­ity?

There are a few com­mon mis­con­cep­tions about the — very con­trived — ex­am­ples pre­sented in this ar­ti­cle, ques­tions re­gard­ing their use­ful­ness, or if one should ever-ever use these things at all.

Let’s take the be­low as an ex­am­ple.

if some-com­mand; then : # com­mand re­quired else echo command failed” fi

Of course you can use if ! some-com­mand and get rid of the branch­ing, but that is­n’t the point of the snip­pet — the point is to show that the null-com­mand can be used in places where a com­mand is re­quired, but noth­ing is de­sired.

It was never meant to be read as oh, if I have an if-state­ment I should use null-com­mand”, it is in­tended to be read as oh, if I am in a con­text which re­quires a com­mand, I can use the null-com­mand to no-op it”.

Clever real-world us­age of : in the wild

User if­philipe posted what fol­lows as a com­ment on news.ycombi­na­tor.com, which is the di­rect equiv­a­lent of need­ing a com­mand which does ab­solutely noth­ing.

I use the colon as EDITOR with Git when I want to do an in­ter­ac­tive re­base com­bined with auto squash with­out hav­ing to edit the todo list. I have an alias[1] for that which I call a quick in­ter­ac­tive re­base: riq = -c se­quence.ed­i­tor=: re­base –interactive

I use the colon as EDITOR with Git when I want to do an in­ter­ac­tive re­base com­bined with auto squash with­out hav­ing to edit the todo list. I have an alias[1] for that which I call a quick in­ter­ac­tive re­base:

riq = -c se­quence.ed­i­tor=: re­base –interactive

Could this ar­ti­cle have used the above rather than the so much de­bated if-state­ment? If I was clever enough to come up with it — yes.. but would it be as com­pre­hen­si­ble in terms of un­der­stand­ing what : re­ally is? I strongly sus­pect not.

GrapheneOS protections against data extraction from locked devices

discuss.grapheneos.org

GrapheneOS Discussion Forum

Inside the growing vigilante movement to knock out Flock surveillance cameras

www.theguardian.com

The first time that NoMark” tried to knock out a Flock cam­era feed, he waited an hour for the per­fect mo­ment — pac­ing in and out of bushes that tow­ered over him, a few feet be­hind a pole hold­ing up the de­vice.

I was just so ner­vous,” he said.

NoMark, as he’s known on Instagram, had al­ready gained an on­line fol­low­ing of hun­dreds of thou­sands for post­ing videos of him­self wear­ing a black mask and tak­ing on small-time vig­i­lante mis­sions: break­ing up fights out­side a bar and break­ing into a re­fin­ery he be­lieved was polluting the city real bad”. The Minnesota Star Tribune dubbed him Minneapolis’ Batman”. He spoke to the Guardian un­der con­di­tion of anonymity to dis­cuss po­ten­tially il­le­gal acts.

On this June night, he set his sights on a new tar­get: au­to­mated li­cense plate read­ers (ALPRs) made by the US com­pany Flock Safety.

Allow Instagram con­tent?

This ar­ti­cle in­cludes con­tent pro­vided by Instagram. We ask for your per­mis­sion be­fore any­thing is loaded, as they may be us­ing cook­ies and other tech­nolo­gies. To view this con­tent, click Allow and con­tin­ue’.

These black cam­eras, which are hooked up to a rec­tan­gu­lar so­lar panel and typ­i­cally mounted on a pole, snap pho­tos of pass­ing ve­hi­cles and run the pic­tures against large data­bases. They have sparked na­tion­wide back­lash from pro-pri­vacy crit­ics, who point to pub­lic records sug­gest­ing that these de­vices can help law en­force­ment keep tabs on spe­cific li­cense plates and the peo­ple dri­ving these cars. That they can sweep in so many peo­ple’s lo­ca­tion from an in­no­cent act in a pub­lic space — re­gard­less of whether the tar­get is a sus­pect in a crime, and with­out a war­rant — has led to fears of mass sur­veil­lance.

Flock, based in Georgia and val­ued at $8.4bn, says its cam­eras scan li­cense plates bil­lions of times each month in about 6,000 com­mu­ni­ties in nearly every state in the US.

The com­pany said in a February blog­post that its ALPRs are not mass sur­veil­lance tools” and that it cannot track ve­hi­cles, much less in­di­vid­ual peo­ple”.

Across the street from a Taco Bell, NoMark could­n’t stop think­ing about whether he would get caught, and the adren­a­line felt par­a­lyz­ing — even though this felt on brand” for his on­line per­sona, which has won him more than 700,000 fol­low­ers on Instagram and TikTok. After a few min­utes of not spot­ting any cars on the road, he climbed a few feet up the pole, taped up the cam­era to block its lens and snipped the wires that pow­ered the whole op­er­a­tion. Then he ended his phone’s record­ing and fled.

Nowadays, NoMark is much calmer on these ex­cur­sions, and it only takes him a few min­utes to get the job done af­ter hav­ing taken down more than a dozen cam­eras, he says. But he still as­sumes the po­lice are look­ing for him. Even if he does get ar­rested, he’s hope­ful the charges won’t be too se­vere — and more im­por­tant, he just wants to send a mes­sage”.

I’m not afraid to do things if I think they’re right,” he says. These things are com­ing up so fast across the coun­try that this is kind of the only way to com­bat them.”

The Minneapolis cam­era de­stroyer is not alone. As anger grows to­wards law en­force­ment con­tracts with Flock, vig­i­lantes across the coun­try are tak­ing mat­ters into their own hands by smash­ing, ob­struct­ing or tak­ing down these cam­eras. Many are lean­ing into their cre­ative side: paint bomb­ing” the de­vices, plant­ing American flags at the scene af­ter dam­ag­ing them, 3D print­ing ob­jects to help ob­struct the cam­er­a’s view and leav­ing col­or­ful mes­sages like hahaha get wrecked ya sur­veilling fucks”. Some in­flu­encers are even cre­at­ing fake cease-and-de­sist let­ters from Flock, cap­i­tal­iz­ing on the com­pa­ny’s neg­a­tive pub­lic per­cep­tion.

The Guardian has iden­ti­fied at least 33 in­stances of peo­ple dam­ag­ing, van­dal­iz­ing and de­stroy­ing Flock cam­eras, across 23 states, that ap­pear to have the ex­plicit mes­sage of protest­ing sur­veil­lance.

Allow Instagram con­tent?

This ar­ti­cle in­cludes con­tent pro­vided by Instagram. We ask for your per­mis­sion be­fore any­thing is loaded, as they may be us­ing cook­ies and other tech­nolo­gies. To view this con­tent, click Allow and con­tin­ue’.

Flock, along with po­lice de­part­ments across the US, say these cam­eras are in­te­gral for pub­lic safety, and cap­ture ve­hi­cle de­tails that can help in in­ves­ti­ga­tions, such as li­cense plate num­bers and the make and model of ve­hi­cles. Flock’s web­site also ad­ver­tises how these cam­eras can stop crime in real time” by alert­ing of­fi­cers the mo­ment a sus­pect car passes by” — sug­gest­ing that cops can act quickly on these leads to pur­sue a tar­get. The com­pa­ny’s CEO, Garrett Langley, has de­scribed some pro-pri­vacy crit­ics as want­ing to normalize law­less­ness” and weaken pub­lic safety”.

NoMark has not been caught in his cam­paign against Flock cam­eras. Others are fac­ing charges. Jeffrey Sovern in Suffolk, Virginia, has been charged with de­struc­tion of prop­erty for al­legedly dam­ag­ing more than a dozen Flock cam­eras. Sovern has not ad­mit­ted to the act but did tell po­lice that he finds these cam­eras to be un­con­sti­tu­tional.

He wrote on a GoFundMe cre­ated to pay for le­gal ex­penses: I will take the sil­ver lin­ing that this can be a cat­a­lyst in a big­ger move­ment to roll back in­tru­sive sur­veil­lance.”

A hand­ful of other cases have drawn crim­i­nal charges, too. In New Mexico, Jevon Martinez was ar­rested af­ter al­legedly de­stroy­ing 13 Flock cam­eras.

When asked if he would continue to take down these Flock cam­eras”, Martinez told lo­cal news sta­tion KRQE: Absolutely. They are a clear and pre­sent threat to pub­lic safety.” The news out­let also re­ported that a sign near one of the dam­aged Flock cam­eras read: You’re wel­come, the Republic of New Mexico.”

Flock did not com­ment on vig­i­lantes knock­ing out its cam­eras but did pub­lish a blog­post in mid-July about help­ing gov­ern­ment agen­cies re­spond if a cam­era is dam­aged.

We’ve planned for it,” the com­pany wrote, adding that pro­tec­tion plans are avail­able for pur­chase.

Law en­force­ment is aware of the back­lash and re­spond­ing. Dozens of state fu­sion cen­ters — col­lab­o­ra­tive hubs where fed­eral and lo­cal agen­cies share in­tel­li­gence about crime and ter­ror­ism — cir­cu­lated memos across law en­force­ment agen­cies this sum­mer di­rect­ing of­fi­cers to mon­i­tor anti-Flock ad­vo­cacy as part of a di­rec­tive to pro­tect na­tional se­cu­rity, ac­cord­ing to re­port­ing from jour­nal­ist Dan Boguslaw. One re­port Boguslaw ob­tained from a Wisconsin in­tel­li­gence agency calls for in­creased vig­i­lance and pa­trols dur­ing protests and events such as a national week of ac­tion” in mid-Au­gust. That in­tel­li­gence di­gest also ad­vised lo­cal law en­force­ment to re­port vandalism, dis­rup­tion or sab­o­tage” of ALPRs to fu­sion cen­ters.

Flock faces pub­lic blow­back

The winds of sym­pa­thy on­line are not blow­ing in Flock’s fa­vor. News ar­ti­cles and videos about vig­i­lantes’ cases have drawn sup­port from on­line com­menters, who post made-up, neigh­borly al­i­bis like see­ing ac­cused par­ties res­cu­ing dogs or serv­ing meals at a soup kitchen at the time a cam­era was de­stroyed.

The anti-Flock on­line ecosys­tem also fea­tures an ex­change of tips and strate­gies for kneecap­ping the cam­eras. One Reddit poster shared a 3D print file for an ob­ject he says can help block cam­eras with­out dam­ag­ing them or vi­o­lat­ing van­dal­ism laws.

NoMark, in Minneapolis, says he re­ceives dozens of mes­sages daily from peo­ple want­ing to help, let­ting him know they’re tak­ing sim­i­lar ac­tions or ask­ing for ad­vice on stay­ing safe. He keeps his replies vague, as he does­n’t want his words to get peo­ple ar­rested. He tells those writ­ing to him to avoid dri­ving past the cam­eras, and to make sure they’re go­ing out late at night when they no one else is around. He re­it­er­ates that they should cover up com­pletely, in­clud­ing their face and hands.

He also tells them: Always cover the cam­era.”

Minneapolis’s Batman thinks you need both po­lit­i­cal pres­sure on elected of­fi­cials and vig­i­lan­tism to achieve change. He be­lieves show­ing up to city coun­cil meet­ings — and he’s shown up to a few with­out his mask — is help­ful but it does ob­vi­ously take time, and it’s not al­ways ef­fec­tive”.

The more time you take, the more data they get on peo­ple,” he said.

Privacy ad­vo­cates pur­sue pol­icy changes as vig­i­lantes tear down cam­eras

More than 80 cities have dis­banded, de­cided not to re­new or re­jected con­tracts with Flock in re­cent years, or de­ac­ti­vated the com­pa­ny’s cam­eras, in­clud­ing Austin and Denver, al­though ac­tivists re­main con­cerned about the de­vices’ con­tin­ued use in those ar­eas.

Beyond gen­eral sur­veil­lance creep, pri­vacy ad­vo­cates fear US Immigration and Customs Enforcement’s abil­ity to ac­cess these cam­era feeds through le­gal loop­holes to pur­sue im­mi­grants.

Police of­fi­cers have used the cam­eras for their own per­sonal ends as well. Several have lost their jobs af­ter mis­us­ing the de­vices to stalk peo­ple. Though li­cense plate read­ing is the cam­eras’ bread and but­ter, 404 Media re­ported last week that cops have used Flock’s search fea­ture to look for peo­ple with dis­tinct mark­ers — like tat­toos and spe­cific T-shirts — and not just cars.

Congress is tak­ing note, and ear­lier this month a Texas law­maker in­tro­duced a bill re­quir­ing war­rants for data col­lected by Flock cam­eras.

Not all anti-Flock ac­tivism takes the form of cam­era de­struc­tion. A crowd­sourced map cre­ated by the grass­roots group DeFlock maps out more than 115,000 ALPRs across the coun­try. The or­ga­ni­za­tion’s site also al­lows users to see if their li­cense plates have been searched in Flock’s sys­tem, get di­rec­tions to avoid ALPRs and find up­com­ing meet­ings about mu­nic­i­pal Flock con­tracts.

Flock’s CEO has taken note of DeFlock’s ad­vo­cacy, too, and char­ac­ter­ized the or­ga­ni­za­tion as terroristic” but re­cently apol­o­gized for that la­bel. In a tweet, he at­trib­uted DeFlock’s pop­u­lar­ity to his com­pa­ny’s inadequate re­sponse to the ques­tions and con­cerns that peo­ple have about ALPR. The com­pany is adapt­ing to the back­lash, can­cel­ing an al­ways-on record­ing fea­ture, human dis­tress de­tec­tion”, which was in­tended to de­tect scream­ing.

A lo­cal chap­ter of DeFlock, in Norfolk, Virginia, says it does not en­dorse vig­i­lantes tar­get­ing Flock cam­eras but does not ad­vo­cate against it, ei­ther.

The Virginia chap­ter is work­ing to en­sure the city ei­ther can­cels or does not re­new its con­tract with Flock, but so far it has­n’t had suc­cess, and mem­bers are par­tic­u­larly an­gry about speak­ing re­stric­tions on the topic. At a city coun­cil meet­ing last month, the mayor en­forced a rule about re­duc­ing repet­i­tive com­ments to limit the num­ber of speak­ers who wanted to share their con­cerns about Flock, the Virginian-Pilot re­ported.

We rec­og­nize it’s the in­evitable out­come of a sys­tem de­signed to pre­vent peo­ple’s voices from be­ing heard,” said a DeFlock spokesper­son.

GitHub - slvDev/esp32-ai

github.com

Running a 28.9M pa­ra­me­ter LLM on an $8 mi­cro­con­troller

Open to Work  · 𝕏 slvDev  · LinkedIn

This is a 28.9 mil­lion pa­ra­me­ter lan­guage model that gen­er­ates text on an ESP32-S3, a mi­cro­con­troller that costs about $8. It runs on the chip it­self, with noth­ing sent to a server, and it writes each word to a small screen wired to the chip at roughly 9 to­kens per sec­ond. The last lan­guage model peo­ple ran on a chip like this had 260 thou­sand pa­ra­me­ters, so this one holds about a hun­dred times more. It fits be­cause most of the model lives in flash in­stead of RAM, us­ing an idea from Google’s Gemma mod­els called Per-Layer Embeddings.

The num­bers

Why it is hard, and how it fits any­way

A mi­cro­con­troller has very lit­tle fast mem­ory. The ESP32-S3 gives you 512KB of SRAM. Normally the whole model has to be reach­able from there, which keeps you stuck with tiny mod­els, and that is why the pre­vi­ous model on a chip like this had only 260 thou­sand pa­ra­me­ters.

The way around it is to stop putting the model in fast mem­ory at all. Most of a lan­guage mod­el’s pa­ra­me­ters sit in an em­bed­ding table, which the model reads from rather than com­putes on. So you can leave that 25 mil­lion row table in slow flash and pull only the few rows each to­ken needs, about 450 bytes, while the small part that does the ac­tual work stays in fast mem­ory. The large model then costs al­most noth­ing to run, be­cause you never load most of it. It just sits in flash and gets sam­pled a lit­tle at a time.

That idea is Google’s Per-Layer Embeddings, from Gemma 3n and Gemma 4. Here it runs on the mem­ory lay­out of a mi­cro­con­troller in­stead of a phone or a GPU. As far as I can tell, no­body had tried it on a chip this small.

SRAM (fast, tiny) the thinking” core, used on every to­ken PSRAM (medium) the out­put head and work­ing mem­ory FLASH (huge, slow) the 25M-param table, about 6 rows read per to­ken (~450 B)

What it does, and what it does not

The model was trained on TinyStories, so it writes short, sim­ple sto­ries and mostly keeps them co­her­ent. It will not an­swer ques­tions, fol­low in­struc­tions, write code, or know facts. That limit comes from the small part of the model that does the rea­son­ing, and the mem­ory trick does not change it. What is in­ter­est­ing here is the ar­chi­tec­ture, fit­ting a large model onto a tiny chip, rather than what a 28.9 mil­lion pa­ra­me­ter model can say.

Running it your­self

The firmware, the wiring, and the flash­ing steps live in firmware/​es­p32_llm/​README.md. The train­ing, ab­la­tion, and quan­ti­za­tion code is in src/ and ex­per­i­ments/. The full method, the ab­la­tions, and the on-chip mea­sure­ments are writ­ten up in RESULTS.md.

Credit

TinyStories is the dataset this trains on: short syn­thetic sto­ries sim­ple enough that a small model can still learn to write co­her­ently (Ronen Eldan and Yuanzhi Li, Microsoft Research, arXiv:2305.07759). The other half is Per-Layer Embeddings, Google’s de­sign from the Gemma mod­els, which is what lets a big model fit on a small chip.

Andrej Karpathy’s lla­ma2.c is why a lot of peo­ple, me in­cluded, be­lieve you can train a tiny lan­guage model and run it in plain C at all. This grew out of that.

How this ac­tu­ally went

I left the messy his­tory in the repo on pur­pose. That in­cludes a bug I found in my own pa­ra­me­ter ac­count­ing, which had in­flated an early num­ber, and the cor­rected re­sult that fol­lowed once I fixed it. The com­mit his­tory and RESULTS.md show where the num­bers moved and why.

Ruff v0.16.0

astral.sh

Ruff v0.16.0 is avail­able now! Install it from PyPI, or with your pack­age man­ager of choice:

uv tool in­stall ruff@lat­est

As a re­minder: Ruff is an ex­tremely fast Python lin­ter and for­mat­ter, writ­ten in Rust. Ruff can be used to re­place Black, Flake8 (plus dozens of plu­g­ins), isort, py­doc­style, pyup­grade, and more, all while ex­e­cut­ing tens or hun­dreds of times faster than any in­di­vid­ual tool.

Migrating to v0.16 #

Ruff v0.16 has a small num­ber of break­ing changes, al­low­ing most users to up­date with­out sig­nif­i­cant changes to code or con­fig­u­ra­tion. The main ex­cep­tion is de­scribed be­low.

Better de­fault rule set #

Ruff now en­ables 413 rules by de­fault, up from 59 in pre­vi­ous ver­sions.

Since Ruff’s de­fault rule set was last mod­i­fied in v0.1.0, the num­ber of rules in Ruff has grown from 708 to 968. Many of these rules catch se­vere is­sues, in­clud­ing syn­tax er­rors and im­me­di­ate run­time er­rors but were not pre­vi­ously en­abled by de­fault. With the new rule set, Ruff will bring these is­sues and many oth­ers to your at­ten­tion with­out any Ruff con­fig­u­ra­tion. Even if you’re al­ready us­ing se­lect or ex­tend-se­lect, we hope that this will draw your at­ten­tion to help­ful rules that you pre­vi­ously had­n’t dis­cov­ered.

The full list­ing of en­abled rules is too long to in­clude here, but you can find it on our new Default Rules page in the doc­u­men­ta­tion. A few of the high­lights in­clude rules from the pop­u­lar flake8-bug­bear (B) and pyup­grade (UP) lin­ters, as well as rules from our own RUF cat­e­gory.

If you want to re­vert to the old de­fault set, you can eas­ily se­lect the old rules with this con­fig­u­ra­tion:

[lint] se­lect = [“E4, E7″, E9, F”]

We view this work as closely tied to our long­stand­ing goal of rule re­cat­e­go­riza­tion, so look for­ward to up­com­ing de­vel­op­ments in this area.

New fea­tures in v0.16 #

Ruff v0.16 also in­cludes sev­eral newly sta­bi­lized fea­tures that are high­lighted be­low.

Markdown code block for­mat­ting #

Ruff can now for­mat Python code blocks em­bed­ded in Markdown files.

In these files, Ruff v0.16 will for­mat fenced code blocks with a python, py, python3, py3, pyi, or py­con info string. pyi blocks are for­mat­ted like stub files, py­con blocks as REPL ses­sions, and the oth­ers use nor­mal Python file for­mat­ting. For ex­am­ple:

# README

Here’s an ex­am­ple:

```py im­port ruff

ruf­f_bi­nary = ( ruff.find­_ruf­f_bin() ) ```

will be re­for­mat­ted when run­ning ruff for­mat:

This can also be used to for­mat Quarto note­books be­cause Ruff still rec­og­nizes the lan­guage when sur­rounded by curly braces (e.g. ```{python}). Note that you may need to con­fig­ure your ex­ten­sion map­ping if your Quarto files use the .qmd ex­ten­sion.

If you need to sup­press for­mat­ting, you have sev­eral op­tions. If you want the sup­pres­sion com­ments to ap­pear in the code block, you can use nor­mal fmt: off and fmt: on com­ments within the code block it­self, or you can use sim­i­lar HTML com­ments to dis­able for­mat­ting for a whole re­gion of the doc­u­ment:

# README

<!– fmt: off –>

```py x = this will be sup­pressed” ```

<!– fmt: on –>

To sup­press Markdown for­mat­ting en­tirely, you can use the nor­mal ex­tend-ex­clude set­ting to ex­clude all Markdown files with a glob like *.md.

See the full doc­u­men­ta­tion for more de­tails.

ruff: ig­nore com­ments of­fer new sup­pres­sion fea­tures #

Ruff now has its own sup­pres­sion com­ment for­mat that can be used on its own line.

In v0.15, the Ruff lin­ter gained a range sup­pres­sion mech­a­nism through paired ruff: dis­able and ruff: en­able com­ments, much like the fmt: off and fmt: on pair de­scribed above:

# ruff: dis­able[N803] def foo( lega­c­yArg1, lega­c­yArg2, lega­c­yArg3, lega­c­yArg4, ): … # ruff: en­able[N803]

Ruff v0.16 builds on this to add two ad­di­tional ruff sup­pres­sion com­ments. ruff: ig­nore can be used to sup­press a di­ag­nos­tic on the same line, like noqa, or on the fol­low­ing log­i­cal line:

im­port math # ruff: ig­nore[F401]

# ruff: ig­nore[N803] def foo( lega­c­yArg1, lega­c­yArg2, lega­c­yArg3, lega­c­yArg4, ): …

In this case, the log­i­cal line spans the whole func­tion header (from def to the colon), so the ruff: ig­nore sup­presses all of the same N803 di­ag­nos­tics as the dis­able/​en­able pair above.

ruff: file-ig­nore com­ments can be used to sup­press di­ag­nos­tics for the en­tire file, just like ruff: noqa com­ments:

# ruff: file-ig­nore[F401] Allow un­used im­ports in this file

im­port foo im­port bar im­port baz

As this ex­am­ple also shows, each of these com­ment kinds can have an as­so­ci­ated reason” ex­plain­ing why they were added, in this case Allow un­used im­ports in this file.

ruff: ig­nore com­ments can be added au­to­mat­i­cally with the new –add-ignore CLI flag, and in pre­view, all of these ruff sup­pres­sion com­ments sup­port rule names in­stead of codes:

❯ echo import math’ > try.py ❯ uvx ruff@lat­est check –preview –add-ignore try.py Added 1 ig­nore com­ment. ❯ cat try.py im­port math # ruff: ig­nore[un­used-im­port]

You can find the full spec­i­fi­ca­tion for all of these com­ments in the doc­u­men­ta­tion.

Fixes are now shown in check and for­mat –check out­put #

Ruff now shows the diff for lin­ter and for­mat­ter fixes when ren­der­ing di­ag­nos­tics.

Both the check and for­mat sub­com­mands have long sup­ported the –diff flag for show­ing the changes in­tro­duced by ap­ply­ing fixes with check –fix or for­mat, but this was sep­a­rate from the nor­mal out­put and sup­pressed the ac­com­pa­ny­ing ex­plana­tory di­ag­nos­tics. In v0.16, avail­able fixes are now shown as part of the de­fault full out­put for­mat, ren­dered be­low the help sub­di­ag­nos­tic:

The same is true for for­mat –check. Given the fol­low­ing in­put:

# ex­am­ple.py

if True: pass elif False: pass

The for­mat­ter pro­duces:

for­mat –check also now sup­ports the full se­lec­tion of out­put for­mats sup­ported by the lin­ter. You can use this to ob­tain ma­chine-read­able JSON out­put or pro­duce the for­mats ex­pected by GitHub and GitLab to ren­der an­no­ta­tions in CI, as just a cou­ple of ex­am­ples. See the CLI help or doc­u­men­ta­tion for the full list of sup­ported for­mats.

One fi­nal note on out­put for­mats is that there is a small break­ing change to the JSON out­put in v0.16. The file­name, lo­ca­tion, end_lo­ca­tion, fix.ed­its[].lo­ca­tion, and fix.ed­its[].end_lo­ca­tion fields may now be null rather than de­fault­ing to the empty string and row 1, col­umn 1, re­spec­tively. This should af­fect very few of Ruff’s ex­ist­ing di­ag­nos­tics but bet­ter re­flects the in­ter­nal di­ag­nos­tic rep­re­sen­ta­tion and may be­come more com­mon in fu­ture rules.

Rule sta­bi­liza­tions #

The fol­low­ing rules have been sta­bi­lized and are no longer in pre­view:

air­flow3-in­com­pat­i­ble-func­tion-sig­na­ture (AIR303)

miss­ing-copy­right-no­tice (CPY001)

un­nec­es­sary-from-float (FURB164)

sorted-min-max (FURB192)

im­plicit-string-con­cate­na­tion-in-col­lec­tion-lit­eral (ISC004)

log-ex­cep­tion-out­side-ex­cept-han­dler (LOG004)

in­valid-bool-re­turn-type (PLE0304)

too-many-po­si­tional-ar­gu­ments (PLR0917)

stop-it­er­a­tion-re­turn (PLR1708)

none-not-at-end-of-union (RUF036)

ac­cess-an­no­ta­tions-from-class-dict (RUF063)

du­pli­cate-en­try-in-dun­der-all (RUF068)

Other be­hav­ior sta­bi­liza­tions #

This re­lease also sta­bi­lizes some ad­di­tional be­hav­ior, pre­vi­ously only avail­able in pre­view mode:

blind-ex­cept (BLE001) is now sup­pressed when the ex­cep­tion is logged via log­ging meth­ods other than crit­i­cal, er­ror and ex­cep­tion.

fu­ture-re­quired-type-an­no­ta­tion (FA102) now checks for ad­di­tional PEP 585-compatible APIs, such as those from col­lec­tions.abc.

f-string-in-get-text-func-call (INT001), for­mat-in-get-text-func-call (INT002), and printf-in-get-text-func-call (INT003) now check for ad­di­tional com­mon ways of us­ing the get­text mod­ule, such as as­sign­ing it to builtins._.

sus­pi­cious-url-open-us­age (S310) now re­solves lo­cal string lit­eral bind­ings to avoid more false pos­i­tives.

snmp-in­se­cure-ver­sion (S508) and snmp-weak-cryp­tog­ra­phy (S509) now sup­port the rec­om­mended API from newer ver­sions of PySNMP.

typ­ing-text-str-alias (UP019) now rec­og­nizes typ­ing_ex­ten­sions.Text in ad­di­tion to typ­ing.Text.

Thank you! #

Thank you to every­one who pro­vided feed­back re­gard­ing the changes in­cluded in Ruff’s pre­view mode and to our con­trib­u­tors. It’s an honor build­ing Ruff with you!

View the full changelog on GitHub.

Read more about Astral — the com­pany be­hind Ruff.

Thanks to Zanie Blue, David Peter, Micha Reiser, and Alex Waygood who con­tributed to this blog post.

JetZero

www.jetzero.aero

Made up of lead­ers from aero­space, tech­nol­ogy, and mo­bil­ity from around the world. Half of the team is lo­cated at our Long Beach CA cam­pus, with other team­mates work­ing re­motely near our sup­pli­ers, fu­ture cus­tomers, and part­ners.

An ESP32 based plane radar

blog.ktz.me

This pro­ject made for a per­fect lazy Saturday un­wind, af­ter a busy week giv­ing a talk at Devrelcon in NYC. Makerworld had this thing as one of their fea­tured mod­els about a week or two ago, and the parts came in while I was away.

GitHub repos­i­tory ESP32-Plane-Radar Open-source ESP32 firmware for a 1.28″ round dis­play that shows live ADS-B air­craft around your lo­ca­tion as a sonar-style plane radar. by iron­icbad­ger · C++ · MIT

Plane radar is a neat lit­tle pro­ject that turns an ESP32-C3 and a 1.28-inch round dis­play into a live air­craft radar. It pulls nearby ADS-B traf­fic, plots each air­craft by dis­tance and bear­ing, and shows the de­tails di­rectly on the screen.

It was an easy build, al­though it did re­quire a lit­tle sol­der­ing. I al­ways en­joy do­ing that as it re­minds me of my days build­ing rac­ing drones. Thin, sil­i­cone based wires made quick work of the ca­bling. And af­ter about 15 min­utes, we were ready to go.

It is in­sanely easy to flash firmwares to a fresh es­p32 these days us­ing the browser-based ESPHome web flash­ing tool. Under 30s and you’re done.

A quick note about the 3d model

The orig­i­nal model was fea­tured on Makerworld, be­cause it looks great. Reality though was, in prac­tice, it’s not ac­tu­ally that great.

MakerWorld

5.4Klikes 3.3Kdownloads 15.1Ksaves 2.4Kmakes

Original 3D model ESP32 Plane Radar Live ADS-B on a Round Display by matixovi · Published May 31, 2026

Unfortunately the tol­er­ances are just too tight to be us­able with the batch of boards I got. So I’m likely go­ing to model my own re­place­ment at some point, but for now I ended up print­ing this model in­stead.

MakerWorld

154likes 195downloads 471saves 103makes

Original 3D model ESP32-S3 1.28″ Waveshare Plane Radar

by ThePrintableWatch · Published Jun 10, 2026

Customising the firmware

I’ve spent to­day im­prov­ing my fork of ESP32 Plane Radar pro­ject, with the help of pure vibes.

The biggest im­prove­ment is proper flight con­text. Where the data is avail­able, air­craft now show their ori­gin and des­ti­na­tion in­stead of just their tail num­ber, with the call­sign used as a fall­back. Aircraft types are also more de­scrip­tive, some­thing like B737 – 800 rather than sim­ply B737. I added lo­cal weather, tem­per­a­ture, hu­mid­ity, time and date as well.

The web in­ter­face can now mod­ify co­or­di­nates af­ter ini­tial setup. Display op­tions can now be changed with­out re­set­ting the Wi-Fi con­fig­u­ra­tion, and there are con­trols for units, run­ways, weather, tem­per­a­ture for­mat and 12/24-hour time. Text is 10% larger by de­fault, with a per­sis­tent 80 – 130% slider for ad­just­ing it.

Finally, the firmware now sup­ports au­then­ti­cated OTA up­dates, so fu­ture builds can be in­stalled through the browser in­stead of con­nect­ing the board over USB.

This is a bit like how ESPHome ap­plies firmware up­dates. Compile the bi­nary on your lo­cal lap­top and then up­load it to the ESP32 wire­lessly.

Next up might be port­ing it to a larger dis­play, and de­sign­ing a more for­giv­ing 3D printed en­clo­sure for it.

Plain-text weather forecast for York, York, England, United Kingdom - brolly.sh

brolly.sh

brolly.sh

plain text weather fore­cast

change lo­ca­tion

=============================================

Now

over­cast

tem­per­a­ture 19.8C (feels 16.8C)

wind 14 (28) mph / uv 2.1 / aqi 22

Today

over­cast

tem­per­a­ture 16C - 21C

wind avg 12 mph (gusts 24 mph)

pre­cip­i­ta­tion 0.1mm

=============================================

This Week

Day Conditions Temp Wind Precip Yesterday over­cast 15 – 22 11/23 0 *Today over­cast 17 – 21 12/25 0.1 Mon 27/07 p.cloudy 14 – 21 10/21 0.1 Tue 28/07 over­cast 18 – 25 9/17 0 Wed 29/07 m.clear 17 – 26 7/13 0 Thu 30/07 m.clear 14 – 22 8/14 3.6 Fri 31/07 over­cast 12 – 18 8/15 0 Sat 01/08 over­cast 10 – 20 8/14 0

< Yesterday Today Mon 27/07 >

––––––––––––––––––––––-

Conditions

Time Conditions Temp Wind MPH » show ear­lier hours (00:00 – 16:00) 17:00 over­cast 20(17) 14/28 <- now 18:00 over­cast 19(16) 14/27 19:00 over­cast 18(16) 12/24 20:00 over­cast 18(16) 10/20 21:00 over­cast 18(15) 11/22 22:00 over­cast 17(15) 12/25 23:00 over­cast 17(14) 12/24

< Yesterday Today Mon 27/07 >

––––––––––––––––––––––-

Precipitation

» show ear­lier hours (00:00 – 16:00) 17:00 0mm 30% <- now 18:00 0mm 21% 19:00 0mm 14% 20:00 0mm 9% 21:00 0mm 5% 22:00 0mm 2% 23:00 0mm 1% +––+––+––+––+ 0 0 0 0 0

now 0mm (30%)

peak 0mm (30%) @ 17:00 – 23:00

< Yesterday Today Mon 27/07 >

––––––––––––––––––––––-

UV

8| 6| 4| #### 2| ######### 0+–––––––––––– 0 6 12 18 ^ now

now 2.1 (low)

peak 4.35 (moderate) @ 12:00

key 0 – 2 low 3 – 5 mod­er­ate 6 – 8 high 9 – 10 very high

< Yesterday Today Mon 27/07 >

––––––––––––––––––––––-

Air Quality

40| 30| 20|### ### ############# 10|######################## 0+–––––––––––– 0 6 12 18 ^ now

now 22 (fair)

peak 22 (fair) @ 17:00 – 19:00

< Yesterday Today Mon 27/07 >

––––––––––––––––––––––-

Pollen

Grass ………––––––-*- Mugwort .*…………………. 0 6 12 18 ^ now . low - medium = high # v.high * peak

now grass 11.5 (medium)

now mug­wort 2.2 (low)

peak grass 14 @ 22:00

peak mug­wort 5.7 @ 01:00

=============================================

weather data last fetched at: 17:10

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.