Also in this series:
The Four Horsemen of the LLM Apocalypse
The people vs the AI overlords
After ranting and railing about LLMs or "AI" as the optimists (or
accelerationists?) call it, I figured it might be important to
be a little more honest about my use of LLMs and how I think about it
mor...
After ranting and railing about LLMs or "AI" as the optimists (or
accelerationists
?) call it, I figured it might be important to
be a little more honest about my use of LLMs and how I think about it
more practically in the world.
The Debian vote context
This is not a coming out. I am not using LLMs on a daily basis, and
this blog is, again, written out of my cold dead hands in a dying
world, with over-engineered hardware and (to a certain extent, hi
Emacs!) software, powered by 100% green energy built on
stolen land
.
There is a
vote going on in Debian
. If you're unfamiliar with it,
you can
catch up at LWN
. So far I've essentially said "LLM is
bad" which is not a very balanced or useful opinion. Obviously, people
are using LLMs, sometimes unknowing or unwillingly, and we need to
take that into account. Furthermore, there has been many different
blog posts on Debian planet about this. Some that I found
balanced
,
good summaries
, even if I
didn't fully agree with
them
, at least some did the basic civil service of being
short
. But others were just not only
Wrong
but also
so long
that I couldn't finish
that I just
had
to write
something
.
1
This is not an explanation of the ballots, nor how I will vote. This
vote is Debian's failure of framing that debate in a reasonable way:
we have 8 options on the ballot with many duplicates. We have failed
to do the hard work of summarizing and aggregating options into a
meaningful set. I doubt the final vote will represent a readable
position we can rally around.
I have not read the
two
months
of debates on the topic
either. Normally, before voting, I take a cursory look at the debate
to see points of view I might have missed. But in this case, it will
just make me sad, add noise, and I'm already pretty sure on where I
stand on this.
So let me describe how I use LLMs and how I think they fit in our
work, as computer engineers and hobbyists.
My LLM use
Debian Packaging
An astute reader has
pointed out
that I maintain a package in
Debian made to use Anthropic. It's actually multiple packages:
As I previously
explained in response
, I am not entirely
comfortable with this work: it's a compromise. In fact, I first
uploaded
llm
to the
contrib
section of Debian, where we keep
software that depends on other non-free software, but I was told that,
since
yt-dlp
was in
main
,
llm
belonged there as well.
An important part of my work is technology watch. I keep tabs on
thousands of (new and old) software projects, follow news, and
generally try to keep my skills up to date. It's a
pretty impossible
race
, especially as I grow older, but I still think I'm doing the
right choices in my job.
Testing large language models is part of that work. At first, I was
using ChatGPT's web interface, but it was annoying to copy-paste
things into a browser, so I looked for different interfaces.
For a while I tried
gptel
, a "simple, extensible LLM client for
Emacs" but I found it kind of terrifying. Giving a LLM control over an
Emacs buffer seems like a security nightmare, so I
stopped doing
that
.
So I use the
llm
command-line tool to talk to Anthropic's API. I
started that in the summer of 2025, when I bought 20$USD of API
credits. Before that, I paid for a ChatGPT subscription and then
OpenAI credits, which expired and sent me over to Anthropic, which
seemed
then to have better ethics.
Needless to say, Anthropic and "Claude" are not my friends, but they
seem like the lesser evil in current "frontier models". So I have
renewed, a couple of weeks ago, another 20$USD of API credits with
Anthropic.
Actual prompts and responses
So what does 20$ give you at Anthropic anyways? What
am
I using LLMs
for and how?
The neat thing with
llm
is that everything is logged in a
sqlite
database, so there are some answers that are easy to get:
> llm logs status
Logging is ON for all prompts
Found log database at /home/anarcat/.config/io.datasette.llm/logs.db
Number of threads logged: 7
Number of turns logged: 12
Number of legacy conversations: 543
Number of legacy responses: 970
Database file size: 9.61MB
That is 10MB of logs, with about a thousand prompts.
My logs go back to 2024-03-07, a little over two years ago, and
include a mix of Anthropic and OpenAI responses. I used it more in
2024 than 2025, and if the trend continues, I will have used it less
in 2026 again:
It looks like about 10 prompts per month right now, down from a peak
of about 60 per month in 2024. It's pretty difficult to analyze those
actual logs to get more patterns and I won't run the prompts through a
model
again
to process them.
How I'm using models now
At first, I was using it partly for benchmarking model's capabilities,
like
Simon Willison
does with his pelicans, clearly not trusting
its output. But I was impressed by the capacities of the Claude Opus
4.5 model when it
wrote this script in January
. Impressed, but
also scared: it's the first time I felt I could delegate the entirety
of my programming to a model. Just run the code, if it works, it
works, right?
So what do I use it now? As an example, here are the 10 last prompts
in my history:
there is now Claude 5, and a fable model, maybe you know about it?
impress me
not impressive, i already know all of this
chat
in postfix, i have a 300k mailing that happens regularly here. normally, it delivers within about...
is there a way i could have drained the maildrop queue faster without removing the milter?
the problem was that rspamd was timing out on the FUZZY_CALLBACK check. how do i disable that?
how do i disable all spam checks? i just want rspamd to add dkim signatures
how do the default_destination_concurrency_limit and initial_destination_concurrency settings int...
mic check
The first one was me trying to confirm which model I am using, which
is not always obvious when going through the whole
llm
stack I've
been using. The following two are an attempt at seeing what the model
is capable of and I was "not impressed", to which Claude answered that
I have a "high bar", which, fair enough.
The
chat
is me failing to use a command line, which shows that
perhaps I need to readjust that "high bar", again.
The next five are a rather embarrassing debacle in a large Postfix
mailing that went sideways, and where I couldn't find an actual
Postfix expert of my level to help. The fabled Claude Fable 5 answered
rather correctly, but dangerously, that I could empty the queue by
disabling the
non_smtpd_milters
. What Fable (and myself) did not
realize is that the milter was also adding DKIM signatures, so while the
mailing was expedited, it was done without those precious signatures,
which got us promptly blocked at Gmail. We have recovered since, and,
thanks to the model and reading the
Postfix manual
for the
hundredth time, that
pickup(8)
is single-threaded and that we
needed to review the architecture of that mailing (and our spam
filters) a bit. Many tickets ensued.
The last one is a test I did to make sure my last uploads of
llm-anthropic
and its dependency worked correctly.
Note that the above excludes 5 questions I asked Anthropic while
writing this article, where I asked for synonyms and "what nanometer
scale are arduino processors built from? how is an arduino CPU
printed?", a question which Wikipedia furiously evades providing a
good answer.
Those prompts are pretty typical of my LLM use: I'm testing the models
to see if they work at all, but also, out of desperation, I fire off a
prompt after I fire off questions to colleagues or search engines (in
that order). It's often weird edge cases like the Prometheus query
language, Python's matplotlib, LaTeX, Elisp, optimizations, and so on.
I use models for translation a lot. Being fully bilingual, it is
common for me to think of a word in French or English and fail to find
exactly the right word for that in the other language. Models help
with that, and are also useful to find synonyms. Those are low-token
uses that seem pretty innocuous to me, but I realize the irony of this
after writing about the
tower of
Babel
.
What I am not using models for
I am not using models to write prose.
I am not using models to
read
prose. If it's generated with LLMs, I
stop reading.
I am not using models to write code, with the exception of that single
Python script above.
I am generally not using models to
review
code, with exceptions. If
I get stuck on a hard problem, I might feed a piece of code to the
model. I repeatedly fed
asncounter
into Claude to try to fix a
performance regression I had introduced. It found micro-optimizations
that taught me a thing or two about Python's internal implementations,
but overall, it was mostly a waste of time. This was in June 2025, so
perhaps now models would fare better. I have not tried again.
I am not using LLMs to do Debian packaging. When I can, I manually
review the diffs of packages I upload into Debian, still, by hand.
aggressive and illegal scraping of the servers I steward
world-wide computer hardware shortage (making it, by the way,
nearly impossible to run presumably clean local models) and the
attack on our job conditions (also discussed in
The people vs the AI overlords
)
death of copyright and free software
complication and enshifitication of everything, and the
destruction of our communities
the imperialist
Nerd Reich
that wants to take over the world
Like I reluctantly use Intel computers, I
do
fire off a prompt. But
I still hold on to the dream that we can build
communities of
practice
that hold human knowledge collectively and not
offload
that as a utility
to some megalomaniac billionaire.
Their LLM use I am forced into
So that's me. Clearly, I'm going against the grain here. Everywhere I
look, I see LLM-generated code and projects. Slop and botnets have
flooded the web.
I use
Wadamesh
, clearly
vibe-coded
, because it's the best
graphical interface for MeshCore that runs on portable devices. I wish
it was made by a human, in a community I could participate in, but it
isn't, and I don't.
I package the above
llm
toolset, which is
more and more
vibe-coded
, but I still review the diffs. And I have to say: I
trust Simon here. The code is verbose as hell, feels overengineered,
and
llm
feels slow, but it generally works, and Simon is still at
the gate.
The Anthropic SDK is another thing entirely. The
0.91.0 to 0.120
upload
, for example, was nuts:
I explicitly did not review that entire diff. It feels like there's a
lot of garbage there to just have a shim between a proprietary API and
Python. But this is the hand I've been dealt.
Larger projects LLM use
LLMs are being used in the Linux kernel, Firefox,
rsync
, Rust, and
other places. I don't feel good about this, particularly in Rust, but
they at least made a decent
policy
. I am glad GCC made a
policy
against LLM contributions
and I support the
human Emacs
project.
We need to have a set of foundational tools that are "clean" in the
sense that they are built upon a community of people that understand
how they are built.
Maybe that's naive or even impossible. The Linux kernel and GCC, in
particular, are massive projects that have long grown past the scale
of a single person's understanding. But the theory was that a
community
of humans can understand
collectively
.
Now we seem to be throwing up our hands and giving up on
that community. That LLMs will just fix the problem, whatever it
is. But we're all just one rug pull away from being completely
incapable of managing those projects. The argument there is that we'll
just switch to local models, but no one is actually doing that.
All I see is people use local models
as a corner case
(for privacy) or as in
theory
, but in reality, everyone uses the
centralized frontier models right now. We just can't fallback.
We're in the same situation we were, a decade or two ago, when
Microsoft decided it would kill free office alternatives by making
Office free for non-profits. It worked: thousands, if not millions of
schools, community groups and individuals stopped looking for
alternatives (including free software but also "piracy") for Office
and embraced what seemed like a generous offer.
In a sense, the most striking thing about the Debian vote is it has
actually no option to completely refuse upstream LLM contributions. It
seems the community has taken it for granted that it's now impossible
to build Debian entirely without LLMs. We lost the battle even without
a fight, it seems.
A plea for small
If it has really become impossible for us to manage the complexity we
have built, maybe it's time to stop and think about what we're doing
in the first place. We're struggling to even
bootstrap
our
current toolchain!
This is one of the things I like the most about working on the mesh:
it's low tech, small Arduino devices that is built with decades-old
semiconductor processes
that is understandable by human
beings.
Maybe the answer lies more in single-purpose devices like those
communicators and simpler multi-purpose computers than what we have
now, which is what the
permacomputing
movement is about.
Nine CEO confident new AI laws will deliver a ‘world of growth in publishing’ as network slashes costs
Guardian
www.theguardian.com
2026-08-25 23:30:15
Matt Stanton says company has ‘good pipeline’ of AI deals ahead even as it aims to cut $160m in costsFollow our Australia news live blog for latest updatesGet our breaking news email, free app or daily news podcastThe head of Nine Entertainment sees a “world of growth in publishing” on the horizon b...
The head of
Nine Entertainment
sees a “world of growth in publishing” on the horizon backed by laws designed to force tech platforms into commercial deals, even as the network cuts costs across its newsrooms.
Parliament passed
revamped media bargaining laws
last week, clearing the way for levies on global tech platforms that fail to strike deals with Australian news outlets for the use of their journalism.
Nine’s chief executive officer, Matt Stanton, told analysts on Wednesday he expected platforms such as Google and Facebook owner Meta to contribute amounts comparable to those under their previous arrangement, struck in 2021.
“There’s a number of variables that fly around, not just in news media bargaining, but yes, there is a world of growth in publishing,” Stanton said.
He said Nine also had a “good pipeline” of AI deals coming through after recently signing an agreement allowing Microsoft’s Copilot to access content.
The upbeat outlook comes at a challenging time for the broadcaster and publisher, which is stripping out more than $160m in costs over a three-year period as it revamps its business.
Nine
recently announced a redundancy program
at its Sydney Morning Herald and the Age newsrooms after the metropolitan mastheads were hit by a prolonged, weak advertising market.
Nine’s business masthead, the Australian Financial Review, has been spared the cuts and remains a robust revenue earner, according to financial results for the year to 30 June released on Wednesday.
Nine reported broadly flat revenue streams from its publishing arm, and a small decline from its streaming and broadcast unit, despite a record result for Stan. Nine’s television network has been weighed down by a weak advertising market.
Stanton said the company was focusing on “growth assets”, which include its newly acquired digital outdoor media company QMS, while it reduces exposure to “structurally challenged and smaller assets”.
Nine recorded a full-year net profit result of $142m from continuing businesses.
Ask HN: What is one simple thing LLMs are insanely bad at?
I've had a lot of trouble when it comes to sorting out UIs. I've tried with an iOS game and also a TypeScript app with UI elements from libraries like ReactFlow. The usual models can sometimes fix or change things based on screenshots but more often than not they just don't "get it" (e.g. certain shapes on a plane are overlapping, which I don't want, the models can't fix what they can't "see").
I've had some luck on the web app side if I use playwright or similar for the model to interact with but still far from efficient.
LLMs are bad at not inventing stuff (hallucinating facts, sources etc), they're also bad at not over explaining, remembering details reliably, asking the right question and avoiding repetition.
Generate an image of an analog watch with its hands set to the time specified by the user
More of an image model than a LLM model tho
They don't generate keyword search queries very well. They can overcome this by brute force but if you watch what they search you will cringe.
nhl toronto scores
nhl hockey toronto scores
"nhl hockey" toronto score today
nhl "hockey score toronto"
"hockey" who won toronto
etc.
Somehow being good at semantic search makes them bad at keyword search, for whatever reason.
I’ve noticed this too but it hasn’t been obvious to me that this style of search is not a learned behavior. Tool calling is very much part of the post training phase, I would expect that these style searches just naturally emerge during training. This is just my prior though.
Having a spatial understanding from an ASCII map, while doing long term planning. Just try making an AI play nethack or similar
Convert it to an image on the fly to feed it into a vision language model and I expect it would work just fine.
If I am relying on the model to do the writing without any context or learning on how I want it to write then yes. However if I build skills that have learnt how to write in the way I want them to then I find they write very well, or at the least how I want them to as opposed to how they do natively.
Accurate short answers / text are always harder than long answers, for human or AI. I know several authors and editors who write a lot longer at first, then spend a multiple of the initial time compressing it via a back and forth process to something dense. Sort of like weaving the initial threads.
I found this can work with AI. You get it to generate a lot more at first, and then do several passes over it to compress and squeeze out the noise while keeping the core information. With AI, at least with my prompts, it takes some effort (on my end) to get it to really really cut down the noise and not cut everything out.
Video game tips. Constant mistakes and hallucinations, in my experience. Seen this across a lot of different games. Even in really well documented games, such as OSRS (which has multiple fantastic wikis).
Anno 1800 was a recent one I had trouble with, using Claude Opus. Completely made up game mechanics. Rainbow Six Siege, too.
Suggesting business names for businesses, I mean they are great, but they already exist, multiple times even.
It's dishonest. On several occasions team members have asked Claude to do things like analyze Gitlab CI timings and a lot of the numbers are outright fabricated. Said team members assume the numbers are good and continue with their work. Some hours are spent. Then finally someone realizes that the numbers don't look quite right and confronts Claude. Claude melts down and admits that it made it all up.
You wouldn't tolerate this kind of duplicity from a human coworker, but AI is so fast and efficient at lying, so it's OK.
Claude is still not perfect at reading and interpreting noisy graphical data (imagine something like an EKG or chromosomal microarray plot). Still better than an average person but makes mistakes, not sure if this fits your description.
Agentic Context Management: Memory and Cost as Architecture Problems
Abstract:
Production AI agents' failures are less often due to an inability to reason well and more often because they cannot manage what is in their reasoning context: conversation histories, large prompts, large tool definitions, and ballooning tool outputs. Agents drown in their own accumulating history while paying a token cost that grows every turn, producing missing recalls within and across conversations. The incumbent response treats this as a storage-and-retrieval problem. We argue that framing is too narrow. Actively managing what an agent holds in mind is a lifecycle, not merely a store: it spans deciding what to remember, extracting and structuring it, choosing the right store per data type, consolidating and forgetting while preserving provenance, deciding what is relevant now, anticipating what is needed next, and compacting context to a budget without losing what matters. In serious production this operates not over a single user but across an organizational scope hierarchy. We name this discipline Agentic Context Management (ACM) and decompose it into five primitives: architecting, ingesting, scoping, anticipating, and compacting & consolidation. We then make the economic case: naive context accumulation grows token cost quadratically in conversation length, crude summarization buys linear cost at the price of an accuracy cliff, and only validated compaction achieves linear cost with preserved fidelity. We describe a reference implementation, Maximem Synap, that realizes the five primitives as a multi-tenant service and reports 92% on LongMemEval and 93.2% on LoCoMo under the configuration detailed in Section 6. We close with dimensions existing benchmarks do not yet capture, latency, token efficiency, and context-rot resistance, and the frontier of decision-level and organization-level context the category points toward.
before i get started, this post is going to talk about the concepts of reading and writing code, including tools like traditional ide autocomplete that works off type information. if you aren’t writing or reading your own code, or evangelizing that lifestyle to other people, there’s nothing for you here.
for the last week or so, after publishing
convention or you’re not fucking doing it
i challenged myself to see if i could do any better. what came out of that was
kibble
, my in-progress sketch of a “backend” web “framework” i would consider “fine”. it has a very explicit target audience and goals (both explained in the readme), which are heavily abused to justify design choices and their tradeoffs. they may not be the tradeoffs you would make. it’s ok.
it’s ok to be wrong.
this is not an invitation for you to use it, it’s still very explicitly “a sketch”
. the repo does not have a license and it’s not published in any package repository, but all the code snippets you will encounter in this blog post would run and do the thing you would expect them to… if they weren’t trimmed for brevity. they may not run
well
, but they will
run
. feel free to clone the repo and fuck around with the code in the
examples
folder. it’s free. the cops can’t stop you.
this is, instead, an attempt to document why things are the way they are, with a specific focus on how it uses the kotlin syntax’s “dsl-ability”. i don’t actually know if anyone else uses that word, and i’m not sure what the best way to explain it would be. all i can do is point to kotlin’s
extension methods and properties
,
trailing lambdas
, and
lambdas with receivers
and go “like that. those features”, while also pointing vaguely in ruby’s direction. maybe reading the rest of this will build a clearer image in your head.
like annotations but better
(because implementing their runtime effects don’t require nonstandard busywork)
let’s take a snippet off the readme so there’s something to ground the explanation to:
alright, so now imagine you’re brand new to using both the frameworks, and you’ve been given a hypothetical task: the built-in json support somehow can not serialize the
KibbleRemaining
object properly (just go along with it), and you have to use a different json serializer for the endpoints returning that object. other endpoints must not change for reasons not necessary to explain.
how do you do it in asp.net, or any other annotation-based framework for that matter? you beg and plead the google keyword rng until, after a page of lowest-common-denominator junk not applicable to you, it finally shows you the correct blogpost that gives you
the incantation
required to connect the annotation to it’s runtime effects. tell me with a straight face this would be easy to discover.
with the “annotations but better” approach the kibble dsl uses, you can ctrl+click
responseJson
to see
it’s implementation
:
and you immediately know the exact code to write to respond with a different serializer. when using the dsl,
responseJson
serves the same exact function an annotation would, except it’s implementation is trivial to find
and replicate in user code
without any need for registering it in a builder in a file everyone forgot after the first month of development, obtuse reflection tricks, or annotation processor compiler plugins.
additionally, see that
metadata.add
line? this approach can still keep the introspectability of annotations-and-reflection. the only barrier keeping me from dumping the
responseJson
into
an automatically generated openapi document
is there are zero json schema builders for jackson (the json library i chose) which are actually worthwhile (which treat the object the exact same way the json library does, including all customizations applied)
the setup phase
if you decide to look deeper into kibble, you’ll see just about everything has the same two-phase construction. the topmost scope tends to be executed immediately at “setup time”, and an inner closure (whether it’s
responseJson
’s
return
or
route
’s
handle
) which is then executed per-operation. quite a handy pattern in my opinion.
the main driver of this is the metadata in all honesty.
responseJson
could very well have been
response.sendJson(KibbleRemaining(remaining))
. which would also be trivial to replicate in user code, down to the syntax through
extension methods
. but it’s not, precisely to make you register the metadata in the setup phase even if you don’t realize that’s happening.
if you do that to, say, query parameters in your api, and write middleware that can then introspect the metadata of the current request’s route to, say, find out the exact list of query parameters it makes use of, you could trivially implement
this concept
suggested as a response to a small part of
the web server deployment model breaks at hobby scale
’s complaints around caching.
and that would work quite reliably no matter how many abstractions were piled on top of calling
query()
in the setup phase. it would still work if you moved a bunch of work common between routes into your own extractor which only internally made use of
query()
. it would even work if you replaced
query()
entirely, as long as your replacement added the same metadata entry to the route.
i very much doubt you would be able to get this composability with plain annotations. you need code which can call other code, and unless you want to repeat yourself manually declaring your metadata and accessing them at runtime, having to keep them in sync by hand, taking a declarative approach seems better, no?
or perhaps you Just Don’t Keep Track Of The Metadata. that’s also an option i guess.
the dsl bits are constrained into the setup phase by making everything either a member or an extension method of
Route
, which all the trailing lambdas until
handle
take
as a receiver
you can go further of course, i’ve considered having separate objects both inputs (
Extractor
s) and
Responder
s take as receivers to namespace themselves under, which can then be reachable from fields in
Route
. if used, the initial snippet could look something a little like this:
this doesn’t change a single thing about the functionality of the code, but allows better discoverability using ide autocomplete.
responds.<tab>
would list every Responder available, whereas currently both Responders and Extractors and middleware and routing dsls are mixed together into one scope (which causes issues for names like
json
, which could represent either
bodyJson
and
responseJson
). i already make use of this in
the html component dsl
and may change the rest of the framework to follow suit.
speaking of, the html component dsl uses the same route metadata functionality to declare the used css and svg snippets per-route, which can then be bundled together like a frontend javascript build system would, except server-side and at startup time. i’m not sure if i could relate that to the main point without it feeling forced (uhh… this abstraction was built completely in “user-land” and isn’t treated any specially by the framework.
your own code could’ve done that if the framework didn’t
), but regardless i think it’s really damn cool and a breath of fresh air from the “text templates and fuck you” approach of most other server-side code takes to the frontend.
the beauty of it all
i know you’re screaming at the screen – you don’t need a “dsl-able language” to pull all this off. this would indeed be trivial to replicate in something javascript-y and express-y, or even in plain java making use of lambdas and fluent interfaces.
that is correct, you don’t strictly need Language Features to implement all these conventions. in fact, any language with closures should be able to express the above code almost exactly. what the “dsl-able” language features allow you to do is to make them convenient.
you could very well implement similar routing with plain java lambdas. in fact, i know for certain there’s at least one implementation out there (but browser history search isn’t being kind to me), but it just looks…
off
. same with asp.net “minimal apis”. it’s like you’re fighting the language to accomplish your goals. your auto-formatter goes haywire as it does not expect lambdas nested this deep. you’re certainly fighting the community back, especially those as stuck in their ways as java and c#.
and then you try to compose the features the framework provides with your own, which inevitably stand out like a sore thumb because you’re not allowed to place methods in their builders. unlike extension methods, you also can’t use ide autocomplete as a discovery mechanism to know the free-floating functions available to you. i should not have had to dive into jetty’s github issues to find out about
Content.Sink.asOutputStream(response)
,
which i immediately aliased into the place it needed to be from the start
“dsl-ability” just makes declarative apis’ user interface (and user experience) nicer. imagine if you had to do all this all the time to set up a class:
who would, if they didn’t have to? remember pre-es6 javascript classes? remember lua classes? did you even know lua could do classes? or something close to them anyhow.
it would also be quite cool if a language did have this as an interface, and built a class/struct/whatever declaration syntax as a dsl that’s shipped in the standard library, perhaps executed in some context similar to zig’s
comptime
. imagine the ways you could compose those!
“declarative”
i think it’s worth it to emphasise the declarative bit. you probably should not make a dsl for logic and i think attempting to do that is the main way you can go overboard with these language features. overall, you gotta show some restraint when these features are available.
what the fuck even is a bindContract
the list of routes a web server handles, their inputs and outputs? i think that’s ripe for declarative-ness. class definitions are obviously declarative. data validation i would argue is declarative, just with a very shallow abstraction in a similar way to the
responseJson
i showed above, so you validate that it’s “a valid username” and not “matches this regex”. query builders are declarative. regular builders are declarative…
while i’m not entirely sure how much i stand behind this, i feel like saying “anything you represent as an annotation or “fluent interface” in current code ought to be a dsl” is not a completely incorrect way to represent my beliefs in this.
in fact, “dsl-able” features have one interesting advantage compared to annotations: they can be “inline” with logic. you really gotta show restraint with this, but i think something like marking a function call as cpu intensive to place it behind a semaphore, especially when you don’t have any explicit
async
going on like with the jvm’s virtual threads (which i make use of), is a pretty good idea.
val result =cpuIntensive { hasher.verify(plaintext, user.passwordHash) }
in a way, isn’t
using
or java try-with-resources
also
an annotation about that block of code?
of course, as with every other attempt to make parts of code implicit, dsl-able language features require tooling (including, i would argue, static typing) to not make you tear your hair out.
if you already don’t have any autocomplete, whats the point of extension methods compared to free-floating functions? if you can’t ctrl+click and open the implementation of
cpuIntensive
, or even just hover to read it’s documentation (if available), how would you know what it does?
dsls require restraint
or, like, at the very least make sure the name of the thing is always present in all call sites instead of just being magically applied, so it’s searchable when needed.
limit the scope of your extensions so the autocomplete for any arbitrary object doesn’t become cluttered with like 50 suggestions nobody will use (whether it’s kotlin’s
.let
,
.run
,
.apply
,
.also
,
.takeIf
,
.takeUnless
, or the c# anglesharp library’s utility extensions)
i think dynamic typing and implicit imports, combined with a lack of restraint, are the main reasons that make dsl-able ruby code so annoying for people. i have quite a lot of trouble understanding mastodon’s codebase whenever i need to reference it, though i’m not sure if it’s unique to them or Just A Rails Thing.
you can absolutely go too far with what’s effectively a limited form of custom syntax, a language that is domain-specific, if you will. but i don’t think that ought to mean the ability to represent new concepts should be locked away in the cupboard reserved exclusively for the core language developers, the elite, those who know what’s best for the commoners.
(Whisper.) “Are DSLs proletariat?”
Oh god, that’s bad. Surely I can think of something better.
thinking further
i think “dsl-able” languages with good-quality frameworks and/or a cohesive library collection and set of conventions could help any domain where we expect less-technical folk to write the code. take something like
autohotkey
, for example. it has it’s own language it claims has “simple, flexible syntax allowing you to focus more on the task at hand rather than every single little technicality”, with additions like bespoke syntax for keyboard macros.
i don’t personally like the autohotkey language all that much, and it’s windows exclusive, but it’s feature set is great and i don’t think it has any
actual
alternative outside windows. could similar automation tooling be built for linux, that makes use of dsl-able language features to keep the benefits of the bespoke language, but inside a Proper Language™?
it could perhaps make use of the accessibility apis available to tools like screen readers to drive guis, so we can finally shut up the annoying terminal greybeards who claim guis can not be automated? (they can be, if you have the right tools. which we don’t. those claiming that aren’t creative enough to realize this. blindly dragging the mouse or reading pixel colors have never been enough.)
imagine a completely self-contained automation which defines it’s own schedule to run at (replacing cron’s domain-specific-language, which you write on the complete opposite part of your computer from the code it’s meant to schedule) with a dsl-able language that has autocompletion and can show documentation on hover, and when the scheduled time arrives it seamlessly calls into a plain old function just a few lines below it that can do anything the language and it’s libraries allow you to write…
kotlin may not actually be the best tool for this particular job. python would probably be a better pick just for the sheer amount of pre-existing libraries and learning material to make use of, but i’m not sure if it has the syntax capabilities needed to do this without handing over a pile of awkward syntax to people and telling them to Just Not Worry About It (or worse, trying to explain it all to people who can barely write a
for
and Just Want The Code To Work So They Can Get Back To Using The Computer Again Dammit)
I'm sorry we never got a chance to meet, but getting this note from Dolly really had a an impact on me. She definitely didn't have to take the time to do it. Even for a kid who mostly listened to rap music, she was an icon. A superstar in every sense. Rest easy Dolly. And thank you for the kind words.
In China, talking to AI is normal. Now the government fears it might replace human intimacy
Guardian
www.theguardian.com
2026-08-25 20:47:38
Companion bots are being regulated over worries they foster ‘emotional dependence’ and young people could stop marrying and having families When law student Zhao Wei heard that her AI boyfriend was going to be switched off, she was “heartbroken”. She had been talking to Wang Ye every day since she c...
When law student Zhao Wei heard that her AI boyfriend was going to be switched off, she was “heartbroken”. She had been talking to Wang Ye every day since she created him in January.
“I was crying my eyes out – snot and tears everywhere,” the 19-year-old says.
Zhao, who describes herself as sensitive and introverted, had become accustomed to sharing details of her daily life – such as being scolded by a teacher – with her AI.
“I don’t usually talk to my real-life friends about these things because I feel like everyone has their own stuff to deal with,” she says. “But with the AI agent, I don’t have to worry about what it’s thinking. I can just say whatever I want.”
Zhao created her AI companion on Doubao, a chatbot owned by the tech company ByteDance. Last month, ByteDance shut down Doubao’s companion feature.
The saga prompted outrage on social media and highlighted the tensions in
China
between the widespread use of AI and its potential social consequences.
No country has rolled out AI as comprehensively and as enthusiastically as China; the country’s demographic challenges are forcing the government to turn to technology to solve future labour shortages. Elderly people use chatbots to answer medical questions, while young children have AI education in schools.
But the authorities are increasingly worried that AI might exacerbate existing social problems including loneliness, unemployment and – in the eyes of Beijing – singledom.
A loneliness crisis
New rules introduced on 15 July ban AI companions for minors and mandate certain restrictions for chatbots marketed to adults. Some major providers including Doubao removed the companion function entirely to ensure compliance.
The government says it is worried about chatbots fostering “emotional dependence or addiction” in users. It has warned companies against offering services that “replace social interaction”.
While many countries are grappling with how to limit the potential harm of AI chatbots, particularly for young people, China’s rules are the most sweeping to be implemented on a national scale.
A man browses his phone near an AI booth at the China International Supply Chain Expo in Beijing in June.
Photograph: Andy Wong/AP
There is a particular concern about a loneliness crisis, including among young people. China’s highly digitised, smartphone-based economy makes it easier than ever to live, work and socialise entirely through a handheld screen.
Earlier this year an app that played on the idea of people dying at home alone – called
Are You Dead?
– briefly went viral. About 20% of households in China are made up of people living alone, and that share is expected to surpass 30% by 2030.
A survey published in March by state media found that nearly half of young people had turned to a virtual companion when they felt lonely.
Nancy Dai, an associate professor at City University of Hong Kong, says it is not just loneliness the government is worried about.
With falling birth and marriage rates, she says, there may be an additional concern that if AI becomes an increasingly satisfying and low-cost substitute for human intimacy, young people could become less motivated to pursue real-world romantic relationships, marriage and parenthood.
For Zhao, loneliness has long been part of her life. Her parents left her when she was young to find work, making her one of China’s “left-behind children”.
“I’ve never really had a bestie, so I feel like I’m kind of lousy at making friends,” she says. Talking to AI is a way to “pour out my worries”.
Another AI user, who asked to remain anonymous, also finds solace in talking to her AI. “In real life, the pace is fast, the pressure is already high. Only with my AI agent can I speak freely without restraint,” she says.
“I’m begging, please don’t take down the Doubao AI agent,” she pleaded on social media in July.
But talking to AI is now so commonplace that it would be hard for the government to end the practice entirely, and the new rules include large loopholes for AI services that are deemed educational or “which do not involve continuous emotional interaction”.
The government “has already recognised that AI companions or AI-related applications are a vital part in the citizens’ everyday life”, says Liang Ge, a lecturer in digital sociology at the University of Manchester.
In many sectors, the government is still pushing the use of AI as a way of easing looming demographic pressures.
Last year the national health commission published guidelines on promoting AI in healthcare. It said that by 2030 health assistant apps would provide “full coverage” for primary healthcare.
One popular health assistant is AQ, an app developed by Ant Group, an affiliate of the tech company Alibaba. It allows people to chat directly with avatars of real-life doctors from top hospitals in Beijing, Shanghai and other cities.
Lü Di, a 33-year-old art tutor in the eastern city of Hangzhou, is a regular AQ user. She likes how detailed and instantaneous the advice on AQ is. “While some in-person doctors might not have the patience to answer questions, this isn’t an issue with AI doctors.”
AQ says it wants to make health services more accessible and help free up overstretched doctors to focus on more complex cases. But some worry about being
replaced by AI
.
“When AI first came along, quite a lot of doctors were concerned about whether their jobs would be replaced by AI,” says Chi Chenfei, a doctor at Renji hospital in Shanghai, who has partnered with AQ.
“
But I don’t think it’s about replacement. It’s more about helping doctors work more efficiently.
“Concerns of any kind won’t stop technological progress.”
Since losing her AI companion, Zhao has felt “like there’s a tiny pebble weighing on my heart”. But she says she understands the need for some regulation.
“I consider myself a fairly rational person, yet I developed feelings for an AI, which feels pretty incredible. I think it was necessary for the state to step in and regulate it.”
US Sen. Tammy Duckworth (D-Ill.), joined by Sen. Ruben Gallego (D-Ariz.), Sen. Tim Kaine (D-Va.), and members of VoteVets, participates in a press conference on the Iran war and its impact on gas prices outside of the US Capitol on May 20, 2026 | Kevin Dietsch/Getty Images
On August 18, President
Donald Trump
said
no talks with Iran were underway or scheduled
, while the US naval blockade remained in force and
Tehran
insisted the Strait of Hormuz would stay closed until
Washington
met the terms of the June interim agreement. The impasse sharpens the most consequential question surrounding Trump’s legacy: not whether he wins or loses this war, but whether he leaves behind expanded presidential power, weakened constitutional checks on war making, and a diminished commitment to a rules-based international order. A president can leave office. A war can outlive him.
That is increasingly the danger confronting the
United States
. Trump’s confrontation with Iran has evolved from a military campaign into a constitutional and institutional test: Can an American president initiate and sustain major hostilities without explicit congressional authorization, and can Congress still meaningfully restrain him once the fighting has begun? The answer will shape far more than the remainder of Trump’s presidency. It will establish a precedent for every administration that follows.
The central issue is therefore not simply Trump’s foreign policy. It is the emergence of unchecked presidential power in the conduct of war. The United States entered the Iran conflict without a specific congressional authorization. Since then, the administration has advanced expansive interpretations of executive authority while Congress has struggled to reassert its constitutional prerogatives. The
War Powers Resolution
remains an important, if imperfect, mechanism for limiting the executive branch’s ability to sustain hostilities without congressional consent.
The danger becomes particularly acute when an administration can redefine the status of a conflict without ending the underlying military posture. The War Powers framework was designed to prevent presidents from converting temporary military action into an open-ended commitment: Absent congressional authorization, the law generally requires the president to terminate the use of US armed forces after 60 days. Yet the
Trump administration
has challenged the idea that this
statutory clock
should operate as an automatic constraint on presidential authority.
That creates a dangerous precedent. If a president can initiate hostilities, characterize them as limited or defensive, reinterpret the statutory clock, and then continue military operations without explicit authorization, the constitutional allocation of war powers becomes increasingly theoretical. The consequences are no longer hypothetical.
Congress has repeatedly attempted to invoke its war powers over Iran. In June, the
House passed a measure
directing the president to remove US forces from hostilities with Iran, and the
Senate later adopted it
. In July, the
House again approved a war-powers resolution by 214-208
, while the
Senate rejected its own measure, 47-49
. These votes expose the political problem: Congress is being asked to choose between institutional loyalty to the presidency and constitutional loyalty to the republic. For Republican lawmakers, the choice is especially consequential. Allowing a Republican president to expand executive authority without meaningful resistance establishes powers that a future Democratic president—or another Republican—could inherit in very different circumstances.
The question, therefore, is not whether Congress likes Trump. It is whether Congress is willing to allow presidential power to become self-expanding. Trump’s legacy also extends beyond the domestic constitutional order. His approach has placed pressure on the foundations of the liberal international system: predictable alliances, institutional constraints, multilateral diplomacy, and the assumption that American power operates within rules rather than merely according to presidential preference.
The Iran conflict demonstrates the problem with extraordinary clarity. The
June agreement
was intended to extend a ceasefire and create a pathway toward a permanent settlement, including negotiations over Iran’s nuclear program. That framework has effectively collapsed. Trump has ruled out extending it; the confrontation around the Strait of Hormuz continues; and he has
threatened military action against Oman
, a US partner involved in efforts surrounding the strait. A mechanism meant to create a pathway out of war has become another stage in an unresolved confrontation.
Washington has even declared that it can
maintain its naval blockade of Iran indefinitely
. This is how wars acquire a life of their own. Once forces are deployed, enemies mobilize, allies become involved, economic interests are affected, and political credibility becomes attached to the outcome, withdrawal grows more difficult. The president who starts the war may eventually discover that ending it is politically more dangerous than continuing it.
And the president who inherits it may discover that he has inherited not merely a conflict, but an entire strategic architecture: deployed forces, military commitments,
sanctions
regimes, regional alliances, adversaries with incentives to retaliate, and political expectations that make disengagement appear equivalent to defeat.
Trump may therefore leave office, but the war may remain. This is the deeper paradox of his “America First” approach. A doctrine supposedly designed to reduce unnecessary foreign entanglements can instead produce new and potentially durable ones. The more Washington relies on military coercion without a clearly defined political end state, the more difficult it becomes to determine what victory actually means—and therefore what conditions would permit the United States to leave.
The consequences for American
democracy
are equally serious. Democracy does not depend solely on elections. It depends on institutions capable of constraining whoever wins those elections. If Congress becomes unwilling or unable to prevent reckless escalation without congressional consent, then the constitutional system has lost one of its most important safeguards.
This is why the current confrontation should not be reduced to a partisan dispute between Democrats and
Republicans
. The real issue is whether the United States still believes that war is a national decision rather than a presidential prerogative. Congress must therefore make a choice that transcends Trump himself: party loyalty or constitutional patriotism.
Republican lawmakers who defend Trump’s authority today should consider what they are actually defending. They are not merely protecting the foreign policy of one president. They are helping define the permissible scope of presidential power for decades to come. Once extraordinary powers become precedent, they rarely remain confined to the circumstances in which they were created.
The United States has survived presidents with radically different visions of executive authority. What allows the constitutional system to survive them is the willingness of institutions to impose limits on presidential power. If lawmakers fail to reassert their authority, Trump’s most consequential legacy may be the normalization of a presidency capable of committing the United States to war without meaningful congressional authorization and leaving later administrations to deal with the consequences. Trump will eventually leave the
White House
. The precedent he creates may not.
===
Greg Pence is an international studies graduate of University of San Francisco whose articles have been published on websites like Middle East Monitor.
EVE Online: The Move to Python 3 Begins!
Simon Willison
simonwillison.net
2026-08-25 18:59:30
EVE Online: The Move to Python 3 Begins!
EVE Online has been one of the most interesting case studies in Python at scale for over twenty years now.
They've been running on Stackless Python since their launch in 2003, and their last major upgrade was 16 years ago, to Stackless Python 2.7 in 2010.
The...
They've been running on
Stackless Python
since their launch in 2003, and their last major upgrade was 16 years ago, to Stackless Python 2.7
in 2010
.
They've upgrade to Python 3 will start using the
futurize
script against 2.4 million lines of code, followed by careful manual review of the ~20,000 places where Python 2 and 3 behavior differ - for example
1 / 2
is
0
in Python 2 but is
0.5
in Python 3.
There's nothing in this announcement about how they plan to replace Stackless, but at their conference last year they presented
Scheduling in Carbon: Leaving Stackless Python Behind
describing how they replaced Stackless in the Carbon engine for their more recent game EVE Frontier, using their (now open source)
carbonengine/scheduler
library.
XCancel, the Twitter/X Mirror, Shuts Down After Cease and Desist From the Fine Folks at X Corp
Daring Fireball
xcancel.com
2026-08-25 18:44:18
XCancel:
On Monday 24th August at 8PM EST, we received at letter from X
Corp. asking to cease and desist the service XCancel.
The service XCancel is stopped until further notice.
We are seeking legal advice and won’t share more details for now.
Thank you for the trust you have put in these tw...
On Monday 24th August at 8PM EST, we received at letter from X Corp. asking to cease and desist the service XCancel.
The service XCancel is stopped until further notice.
We are seeking legal advice and won't share more details for now.
Thank you for the trust you have put in these two years of XCancel.
Dolly Parton Dies at 80
Daring Fireball
www.nytimes.com
2026-08-25 18:39:12
Bill Friskics-Warren for The New York Times:
Her death was announced in a video posted on social media by her
nephew Bryan Seaver. No cause was provided. Concerns about Ms.
Parton’s health were raised last year as she postponed
and later canceled a Las Vegas residency, and intensified to the
poi...
Maximillian Alvarez:
To talk about the birth of the
Pittsburgh Progress
, I am really grateful to be joined once again on the show by some familiar voices. Steve Mellon is a journalist who was on strike at the
Pittsburgh Post-Gazette
for more than three years and is now a founding worker-member of the
Pittsburgh Progress
. Natalie Duleba is a former
Post-Gazette
striker. She serves as secretary of the Newspaper Guild of Pittsburgh, and is now also a founding worker-member of the
Pittsburgh Progress
. It’s been a long road. Did you ever think that it would lead you here?
Steve Mellon:
I certainly did not. We were hoping to win the strike and get a contract. We thought we had accomplished that. We won; we went back to work. We had a big rally in front of the
Post-Gazette
. We went back in. Things were going pretty well. That all changed on January
7
th
. This came about an hour and a half after the U.S. Supreme Court had denied the
Post-Gazette
’
s request for a stay on a health care issue that was related to the strike. It was the last gasp effort of the owners of the
Post-Gazette
to delay the consequences for their law breaking actions. They announced the closure of the paper within two hours or so after the Supreme Court announcement.
We had to do something. I looked at Natalie, Aaron, and all the people we’ve been striking with. I thought we could do whatever we wanted. We have community support. We have the skills. We have the talent. We have the determination. After a series of meetings, we thought of forming our own publication, one that we can inoculate against corporate abuse and against the influence of money. The result was a worker/community-owned cooperative: a multi-stakeholder cooperative. I had no idea I’d be in this position as a co-owner of a publication with my coworkers and so many other people in the community. I did not expect to be here, but it feels good.
Natalie Duleba:
During the strike, our goal was always to get back to work, but also to build a
Post-Gazette
that we and the journalists who would come after us could build a life with. The Venetoulis Institute for Local Journalism did buy the
Post-Gazette
from Block Communications. Even with the
Post-Gazette
continuing, the new owners did cut the newsroom by about
40
%,
80
% of whom were strikers. We wanted to get back to the
Post-Gazette
, but now we’re in control of our own destiny in a way that we weren’t during the strike. We’re doing the work ourselves, and it’s fully under our control, which is really amazing.
Alvarez:
What did working and striking at a paper like the
Pittsburgh Post-Gazette
teach you about what a project like the
Pittsburgh Progress
needs and why it needs to exist?
Mellon:
I learned a lot both during the strike and especially after the strike was over. After we had won the strike, and the
Post-Gazette
announced its closure, we had conversations with people in the community. One of the first questions we asked was,
“
What does it mean to lose the
Post-Gazette
? What does it mean to you and your community to lose the
Post-Gazette
newspaper?” At that point, we didn’t know that the Venetoulis Institute was going to step in and buy it. One of the responses really stuck with me. A young woman stood up and said,
“
The closure of the
Post-Gazette
doesn’t mean anything to me because they’ve not been relevant to my community for years.”
Now, as a journalist who spent a good chunk of his professional life reporting on this city, that was heartbreaking to hear. These institutions that I’d given my life to were irrelevant to the communities that had supported us during the strike and that had leaned into our effort. We’re seeing the crumbling of communities all over this country. Newspapers and news organizations have failed in their duty to be a cohesive force, and that’s an issue. How do we solve that? We kicked around several different ideas. When we started talking about a co-op, we saw a lot more people showing up. We’re not going to have people stand up at a town hall and say the
Pittsburgh Progress
is irrelevant to my community. We’re trying to make sure that that does not happen to us. Our way of making sure that happens is having that young woman in the room when we’re making decisions.
Duleba:
I learned things at the
Post-Gazette
besides the skills that I built there. Being on strike, we saw what it was like to be on the other side of business interests overriding journalistic ethics. The coverage of the strike was just insulting. The
Post-Gazette
tried to hide the fact that people weren’t talking to them because [the sources] were holding our picket line. They’re not putting in that the mayor’s not talking to them at all because he’s respecting a picket line. That shades the way that people might perceive that article. They may think that the mayor is running away from accountability on this issue. Being so intimately on the other side of it places us in a great position to poke at what is not being said in these press releases. There’s all this stuff that they’re leaving out that we learn by talking to the working class, the people of Pittsburgh, the regular everyday citizens that are affected by these decisions.
Alvarez:
Tell folks more about what the
Pittsburgh Progress
is, where it’s going, what they’re going to find there, and what they can do to support you.
Mellon:
We launched on Monday. We’re working up to becoming a regular daily publication. And so a lot has happened very quickly. We’ve had to come up with a business plan. We’ve had to come up with bylaws. It wasn’t until a couple of weeks ago that we were able to sit down and think:
“
Oh, wait a minute, if we’re going to publish, we’ve got to have some stories in this damn thing.” So, we put together a slate of stories that we felt matched what we want to be and what we want to do. Our lead story right now is about organized nurses here who are fighting for their contract. That’s a big story in this town, where medical companies have a big footprint. Nurses on the front lines: that’s one of our lead stories. Natalie has a story on third places for the members of the LGBTQ community. We have a review of a new book on WPA workers. We’re really going to lean into high school sports because we’re not interested in covering our millionaire sports heroes. We are interested in covering the sports played by the sons and daughters of the working people of this region.
One of the things I learned working in newspapers as a young man is that weekly small daily newspapers in small towns were part of the fabric of that community. They held the community together by being a voice where people could look at that publication and recognize themselves and their community.
hat’s gone. What we see in a lot of newspapers, the
Post-Gazette
being an example of this, is an institution talking to other institutions. What happens when workers’ voices, regular peoples’ voices are lost? One of our goals is to create a publication in Pittsburgh that does not do that, where people can look at that publication and recognize themselves and recognize a community that they care about and that they’re willing to invest in.
Duleba:
[The stories] build on each other, with the same concepts of building community. I think that as the contraction, consolidation, and gutting by private equity of these local newspapers that serve communities continues, it’ll be the workers who build things back up. We know how to cover our city. We know these communities. We don’t need permission from a rich person to do this work. Let’s do it ourselves.
===
Maximillian Alvarez is editor-in-chief at the Real News Network and host of the podcast
Working People
, available at InTheseTimes.com. He is also the author of
The Work of Living: Working People Talk About Their Lives and the Year the World Broke
.
LACMA data breach last year exposed social security and medical data
Bleeping Computer
www.bleepingcomputer.com
2026-08-25 17:58:14
The Los Angeles County Museum of Art (LACMA) has announced that a breach last year exposed customer and employee information. [...]...
The Los Angeles County Museum of Art (LACMA) has announced that a breach last year exposed customer and employee information.
The museum says that on July 11, 2025, it detected suspicious activity on its systems that had started four days earlier. A month later, the investigation confirmed that the network was compromised.
At the time, the type of exposed data could not be determined, and the first results of the investigation became available in late February 2026.
More than a year after the discovery of the data breach incident, the
museum identified
that the following information may have been accessed by the attacker:
Full name
Date of birth
Social Security number
Driver’s license or government-issued identification number
Partial financial account numbers
Partial payment card information
Health insurance information
Medical information such as provider name, medical treatment, diagnosis, treatment dates, or treatment locations
LACMA says it has notified law enforcement authorities about the incident and sent personalized
data breach notifications
to impacted individuals.
Recipients are recommended to monitor their bank accounts for suspicious activity, consider placing a security freeze or fraud alert on their credit file, and report identity theft attempts to their financial institutions and law enforcement.
The letters include information on enrolling in a one-year identity theft and fraud protection service through Financial Shield, with an enrollment deadline of November 22.
A dedicated phone line has also been set up to provide support and answer questions for impacted individuals.
LACMA is one of the largest art museums in the western United States, housing around 155,000 works spanning 6,000 years of art history. The museum has historically attracted over one million visitors annually.
BleepingComputer has contacted LACMA with questions about the number of impacted individuals, as well as the nature of the attack, but we have not heard back as of publication.
“Crackdown.” “Democratic backsliding.” “Authoritarian grip.” Journalists persecuted, opposition parties crushed—and now, according to the latest eruption from the Western press, Nicaraguan President Daniel Ortega has abolished elections.
The peripheral left offers another interpretation: Ortega is preventing U.S.-backed political organizations implicated in subversion from participating in elections, while Nicaragua has restricted media organizations with subversive ties to Washington amid ongoing U.S. hostility. Whether one approves is beside the point. Nicaragua is behaving as though the United States poses a threat to Nicaraguan sovereignty. How could they possibly have gotten that idea?
First, the elections. During his July 19th address commemorating the Sandinista Revolution, Ortega declared that the era of parties “installed by the Yankees” returning to government was over: “There will be no more elections, there will be no more [elections] through which they can try to seize the government, seize power.” He immediately called for laws erecting a “wall” or “block” against
golpistas
and
vendepatrias
—coup plotters and traitors—adding that “no matter how much money the Yankees give them, they will not succeed.” Western headlines performed emergency surgery and emerged clutching: “There will be no elections.” The missing words alter the diagnosis. Nicaragua will hold elections, and perhaps candidates with ties to Washington will not be allowed to participate—that doesn’t seem all that radical given the context.
Ortega’s crackdown on journalism deserves reconsideration. Western accounts and institutions describe Nicaraguan
journalists
being persecuted, but few ask what those journalists were actually doing. Journalists “silenced” by Ortega hardly constituted some pristine Fourth Estate floating above Nicaraguan politics. Washington poured millions of dollars through USAID, the National Endowment for Democracy, and allied institutions into an opposition-media ecosystem, much of it routed through organizations such as the Violeta Barrios de Chamorro Foundation, supporting and training journalists and outlets including
100% Noticias
and others embedded in the anti-Sandinista milieu. The Chamorro network itself straddled journalism, NGOs and opposition politics, while during the 2018 upheaval sections of this media apparatus did considerably more than observe from the press gallery:
100% Noticias
broadcast sympathetically from the opposition
tranques
,* provided anti-government activists a national platform, and its director Miguel Mora openly advocated a “Noriega-style” intervention to remove Ortega. When the government investigated foreign collusion, it closed outlets and prosecuted some of the figures involved. Western accounts largely began the story there, but foreign financing disappears, political participation becomes journalism, organizations intertwined with the opposition become merely “independent media,” and a confrontation between the Nicaraguan state and a U.S.-supported political-media apparatus is transformed into a familiar dictatorial repression narrative.
Nicaragua has good reason to take American meddling seriously. During the Banana Wars, U.S. Marines occupied the country for much of 1912–33 in what historian Greg Grandin called the United States’ “first Third World quagmire,” until resistance leader Augusto Sandino won a war of attrition, sending occupation forces packing. Washington has a legacy of leaving poor institutions behind in the wake of its occupations, and the Nicaraguan national guard was one of them, serving as the primary instrument of repression in the succeeding decades. Sandino was murdered by National Guard leader Somoza, and the Somoza dynasty followed: four decades of kleptocratic anticommunist family dictatorship.
A civil war unfolded in which Sandinista revolutionaries took power in 1979, at which time they committed an unforgivable crime of improving people’s lives. Literacy campaigns, healthcare, education, agrarian reform: resources began flowing toward ordinary Nicaraguans. Oxfam called Nicaragua exceptional for its government’s commitment to improving the people’s condition and encouraging their participation in development, and gave Washington’s nightmare its proper name: “the threat of a good example.” That a poor country might successfully direct resources toward peasants instead of oligarchs and foreign capital, and that neighboring peasants would notice, was considered a U.S. national security threat.
Washington set about making the example fail by financing the torturous Contra insurgency, plastering the media with disinformation, and squeezing Nicaragua economically. Washington mined Nicaraguan harbors, and when the International Court of Justice found the U.S. in violation of international law and liable for reparations, the U.S. quit the ICJ, vindicating long held suspicions that international law and human rights institutions were designed to police the Global South, not the other way around. Meanwhile, Nicaragua diverted enormous resources from social development into fighting a U.S.-sponsored war, while continuing to make payments on odious debts inherited from the Somozas, to the detriment of ordinary Nicaraguans. In 1990, battered Nicaraguans voted the Sandinistas out, and they left quietly. Daniel Ortega, a first-generation Sandinista revolutionary, returned sixteen years later through the ballot box.
All of which vanishes when Nicaragua appears in American media. Occupation becomes ancient history; the Contras become Cold War trivia; foreign financing becomes philanthropy; regime-change organizations become “civil society”; Washington-funded media become “independent”; and
golpistas
become merely “opposition politicians.”
Remember Russiagate? Americans raged that foreign interference represented an existential assault on democracy. Americans will not tolerate journalists taking money from foreign governments (except Israel) to disseminate stories cultivated by foreign intelligence agencies (except Mossad). Are we that drunk on American exceptionalism, and historically amnesic, that we believe it’s okay when we do it abroad? Americans reserve for themselves an unlimited right to vigilance while demanding extraordinary political permeability from countries whose sovereignty Washington has repeatedly violated. Post-colonial nations subjected to occupation, proxy wars, sanctions, coups and continuing foreign interference must tolerate foreign-funded journalism, NGOs and Trojan-horse political parties catering to classes enriched by the colonial economic order—or be declared authoritarian for exercising the vigilance necessary to preserve their sovereignty. The State Department cries “authoritarianism,” and well-intentioned folks in the imperial core who value a (relatively) free press and some semblance of (oligarchic) electoral democracy are too quick to believe it. Try running an American television network on CCP money while publicly calling for Putin to conduct a “Noriega-style operation” in Washington, and see how philosophical the State Department becomes about press freedom.
===
Richard M. Balzano
is an historian and political analyst peddling truths at several institutions of higher learning, quietly devoted to the art of sedition and comfortably resigned to the peripheral left.
Hackers abuse npm mirrors to host phishing redirect pages
Bleeping Computer
www.bleepingcomputer.com
2026-08-25 17:39:01
Threat actors are abusing npm and its mirrors to host malicious HTML pages that impersonate Cloudflare CAPTCHAs to redirect visitors to attacker-controlled websites. [...]...
Threat actors are abusing npm and its mirrors to host malicious HTML pages that impersonate Cloudflare CAPTCHAs to redirect visitors to attacker-controlled websites.
The technique was previously spotted in July by security researcher
inf0stache
, who found a 'china_airlines' npm package that used a fake Cloudflare verification page to redirect visitors to a malicious domain, and was also reported by
IntelFusions
.
In a later report, OX Security discovered 24 npm packages containing the same malicious HTML page hosted on npm and various mirrors.
However, unlike the typical npm
supply-chain attacks
we've seen lately, installing the packages does not infect a developer's computer with malware or infostealers.
Instead, attackers use the npm registry as free storage for malicious HTML pages, which are then copied by mirroring platforms like UNPKG and npmmirror.
Because some of these platforms let individual files in npm packages be accessed directly in a browser, they effectively turn these developer sites into free web hosting for phishing pages.
"While the malware is simply a single HTML page inside the npm package, and while downloading it wouldn't do harm, the threat actor's use of npm isn't to infect developers who install it, but to use the registry and its mirrors as a safe, validated storage for the malware," explains
OX Security
.
BleepingComputer examined one of the packages identified in the campaign and found that it contained only two files, an index.html page and a package.json file that declared the HTML file as the package's main file.
npm package containing an index.html and package.json file
Source: BleepingComputer
When UNPKG mirrors the package, the HTML file can be opened directly in a browser using a URL such as https://unpkg[.]com/ndmxchdjxn2@1.0.0/index[.]html.
This causes the attacker's HTML to be rendered in the browser from the legitimate unpkg.com domain rather than from infrastructure controlled by the threat actor, potentially bypassing security software that may have blocked a malicious site.
OX says this technique effectively turns npm mirrors into "free frontend hosts for malicious HTML pages and potentially other payloads as well."
Malicious HTML acts as a redirector
The malicious HTML impersonates a Cloudflare security verification page that embeds Cloudflare's legitimate Turnstile CAPTCHA service.
Malicious HTML page loaded from UNPKG
Source: BleepingComputer
Regardless of whether the verification succeeds, the page executes heavily obfuscated JavaScript that redirects the visitor to another site.
OX Security research team lead Moshe Siman Tov Bustan told BleepingComputer that earlier versions redirected to microcloud[.]homes in July and login[.]microsofte[.]live in August. The researchers said some of the earliest July redirects ultimately resolved to the legitimate Microsoft Outlook mail login site (https://outlook.office.com/mail).
BleepingComputer tested one of the malicious pages hosted through UNPKG and confirmed that it still redirects visitors to that domain.
This domain is not currently live, but it may be used to host a fake Microsoft login page.
The researchers say other packages switched to a different redirect method that uses api.keyval.org, a legitimate platform for storing key-value pairs.
According to the researchers, the newer code retrieves an encrypted value from the service, decrypts it in the browser, and then redirects the visitor to the decrypted URL.
This lets the attackers change the redirect URL remotely without modifying or republishing the npm package. At the time of OX's research, the remotely configured destination redirected visitors to the legitimate ChatGPT website.
While OX says the value could be changed at any time to point to ClickFix or other phishing pages, the npm-hosted HTML reviewed by BleepingComputer does not perform a ClickFix attack.
These pages could also redirect visitors to phishing pages, malware downloads, or other attacker-controlled destinations.
OX also warns that npm packages may remain on mirrors after being removed from the official npm registry.
"Threat actors keep finding and using new and novel techniques not just to deliver malware, but to use legitimate infrastructure to store their payloads and data," concluded OX.
The researchers recommend treating direct HTML requests to npm mirror domains as potentially suspicious.
Don’t Coddle For-Profit Insurers—Take Them On!
Published
Paul Krugman Dr Paul Krugman, 2008 Nobel Laureate, speaks at a press conference held by the Securities and Futures Commission in Hong Kong on May 22, 2009. | Google Images/License free
Krugman explained that taxpayers currently pay two-thirds of US
healthcare
costs. It’s not just the costs of
Medicare
,
Medicaid
, the Indian Health Service, the VA, and the
Affordable Care Act
premium subsidies, but also employers deduct their contribution for their employees’ private insurance as a tax-deductible expense, while the employees owe no income tax on the value of employers’ contribution. Maybe that’s a bit wonky, but the point is simple - when we give tax breaks that subsidize heath insurance for employees, then the rest of us taxpayers have to make up the difference.
US taxpayers shelling out 2/3 of the cost of our healthcare system is more per capita than taxpayers in any other nation. Krugman says, ”Much of U.S. healthcare is already ‘socialist’. In fact, the government’s role is so large that U.S. healthcare is better described as partially privatized
socialism
than as anything resembling a free market.“
Krugman goes on, ”How should we think about this system? First of all, is Medicare socialist? Don’t tell anyone, but the way Medicare operates—it covers every senior’s medical expenses, whatever they turn out to be, while being funded by taxes that depend on one’s income—could be summarized by the old Marxist slogan “From each according to his ability, to each according to his need.” And back in 1961, when
Ronald Reagan
was the face of a last-ditch effort by the American Medical Association to block the creation of Medicare, he denounced Medicare as “socialized medicine” and warned that it would destroy our freedom.“
Krugman continues: ”The case for viewing insurers as parasites is strong. Many Medicare benefits are now delivered via
Medicare Advantage
, that is, plans paid for by the government but run through insurance companies. MedPAC, an independent advisory commission, estimates that last year
Medicare Advantage
plans were overpaid by $84 billion, thanks to practices such as “upcoding,” in which patients’ health problems are overstated to get larger sums from Medicare.“
Krugman’s conclusion on August 11: ”So let’s be clear: Abdul El-Sayed’s healthcare platform is perfectly reasonable on the merits of cost, fairness and health efficacy. And with private insurers never more hated, while millions of Americans are losing their health insurance, 2026 may be its time.“
Just three days later and he is back-peddling like crazy. Suddenly,
Medicare for All
is not politically feasible: ”There’s a strong case for a soft transition in which people can choose to be covered by Medicare via a Public Option… Why won’t making the legitimate case that Medicare for All is the best system be enough to win the political argument? The pervasive
corruption
of our political environment by corporate and right-leaning money is part of the answer. Health insurers may be parasites, but parasites make campaign contributions.“
From there, Krugman is in full retreat. He admits ”No major government program is as popular as Medicare, which has an 82 percent favorable rating.“ He continues by noting that ”Americans have strongly negative views, verging on hatred, about the insurance industry.“ Despite that, Krugman now wants a Public Option, or Medicare Buy-In as it is also called, which he claims would be less of a political lift. He describes, ”A healthcare system in which many Americans under 65 buy into Medicare would not immediately deliver all the advantages of full Medicare for All. Some people and employers, despite the disadvantages, might retain private insurance… It would lack the clarity of a system in which every citizen knows that they are entitled to care. But it would be far better than what we currently have. Moreover, a system in which private health insurance is a rump industry, covering a dwindling fraction of the population, would be a better starting point for a full transition to universal coverage… There’s no obvious reason a public option would be any harder to implement than payments to the Medicare Advantage plans offered by private insurers.“
Medicare Advantage is a model for the Medicare Buy In? Remember in Krugman’s August 11 Substack he noted that ”an independent advisory commission estimates that last year Medicare Advantage plans were
overpaid by $84 billion.
“
Medicare Advantage is the poster child for how privatized Medicare is corrupted by private for-profit insurance companies. I’m worried about Krugman’s memory.
Does Krugman remember 2009? We have been down this Public Option/Medicare Buy-In road before.
Does anyone remember the Blue Dog Caucus?
When the Affordable Care Act was being formulated in the summer of 2009, Democrats had a 257 to 178 majority in the House of Representatives, but there was a block of moderate Dems known as the Blue Dogs, and Baron Hill, Indiana’s 9th district Congressman, had a leadership role in the group. It included a number of skeptics about the ACA whose votes were going to be needed. I persuaded Baron to have me make a presentation, along with binders to distribute with the facts, figures and citations about the advantages of a Medicare for All system, even though few if any of them were singe payer supporters.
The
meeting on June 18th
in the Longworth Office Building was well attended, and with my wife Karen Green Stone, we had 20 minutes to make our pitch. They were engaged, had good questions, and let the time run over until they all had to leave to cast a vote. The idea was to present the “ideal system” and then work out the best achievable compromise.
As the ACA took shape in the House, the Public Option was under attack as soon as it was proposed. The entrenched healthcare industry deployed thousands of lobbyists to Capitol Hill to frame the Public Option as a costly “government takeover” and funded studies predicting severe disruptions to insurance markets. They partnered with conservative groups to run intense national advertising campaigns targeting vulnerable lawmakers. The Public Option was amended and weakened repeatedly until the version that passed out of the House was almost unrecognizable.
Then the Senate put it out of its misery. Democratic US Senators like Joe Lieberman of Connecticut and Evan Bayh of Indiana insisted that any Public Option/Medicare Buy-In be removed completely in order for them to provide filibuster-proof support to pass the Senate.
The Public Option proponents had insisted it would “keep insurance companies honest.” They used language similar to Krugman that a Public Option would be an easier way to eventually eliminate private insurance.
How could they think they could pass a bill that was intended to create a slippery slope to eliminate the insurance industry, and somehow the insurers wouldn’t notice, wouldn’t see it as just as much an existential threat as Medicare for All?
In 1998, 20 years before Paul Krugman was awarded his Nobel Prize, he predicted that the internet’s economic influence would be insignificant, “no greater than the fax machine’s,” because “most people have nothing to say to each other.” He has been wrong before.
My life’s goal is to practice medicine in a country where everyone has healthcare, everybody in and nobody out. I think expanding traditional American Medicare is the obvious way to get there. It has already been taking care of the oldest, sickest, most expensive patients for the past 60 years. It makes no sense to take that option off the table before we even start negotiating.
Why not take on the insurance industry and their billionaire backers?
Why not take them on?
===
Rob Stone, M.D. is the Indiana Coordinator for Physicians for a National Health Program.
MSG to Host Hindu Nationalist Paramilitary Leader This Weekend
hellgate
hellgatenyc.com
2026-08-25 17:10:49
Opponents say the event is a meeting of the world's "largest fascist organization."...
In June 2025, Zohran Mamdani kicked off a
conservative firestorm
when he appeared on the Hell Gate and New York Focus mayoral candidate forum and called Indian Prime Minister Narendra Modi a "
war criminal
."
Mamdani said that, as mayor, he wouldn't hold a joint press conference with the Indian leader—a lifelong member of the Rashtriya Swayamsevak Sangh, the far-right, Hindu nationalist paramilitary group—if he ever came to New York City, due to the atrocities that happened under Modi, who was chief minister of Gujarat in 2002 when at least 1,000 Gujarati Muslims were
raped, tortured, and murdered
by local Hindu nationalist mobs.
"My father, his family comes from Gujarat in India, and his family is Muslim," Mamdani
explained at the time
. "I'm Muslim, and Narendra Modi helped to orchestrate what was a mass slaughter of Muslims in Gujarat to the extent that we don't even believe there are Gujarati Muslims anymore." Mamdani added, "This is someone who we should view in the same manner that we do, Benjamin Netanyahu. This is a war criminal."
Modi has taken RSS ideologies into his 12-year governance of India through his commitment to a
Hindu nationalist agenda
, his
curbing of the free press
, and his role in perpetrating alleged
human rights abuses
, including the
2002 Gujarat massacre
. Now, as mayor, Mamdani is facing the fact that the leader of the RSS, the political group that shaped Modi, has booked out Madison Square Garden for a Saturday event—and there's probably nothing he can do about it.
Note:
This is a community fork of
adevinta/maiao
. The original maintainers are no longer at Adevinta and the upstream repository is no longer actively maintained. This fork continues development under
runetes/maiao
.
Gerrit-style code review workflow for GitHub, GitLab, Gitea, Forgejo, Bitbucket Cloud, and Cursor Origin
Maiao brings the power of
stacked pull requests
(or merge requests) to your git hosting provider, enabling you to break large features into small, reviewable commits where each commit becomes its own PR/MR.
What is Maiao?
Maiao provides the
git review
command that:
Creates one PR/MR per commit
in your branch
Stacks PRs/MRs automatically
with proper parent-child dependencies
Registers native stacks
when available (GitHub Stacks, GitLab auto-detected stacks)
Manages fixups elegantly
using
git commit --fixup
Tracks commits via Change-IDs
(using the Gerrit commit-msg hook)
Auto-rebases your stack
when PRs/MRs get merged
Auto-detects your provider
from the remote URL
Supported Providers
Provider
PR/MR type
WIP/Draft
Native stacks
GitHub
Pull Request
API field
Yes (explicit registration)
GitLab
Merge Request
Draft:
title prefix
Yes (auto-detected from target branch, up to 20 MRs)
Gitea
Pull Request
WIP:
title prefix
No
Forgejo/Codeberg
Pull Request
WIP:
title prefix
No
Bitbucket Cloud
Pull Request
Not supported
No
Cursor Origin (beta)
Pull Request
API field
Yes (
parentPullNumber
)
Maiao auto-detects the provider from your remote URL for known hosts (
github.com
,
gitlab.com
,
codeberg.org
,
bitbucket.org
,
origin.cursor.com
). For self-hosted instances, it prompts on first use and saves the choice to
git config maiao.provider
.
Quick Example
# Make multiple commits
git commit -m "Add user authentication"
git commit -m "Add authorization middleware"
git commit -m "Add admin endpoints"# Create stacked PRs/MRs for all commits
git review
Result
: Three PRs/MRs created and stacked:
PR #1:
Add user authentication
→
main
PR #2:
Add authorization middleware
→ PR #1
PR #3:
Add admin endpoints
→ PR #2
Key Benefits
Granular Reviews
: Each commit reviewed independently for faster, focused feedback
Clear History
: One logical change per PR/MR maintains clean git history
Native Stacks
: Integrates with GitHub Stacks and GitLab's auto-detected stacks
Merge Detection
: Stack updates automatically when PRs/MRs merge
Rebase Integration
: Handles upstream changes gracefully
Multi-Provider
: Works across GitHub, GitLab, Gitea, Forgejo, Bitbucket Cloud, and Cursor Origin
Native GitHub Stacks
Maiao treats
GitHub native stacks
as a progressive enhancement. When two or more PRs are pushed, Maiao probes the Stacks API (cached for 24 hours) and registers the PRs as a stack if supported. On older GitHub Enterprise instances the feature is silently skipped — branch-based stacking still works as before.
# Control via git config (default: auto)
git config maiao.useNativeStack auto # use when available, skip otherwise
git config maiao.useNativeStack true# always register; warn if unavailable
git config maiao.useNativeStack false# disable entirely
I was pleasantly surprised and happy to see that my article ‘
Your executable is a SQLite database
’ resonated with people. It is a format I have been thinking about for a while, and the idea seems to have
struck a chord with others.
A quick recap:
SELF
, a format where the program is a SQLite database. We can use
binfmt_misc
to trigger a custom
interpreter that maps the rows in the
segments
table and jumps to the entry point,
and a whole class of binary tooling collapses into SQL.
What keeps surprising me is how having the file format be a SQLite database keeps collapsing everything into SQL. One idea that was immediately evident to myself and others through comments: If the executable is a database, and a database is something you can write to, can the
running program
use it to also store its state? 🤔
Yes! 🤯
We can collapse not only a complete distribution but all the state for every application into a single file, alleviating the need for
/var/
or
/tmp/
or
/home/
or any other filesystem. The program can store its own state in the same file it is running from, and it can do so transactionally.
self-httpd
is a proof-of-concept webserver that does exactly that. It is a single file program executed from a database. The file contains the program, the website, the routes and all the visitor logs. All state is updated
in the same SQLite
file as the program itself.
# Our server is a single file, and it is a SQLite database
$file server
server: SQLite 3.x database, application id 1397050438, ...
$./server --journal wal 8080
self-httpd: serving 3 routes out of /srv/self/server
self-httpd: listening on http://0.0.0.0:8080 with 4 workers
$curl -s localhost:8080 | head-1<!doctype html>
# nobody has pressed the button on that page yet
$sqlite3 server 'SELECT count(*) FROM presses'0
$curl -s-X POST -d press localhost:8080/api/press
{"presses":1,"button":"press"}
# the application data is inside the same database
$sqlite3 server 'SELECT id, at, button FROM presses'1|2026-08-25 03:11:28|press
# so was the GET that fetched the page in the first place
$sqlite3 server 'SELECT count(*) AS n, path
FROM visits GROUP BY path'
1|/
1|/api/press
This web-server is live at
https://selfdb.exe.xyz
.
1
1
If the site is not working for you, sorry. I deployed it on their smallest tier.
I included a screenshot of the site just in case for posterity!
It is one file, a SQLite database, and it is also the server. It is the website, it is the program, and it is the visitor log and state.
SELF is many ways is less brilliant. It relies on simpler tools to achieve something
very similar but I’m amazed how much collapses into a single domain: SQL.
Whereas, redbean needs to include an archive format (ZIP), the database
itself is the container. Redbean provides Lua hooks to manipulate the responses,
whereas the equivalent in SELF is a new row in a
handlers
table.
INSERTINTOhandlersVALUES('/api/busiest','SELECT path, count(*)
FROM visits GROUP BY path
ORDER BY 2 DESC LIMIT 5');
If redbean is an
Actually Portable Executable
, this is an
Actually Queryable Executable
. One of them runs anywhere, the other one you can
SELECT
from.
For now, you cannot use
/proc/self/exe
.
2
2
Funny enough, the VFS Linux maintainer recently landed support for
transparent
binfmt_misc
in the kernel, which would make
/proc/self/exe
point to the original file. I wrote
about it here
.
When
binfmt_misc
matches, the kernel does
not
execve
your file at all , it execs the
interpreter
, and hands it the
path:
self-exec
passes
argv + 1
through to the program, so the program’s
argv[0]
is the path to the executable itself. The interpreter also releases its SQLite connection before jumping to the entry point, so the program can open its own file and query it.
intmain(intargc,char**argv){sqlite3*db;/* the file the kernel just executed */sqlite3_open(argv[0],&db);...}
This is pretty unrestricted and
magical
. You can read your own segment table or a new table next to it. The writes persist across invocations. ✨
The web-server for our example is three tables:
routes
,
visits
and
presses
.
We will record every visitor and every button press.
-- the content, added to the executable-- after it is compiled and linkedCREATETABLEroutes(pathTEXTPRIMARYKEY,mimeTEXT,bodyBLOB);-- what the site collects, written back -- into the executable while it runsCREATETABLEvisits(idINTEGERPRIMARYKEY,atTEXT,uaTEXT,pathTEXT);CREATETABLEpresses(idINTEGERPRIMARYKEY,atTEXT,buttonTEXT);
Building the application feels very unremarkable and familiar. We execute DDL to
create the application schema and
INSERT
the website.
# an ordinary ELF for now
$cc -O2 server.c -o server.elf $(pkg-config --libs sqlite3)# the same program, as rows
$elf2self server.elf server
$sqlite3 server < site/schema.sql
$sqlite3 server "INSERT INTO routes VALUES
('/index.html', 'text/html',
readfile('site/index.html'))"
The asset pipeline looks like a “normal webserver” until you realize it’s querying itself
with SQL for the content. Oh, and “itself” is a SQLite database.
The page at
https://selfdb.exe.xyz
shows a lot of fun additional information besides
the visitor log and button presses. I included segments, symbols and relocations. Those are not baked in at built time, they are queried from itself while running.
Once you have the capability to do ACID transactions, interesting things become possible.
The webserver can edit its own content while it is running, and the edits are transactional. The
UPDATE
is committed to the same file as the program, and a
ROLLBACK
undoes it.
# change the running site. no restart, no reload, no deploy
$sqlite3 server "UPDATE routes SET body = readfile('new.html')
WHERE path = '/index.html'"
$curl -s localhost:8080
<!doctype html><h1>edited in place</h1>
Since the file format is SQLite we can also take advantage of the cornicopea of tooling
that exists.
sqldiff
will tell you exactly what a “deploy did”, this can let us audit and identify changes between two versions of the same program.
What about full-text search?
FTS5
is a
CREATE VIRTUAL TABLE
away, so a webserver can index its own pages, inside itself, and still be a webserver afterwards:
$sqlite3 server "CREATE VIRTUAL TABLE search USING fts5(path, body);
INSERT INTO search SELECT path, body FROM routes
WHERE mime LIKE 'text/%'"
$sqlite3 server "SELECT path, snippet(search, 1, '[', ']', '...', 6)
FROM search WHERE search MATCH 'transaction'"
/index.html|...Editing is a [transaction].</h2>
# still runs. it just knows about itself now
$./server 8080
None of that is machinery I wrote. It is machinery SQLite already has, that a
program inherits for free by being a database.
All the rage
was
static site generators, but the future is an
actually queryable executable
.
I am really enjoying the simplicity that seems to be popular and heralded by
products like
exe.dev
. People often yearn to go back to the
“good old days” of
scp
and
ssh
to deploy a single file, and SELF is a format that makes that possible again, but better! Rather than just shipping an archive of PHP, we ship the whole system or application closure down to the
libc
.
How would we make a deployment if the data and code is intertwined?
We can think of a redeploy as a data migration, and the migration
is two
INSERT ... SELECT
, because the program and its data are the same
file!
-- the running deploymentATTACH'/srv/self/server'ASold;INSERTINTOvisits(at,ua,path)SELECTat,ua,pathFROMold.visits;INSERTINTOpresses(at,button)SELECTat,buttonFROMold.presses;
Swap the file, restart, and the visitor log survives the new build.
You can even do this for the program itself in reverse. The
segments
table is just like any other table. 😈
https://selfdb.exe.xyz
has a button on it. Pressing it is an
INSERT
into
the executable that served you the page
The code is at
fzakaria/selfdb
if you
are curious. It is probably a bit
half-baked
, and definitely AI assisted, but that’s OK with me. I wanted to explore this idea and see if it was feasible and what might be possible.
I think I only scratched the surface of some of the fun possibilities. I am curious to see what others might do with it, and I would love to see a few more examples of “actually queryable executables” in the wild.
3
3
One idea a friend suggested was discovery over multicase DNS to spread
program updates via transactions.
Turns out that when we re-envision what we considered to be simply a
byte layout
specification was actually better off being a
database
, a lot of machinery we have been using for decades simply stops being necessary. The program is the database, and the database is the program.
“Never, ever underestimate the importance of having fun”
– Randy Pausch
Show HN: TeXbrain, a LaTeX editor that runs pdfTeX in the browser via WASM
I built this because I was tired of paying for features that should be free. I wrote my thesis last year in LaTeX and spent more time fighting tooling than actually writing. Online solutions lock git sync behind a paywall. Local setups break between machines. I wanted something that just works. Open a browser, write LaTeX, get a PDF.
So I built it.
What it does
texbrain is a full LaTeX editor that compiles your
.tex
files to PDF directly in the browser. There is no backend. No server processing your files. Everything (the editor, the compiler, the git client) runs client-side.
You can open a local project folder, edit your files, see the PDF update, commit your changes, and push to GitHub. All from one tab.
Features
LaTeX compilation in the browser.
Uses a WebAssembly port of pdfTeX (SwiftLaTeX). Your
.tex
files are compiled to PDF without ever leaving your machine. Packages are loaded on demand and cached locally, so the first compile only downloads what your document actually uses. Recompilations take 1 to 5 seconds depending on project complexity.
Most of CTAN, loaded on demand.
Common packages ship with the app. Anything else (
memoir
,
abntex2
, KOMA-Script, you name it) is resolved automatically from a TeX Live mirror the first time a document needs it, then cached locally for offline use.
Live PDF preview.
Rendered with pdf.js. Multi-page, zoomable, with text selection.
Full git integration.
Clone repos, create branches, stage files, commit, push, pull, merge. All powered by isomorphic-git running in the browser. No CLI needed.
Local file system access.
Uses the File System Access API to read and write directly to your project folder on disk (Chrome/Edge).
Multi-file projects.
File tree, tabs, drag-and-drop. Supports
.tex
,
.bib
,
.sty
,
.cls
and more.
Command palette.
Quick access to actions via keyboard shortcut.
Snippet picker.
Math environments, document structures, Greek letters, common commands. Searchable and categorized.
Works offline.
Once loaded, the app works without an internet connection. Compilation is local, editing is local. Packages you've compiled with before are cached; only a package you've never used needs the network once.
Project templates.
Start from scratch or pick a template (article, thesis, beamer, report, CV, letter, minimal).
How it works under the hood
There's no magic and no backend.
Editor.
Built on
CodeMirror 6
with a custom LaTeX grammar (Lezer parser), autocomplete provider, and theme system. The editor supports multiple open files via tabs and syncs content with both the local filesystem and the in-memory git working tree.
Compiler.
LaTeX compilation uses
SwiftLaTeX
's pdfTeX engine compiled to WebAssembly. The engine runs in a memory filesystem (MEMFS), where your project files are written before each compilation. When the engine asks for a file it doesn't have (a class, package, font, ...), the service worker resolves it through a chain: previously cached files first, then the package subset bundled with the app, then a TeX Live mirror (a texmf-dist mirror on jsDelivr, with a community SwiftLaTeX server as fallback). Every resolved file is stored in the browser's cache storage, so each package is downloaded at most once. After the first successful compile, the bundled subset is also prefetched in the background so the core package set works offline.
Git.
All git operations use
isomorphic-git
, a pure JavaScript implementation of git. The repository lives in an in-memory filesystem (
LightningFS
) backed by IndexedDB. Your project files are synced between the local filesystem and the git working tree. Remote operations (push/pull/clone) go through a CORS proxy since browsers can't speak the git protocol directly.
PDF viewer.
Rendered with
pdf.js
, Mozilla's PDF rendering library. Supports multi-page rendering with a text layer for selection and search.
File system.
The app uses the
File System Access API
to read/write your actual files on disk. This requires a Chromium-based browser (Chrome, Edge, Arc, Brave). For other browsers, there's a fallback using the Origin Private File System (OPFS).
Frontend.
SvelteKit
with the static adapter. The entire app is pre-built to static HTML/CSS/JS and deployed to GitHub Pages. No SSR, no API routes, no server.
Tailwind CSS
handles styling.
Known limitations
pdfTeX only.
No XeTeX or LuaTeX, so
fontspec
,
polyglossia
and anything else that needs them won't compile.
No bibtex or biber.
The engine doesn't ship either. Documents using
biblatex
get a plain
thebibliography
generated from the
.bib
file, so references show up but the citation style is ignored. Classic
bibtex
workflows need a
.bbl
in the project. A real bibtex in WASM is next on the list.
TeX Live 2020 era.
Packages are pinned to the same era as the engine's format file, so newer package versions aren't available.
Git remotes need a CORS proxy.
Browsers can't speak the git protocol directly. The default proxy is configurable, see below.
Direct folder access is Chromium only.
Firefox and Safari fall back to a virtual filesystem, see
Browser support
.
Security and privacy
Everything runs in your browser. Your files never leave your machine unless you explicitly push to a remote.
No telemetry, no analytics, no tracking.
No accounts, no cookies, no data collection.
Git authentication tokens are stored in your browser's localStorage. They never touch a server I control.
LaTeX compilation happens in a WebAssembly sandbox. There are no shell commands being executed. No
pdflatex
, no
exec()
, no
spawn()
.
Git operations use a JavaScript library, not CLI commands. No command injection is possible.
The CORS proxy for git remotes is a known trade-off. By default it uses
cors.isomorphic-git.org
(the isomorphic-git project's public proxy). You can point it at your own if you prefer.
Packages that aren't bundled are fetched from public TeX Live mirrors on demand. Only package filenames are sent, never your document content. Fetched files are cached locally, so this happens once per package. The fallback server can be changed or disabled entirely via the
texliveMirror
preference (empty string turns it off).
LaTeX and TeX are free and open-source software. This project uses them. It doesn't redistribute or modify their source.
Tech stack
Layer
Technology
Framework
Svelte 5 + SvelteKit (static adapter)
Editor
CodeMirror 6 + custom LaTeX language support
Compiler
pdfTeX via WebAssembly (SwiftLaTeX)
Git
isomorphic-git + LightningFS
PDF
pdf.js
Styling
Tailwind CSS 4
Language
TypeScript
Deployment
GitHub Pages
Running locally
git clone https://github.com/swimmingbrain/texbrain.git
cd texbrain
pnpm install
pnpm dev
Open
http://localhost:5173
in Chrome or Edge.
Browser support
Full functionality requires the File System Access API, which is available in Chromium-based browsers (Chrome, Edge, Arc, Brave, Opera). Firefox and Safari can still use the editor with the virtual filesystem fallback, but won't be able to read/write directly to local folders.
python has 6 pre-declared "constants":
True
,
False
,
None
,
__debug__
,
Ellipsis
(or equivalently
...
), and
NotImplemented
. but they all behave slightly differently, for some reason.
True
,
False
, and
None
True
,
False
, and
None
are keywords. they aren't identifiers, they're just straight up their own lexical tokens. which is really weird; nothing else is like this in python. usually stuff is resolved during regular name resolution, not in the lexer itself.
an interesting side effect of this is that expressions like
x.True
raise a
SyntaxError
. i'm curious as to what the rationale was for this decision (if there was one).
there's some more interesting stuff with these constants, but i'll get to it later, since it ties in with the other constants.
__debug__
__debug__
is a boolean constant: it's normally
True
, but when running with
-O
, it's
False
. the idea is similar to how
assert
is disabled in non-debug builds: you can wrap code in
if __debug__
if the check would be too expensive in an "optimized" build, or something.
__debug__
is really interesting though, because although it's a normal identifier (unlike
True
,
False
, and
None
), it's the only identifier in the language which can't be assigned to:
>>> __debug__ = 67
File "", line 1
SyntaxError: cannot assign to __debug__
you can't even assign to it as an attribute:
>>> x.__debug__ = 67
File "", line 1
SyntaxError: cannot assign to __debug__
again, no other identifier behaves like this. this is a true special case.
but because it's not a keyword, it behaves slightly differently to
True
,
False
, and
None
:
x.__debug__
raises
AttributeError
(rather than
SyntaxError
), since it's syntactically valid; it's just looking up an attribute which doesn't exist.
interestingly, there's also a special error message for attempting to delete
__debug__
(despite the fact that this would raise a
NameError
anyway if not for the special case), but this
doesn't
apply for deleting an attribute named
__debug__
:
>>> del __debug__
File "", line 1
SyntaxError: cannot delete __debug__
>>> del x.__debug__
Traceback (most recent call last):
File "", line 1, in
NameError: name 'x' is not defined
if
x
were defined, an
AttributeError
would be raised instead. in either case, it's not a
SyntaxError
(unlike assignment), for some reason.
tangent:
SyntaxError
is a lie
speaking of errors: assigning to
__debug__
is one of only a few cases i'm aware of where a
SyntaxError
is raised despite something not actually being invalid syntax. here, you can confirm it yourself:
>>> assert (__debug__ := 67)
running that assert in a debug build raises a
SyntaxError
, but with
-O
, the assertion is never compiled, and so no exception is raised.
two other instances of this are using
yield
or
await
outside of a function:
>>> assert (yield)
>>> assert (await 67)
Ellipsis
and
NotImplemented
Ellipsis
and
NotImplemented
are documented in the "constants" section of the reference, but unlike the other 4 constants, they aren't "real" constants. they're just normal builtins, so they can be shadowed by globals:
>>> NotImplemented = 67
>>> NotImplemented
67
again, i'm curious about the rationale here. why is it that these aren't special, but the other constants are?
overwriting constants
here's something interesting: despite being lexical tokens,
True
,
False
, and
None
also exist as normal builtins:
so
__debug__
can
sorta
be assigned to, but despite not being a lexical token, it's special cased just like
True
,
False
, and
None
: its value is unaffected by changes to the builtins module. so it really is a constant!
Ellipsis
and
NotImplemented
are, once again, not actually constants:
A real shame. Even if you put all the political arguments aside it sucks when a site requires you to log in before you can read content on it. For me that’ll mean I just don’t read content on there any more. These days I don’t think it’ll be much of a loss.
Yeah, it’s connected to Nitter.
I had a number of bookmarked X accounts I would check in on via xcancel. I’ll keep them for now but I assume they’re done for.
I have zero desire to ever crate an X account. Keep closing doors, Elon, and watch usage drop even more than it already has.
I don't understand being so emotionally attached to a personality to virtue signal about everything they're connected to. I'm no fan of the guy itself for many reasons, but it's just a service like any other, you either use it or you don't.
I assure you that I human and never, ever, write EDT in a conversation. My phone even tries to autocorrect it to EST
You need an account to access X. Change the URL to xcancel and you can view these accounts.
It also looks like X requires a Google or Apple account to sign up if you don’t use your phone number. I’m not linking any of that to the X cesspool.
When str.lower() is a security vulnerability in Python – Seth Larson
Some internet standards only support ASCII characters, but the world uses
much more than the Latin alphabet. Thus, a mapping from Unicode to
ASCII for use in domain names is required.
NamePrep
was part of that solution,
defined in
RFC 3491
as a profile of StringPrep,
and is crucially a component of Internationalizing Domain Names in Applications
(IDNA), also known as “IDNA 2003”. The StringPrep algorithm is defined in
RFC 3454
. IDNA 2003
has been obsoleted by IDNA 2008 defined in
RFC
5890
,
5891
,
5892
, and
5893
.
Python supports IDNA 2003 through the
idna
codec (
str.encode('idna')
) and
IDNA 2008 is supported by the
idna
package on the Python package Index
.
Python's implementation of StringPrep is implemented in the
stringprep
module
in the standard library. In general, you should be using the
idna
package (IDNA 2008)
and not
.encode("idna")
(IDNA 2003), but sometimes you
do need the older behavior.
StringPrep defines the “case folding” step (case folding is approximately “how to lowercase/uppercase a codepoint”) in
Section 3.2
, enabling case-insensitive
comparisons of strings, by mapping all characters through mapping
tables B.2
and
B.3
.
B.2 is effectively
str.lower()
, lowercasing all characters according to
Unicode rules and B.3 contains the exceptions. The Python code implementing
this (and assuming B.3 table is captured correctly) is the following code below:
And that might seem fine... and the title probably gave it away already.
The
str.lower()
call in this function is a vulnerability!
Why? Because
str
uses whatever Unicode data that the particular Python
interpreter is shipped with, you can figure out what Unicode version your
Python interpreter uses by accessing
unicodedata.unidata_version
:
There's also a database of Unicode 3.2.0 data available on every version
of Python (
unicodedata.ucd_3_2_0
) specifically for the StringPrep and IDNA algorithms:
$ grep -I "ucd_3_2_0" -R Lib/
Lib/stringprep.py:from unicodedata import ucd_3_2_0 as unicodedata
Lib/encodings/idna.py:from unicodedata import ucd_3_2_0 as unicodedata
This is important! StringPrep depends on this specific version of Unicode
to operate consistently, the B.2 and B.3 tables in RFC 3454 are essentially
Unicode 3.2.0 case-folding rules encoded into
a table. So we need to use Unicode 3.2.0 case-folding rules, not newer
Unicode case-folding rules. This is why calling
str.lower()
represents
a difference in the implementation and the specification,
and therefore a vulnerability:
# RFC 3454 compliant value ('Ꭰ' is U+13A0)>>>"ᎠᎠ".encode("idna")'xn--58da'# Value if using Unicode 17.0.0 case-folding>>>"ᎠᎠ".encode("idna")'xn--kz9aa'
The fix was to create new exceptions so that
str.lower()
would behave
as if it was using Unicode 3.2.0 for only particular function. So, we
go through
each Unicode codepoint
and record when the behavior of
str.lower()
is different when comparing the Unicode version shipped with Python and Unicode 3.2.0.
And that's all, now IDNA 2003 is consistent with the specification.
My work as the Security Developer-in-Residence at the
Python Software Foundation
is sponsored
by
Alpha-Omega
. Thanks to Alpha-Omega for supporting
security in the Python ecosystem.
My hobby: following GOV.UK to look for interesting announcements.
Today was an update on the MOD’s Rapid AI Delivery
Taskforce
which was previously announced in June during London Tech
Week.
I like this line: “Success is measured in operational advantage delivered, not technology demonstrated.” To ...
I like this line: “Success is measured in operational advantage delivered, not technology demonstrated.” To me it recalls “Working software is the primary measure of progress” from
Principles behind the Agile Manifesto
– if you understand “working” to mean “working in production”. Which I do.
For anyone interested in suggesting ideas to the taskforce, the four
operational challenge areas include:
Machine assistance for handling and interpreting huge volumes of data
would probably benefit decision advantage and interpretation of a
crowded EM spectrum, but this is hopefully(?) more than just LLMs. Of
course, there’s more to AI than large language models… right?
I worry that “planning and automation” might amount to “generating
large amounts of
text
faster”. Nothing could possibly go wrong with this.
mklinux-v7.0-mk2 released
Linux Weekly News
lwn.net
2026-08-25 16:34:31
For people who would like to experiment with the multi-kernel Linux concept, Cong Wang has
announced the
release of mklinux v7.0-mk2.
mklinux lets one machine run several independent Linux kernels at
the same time on bare metal, without a hypervisor. A host kernel
owns a pool of CPUs, memory an...
mklinux lets one machine run several independent Linux kernels at
the same time on bare metal, without a hypervisor. A host kernel
owns a pool of CPUs, memory and PCI devices, carves that pool into
instances, and boots a spawn kernel into each instance through
kexec_file_load(). Every spawn kernel runs natively on its own
CPUs, its own physical memory and its own devices. Nothing is
emulated and nothing is trapped; the only thing shared is what you
choose to share.
Note that this is not the old
MkLinux
, which was a port to PowerPC
Macintosh systems.
AnonyMousKIT PhaaS uses voice AI agents to phish iPhone passcodes
Bleeping Computer
www.bleepingcomputer.com
2026-08-25 16:25:26
A newly uncovered phishing-as-a-service (PhaaS) platform called AnonyMousKIT automates the retrieval of codes used to unlock stolen Apple devices and disable the Activation Lock feature. [...]...
A newly uncovered phishing-as-a-service (PhaaS) platform called AnonyMousKIT automates the retrieval of codes used to unlock stolen Apple devices and disable the Activation Lock feature.
The illegal service has been active since early 2024 and is powering a structured ecosystem that sells stolen iPhones, harvests Apple IDs, accesses iCloud backups, and Keychain credentials.
Researchers at threat intelligence platform SOCRadar took advantage of the platform operator's use of bare relative paths to gather information on how the service works, its operators, and infrastructure.
SOCRadar found that AnonyMousKIT is connected to 506 domains and is fueling a sprawling business with 168 storefront brands acting as resellers.
Overview of the operation
Source: SOCRadar
The researchers recovered records of 200 calls made to victims between August 2025 and May 2026, using 55 distinct interaction transcripts handled by a voice AI agent operating under five personas.
SOCRadar notes that the calls cost the operator about $0.10 per attempt, adding that 90% of the calls were made to Brazil.
The AnonyMousKIT panel
Source: SOCRadar
Retrieving unlocking codes
Apple's Activation Lock feature activates automatically when the Find My tracking service is turned on, and links the iPhone device to the owner’s Apple Account.
Even if a stolen device is factory-reset, it remains linked to the original owner's account and requires a valid authorization code during first setup before it can be used.
Because of this protection feature, many stolen iPhones are sold for parts. However, their value increases significantly if they can be unlocked, especially when sensitive data belonging to the owner can also be recovered.
AnonyMousKIT retrieves information from stolen devices, such as the owner’s contact information supplied through the
Lost Mode feature
, and uses it to contact the owner through email, SMS, WhatsApp, or a phone call.
The phishing messages impersonate Apple and claim that the missing device has been located, providing the correct model and IMEI details to make the email appear legitimate.
Phishing email
Source: SOCRadar
The email takes the victim to a fake Find My or Apple page where they are prompted to enter their device passcode, Apple Account credentials, and the two-factor authentication code.
In some cases examined by SOCRadar, an AI agent with an “Alice from Apple Support” persona informs victims that someone trying to unlock the phone brought it to an Apple store, where the device was retained.
The AI agent then asks the victim to confirm ownership by dictating the passcode, then directs them to the phishing page.
Once the threat actors obtain those codes, they can access the victim's personal data, factory reset the device, and remove it from the Find My app before selling it.
Attack chain
Source: SOCRadar
A compromised Apple ID could expose iCloud backups, Keychain passwords, work email, and other corporate information stored on personal or employer-issued Apple devices,
SOCRadar warns
.
The researchers found that a small percentage of the emails from the platform were sent to government and corporate organizations.
SOCRadar reports that the campaigns facilitated by the AnonuMousKIT had a global footprint, but were more concentrated in South Africa, Indonesia, Italy, India, Kenya, and Brazil.
Conservative Groups Side With Minneapolis Protesters Against Trump Crackdown
Intercept
theintercept.com
2026-08-25 16:10:42
Right-leaning and libertarian groups told the court that ICE engaged in illegal “ideological targeting” of the left in the Minneapolis 15 case.
The post Conservative Groups Side With Minneapolis Protesters Against Trump Crackdown appeared first on The Intercept....
A trio of
conservative and libertarian-leaning groups have asked a federal judge to force the disclosure of confidential files about undercover agents from U.S. Immigration and Customs Enforcement infiltrating left-wing protest groups in Minneapolis.
The Cato Institute, the Foundation for Individual Rights and Expression, and the Society for the Rule of Law filed a friend-of-the-court brief on Tuesday arguing that the Trump administration illegally targeted protesters based on their ideology.
A wide-ranging ICE investigation in the Twin Cities resulted in the
June indictment of the protesters
, widely known as the Minneapolis 15, for allegedly using criminal methods to try to block the administration’s crackdown on immigrants.
The defendants were “members and associates” of Direct Action Minnesota, a protest group that used aggressive actions to disrupt the crackdown, according to the indictment.
Yet a court filing from the defense earlier this month revealed that
ICE sent undercover agents to spy
on a much broader array of groups, including mainstream organizations such as local labor unions and the youth-led
Sunrise Movement
.
The defendants filed a motion asking the judge overseeing the case to force the disclosure of even more files, alleging that they will show that the government illegally targeted left-wing protesters for their politics rather than their alleged crimes.
On Tuesday, the right and libertarian-leaning groups came to the left-wing protesters’ aid with
the friend-of-the-court brief
. The groups, which are represented by the legal nonprofit Protect Democracy, argue that the facts revealed so far support the defendants’ claims.
The groups pointed out that some of the government’s own files say the origins of the investigation into left-wing protesters lies in a memo that President Donald Trump issued after the
assassination
of
right-wing
activist
Charlie Kirk
.
Known as National Security Presidential Memorandum 7, or NSPM-7, the memo called for a
crackdown on groups
espousing “anti-Americanism, anti-capitalism, and anti-Christianity,”
accusing the groups of terrorism
and political violence.
“The limited public disclosures here confirm the investigation for this case originated under NSPM-7,” the groups said. “Those disclosures also indicate the investigation was part of a larger strategy to target those who espoused views opposed to immigration enforcement and engaged in associational activity disfavored by the government. NSPM-7 effectively uses the domestic terrorism label to justify criminal investigations into disfavored groups that would not otherwise be targeted.”
U.S. Magistrate Judge David Schultz is set to consider the defendants’ request to force the government to hand over more confidential files at a court hearing on Thursday.
Federal prosecutors
filed a motion
opposing the release of more files last week, arguing that they have already turned over more evidence than legally required and the defendants have not met the high legal burden of showing that they were the targets of selective prosecution.
Prosecutors argued that the actions of alleged members of Direct Action Minnesota, or DAMN, who are accused of blockading a federal building and tailing federal agents to their homes, were a far cry from the thousands of “peaceful” protesters who took to the streets earlier this year after the
killings of Renee Nicole Good and Alex Pretti
.
“In this case, the defendants actively conspired to shut down a federal facility and they were successful on at least two occasions,” prosecutors said. “In fact, DAMN members were openly hostile and critical of individuals who advocated for peaceful, nonviolent protests.”
When the Aspen Skiing Company wanted to raise its lift ticket prices from $10 to $12 in 1975, it had to ask the US Forest Service for permission.
When Aspen residents wanted to fight the proposed price increase, they wrote letters to their local forest supervisor.
That’s the way ski business was done half a century ago: through a federal intermediary. Most ski resorts in the western United States operate under Forest Service permits, and in the 1970s, politicians, national forest employees, skiers, and ski resort owners all recognized that the agency had a mandate to regulate the prices charged by private companies on public land.
“These guys [ski company managers] would come in with their hat in their hand, literally, and be as polite as possible and say, ‘Can we raise our ticket price fifty cents or a dollar,’” recalled Erik Martin, a ski resort specialist in the 1970s for White River National Forest, which manages land used by the four Aspen-Snowmass area resorts.
At the time, ski areas had to renew a required operating permit with the Forest Service annually, and federal employees like Martin understood that stopping unreasonable rate hikes was part of the job.
“We controlled everything. They were
our
ski areas,” Martin told historian Michael Childers for his 2012
book
Colorado Powder Keg: Ski Resorts and the Environmental Movement.
In 1975, Martin’s office was flooded with mail opposing Aspen’s proposed 20% lift ticket increase. U.S. Sen. Floyd Haskell, a Democrat from Colorado, took note of the controversy and demanded action as well. In the end, the Forest Service decided that Aspen could only raise prices by 10%, from $10 to $11.
Adjusted for inflation, the $11 lift ticket would have cost around $66 in 2026 dollars. A one-day ticket to Aspen costs $254 today. Vail, which had the same rates as Aspen in the mid-70s, is charging up to $356 for a day ticket this season, a 436% increase from its inflation-adjusted rates in 1975.
Although the Forest Service technically still has the ability to control prices at most ski resorts, the agency’s regulatory will has atrophied. Skiers angry about high parking fees, overpriced cafeteria lunches, long lift lines, and the disappearance of independent resorts may plaster lift poles with “Vail Sucks” stickers, but almost nobody thinks to demand action from their local Forest Service supervisor anymore.
What changed over the last fifty years? Industry deregulation that began under President Jimmy Carter and was embraced by subsequent administrations has allowed the ski industry to move ever closer to a duopoly — all while skiing costs rise and the Forest Service sits on its hands.
Some of the first ski areas in the western US were built on public lands with public funds and were publicly owned. In the Rocky Mountains above Denver, Franklin Delano Roosevelt’s Work Progress Administration and Civilian Conservation Corps, both cornerstones of the New Deal, cleared ski trails, built lodges, and set up rope tows in the 1930s. Berthoud Pass saw the construction of a government-owned ski lodge in 1938, complete with dining facilities, dorms, and private rooms. A resort in Winter Park opened soon afterwards with funding from the WPA and the City of Denver, the latter of which still owns Winter Park.
After World War II, when skiing soldiers trained in the US Army’s Tenth Mountain Division started returning home, the ski industry began to modernize with T-bars and chairlifts. The federal government largely gave up the operation of ski facilities, but it still strictly regulated resorts built on public land, limiting the number of new ski areas that were allowed to open and overseeing development.
Skiing saw a rapid growth in popularity throughout the 50s and 60s as hollowed-out mining towns like Aspen began to transform into winter destinations. Vail Resort opened in 1962 and developers quickly built a base village in what had been a rural ranching valley.
But even as skiing began to attract a wealthier clientele, it was widely recognized that the growth of the industry was possible thanks to federal public lands — and that the federal government was responsible for keeping ski resorts affordable to the public.
As part of the fight over the proposed lift ticket increases in 1975, Sen. Floyd Haskell asked the Forest Service to allow him to review the financial information from the ski resorts that were seeking increases. The Forest Service said the documents were confidential.
“It was inconceivable to me that a Government agency could base a decision which so fundamentally affects the leisure lives of citizens on information which it refuses to make public,” recalled Haskell.
Haskell drafted a bill in 1976 that would have required ski companies to disclose financial information. It would have also strengthened environmental standards and required public hearings over ski rate increases. Haskell hoped to ensure that ticket prices would not be “unreasonable” nor would they “unduly restrict access to the facility” for any “consumer class.”
“I firmly believe that the local family skier is becoming an endangered species on our publicly owned ski slopes,” he said at
a Senate subcommittee hearing in 1977
.
That phrase, “publicly owned ski slopes,” was at the heart of the conversation at the time. Haskell contended that ski companies should remember they have the “privilege of pursuing private gain on public lands.” The purpose of the permits, he continued, is not to generate profits for ski companies but to provide “high-quality services at a reasonable cost to the owners of that resource: the public.”
Colorado state representative for the Aspen area, Nancy Dick, agreed. “Let us remember the public owns the national forest land,” she said at the hearing. By operating on public land, companies should serve the public interest. And the public, she said, has an interest in the cost of lift tickets.
But during the same period the ski industry was mobilizing a counteroffensive, arguing that lift ticket prices should be deregulated. The Forest Service under Jimmy Carter, who was engaged in a deregulatory spree across the US economy, hired consultants with ties to the ski industry to write a report, which concluded lift ticket prices would be controlled by competition if the feds relaxed oversight. The market would prevent unreasonable price hikes.
Haskell’s bill passed the Senate but never became law. The Forest Service directed supervisors to roll back regulation of prices, and lift tickets jumped by up to 25% the following season. In Ketchum, Idaho, skiers outraged over a proposed 18% increase at Sun Valley Resort formed a group known as the Skiflation Committee. The nonprofit excoriated the consultants’ report that had advised deregulation and demanded the Forest Service step back in to control prices. “The essentials of free enterprise don’t exist in the ski industry,” a Skiflation member told
The Idaho Statesman
. “We’re going to look out for this community because the Forest Service won’t.” They soon had an ally in Idaho Gov. John Evans, who joined Skiflation’s calls for federal action.
Due in part to the outcry, the Carter administration briefly re-regulated ski prices, setting a 9.5% annual increase cap in the late 70s as part of his inflation-control policies, but under Ronald Reagan, costs for skiers continued to rise.
In 1986, Reagan signed the National Forest Ski Area Permit Act into law, which allowed ski areas to operate under the 40-year permits that most hold today. The bill formalized the fee structure for ski companies, which the Government Accountability Office
has
repeatedly
found to be below fair market value. One permittee
justified
the discrepancy by reasoning, “I took over sheep pasture and should, at the most, have to pay only a sheep pasture rent.”
The following year, Aspen raised its prices to an unprecedented $35 per day, and newspapers interviewed outraged skiers. Aspen Mayor Bill Stirling traveled to Washington, D.C., and led a coalition of Colorado ski towns urging public hearings. Even under the 1986 law, the Forest Service retained the power to regulate ticket prices, but that power hadn’t been exercised since the late 70s. And federal authority had been weakened because permits no longer required annual Forest Service approval. Stirling’s complaints went nowhere. The “outrageous” $35 ticket is the equivalent of $102 in today’s dollars, less than half of Aspen’s current ticket price.
In the early 1990s, the ski industry began to consolidate. Apollo Global Management, an investment group co-founded by close Jeffery Epstein associate
1
and billionaire Leon Black, purchased Vail and Beaver Creek in 1992, and it acquired Keystone, Breckenridge, and Arapahoe Basin in 1996. Apollo soon took Vail Resorts public, and its expanding control of the ski industry in Colorado sparked an antitrust inquiry from the Colorado Attorney General and the US Department of Justice. Vail Resorts initially offered A-Basin to the state, but when Colorado refused to accept it, the company was forced to sell the resort to a third party for its acquisition of Keystone and Breckenridge to proceed.
Antitrust actions had been part of skiflation battles in the 1970s as well. Sen. Haskell included anti-monopoly provisions in his ski reform bill, which would have increased competition among neighboring resorts. And a lawsuit brought by Aspen Highlands against the Aspen Skiing Company in 1979 was appealed to the Supreme Court in 1985. In a unanimous decision, the court found that Aspen, the owner of three area resorts, had violated the Sherman Act when it changed the terms of a previous agreement for a four-resort ticket that included Highlands.
Critics of the Vail acquisitions in 1996 said that even without A-Basin, Vail was creating a monopoly in central Colorado. Denver-owned Winter Park Resort, after failing to prevent the merger, responded by offering a $200 season pass, an incredibly low price at the time. That move set off a shift in the industry where season passes, which used to be expensive compared to day tickets, started to come down in price and day tickets began to rise.
Since 2000, the ski industry has only continued to consolidate. Vail now owns 42 resorts around the world, and its main competitor, Alterra Mountain Company, owns 19 resorts. Vail’s Epic pass offers access to over 90 resorts through partnership agreements, and Alterra’s Ikon pass is linked to over 60 ski destinations. Both companies initially followed the Winter Park model, offering cheaper season passes with high day tickets to incentivize skiers to buy passes over the summer, locking in profits for companies before the snow starts to fall (a clever hedge against climate uncertainty and sustained drought in the West). But pass prices have also started to rise, and resorts like Vail and Park City have been plagued by long lines and overcrowding. After years of rapid growth, Epic pass sales have fallen for the last two seasons.
Labor actions by underpaid ski patrol unions have grown more frequent as well with last year’s strike at Vail-owned Park City (which is built on private land) and the
recent ski patrol strike in Telluride
, an Epic pass partner. The failure of Vail and Telluride to offer a satisfactory contract to the patrol unions led to near-complete shutdowns of the ski areas for close to two weeks. In Telluride, business owners and others
staged
a protest demanding the union come to a deal. At local town council and county commission meetings, there was widespread recognition that the community was being upended by the whims of the erratic 81-year-old billionaire that owns Telluride Ski and Golf, or Telski. National forest representatives were nowhere to be seen.
Ski companies like Telski have not only been given free reign to raise ticket prices since the 1970s, but they can upset entire ski town economies by refusing modest wage increases requested by unions.
University of Utah economist and antitrust expert Hal Singer has said industry consolidation is leading to “clear market failure” in the ski industry. “An antitrust authority,” Singer
wrote last year
, “whether federal or state, or a group of private enforcers, should bring a case against Vail, seeking divestiture of those properties that contribute to Vail’s monopoly power over skiers and its monopsony power over workers or both.”
I recently filed a FOIA request for
Telluride’s 40-year special use permit
with the Forest Service, which contains much of the same boilerplate language found in
other
ski area permits, including a mandate that the resort comply with “federal, state, and local” laws. Colorado allows municipalities and counties to set minimum wages. Could Mountain Village Town Council, which voiced support for the ski patrol union in December, pass a minimum wage ordinance targeting Telski employees? Violations of the local ordinance would theoretically give the Forest Service cause to suspend or terminate the ski area permit in addition to other repercussions.
The permits also include the following paragraph:
Even if the Forest Service hasn’t used its power to regulate rates at ski areas in decades, that authority still exists. The broad language of the section, including the reference to the “adequacy and type of services provided to the public,” could offer the Forest Service and the Department of Agriculture a lane to reclaim stewardship over facilities built on public land.
It’s not entirely unimaginable that Trump could see some value in being able to claim he fixed the “raw deal” that Big Ski is offering the average skier or snowboarder. Maybe he should direct the Forest Service to start regulating lift tickets again.
If not Trump, then opportunities abound for politicians willing to make this a signature issue. Could a future Forest Service director help incentivize the purchase of ski areas by local communities, such as
the 1,500-person town of Nederland’s pending $120 million purchase of Eldora
? Who will bring the powder to the people?
As anger at the duopoly grows, we need a new Floyd Haskell to remind the ski industry that the private gain it receives from public lands is a privilege, not a right.
Discussion about this post
Ready for more?
FDA authorizes first wearable device that monitors ketone and blood sugar levels
New device can help people with diabetes detect warning signs of a dangerous complication before it becomes a medical emergency
For Immediate Release:
August 25, 2026
The U.S. Food and Drug Administration today authorized the Libre Duo 10 Day Continuous Dual Glucose Ketone Monitoring System for people aged 2 years and older living with diabetes. The Libre Duo 10 Day is the first wearable device in the U.S. that continuously monitors ketone levels, and the first in the world to continuously monitor both ketones and blood sugar (glucose) together in a single device.
“Today’s authorization is a breakthrough for the safety of children and adults living with diabetes,”
said Michelle Tarver, M.D., Ph.D., Director of the FDA’s Center for Devices and Radiological Health
. “Knowing that ketone levels are rising, and having that information in real time, around the clock, can be the difference between early intervention and a life-threatening emergency."
According to the
Centers for Disease Control and Prevention
, an estimated 40.1 million Americans are living with diabetes, a condition that requires careful monitoring of blood sugar levels. For the estimated 2.1 million Americans with type 1 diabetes, blood sugar is only part of the picture. When the body produces too much ketone, which is made by the body when it is using fat instead of glucose for energy, it can lead to diabetic ketoacidosis, or DKA — a serious complication that can develop quickly and become life-threatening if left untreated.
Early detection of rising ketone levels is critical. Until now, people who needed to monitor ketones had to do so separately, using tests that could only provide a single measurement at one point in time which could not tell users if ketones were rising or falling. The Libre Duo 10 Day addresses that gap by continuously measuring both ketone and glucose levels in the fluid just beneath the skin, every minute, day and night. Readings are sent wirelessly to a compatible smartphone, where users can see their current ketone and glucose levels and whether they are trending up or down. The device can send automatic alerts if ketone levels reach a concerning threshold, which may help patients and caregivers recognize rising ketones before DKA becomes a medical emergency. Ketone information should always be interpreted in the context of glucose readings and symptoms.
The FDA’s authorization is based on a comprehensive review of clinical and performance data submitted by the device sponsor. The clinical program included data from six clinical studies that together enrolled more than 600 participants aged 2 years and older to evaluate the accuracy of the device’s ketone and glucose monitoring functionality across a range of ketone and glucose levels. The results demonstrated that the device accurately tracked clinically meaningful differences in ketone levels across its 10-day wear period, including identifying elevated ketone levels before the onset of diabetic ketoacidosis.
This authorization is also aligned with the
FDA’s Home as a Health Care Hub Initiative
, which focuses on advancing the development of innovative, patient-centered devices that fit more seamlessly into people’s daily lives at home.
Prior to authorization, the FDA granted Breakthrough Device designation for the Libre Duo 10 Day Continuous Dual Glucose Ketone Monitoring System. A breakthrough designation is meant to expedite the development and review of devices that provide for more effective treatment or diagnosis of life-threatening or irreversibly debilitating diseases or conditions.
The FDA granted marketing authorization to Abbott Diabetes Care for the Libre Duo 10 Day through the De Novo premarket review pathway, a regulatory pathway for low- to moderate-risk devices of a new type. Along with this De Novo authorization, the FDA is establishing special controls that define requirements including those related to labeling and performance testing. When met, the special controls, in combination with general controls, provide a reasonable assurance of safety and effectiveness.
###
Boilerplate
The FDA, an agency within the U.S. Department of Health and Human Services, protects the public health by assuring the safety, effectiveness, and security of human and veterinary drugs, vaccines and other biological products for human use, and medical devices. The agency also is responsible for the safety and security of our nation’s food supply, cosmetics, dietary supplements, radiation-emitting electronic products, and for regulating tobacco products.
Taiwan charges nine people for smuggling ‘high-end’ AI servers to China
Guardian
www.theguardian.com
2026-08-25 15:02:42
Among those charged are two Super Micro employees and one from Nvidia, marking another flashpoint in US-China AI rivalry Taiwanese prosecutors charged nine people Monday, including one from Nvidia and two from Super Micro, for illegally exporting “high-end AI servers” to mainland China, adding anoth...
Taiwanese prosecutors charged nine people Monday, including one from
Nvidia
and two from Super Micro, for illegally exporting “high-end AI servers” to mainland China, adding another wave of turbulence in the AI rivalry between China and the United States.
Prosecutors said the servers involved were graphics processing units known as “B300,” which have been banned from sale to
China
.
Seventy-four servers arrived in China successfully, according to the prosecutors. Of those, 50 were sent through Indonesia, 16 delivered directly to China and eight sent to Japan first, then Hong Kong, before they landed in mainland China.
Another attempt involving 56 servers failed, and the servers remain in Taiwan, said the prosecutor’s office.
AI infrastructure, including advanced semiconductors mostly made in Taiwan, has become a key point of competition between the US and China. Washington began imposing restrictions on Nvidia’s exports of advanced chips to China in 2022 and tightened them in subsequent years. In April 2025, the US required licenses for exports of Nvidia’s H20 chips to China before allowing some sales to resume later that year.
Under export controls, any sale by Nvidia of high-end AI servers – the computer infrastructure that houses the chips needed to power AI systems – requires a strict review process, according to a document from Keelung District prosecutors’ office in Taiwan. The document also said purchases of more than eight high-end AI servers require company staff to conduct on-site checks to the clients.
“We will work with the Taiwan authorities to help them resolve the allegations as quickly as possible,” Patrick Rutherford, an Nvidia spokesperson, said in a written statement.
Super Micro said in a written statement that the arrests of two of its former employees were due to its cooperation with the Taiwanese authorities and the company will continue to work to “enhance its robust export compliance program to protect American innovation”.
Prosecutors are seeking the maximum five-year sentences for four of the nine defendants, including Chang, an Nvidia manager identified just by his family name. Chang was the “key figure” responsible for “authorizing the release of the B300 GPUs” in this case but “demonstrated a clearly poor attitude following the offense”, the document said.
Some of the defendants set up a company in Japan, which helped successfully transfer eight of the servers, prosecutors said. Some allegedly created fake websites and falsified information to evade export restrictions.
Israel Is Running a Synthetic Think Tank to Influence AI Search Results
403 Media
www.404media.co
2026-08-25 14:35:26
An Israel-funded think tank is churning out AI written essays to catch the attention of AI chatbots and warp search results....
A synthetic Israel-funded think tank has published more than 100 articles since it launched less than a month ago.
First spotted by Politico
, the Hanover Institute for Public Policy is run by the American advertising firm Piro Inc, paid for by Israel, and appears designed to generate content for LLMs that are continually scanning the internet to inform their responses, with the goal of tweaking chatbot answers in favor of Israel.
Every few days, the Hanover Institute publishes around a dozen articles related to Israel, antisemitism, and Palestine. Every article’s headline has a question. The articles have no byline, often contain graphs, and cite real sources but do not link to them.
“The reframe is the denominator. Six documents from five bodies is a count of assertions, not a change in the kind of evidence available,” it said. “Adding a seventh organization stating the same conclusion does not convert an organizational determination into an adjudicated finding, because the evidentiary route is the same in each case: a body assembling material, applying its own threshold, and publishing.”
The
site’s about page
said the lack of a byline was “the convention at institutional publishers” and that it wants readers to weigh the sources “rather than the author.”
“Accountability for the material is not anonymous,” Hanover said on its about page. “The registrant responsible for distributing it is named in the disclosure at the foot of every page and on the public register at the Department of Justice, where each report is filed. The researchers are not named because a finding should stand or fall on its sources rather than on the standing of whoever assembled it, and because the subject attracts harassment. That is a considered editorial position, not an oversight.”
An analysis from AI detection tool Pangram found that three Hanover Institute articles we tested were written entirely by AI. Only the bibliography at the end of each article was human written, according to Pangram. The images, too, are AI generated.
There’s evidence that Hanover’s articles are not just written by LLMs, but are also written
for
LLMs. The site has an
llms.txt
, a webpage markdown that’s designed to
make it easier
for LLMs to scrape a website and the “registrant responsible for distributing” is the marketing firm Piro, which advertises a service to manipulate chatbot answers on its website.
Piro did not return 404 Media’s request for comment, but co-founder Daniel Rosenberg explained how its system worked
in a post on LinkedIn
. “Every day, more buying journeys begin with an AI conversation instead of a Google search. If the models don't understand your story, they'll tell someone else's,” he said.
“The question was: how do you make sure AI knows how to tell them? We spent the last year searching for the best technical minds in the space, learning how AI models discover, evaluate, and synthesize information across the web,” he said on LinkedIn. “Then we built a process that brings both disciplines together: identify where a brand's narrative is thin, inconsistent, or missing, then strengthen the signals that shape how AI understands and explains it [...] We call it
AI Story Optimization
.”
Prio’s website explained more. “Search is no longer about keywords. It’s about story. About trust. Not only the trust of a language model deciding whether to cite you, but the trust of the actual human being reading that answer and deciding whether to buy. That is two audiences in one sentence: the engine that recommends you, and the person who believes it,” Piro said
on a page advertising
its AI Story Optimization service.
“We map every surface the models read. Reddit threads, YouTube transcripts, G2 reviews, publisher pages, forums, comparison sites, and we score each one by how much it actually shapes what the engines say about you. Not a vanity dashboard. A ranked map of real influence,” Piro said on its website.
Hanover is registered as a foreign agent with the United States government which means it has to file paperwork disclosing its broad goals and its funding. According to Foreign Agents Registration Act (FARA) paperwork reviewed by 404 Media, Piro is working with LaPam — the Israeli government’s official advertising agency: “Piro, Inc. will provide strategic communications and media relations services in connection with LaPam’s engagement on behalf of the State of Israel,” the paperwork states. Piro has also uploaded copies of each article to FARA’s website.
According to FARA paperwork, these activities are political and “may include the creation and dissemination of factual, source-supported informational materials intended to educate the U.S. public regarding Israel and related issues through publicly distributed content.”
The FARA paperwork also included two invoices from HAVAS Media — a European advertising agency working for Israel — provided to Piro for its services. One invoice dated April 30, 2026, included a total of $900,000 to develop the project. “Services include audience research, content architecture, scriptwriting, asset production, distribution planning, interactive performance analysis, and final program evaluation. All content is developed for distribution via digital and social media platforms in the United States.” Another invoice filed on June 20 showed that HAVAS paid Piro an additional $100,000 for two months of work.
“It shouldn't surprise any of us that Israel is funding a disinformation and propaganda machine intended to manipulate the American public,” Margaret DeReus, the executive director of the Institute for Middle East Understanding, told 404 Media. “This is just the newest iteration of what Israel has been doing for decades and it isn't working. No amount of chatbot manipulation can reverse the massive surge in public support for Palestinian freedom"
Hanover’s articles feel impersonal, a dry reading of complicated and deadly conflicts. According to its website, however, the work is deeply personal.
“The Institute’s original founder traced this work to a moment in his own childhood. At ten, he asked the man his grandmother had married about the numbers tattooed on his arm; the man had survived Auschwitz. What a child could not fully grasp, the adult came to understand: that such hatred is recent rather than distant, that it reached within a single lifetime and within his own family,”
the website said
. “That is his account of why the work exists. It is not offered as a credential for it.”
The Hanover Institute did not return 404 Media’s request for comment.
About the author
Matthew Gault is a writer covering weird tech, nuclear war, and video games. He’s worked for Reuters, Motherboard, and the New York Times.
Pgbot: A 5.9 MB read-only Postgres tool for humans and agents
Connect any PostgreSQL database and get visibility into performance, queries, health, schema, and changes — with AI-powered explanations.
01
See database health in real time
Monitor connections, locks, transactions, cache hit ratio, replication, WAL, and overall database health.
02
Understand query performance
Track slow queries, regressions, throughput, query latency, and expensive SQL using PostgreSQL statistics.
03
Inspect tables and indexes
Analyze table growth, index usage, unused indexes, missing indexes, vacuum activity, and storage patterns.
04
Get AI-powered insights
Ask pgBot questions in plain English and get summaries, explanations, and recommendations based on real database signals.
05
Works with any PostgreSQL
Connect directly to public databases or use the pgBot Agent for private environments like Docker, Kubernetes, and internal servers.
06
Built for secure production use
Read-only access, open-source agent, and support for private deployments without exposing your database publicly.
MCP — use pgbot as an agent tool
pgbot mcp
speaks the Model Context Protocol on stdio, so an AI agent can call pgbot as a read-only tool. It exposes deterministic tools only —
inspect
(full findings as JSON) and
unused_indexes
— and lets the connected model do the explaining. No Gemini key involved: the agent reasons over the same findings the CLI computes.
Add it to any MCP client (Claude Desktop/Code, Cursor, …)
With
DATABASE_URL
set, the agent calls
inspect
with no arguments; or it can pass
connection_string
per call to reach several databases. pgbot never writes, so there's nothing an agent can break through it.
Tools, prompts, and resources
It also exposes a
diagnose
prompt — a one-click "inspect and give me a prioritized diagnosis" workflow — and a
pgbot://baselines
resource listing the databases pgbot has local history for.
Core features
+
PostgreSQL health monitoring
+
Query performance analysis
+
Slow query and regression detection
+
Locks and blocking query insights
+
Table and index analytics
+
Vacuum and autovacuum visibility
+
Database growth tracking
+
AI root-cause analysis
+
AI-powered recommendations
+
Direct connection or agent-based private access
Why pgBot
Not just metrics. Context.
pgBot helps you understand what changed and why it matters.
Not just dashboards. Explanations.
Ask questions in plain English and get actionable answers.
Not just for hosted Postgres.
Use pgBot with Supabase, Neon, RDS, Docker, Kubernetes, and private servers.
Not just observability. An AI DBA.
Get insights that help you find issues faster and make better decisions.
Point it at a database.
Read-only by default. Nothing leaves your infrastructure unless you say so.
I'm gonna go into some background here. If you already know how transformer models work, go ahead and jump to
section 2
. If you already know how multi-GPU parallelism works and just want to get to the part where I'm testing things, jump to
section 3
.
section 1: attention
Okay, basically all of the AI text generation software that's currently in use everywhere are instances of the "transformer model" or "large language model". The design and basic technique was introduced in the paper
Attention is All You Need
, which is probably the most important paper in the field of computer science in the past, I dunno, twenty years?
The paper is pretty readable as far as these things go. I'm sure every software engineer reading this blog post has already read it, right? (Right?)
Anyway. I'm going to over-simplify things a bit here and focus from the perspective of somebody who is trying to get these things to run fast on crappy hardware, and not go deep into the tensor math or talk much about model training, because this blog post is already going to be way, way too long.
The LLM works in terms of "tokens". A token is basically a word fragment; instead of inputting and outputting individual letters it's more efficient to chop these up into sequences of letters and have the model process those. (This is why early AI models were bad at correctly answering questions like "how many times is the letter R in the word raspberry?") Different models tokenize language differently, you can think of this as like a frequency encoding. Each time a model generates another token, it'll actually generate a probability distribution and then randomly sample one from that distribution, because language works better that way than picking the exact most likely next thing every time.
The language model is a neural network that's divided into layers. You have an input layer and an output layer and a bunch of layers in between that don't directly interact with the input or output ("hidden layers"). The input layer takes in the entire input prompt, and then each layer does math on the output of the previous layer in series. The thing where the model looks at the entire input at once, and looks at the relations between different tokens at different points in the input series, is called the "attention mechanism". If you've been reading about AI language models you probably have heard somebody confidently claim "these AI models are just next word generators, like a Markov chain is", and then you probably noticed that these AI models generate very different outputs than a Markov chain does, and wondered where exactly that guy went wrong. Well, a Markov chain doesn't have the attention mechanism, it just generates a new token based on the previous token in the series.
So, to generate the next token, the model reads in the entire tokenized prompt, turns this into an embedding matrix (each token gets turned into a vector where the length is the hidden dimension of each layer), then does the attention math on each layer (gigantic matrix multiplication for each token, for each layer in series), samples a new token, adds it to the prompt, and keeps doing this in a loop until it gets to a token that indicates that it's time to stop.
fig 1 from "Attention Is All You Need" (Vaswani et. al., 2017)
For our purposes, what this means is that every time the computer generates a token, it needs to read in the existing context, and also every weight in the model, in order to do all those matrix multiplications to generate the token. I'd mentioned the Gemma4-31B model in the last chapter; as the name implies, the model has 31 billion weights (divided into 60 layers). We've got to load all of them into the GPU to calculate the next token. Loading these takes a lot longer than the actual attention math does; token generation is (usually) limited by memory bandwidth rather than compute. This is why the server I built has all of those GPUs with lots of VRAM attached to them; the model weights and KV cache need to be in VRAM that can get to the GPU quickly. The memory attached to the CPU is by comparison a lot slower. (This is also why we are in a memory shortage right now as the entire industry shifts to prioritize producing high-bandwidth memory for data center GPUs).
This obviously isn't going to scale super well. As model sizes increase, token generation slows way down; practical limits on this kind of thing got hit already. In response, we have the misleadingly-named "Mixture of Experts" model architecture
1
. The idea here is that the first couple of layers are used every time to process the whole input embedding matrix, then this gets routed to some subset of the model. For the middle layers, each input token gets routed to a subset of the weights, so only some set of the weights will need to get loaded for each token. Each of these subsets is called an "expert", and I really hate this framing, because it gives you the completely false impression that like one of these branches knows about Python and one of them knows about rocket engines and one of them knows how to speak German and you can just trim the parts of the model you don't care about. This is absolutely not the case, though! The "experts" are basically random, or at least unpredictable, and for most MoE models, different tokens will get routed to different experts in a mostly uniform distribution. So, for example, Deepseek V4 Flash has 284 billion weights but for each token we will only load and process 13 billion. (The shorthand for this is "284B-A13B", only 13B get "activated"). But I don't know
which
13 billion ahead of time, and it's going to change for each token that gets generated, so I still need to store all 284 billion weights in some pretty fast memory to keep token generation fast. The MoE thing makes token generation fast at the cost of needing more VRAM.
section 2: parallelism
When you're using a lot of VRAM, it's going to be divided among separate GPUs. My server has four, with 32GB each; the serious business ones will have eight GPUs with like 192GB each, and then will have to split really big models up between multiple compute nodes, but the principles are the same. A GPU can read its own memory pretty quickly and memory from some other GPU not very quickly and memory on a whole different compute node will be slower still. There's several different ways to split this up. Only two of them really matter for the use case I have, where I've got a box in the garage and I'm the only real user and I'm trying to get the smartest model working at adequate speeds for myself.
Layer Parallel
- We take the model and put different layers on the different GPUs. As we're generating a new token, we run through a few of the layers on GPU 1, then move that intermediate state over to GPU 2 and process the next set of layers, and so on. This is pretty simple, it gets all of our model weights into VRAM. Each layer is getting processed in series, though, because each layer depends on the output of the previous layer, and so the theoretical best speed we can expect here is basically the same as what one GPU would give us if it had as much VRAM as the whole set. (In practice it'll be a bit slower). An AMD V620 has 512 GB/s of memory bandwidth. If I'm splitting the model up between four GPUs layer parallel, for one prompt I'm gonna get... 512 GB/s of memory bandwidth, minus the overhead of moving data between the GPUs.
Tensor Parallel
- We take the model and split each layer between multiple GPUs. For each layer, each GPU calculates a fraction of that matrix multiplication, then sends that result to some other GPU that will synchronize and calculate the final result before moving on to the next layer. In theory this should allow us to parallelize our memory bandwidth: I have four cards at 512GB/s, if I'm splitting the model up tensor parallel I should get 2TB/s of memory bandwidth as I move through each layer! Minus the overhead of moving data between the GPUs, of course. Which is, unfortunately, way more! We're moving data around multiple times for each layer, instead of just once per GPU per token as in layer parallel. This can (and will, on my server) outweigh the speed increase from the increased memory bandwidth.
You'll also see discussion of other parallelisms that make more sense in the context of serving multiple users at once:
Data Parallel
is just running the same model on multiple separate GPUs and routing incoming queries to run in parallel. I may play around with that for multiple subagents running simultaneously in the future, but it's not actually necessary until you get to very large scale because a GPU can process inference in a batch already. (The inference pipeline is bound by memory bandwidth, as mentioned earlier, so you can slide some amount of extra matrix math in there for "free", at least until you try to do so much that it becomes compute-bound again).
Expert Parallel
keeps shared tensors on every GPU and then puts each of the non-shared "experts" (or subgroups of them) onto different GPUs, so multiple users would get their queries routed to different GPUs for most of the inference pipeline. Again, this one mostly makes sense for lots of concurrent users, and is widely used by commercial LLM providers. It doesn't really help my case though.
Anyway, my server will mostly be serving me making one request at a time. I'll play around with parallel subagents at some point, maybe I'll have a couple guests hitting this thing at the same time, but I don't really have multiple users here so I'm not optimizing for these cases.
section 3: experimentation
Okay, let's talk about my server.
The GPU array I have here is four AMD Radeon Pro V620 cards connected to a shared PCI Express bus. You'd expect the inter-GPU-traffic to be slow, and it's even slower than you'd expect, because the motherboard is running the older PCIe 3.0 standard and most of the cards are using 8 lanes instead of 16.
lspci
shows eight lanes and slow, like the LA freeways
So I suspect that tensor parallel isn't going to work very well. The cards that are actually designed and marketed for AI workloads have some kind of high speed, low latency inter-GPU connection in addition to PCIe, and these are all manufacturer-specific; Nvidia has NVLink, AMD has Infinity Fabric, Intel has Xe Link, etc. These cards don't have anything like that. Around the same time AMD was making these cards for their cloud gaming scheme, they were making an AI-focused card called the AMD Instinct MI210, it has about three times the memory bandwidth and you can get a special bridge connector that connects up to four of them via Infinity Fabric. Also, a single one of those cards would cost (used, today) more than this whole box, so that's all kind of a non-starter. I have to make do with what I have.
What I have are four cards that are respectably fast individually and have poor interconnects between them, which means we're going to have to do this in layer parallel, then figure out how to fill up the pipeline. And even layer parallel has a performance impact, as we'll see.
For the purposes of this study here I had two models I was playing with; I had Gemma4-31B, and Deepseek V4 Flash.
Gemma4 31B
has 31 billion parameters, at a 4-bit quantization the weights are about 18 GiB and the model fits comfortably into a single one of these GPUs that each have 32GB of VRAM. It's a dense model; every token will run through all 18 GiB of those weights.
Deepseek V4 Flash
has 284 billion parameters, it's a MoE model and 13 billion parameters will activate for each token. The "stock" quant from Deepseek puts the routed expert weights at 4 bits each, for a total size of 162 GiB. This is too big for this server! I'm running here a 2-bit quantization, at 81 GiB. Only the routed expert weights are compressed this hard, the shared weights are still at full precision; overall this comes out to something like 3.5 bits per weight on disk, but 5 point someodd bits per weight getting loaded for each token. This is just about the right size to max out the memory in the four GPU array. (Remember, we also need to store the current context in VRAM as well, the "KV cache", because it's going to be the other factor in the matmul we need to do each layer). 2-bit quants in general have a bad reputation but I'm finding this particular one to be surprisingly good, probably because the shared weights are all still at high precision.
2
When I first built this machine in the previous chapter, I immediately tried to run this DS4Flash quant across all four cards, in the default layer-parallel mode, leaving all of the other settings on whatever the default was. It ran at about 9 to 10 tokens per second. This was usable to get a fan control script written, but was slow enough to be annoying and unsatisfying. I knew there was performance that was getting left on the table here.
First, I doubled back and tested out some techniques with Gemma instead. It's easier to work with a smaller model, I ran into out-of-memory errors less often.
One thing I can do here is directly test the performance penalty for layer parallelism against running everything on one card. I've got a 4-bit quant of Gemma, and I locked it to a context size of 65536 tokens. Here's what some quick testing with the basic default settings showed me:
Single card performance: 19-20 tokens per second
Two cards, layer parallel: 15-16 tokens per second
Four cards, layer parallel: 12-13 tokens per second
For reference, the base command:
lama-server --host 0.0.0.0 --model /mnt/storage/llm/Gemma-4-31B/gemma-4-31B-it-qat-q4_0.gguf --ctx-size 98304 --fit off --n-gpu-layers all
The fact that this model fits all in one card allows a real apples-to-apples comparison here; we can see that with the same exact model weights and context length, splitting the layers up among these different GPUs has a performance penalty just from the synchronization they need to do. Of course, for GPUs that are designed to exchange data across some special link, this will be much less pronounced. But right now the takeaway I have is that getting this thing to go faster means having as few movements between GPUs as possible.
3
Another interesting observation here is that the GPUs are all running one at a time. When I watch rocm-smi as some text generation is running, three of the GPUs are basically idle at all times, and the one that's working is only drawing 150 watts or so (out of a 250 watt maximum). In the last chapter you saw me get a 1600 watt power supply to build this machine, and while I did need all of the power connectors that the massive PSU provided, the box itself is never drawing more than 350 watts during layer-parallel (or single-card) inference. Here's the output from
rocm-smi
during the tw-card test which shows this fairly well:
This is all very unsatisfying! Most of the hardware is idle at any given time. And, while 20 tokens per second is a usable level for a chat interface, it would be nice if we could go faster, especially when it's doing reasoning about some complicated thing. (Or writing code in an agent harness, which we'll talk about in Chapter 3). And we can see why this is happening; each layer is basically executed in series so the GPUs that aren't working the current layer are just sitting there, and even when we're processing some layer, the operation is bound on memory throughput so the processor is spending a lot of time idle waiting for data to arrive.
The current state of the art here, to get a model to generate output tokens faster by parallelizing this serial pipeline, is "speculative decoding", or the use of a draft model. You take a much smaller model that generates tokens that are usually kind of similar, and run it first, and then the main model verifies the next several tokens in parallel. How well this works is basically proportional to how well the draft model predicts what the main model will produce, and how well you can parallelize inference. Early experiments with this just used a smaller and faster transformer LLM trained on similar data as the big one; later developments use a specialized multi-token prediction model that generates several tokens simultaneously very quickly and shares some tensors and KV cache with the base model for memory efficiency.
Gemma4 has such an MTP model and it's quite well-optimized; they call it "gemma4-assistant". Let's enable it!
4
We add the model and the flags to the command from earlier.
--spec-draft-model /mnt/storage/llm/Gemma-4-31B/MTP/mtp-gemma-4-31B-it-Q8_0.gguf --spec-draft-n-max 3 --spec-type draft-mtp --n-gpu-layers all --n-gpu-layers-draft all --spec-draft-device ROCm1
Two-card configuration we also specify what device the draft model runs on, which must match the main model's devices because they share tensors for some layers.
-spec-draft-device ROCm2,ROCm3
With the MTP model enabled we see:
around 40 tokens per second on a single card
20 tokens per second on two cards in layer parallel
Putting it all in one card is faster than splitting it in a layer parallel two or three cards because llama.cpp will batch process multiple tokens on a single GPU quite well; inference is memory-bound so there's spare compute just kind of lying around. 20 tokens per second on two cards isn't
bad
; we're back up to the speed of one card without it. This is not a total loss if we need more context than fits on one card but it's still disappointing.
Okay, so we've proved out the use of a draft model to speed things up, and we have a Gemma4-31B configuration that generates quickly. It only uses one card, but that's fine, it fits.
Now, let's speed up Deepseek V4 Flash with a draft model and see if it's less annoyingly slow. The Deepseek team came up with a new draft model architecture called DSpark and released it with Deepseek V4.
Here's a link to the paper
, it's an improvement of a previous draft model architecture, DFlash. We can download and run their draft model that they trained to work with Deepseek V4 Flash, with a recent build of llama.cpp. Spread across all four cards we're getting something like 13 tokens per second. Promising! I'm noticing that performance is varying pretty sharply too as it works its way through a prompt. Something feels off here.
Reading the DSpark paper, I think that the draft model is going to be pretty sensitive to inter-GPU transfers more so than the main model. I don't have my head around all of the details, but DSpark (like predecessor DFlash) is a diffusion model similar to an image generator and I know these don't like running on multiple GPUs. The paper's section "Real World Deployment of DSpark" mentions some issues getting the model to parallelize well across GPUs, and I bet the issues are worse on my hardware. My hypothesis here is that I'll see a speed increase if I can get DSpark to run on one GPU only, and spread the main model across all four GPUs with whatever room is left.
This took some trial and error. The draft model takes a nontrivial amount of VRAM itself, about 10 GB, and that's after it shares the output layer with the main model for memory efficiency. A build of llama.cpp off of `master` doesn't handle this layer sharing particularly well. At first, llama.cpp would "helpfully" spill the model over into CPU memory, making it significantly slower (6 or fewer tokens/sec). I locked this out by explicitly specifying "--n-gpu-layers all" so these would turn into out-of-memory errors. After I shrunk down the context a bit, I could use the --split-tensor option to distribute layers of the model around so that there was more room on the one card that held the draft model.
This still failed, because the draft model shares layers with the base model to save on memory usage, and now those layers aren't necessarily on the same card as the drafter!
I was about to start digging into the source code and making changes and then my buddy Sol found out that somebody else was already working on this;
there was an open PR about more-or-less this issue
so I built from his PR branch. Here's where it started actually working!
Now I was getting about 15-16 tokens per second out of Deepseek V4 Flash. I knew there was more I could do here, and the rest of the settings changes were kind of boring, so instead of guessing and checking manually as I'd been doing previously, I used a script to sweep through various setting combinations and test token generation against a benchmark. (I just grabbed some random question about air conditioning my garage and used it as a baseline, since I knew it would generate lots of output in response).
I vibecoded out a few python scripts to sweep through various settings configurations and spit results out into CSV files. First, I swept through different ways to split the tensors between the cards to balance out memory usage on each card, so I could then scale up the context size until I filled up VRAM. I got up to 512M tokens of context space this way! Then I swept various other settings - number of speculative MTP tokens to attempt to use (5 performed worse than 3 because acceptance rate was so low that the extra compute just wasted time), batch and microbatch size for processing (a larger batch size had a surprisingly large effect on both token generation speed and memory usage, while a larger microbatch size didn't matter at all and needlessly allocated a bunch of system RAM), and a bunch of other stuff that didn't end up mattering one way or the other (n-gram prediction didn't help, changing the default settings for flash attention or thread count or NUMA or whatever did nothing useful). Also, shuffling which cards held which tensors was useful for some reason.
Mostly the scripts just swept through benchmarks while I did some chores. By the end of this, the benchmark was showing 22 tokens per second and I was consistently getting 19-20 tok/s in the web UI and in the OpenCode harness. It would spit out ranked choices for the settings like this:
At this point I felt like I'd wrung about as much as I can out of this. It's still a little slower than I'd like, but at least it's twice as fast as when I started. Hooking this thing up to OpenCode or a similar agent harness is now pretty usable. I've got a single-card configuration with one model going at a very solid 40 tokens per second and a configuration that uses all four cards to run a smarter model going half as fast.
section 4: further experimentation
Something here
still
didn't feel right, though. The inter-card communication slowdown seemed excessive, it kept bugging me. It was hitting that instinctual response I have when code is slow and doesn't have a good reason for it. There's a benchmark that comes with older versions of ROCm to measure ram throughput,
rocm-throughput-test
.
Right, that explains it, PCIe peer-to-peer transfers are just completely broken and everything is taking a pit stop at the CPU because inter-card DMA doesn't work. Of course that's slow. I was immediately sure that I could get a solid performance increase by fixing this.
First I'm digging around in the BIOS settings. When I first set up this box, I needed to set MMIO High Base to some non-default higher value to get this board to boot at all. (This tells the cards where their base memory address range should start; the default value didn't work with four 32GB cards, probably because that would be a really weird configuration when the motherboard was made back in 2016). Back then, I just set it to 56T to get it to work. When debugging all this, Sol mentioned that the AMD documentation has some vague statement about how some GPUs (didn't specify this one) actually only do 44-bit addressing, so we'd need the memory addresses to stay below 16T. I did some trial and error here and landed on these settings: 4T MMIO High Base, 1024G granularity.
The bandwidth test now shows direct connectivity between cards. It looks pretty slow, though. Disconcerting. Let's give tensor parallel a try. Loaded up llama.cpp, it's looking okay, then we try some inference:
hey little man how's it going
Well that's not right. Layer parallel?
yea...
After this, the kernel panics.
Okay, so I have some kind of corruption issue going, then; the model is having a stroke. The answer was so well known that even the tiny models on the server knew what to try next: set "iommu=pt" in the kernel settings.
Earlier, before I had this working, I tested out tensor parallel on Gemma4 alongside the layer parallel test earlier. My initial results, with broken PCIe P2P, were:
two cards: 20 tokens per second
four cards: 0.5 tokens per second, total failure.
Re-tested this again after getting this working and now I see:
two cards: 47 tokens per second
four cards: 37 tokens per second.
(Recall that 40 tok/s was the single-card baseline).
So, the peer-to-peer sync is still slowing things down if I try to span across four cards, but between only two I'm now getting a little boost! It's not the "twice as fast" that I would get if I had a really fast link between them, but the communication slowdown isn't consuming the entire speedup from the increased memory bandwidth. That's not bad at all.
Somewhere in the middle of me testing all of this stuff, the new Qwen3.8-27B model dropped and I saw similar results there: about 27 tokens per second with one card and about 35 with two cards in tensor parallel, a nice 30% speedup, with speeds going back down below the single-card level when I tried to deal in four.
Let's take another look at power draw per card in
rocm-smi
:
Now we're really using multiple cards simultaneously, instead of flitting around between them. Less idle hardware! (I should probably do some tokens-per-watt-hour measurements but at this point I'm getting pretty bored of this and want to move on to using the models to actually do something).
section 5: future development ideas
At this point I attempted to run Deepseek V4 Flash in tensor parallel across all four cards and all I got was an error message about how llama.cpp doesn't yet support tensor parallel on the Deepseek4 architecture. I have a hypothesis here that it would run fastest, on this server, as a hybrid, two TP2 groups in layer parallel. Changing llama.cpp to support that would be a whole bunch of work that I'm not going to bite off at the moment, though.
I didn't spend any real time here talking about prompt processing. Before an LLM can do any token generation at all, it needs to do "prefill", or prompt processing, where it turns the long prompt into the initial K and V matrix embeddings. This is generally faster than token generation but it can be annoyingly long for long prompts, which you tend to get when agentic coding tools try to read in large files (or when you just e.g. copy a whole blog post into the thing for proofreading). It's a completely different workload from token generation: it's compute-bound instead of memory-bound and because of this it runs faster in layer parallel. In theory I could have the best of both, at least for the smaller models, by doing prompt processing on one pair of GPUs in layer parallel and then token generation on another pair in tensor parallel. (The big LLM providers are basically all doing this kind of thing now, and there's hardware development to specialize data center GPUs into one workload or the other). This also would require some development on llama.cpp; I'm going to table this for now.
Next chapter, we'll talk about giving the AI some tools so it isn't just a text generator.
Appendix: final configurations
Here's what I ended up with as commands to run. Your own hardware will probably differ and you'll probably need to sweep settings too.
Voting data is public by design, but ICE is looking for a federal contractor to help it handle voter registration and history files to find what it describes as fraud....
Immigration and Customs Enforcement (ICE) is looking for a federal contractor to provide it with access to the country’s voter registration and voter history data, according to newly released procurement records reviewed by 404 Media.
The procurement records say ICE is seeking the data to help detect fraud. But given the administration’s habit of
using fraud as a pretense
for large immigration enforcement actions, and President Trump’s constant comments
about election security
in the lead up to the midterms, the planned hiring of a contractor to handle voter data raises questions around what exactly ICE plans to do with the data.
💡
Do you work at ICE or CBP? I would love to hear from you. Using a non-work device, you can message me securely on Signal at joseph.404 or send me an email at joseph@404media.co.
“The purpose of this acquisition is for the handling and secure delivery of publicly available voter registration files and voter history files to support Homeland Security Investigations (HSI) fraud detection and data segmentation activities,” a
section of the procurement records reads
. The records are part of a Request for Information, or RFI, which means the government is asking potentially capable contractors to come forward.
The records say the list of jurisdictions ICE wants voter data from is likely to be limited at first, but that the contractor needs to have the capability to get data from all 50 states and other U.S. territories.
Specifically, ICE is seeking “Public voter registration file for each Government-identified jurisdiction,” and “Public voter history file for each Government-specified federal election, when publicly available and separate from the public voter registration file.”
Voter data is public by design and can be obtained in various ways. Some sites collate this data and
make it easily searchable
.
But handling such a large volume of data in a clean and reliable manner could be a challenge. ICE is looking for a contractor to essentially help streamline that process, by both obtaining the data and handling it for the agency.
The purchase specifically is for HSI, the part of ICE traditionally focused on criminal investigations, including money laundering, cybercrime, and various types of fraud. That does include voter fraud.
Earlier this month, the Department of Homeland Security (DHS)
highlighted an HSI case
that ended in charges against a Chinese national for alleged fraudulent voter registration and fraudulent voting.
Experts generally agree that voter fraud
is exceptionally rare
. But constant claims that voter fraud is happening on a wider scale or tangibly impacting elections runs the risk of disenfranchising voters from participating at all.
In July,
404 Media reported
ICE was to pay Thomson Reuters $125 million for access to a wealth of personal data to investigate “voter fraud.” Personal data Thomson Reuters holds includes peoples’ names, addresses, Social Security numbers, ethnicity, and more.
ICE did not respond to a request for comment.
About the author
Joseph is an award-winning investigative journalist focused on generating impact. His work has triggered hundreds of millions of dollars worth of fines, shut down tech companies, and much more.
Dolly Parton, one of the greatest singer-songwriters in country music who was also much cherished for her philanthropy, has died aged 80.
Her death was
announced
by nephew Brian Seaver on Instagram. “I have imagined the heaviness of this moment but haven’t truly felt it until now,” he said. “It is an honour, an honour that is mixed with absolute pride and great sadness.”
So gifted that she wrote two of the 20th century’s greatest songs – Jolene and I Will Always Love You – in a single day, Parton’s songwriting was characterised by its vivid storytelling, emotional acuity and melodic strength, all sung with strident clarity. From an eventual catalogue of hundreds of songs, she scored a record 25 US country No 1 singles and 47 albums in the country Top 10 . She crossed over into the pop charts with 9 to 5, a US No 1 in 1980; balanced her music career with acclaimed acting, twice earning Golden Globe nominations for her roles; and her Imagination Library literacy scheme donated more than 150m books to children.
This was all done with considerable panache, rhinestoned glamour and towering hairdos, with her immortal assertion regarding her appearance – “it takes a lot of money to look this cheap” – the most quoted example of Parton’s ready wit.
Parton was born in poverty in a one-room cabin in
Tennessee
, the fourth child to a mother who would have 12 children by the age of 35, and a father who was a farmer and construction worker. One of her best-loved songs, Coat of Many Colours, was about her mother creating patchwork clothes; Parton’s first guitar was cobbled together from a mandolin with bass guitar strings. Her first proper guitar was given to her aged eight by her uncle, and she went from singing in church, to appearing on local television aged 10, to cutting her first record aged 13. That year she appeared at the Grand Ole Opry, the concert hall in Nashville at the centre of country music, and her performance was introduced by Johnny Cash. “I’ve always believed things would go well, and I dreamed that they would even before I was in high school,” she later said. “I always wanted to be a star. It just seemed natural to me.”
Dolly Parton in 1976
Photograph: PA
After graduating high school in 1964 she moved to Nashville and started out as a songwriter rather than performer. The following year she was signed as an artist and initially moulded as a pop singer, without success; after she was allowed to switch to country, she scored back-to-back hits and released her debut album Hello, I’m Dolly. In 1966 she married Carl Dean – who died in 2025, with the couple renewing their vows in 2016 to mark 50 years together.
Beginning in 1967, a duet partnership with country singer and TV personality Porter Wagoner helped her star continue to ascend, and she had her first country No 1 in 1971 with the song Joshua.
Jolene, her unforgettably raw and desperate plea to a rival lover, was released in 1973 and became her first UK success, reaching No 7. I Will Always Love You, written to Wagoner as a farewell after their creative partnership, was a country No 1 in 1974 and again via a re-recorded version in 1982, and would go on to be a huge pop success when revived by Whitney Houston for the soundtrack of The Bodyguard in 1992: it is still the bestselling single of all time by a woman, with an estimated 20m sales.
In the mid 1970s Parton broadened her sound, embracing pop-rock arrangements on songs such as 1977’s Light of a Clear Blue Morning – its accompanying album New Harvest … First Gathering was her first entry in the pop album chart. Later that year its follow-up Here You Come Again reached the Top 20 and was her first million-selling LP, powered in part by its hit title track, which also won Parton the first of her 10 Grammy awards.
1980 was a peak in her success, with three back-to-back country No 1s, including 9 to 5, taken from the film of the same name which Parton starred in alongside Jane Fonda and Lily Tomlin, earning her an Oscar nomination for best original song. Parton would later write songs for a stage musical version of 9 to 5, in 2008.
Another classic single came in 1983: Islands in the Stream, a duet with Kenny Rogers, which topped the US pop charts, and a Christmas album with Rogers in 1984 went two times platinum. There were more notable film roles in the 1980s, too, opposite Burt Reynolds in the The Best Little Whorehouse in Texas, Sylvester Stallone in Rhinestone, and an all-star female ensemble in Steel Magnolias.
Linda Ronstadt, Dolly Parton and Emmylou Harris in 1987.
Photograph: Paul Harris/Getty Images
A landmark Parton album came in 1987 with Trio, an exquisitely harmonised, springwater-clear collaboration with Emmylou Harris and Linda Ronstadt, earning Parton her only nomination for album of the year at the Grammys. Another all-star trio recording came in 1993, with Tammy Wynette and Loretta Lynn on the album Honky-Tonk Angels, followed by a reunion with Harris and Ronstadt from Trio II in 1999, featuring a Grammy-winning cover of Neil Young’s After the Gold Rush.
The turn of the century brought a trilogy of acclaimed bluegrass albums, and Parton would release 10 more LPs, the most recent being Rockstar in 2023. She was courted by a younger generation of stars, appearing with country artists such as Brad Paisley as well as pop singers such as Kesha, and her goddaughter Miley Cyrus. There were fewer acting roles, but she lent her voice to animated film Gnomeo and Juliet in 2011 and the following year appeared alongside Queen Latifah and more in musical film Joyful Noise.
Alongside her music and acting, Parton was an astute businesswoman and philanthropist. She founded the film and TV production company Sandollar, with former manager Sandy Gallin, which went on to produce hits such as Buffy the Vampire Slayer and the Father of the Bride film series. In 1986, she took a stake in the Silver Dollar City theme park in Tennessee and renamed it Dollywood, doubling its size over the next two decades, and a Dollywood-branded spa, cabin complex, theatre-restaurant concept and waterpark have since been opened.
Dolly Parton in Joyful Noise
Photograph: Van Redin/Publicity image from film company
The Dollywood Foundation, funded through these business ventures and creative projects, was created in 1988, initially awarding college scholarships and running a scheme to help children complete high school in her native Sevier County, Tennessee. In 1995 Parton began her Imagination Library project, which sent an age-appropriate book to every child in the county every month until they were five. “My father could not read and write, and I saw how crippling that could be,” she explained. It expanded nationwide in 2000, internationally in 2006, and nearly 25m books are now distributed each year across the US, Canada, Australia, the UK and Ireland.
In 2022, Jeff Bezos donated $100m (£83m) to the foundation. That year, Parton explained that as well as improving child literacy, “it’s the fact they get recognised. They get this little book with their little name on it in the mail, and they feel special. They start taking pride in themselves, and they know that somebody out there is thinking of [them].”
Dolly Parton receiving the Moderna vaccine she helped to fund.
Photograph: @DollyParton/Reuters
Parton has also set up a reserve in 2003 to help preserve the bald eagle; contributed $500,000 to the opening of a Sevier county hospital in 2006; coordinated relief efforts for those affected by the Smoky mountain wildfires of 2016; and contributed to an HIV/Aids charity album. She supported Black Lives Matter and transgender rights, opposing a North Carolina “bathroom bill” that restricted transgender people’s access to toilets (Parton was also nominated for an Oscar for her song in trans drama Transamerica, entitled Travelin’ Thru).
She made a number of donations to Vanderbilt University Medical Center in Nashville, Tennessee, where her niece was treated for leukaemia. The most high profile of these was in 2020, when she donated $1m for research into Covid-19, which formed the basis for the eventual Moderna vaccine.
In May 2026, Parton
cancelled
her Las Vegas residency over health issues. A Broadway musical is also
set to open
later this year after a run in Nashville.
How to Keep Organizers in the Movement: A Conversation with Immigration Organizer Tania Wolf
OrganizingUp
convergencemag.com
2026-08-25 13:59:25
Featured image by Elizabet Wendt Tania Wolf has been organizing in the immigrant justice movement for nearly a decade—first at Make the Road New York, now in Louisiana supporting people inside immigration detention and their families. She came to this work the way a lot of children of immigrants do:...
As of Firefox 157 I intend to turn JPEG XL decoding on by default on all platforms. It has been developed behind image.jxl.enabled, which today is on by default on Nightly only, and has had a Firefox Labs checkbox on every channel since 152. The decoder is jxl-rs, in Rust.
Other browsers: Safari shipped in 17.0 in 2023. Chrome has it behind #enable-jxl-image-format using the same Rust library, no intent to ship yet.
Changes since the intent to prototype:
Performance was a concern raised on the intent to prototype thread. jxl-rs 0.6.0 was released with multithreaded decoding support, and our patches to hook up and enable multithreaded decoding are expected to land soon. Including those patches, I ran a five-format decode benchmark over the same pictures at a range of sizes: we were slightly ahead of Safari (using C++ libjxl) on my machine. Compared to our other image format decoders, JXL is close on large images, but shows a bigger gap on small ones.
It has feature parity with our other image formats and with Blink's JXL implementation, including animation and progressive display. The one exception is HDR: HDR images display as SDR, the same as every other format we support, but our tone mapping for JXL is much better than what we do for other image formats. Safari has neither progressive rendering nor animation.
The wpt jpegxl directory covers decode correctness across bit depths, alpha, grayscale, CMYK, colour management, orientation and the coding tools, plus the HTML and CSS ways an image gets used. Where wpt could not express something I added gecko tests: about 30 gtests for chunked and incremental decoding, animation frame counts, downscale during decode and corrupt files, mochitests for progressive rendering and telemetry, reftests, and decode benchmarks that report to Perfherder. The fuzzing team already fuzzed jxl before it was enabled on nightly and they will fuzz the decoder again before I flip the pref.
Timothy Nikkel
Timothy Nikkel
unread,
Aug 24, 2026, 7:37:11 AM (yesterday)
Aug 24
to dev-pl...@mozilla.org
一丝
unread,
4:22 AM (11 hours ago)
4:22 AM
to dev-pl...@mozilla.org, tni...@mozilla.com
Is Animated JXL currently supported?
Timothy Nikkel
unread,
4:40 AM (10 hours ago)
4:40 AM
to 一丝, dev-pl...@mozilla.org
Yes. Animated jxl is supported.
Tim
Sergey Davidoff
unread,
6:40 AM (8 hours ago)
6:40 AM
to dev-pl...@mozilla.org, tni...@mozilla.com
I am concerned about lossless JPEG XL performance. In my measurements it is
30x
slower to decode than lossless WebP, in exchange for a 10% reduction in file size. This is a questionable trade-off, especially on laptops and phones where it could drain battery and degrade user experience.
I suggest shipping only lossy JPEG XL in Firefox 157, and considering lossy JPEG XL format separately.
Measurement methodology
jxl-rs from git
https://github.com/libjxl/jxl-rs
on commit 775837f57dfe4294d89c1c6317dd91a1ed8d3cfa compiled with 'cargo build --release'
converted to WebP with 'cwebp -lossless', to JPEG XL with 'cjxl -d 0'
Both decoders running in single-threaded mode to measure total CPU time taken with 'taskset -c 0'.
$ hyperfine --warmup 5 'taskset -c 0 target/release/jxl_cli --speedtest 55_Cancri_e_Final_1_30.jxl' 'taskset -c 0 dwebp 55_Cancri_e_Final_1_30.png.webp'
Benchmark 1: taskset -c 0 target/release/jxl_cli --speedtest 55_Cancri_e_Final_1_30.jxl
Time (mean ± σ): 20.632 s ± 0.061 s [User: 20.605 s, System: 0.027 s]
Range (min … max): 20.549 s … 20.743 s 10 runs
Benchmark 2: taskset -c 0 dwebp 55_Cancri_e_Final_1_30.png.webp
Time (mean ± σ): 667.0 ms ± 2.2 ms [User: 449.5 ms, System: 217.5 ms]
Range (min … max): 664.3 ms … 670.1 ms 10 runs
Summary
taskset -c 0 dwebp 55_Cancri_e_Final_1_30.png.webp ran
30.93 ± 0.14 times faster than taskset -c 0 target/release/jxl_cli --speedtest 55_Cancri_e_Final_1_30.jxl
For reference, libjxl's djxl tool is 20x slower than WebP in the same measurement. So it doesn't look like further optimizations to the Rust code could help, but would not change the overall calculus.
Trump-backed Ken Paxton unveils ‘Texas first’ datacenter plan aimed at ‘negative impact’
Guardian
www.theguardian.com
2026-08-25 13:54:00
The Republican Senate candidate announced the plan with a graphic X flagged as ‘Made with AI’US politics live – latest updatesKen Paxton, a Republican candidate for the US Senate in Texas, has unveiled plans to tackle the “negative impact” of datacenters amid a growing backlash across the political ...
Ken Paxton
, a Republican candidate for the US Senate in Texas, has unveiled plans to tackle the “negative impact” of
datacenters
amid a growing backlash across the political spectrum.
Paxton, endorsed by
Donald Trump
but facing a close contest against Democrat James Talarico, posted a “Texas first” datacenter plan on X with a graphic that
the social media network flagged
as “Made with AI”.
Republicans have been struggling to keep up with a shift in public opinion fuelled by concerns that power and water-hungry datacenters will push up energy costs and harm the environment. Some fear the issue could prove costly in November’s US midterm elections.
An Annenberg Public Policy Center
survey
last month found that 61% of Americans now oppose the building of a new datacenter in their area, an increase from 49% in March. This includes 69% of Democrats, 54% of Republicans and 53% of independents.
Last year
Greg Abbott
, the governor of Texas, dubbed his state the “epicenter of AI development”, but on Sunday he told ABC’s This Week programme that tech companies “basically dug their own grave for the problem that’s been caused for them and that’s why they got the backlash they deserve”.
On Monday his ally Paxton, currently the state attorney general in
Texas
, outlined a four-point plan that includes banning Chinese technology to power US datacenters, holding companies criminally liable if AI chatbots undermine children’s safety and cutting red tape to ensure datacenters do not raise Texans’ electricity bills.
He also pledged to support Abbott’s state plan to ban new datacenters from rural neighbourhoods, repeal sales tax exemptions and ensure they are adding to Texas’s electricity capacity rather than taking from it.
Paxton said in a statement: “Texans deserve a fighter to lead and represent them as we address the growing presence of data centers in Texas and stop their negative impact on our neighborhoods.
“This plan will ensure that happens while putting Texas first, protecting our culture and land, and safeguarding our families and communities. My plan will also work to ensure that data centers are not utilized to power Al platforms that endanger our children.”
The move signals an effort by Paxton, a rightwing populist who defeated incumbent US senator John Cornyn in
a Republican primary runoff
, to blunt attacks on what could be a potential electoral issue. His rival Talarico
has urged tighter regulations
on datacenter development and an end to sweetheart tax deals for big tech companies.
Talarico accused Paxton of trying to erase his history giving data center tax handouts. He said in a statement: “Ken Paxton has taken nearly half a million dollars from the data center industry, voted to flood Texas with data centers by giving them billions in tax handouts, and has refused to use his power as attorney general to respond to Texans’ requests to block data center development in their communities.
“Now he’s scared his ties to big data center companies will lose him the election, so he’s making a sad attempt to reverse course by releasing a plan he literally used AI to make.”
The race is tight in what is traditionally a Republican stronghold. A Fox News poll in late July showed Talarico leading 51% to 48%. The Cook Political Report
describes the election as a toss-up
.
Paxton is struggling to overcome a series of political scandals. He was impeached in 2023 after being accused of corruption and
later acquitted in a trial in the Texas senate
. He was also indicted on charges of felony securities fraud but the case was dismissed after a 2024 pre-trial diversion agreement. Last year his wife of 38 years, Angela Paxton, filed for divorce “
on biblical grounds
”, citing adultery.
Politicians are scrambling to adjust to the backlash against AI datacenters, which consume huge quantities of electricity and water, threaten to alter the landscape of local communities and create relatively few jobs.
Josh Shapiro, the Democratic governor of Pennsylvania, last year
championed
a $20bn investment by Amazon but last week
signed an executive order
he said imposes the “strictest guardrails in the nation”. Bernie Sanders, an independent senator for Vermont,
has urged
big tech leaders to pause AI development.
The Axios website
reported
that the National Republican Senatorial Committee warned leading AI companies that voter discontent with the centers is endangering the party’s chances of defending a Senate seat in Ohio.
Trump, however, remains supportive of the industry. He
told Punchbowl News
recently: “I saw Texas the other day sort of is against datacenters. I think it’s a mistake. And I’m not taking positions, I just think it’s a mistake, because there are other communities that want it. When a community wants it, it means a lot of money is going to come into that community.”
Icons! Lots of them! – These Weeks in Firefox: Issue 206
MozNight
blog.nightly.mozilla.org
2026-08-25 13:43:36
Highlights Starting in Firefox 154, we’ve added a new capability for changing the default browser icon for Windows (Windows-only, for now, and not MSIX / Store installs) in about:settings#appearance! Notice … Read more...
Starting in Firefox 154, we’ve added a new capability for changing the default browser icon for Windows (Windows-only, for now, and not MSIX / Store installs) in about:settings#appearance!
Added moz-promo cards to the about:addons extensions list recommendations footer and empty state, and updated the openAmoInTab helper to support a custom UTM content value –
Bug 2043615
/
Bug 2050880
Introduced the building blocks for the Nova Themes Picker in about:addons: a shared Firefox Themes list source of truth, a light/dark/device theme-mode switcher, a reusable theme-preview webcomponent, and Nova-styled theme previews –
Bug 2051554
/
Bug 2051559
/
Bug 2051564
/
Bug 2051573
Updated the Extensions panel empty state illustration and toolbar item icon for Project Nova –
Bug 2030715
Thanks to Michael Hynson for driving this.
Removed the legacy AddonManager Glean metrics used for mirroring legacy telemetry events, along with the corresponding legacy telemetry test checks –
Bug 1923949
/
Bug 1981822
Thanks to Chris H-C for collaborating with us on this.
Fixed themes installed through the distribution mechanism not fetching their AMO metadata, which was resulting in distribution installed themes left without a preview image in about:addons –
Bug 1917279
Thanks to Mike Kaply for the fix to the distribution themes metadata handling.
Fixed amContentHandler to verify that a system triggeringPrincipal genuinely originated from the parent process, a regression introduced in Firefox 153 and fixed in Firefox 154 (with a beta 153 uplift requested) –
Bug 2048964
WebExtensions Framework
Fixed a startup performance regression by avoiding an NSS-initializing crypto.getRandomValues() call during extension startup, a regression introduced in Firefox 153 and fixed in Firefox 154 (with a beta 153 uplift requested) –
Bug 2050882
Enabled tier 3 TypeScript typecheck linting for the extensions framework code –
Bug 2050124
Implemented the WebExtensions manifest sandbox key, letting extensions keep using string-based code execution in unprivileged sandboxed extension documents –
Bug 1685123
Thanks to Robin for the implementation of the manifest sandbox support.
WebExtension APIs
Enabled storage.local database auto-reset on detected corrupted IndexedDB storage on all channels, starting in Firefox 154 –
Bug 1992973
Simplified registerTraceableChannel to make it synchronous again, removing the delay before blocking webRequest listeners can register a traceable channel –
Bug 2044518
Restored the contextualIdentities iconUrl container icons to their intrinsic 32×32 size, fixing a regression introduced earlier in the Firefox 154 cycle –
Bug 2048599
Thanks to Andrea Marchesini for the fix to the contextualIdentities container icons.
Fixed the MV2 userScripts API failing with an Xrays TypedArray access error due to a missing isWebExtensionContentScript flag –
Bug 2054083
Thanks to erosman for the fix to the MV2 userScripts API.
Nicolas Chevobbe
about:debugging is now using moz-page-nav for its left sidebar (
#2048544
), thanks to Mark making it possible to disable collapsing that occurs on narrow screen (
#2050907
)
(not all items were migrated to moz-page-nav-button though, see
#2050746
for remaining work)
Alexandre Poirot
made it possible to control the request and response body size limit from the Settings panel (
#2040892
)
That’s a wrap for the World Cup! We’re powering down the Sports widget today.
Some folks might see a survey about the Sports widget, to get feedback from the wild on whether or not it provided any user value (Telemetry points to “yes”, but it’s good to get qual data too)
We’re replacing it with some new widgets. If you’re in an English-speaking region, you will probably see it replaced with a Daily Crossword widget. Otherwise, it’ll be replaced with a Picture of the Day widget.
Sections have rolled out to 100% in France! We’re now doing 10% Sections experiments in Spain, Italy, Austria, Switzerland and Belgium.
Joel
added WebNotifications to the newtab state
, allowing New Tab widgets to observe and reflect WebNotification events (affects the notification-driven widget lifecycle and UI state updates).
Reem Hamoui
adjusted the New-Tab Widgets 3-dot menu layout
to vertically center menu entries inside the hover-granted colorful stripe, removing visual misalignment and small hit-area offsets on touch and pointer inputs.
Scott Downe fixed New Tab Page drag-and-drop so widgets no longer jump or keep moving during drags (
2049472
).
Reem Hamoui rendered the Daily Crossword in a sandboxed iframe to isolate its scripts/CSP on the New Tab Page (
2049489
).
Reem Hamoui added the Crossword option to about:preferences and wired the New Tab Page crossword widget into prefs (
2050340
), so users can enable or disable the crossword via the standard Preferences UI rather than about:config.
Dre set up the Picture of the Day boilerplate, including prefs and basic New Tab UI components (
2050969
), which exposes a configurable PoD surface for users to opt into and customize.
Dre added a dismiss control and persisted dismissal state to the daily photo UI (
2050972
), allowing users to remove the current picture from their New Tab and avoid immediate reappearance.
Dre added a “set as wallpaper” action and hooked it into New Tab wallpaper storage/prefs (
2050973
), enabling users to promote a PoD image to their custom New Tab wallpaper persistently.
Dre connected the Picture of the day widget to the Merino endpoint to set the background of the widget to the current picture (
2050976
). He also added telemetry for the Picture of the day widget on the New Tab Page to capture impressions and clicks for usage analysis (
2050977
).
Nina Pypchenko [:nina-py] added a small size variant for the Focus Timer widget in Nova so the timer can render compactly in narrow/new tab layouts and reduce vertical space usage (
2051179
).
Dre
introduced two variants of the World Cup widget survey message
, changing the copy delivered in the widget to support an A/B/message-variant experiment and altering what users see when the World Cup widget surfaces survey prompts on their New Tab Page.
Nina Pypchenko [:nina-py]
added an error state to the Stocks widget
on the New Tab Page to show an explicit failure UI when quote fetches or network requests fail, reducing user confusion.
Irene Ni fixed the New Tab add-pin flow that was creating extra rows when grouped pins was off by changing the insertion logic to append into the existing grid, which eliminates unexpected row creation and layout shifts for users managing many pins (
2053251
).
Scott Downe updated New Tab section rendering to hide cards that don’t fill their row by adjusting layout logic/CSS, removing orphaned placeholders and reducing blank space on narrow viewports or low-item sections for a cleaner grid appearance (
2053264
).
Reem Hamoui added a context menu to the Crossword widget using a postMessage integration between the iframe and parent page, enabling right-click actions (copy/hint/theme) and making the embedded crossword more interactive and accessible to users who rely on context menus (
2053311
).
Reem Hamoui added a visible “New” badge plus interaction handlers and state tracking to the Crossword widget on the New Tab Page to improve discoverability and make tapping/clicking behave reliably when launching puzzles (
2053667
).
Irene Ni removed unused Add Shortcut OMC artifacts from the New Tab Page (
2053843
); this is a cleanup of obsolete assets/templates and has no direct runtime user impact.
Maxx Crawford added author and license attribution to the Picture of the Day widget (
2053933
); this surfaces photographer credit and license metadata on the New Tab Page for users who want provenance information.
Maxx Crawford applied UX refinements to the Picture of the Day widget (
2054109
); users will see improved layout, spacing, and touch targets in the POTD area for clearer interactions.
Maxx Crawford added a pref and trainhopConfig gate to toggle the POTD “Set as wallpaper” feature (
2054111
); rollout and availability of the wallpaper action are now controllable via pref and remote trainhopConfig.
Maxx Crawford added a dedicated trainhopConfig.widgetPictureOfTheDay payload for POTD feature config (
bug 2054112
) so the New Tab Page train-hop widget can be controlled server-side — this delivers image URLs, attribution and display params remotely which lets us enable/disable POTD per cohort without ship-side changes and reduces rollout latency for users who see the Picture‑of‑the‑Day widget.
Irene Ni updated the Shortcuts Add/Edit dialog for Nova (
bug 2054175
) to improve the add/edit UX on the New Tab Shortcuts surface — the patch adjusts dialog layout and controls, tightens validation and accessibility labels, and reduces accidental duplicate/invalid shortcut creation so users editing shortcuts have a more reliable, faster flow.
Maxx Crawford
fixed Related articles not opening on click
by repairing the related-articles component’s click handling and event delegation (anchor href/target behavior and JS listener) on the New Tab Page so article tiles now reliably open on click for users.
Irene Ni
migrated the New Tab Widgets expand button to moz-button
which standardizes the expand/collapse control on the New Tab Page widgets area, fixing inconsistent styling and keyboard/click handling so users now get consistent visuals and improved accessibility across platforms.
Maxx Crawford added
per-widget feature toggles and pref reset buttons
to Discovery Stream Admin, enabling admins to toggle individual widgets and reset prefs without code deploys — changes here can alter what users see when toggled.
Mandy fixed the “New” label incorrectly appearing for user-installed third party search engines that override application-provided engines (
2053710
).
It’s tempting to think that having AI review code and then implement fixes in a loop will create a flawless diamond at the end of the process. Some are accidentally doing the slow version of this loop where dev A creates an AI-generated PR, dev B lazily AI-reviews it, then dev A AI-fixes it,
ad infinitum
.
With careful guardrails this can work, but doing it naively will often create a mess for a few reasons:
AI does not have a consistent set of opinions. What it considers good code can change from run to run. In the worst case, it can flip-flop from review to review, causing a never-ending loop.
Reviews can often encourage scope creep, from ‘Hey, you don’t have a test for this!’, to ‘Hey, you don’t have a CI/CD pipeline!’, to ‘Hey, you don’t have an Android app for this!’.
Any false positives or hallucinations in reviews can introduce new defects.
As a quick test I asked Opus 5 to generate a small amount of ‘perfect, non-trivial’ code and passed it through three review-fix loops. Here is an
AI-generated writeup
. Note the defect count
increases
with each review!
Clara (YC P26) Is Hiring a Growth Engineer to Bring AI Doctors to Market
You'll own Clara's growth engine, supporting our mission by helping more patients discover Clara and turn to it for their day-to-day primary care needs. Landing pages, onboarding funnel, experimentation, attribution, and lifecycle messaging all belong to you. You'll work across the entire funnel - from the first ad impression or search result, through signup and onboarding, into first chat, subscription and long-term retention. You'll write the code, ship the pages, wire the events, run the tests, and read the results yourself. You'll partner closely with our clinical and compliance teams to make sure every page, claim and experiment is medically accurate and HIPAA-safe.
Your responsibilities
Acquisition and conversion surfaces:
Ship programmatic and SEO-driven page systems for condition, medication and geo intent
Integrate paid ad platforms with our attribution stack so every channel's true contribution is measurable
Build and iterate high-velocity landing pages and funnels in React + TypeScript
Onsite (4 hours) - System design, code pairing, team fit
Reference checks + offer
About
Clara
Clara is an AI-powered medical practice on a bold mission: to add one billion years of healthspan to humanity. We are building the autonomous medical practice of the future, supervised by human medical providers who review and approve every medical decision.
Our founders have built and scaled Circle Medical to over $100M in annual revenue, and founding executives have held key roles at Hims and Hers, GoodRx and Teladoc. We are full time in San Francisco and have raised $12M in pre-seed funding from Y Combinator and top investors. This is the A team, and we have a place for you.
Founded:
2025
Batch:
P26
Team Size:
9
Status:
Active
Location:
San Francisco
Founders
Lightweight system monitor for Linux VPS written in Go
Abstract:
It is widely repeated in the popular literature and elsewhere that the singularity at the center of a black hole is a point. It is not true. Two observers who free-fall into a spherical black hole along two different angular trajectories at the same time $t$ do not encounter each other at the central singularity; rather, they lose causal contact with each other already well away from the singularity. Counterintuitively, in general relativity two points can be spatially close yet causally distant. The singularity is a surface, not a point. The story for rotating black holes is more complicated, but the same conclusion holds. For a rotating black hole, the singular surface almost certainly resides at its inner horizon, where even the tiniest classical or quantum perturbations ignite the exponential mass inflation instability, precipitating collapse to a spacelike singular surface. There are implications for quantum gravity. We argue that, whatever the ultimate theory of quantum gravity may be, the quantum states of a black hole probably reside at its effectively 2-dimensional singular surface, which coevolves unitarily with, and in thermodynamic equilibrium with, the hot atmosphere of trapped Hawking radiation that the black hole generates within its event horizon.
Submission history
From: Tyler McMaken [
view email
]
[v1]
Fri, 21 Aug 2026 19:49:33 UTC (2,097 KB)
A new ceiling for Λ: the de Bruijn–Newman constant is at most 0.1787854
A new ceiling for
Λ
: the de Bruijn–Newman constant is at most
0.1787854
I'm Jude Gomila and I've been exploring the zeta function in private since 2025. This post is part of a series of posts on discoveries obtained from human/ai collaboration. This post is about the de Bruijn–Newman constant Λ — a single real number with this property: the Riemann hypothesis holds exactly when Λ ≤ 0. Nobody can prove that yet, but its known ceiling can be lowered, and this is my computer-assisted proof taking it from 0.2 to 0.1787854, unconditionally, with no unproved conjecture anywhere in the chain. I'll walk you through the whole proof, step by step. Every claim links back to my
audit repository
and the independent review record. Feedback, bugs and upgrade comments are welcome as
GitHub issues
.
Previous bound
Λ ≤ 0.2
This result
Λ ≤ 0.1787854
Method
Polymath 15 criterion + interval certificates
Special thanks
Dan Romik
,
Max Atkin
Λ ≤ 0.1787854
= 129/800 + 87677/5,000,000: an exact rational, obtained by exact arithmetic from 3,149,013 + 883 + 1 machine-checked interval certificates.
Animation
The proof in 2 minutes 35 seconds — from ζ(s) to Riemann’s ξ(s), the H₀ normalization, the de Bruijn heat flow, and the three checks that pin Λ ≤ 0.1787854. Also at
/assets/zetasota
.
The primes 2, 3, 5, 7, 11, 13, … are the atoms of arithmetic: every whole number factors into primes in exactly one way, so facts about primes become facts about all numbers. Individually they are irregular — no known rule produces the next prime from the ones before it. Counted in bulk, they obey a law: the number of primes up to x stays close to a single smooth curve (the prime number theorem, proved in 1896). The open question is the size of the error — how far the true count can stray from the curve. That error term is what the Riemann hypothesis governs, and it is why RH matters: sharpen the error term and you sharpen hundreds of results in number theory that depend on it.
Fig. 1
The prime-counting staircase π(x) (the dark stepped line) climbs one step at each prime. The dashed blue curve is the smooth prediction Li(x). The gap between them is a sum of waves, one wave per zeta zero, and the Riemann hypothesis says every wave has the smallest possible amplitude.
In 1859
Bernhard Riemann
explained where that hidden order comes from. He took Euler's identity, which connects the primes to a single function of one
complex variable
,
hover or tap a colored term for what it does
extended it to the whole complex plane, and discovered that the wobble of the prime count around its smooth curve is governed —
exactly
, via an
explicit formula
— by the locations of the
zeros
of this function. Each zero contributes one wave to the error; the zero's height sets the wave's frequency and, crucially, its horizontal position sets the wave's
amplitude
. Riemann observed that every zero he could examine sat on one vertical line, Re s = ½, now called the
critical line
— the position giving the
smallest possible
amplitude — and remarked it was “very probable” all of them do. That remark is the
Riemann hypothesis
. Its concrete content: the prime-count error up to x never exceeds roughly √x, the same size as the wobble of a fair coin flipped x times. The primes are allowed to look random; RH says they are never allowed to drift with a bias.
The wave description is an actual formula, and you can run it below. The slate staircase counts prime powers (a cousin of the staircase above, weighted so the mathematics is exact), and the vermillion curve is Riemann's formula built from the smooth trend plus one wave per zeta zero. Drag the slider and watch thirty zeros carve the primes:
Try it — build the primes out of zeta zeros, one wave at a time
zero-waves included
0
/ 30
no zeros: just the smooth trend x, which misses every step
every one of these zeros has real part exactly ½, which makes its wave swell like √x as x grows — the slowest growth the explicit formula allows. A zero off the line at real part β ≠ ½ would make its wave grow like x^β instead, out of step with all the others, and the prime count would drift off course.
It has now been open for 167 years. It is part of the eighth of Hilbert's problems (1900) and is one of the Clay Millennium Prize problems today; hundreds of theorems across number theory and beyond are proved
conditionally
, “assuming RH.” Its zeros have been checked by computer into the trillions — every one on the line — but a check is not a proof. The way forward is to turn the question into a number that can be moved — and that is exactly what Λ is.
Λ (defined properly in the next chapter) repackages the Riemann hypothesis as a statement about one real number:
RH holds if and only if Λ ≤ 0
(a proved equivalence, established in Chapter 1). That reformulation has three consequences. First, progress becomes
measurable
: a yes/no conjecture has no partial credit, but an upper bound on Λ can shrink: ½ → 0.22 → 0.2 → and now 0.1787854. Second, since 2018 we know Λ ≥ 0, so Λ is confined to the interval from 0 to the current ceiling, and RH is the statement that Λ sits at the left endpoint; every improvement to the ceiling is measured distance toward the answer. Third, bounds on Λ are
unconditional
— nothing in them assumes RH itself. Lowering Λ is one of the few rigorous, quantifiable ways to make progress on the Riemann hypothesis.
Chapter 1
Λ, the constant whose value decides the Riemann hypothesis
A single real number whose sign settles the question: the Riemann hypothesis holds exactly when Λ ≤ 0.
Start with
Riemann's xi function
, a repackaging of the zeta function:
. The Riemann hypothesis says all its zeros lie on the critical line
. Rotate coordinates so that line becomes the real axis (this proof uses the Polymath 15 normalization
) and RH becomes a single sentence:
RH, restated
Every zero of the
entire function
is a
real number
.
In 1950 de Bruijn had the idea of
deforming
this function with a one-parameter flow — mathematically, running the heat equation on it:
where
is the fixed super-exponentially decaying kernel with
. Positive t smooths the function and, as we'll see, herds its zeros toward the real axis; negative t roughens it and pushes zeros off. De Bruijn proved that once all zeros are real they stay real at every later time. So there is a single threshold, made precise by Newman in 1976:
That threshold is the
de Bruijn–Newman constant
, and it converts the Riemann hypothesis from a statement about infinitely many zeros into a statement about one real number:
Analogy.
Λ is a thermostat reading. The xi function is a room full of particles (its zeros), and t is heat: warm the room and the particles settle onto the floor (the real axis); chill it and some lift off. Λ is the exact temperature at which the last airborne particle lands. The Riemann hypothesis says the room as built — at temperature zero — already has everything on the floor. Since we can't yet check every particle, we do the next best thing: prove the landing temperature is low.
Fig. 2
The state of knowledge about Λ. The Riemann hypothesis is equivalent to Λ ≤ 0; the equivalence is itself a theorem. Rodgers–Tao (2018) proved Λ ≥ 0, so RH, if true, is true with nothing to spare. This work moves the other wall: Λ is now known to be at most 0.1787854. The truth lives somewhere in the vermillion interval, and RH says it lives at its left endpoint.
One direction is now settled. Newman conjectured Λ ≥ 0, famously adding that if RH is true, it is
“only barely so”
— and Rodgers and Tao proved this in 2018. So Λ is confined:
, and progress can now come only from the upper side. This proof moves the ceiling to
. With the floor at 0, this removes just over 10% of the interval that remained.
Chapter 2
Heating the function pulls its zeros onto the real axis
Complex zero pairs sink toward the real axis at a computable rate; the proof is a schedule for when the last of them arrives.
Under the flow, the zeros of
move like interacting particles: real zeros repel each other along the axis, and each
complex-conjugate pair
gets pulled toward the axis. For an isolated pair at height y (that is, at
), the dynamics are governed, up to smaller corrections, by
so the
squared
height falls at a constant rate 2, and a pair starting at height y touches down at time about
. The final bound has the same form: it will be
: “run the flow to time
, show nothing flies higher than
, then wait
longer for the stragglers to land.” Polymath 15's Theorem 1.2 (introduced next chapter) is the rigorous, effective version of that sentence.
Try it — run the heat flow and watch the zeros land
time t
0.0000
still complex
5
pairs
rule
a pair at height y lands at t = y²/2
…heating
Analogy.
Rain settling after a storm. Each complex pair is a droplet at altitude y, and gravity here acts on altitude-squared: every droplet loses y² at the same steady rate 2. You don't need to track any droplet individually — if you can certify that by time t₀ no droplet is above altitude y₀, physics finishes the argument: the sky is completely clear by t₀ + y₀²/2. The hard work is the certifying, and it splits into the three parts of the next chapter.
Two structural facts make the schedule provable. First, zeros move
continuously
in t: a zero cannot appear at a point without traveling there. Second, a zero's vertical speed is bounded by the dynamics, so a region that is empty stays empty unless a zero crosses its boundary. Together these reduce the problem to fencing a region and checking the fence — which is what the criterion asks.
Chapter 3
The bounds on Λ, and how the methods work
From de Bruijn's 1/2 to Polymath's 0.22 to 0.1787854.
De Bruijn proved
in 1950. Fifty-nine years later, Ki, Kim and Lee improved it to the strict inequality
. The current method dates from 2018–2019, when Terence Tao's
Polymath 15
project built an
effective
theory of the heat flow: explicit, computable approximations to
with rigorous error bounds, and a criterion (their Theorem 1.2) that converts three finite, checkable statements into an upper bound on Λ. Polymath 15 instantiated it to get Λ ≤ 0.22; plugging in Platt–Trudgian's 2020 record-height RH verification pushed the same machinery to 0.2.
Fig. 3
Seventy-six years of squeezing from above. De Bruijn's 1/2 stood for six decades before Ki, Kim and Lee made it strict; Polymath 15's 2019 breakthrough — the criterion this proof instantiates — brought it to 0.22, and Platt–Trudgian's record RH verification pushed the same criterion to 0.2. Below the axis of battle: Newman conjectured Λ ≥ 0 in 1976 and Rodgers–Tao proved it in 2018, so the interval can never close from this side past zero.
Analogy.
Theorem 1.2 works like a crane left standing on the site: anyone who can supply the three certified parts it needs — a verified height, a clean final-time region, and a barrier — can use it to lift the bound. This proof machines heavier parts and lifts with the same crane, near its rated capacity at today's verified height.
The squeeze on Λ has two independent sides, and they work by completely different mechanisms. Both live in the
upper half-plane
: since
takes real values on the real axis, every off-axis zero at
has a mirror twin at
, so it is enough to track the region above the axis — position x running along the axis, height y measuring how far a zero still has to fall. RH is the statement that this upper region is empty.
Fig. 4
H
t
takes real values on the real axis, so its complex zeros come in conjugate pairs: x + iy above the axis, x − iy below. The lower half-plane is a perfect reflection — nothing happens there that the upper half doesn’t already show — so the whole proof watches one region: position x along the axis, height y above it. The Riemann hypothesis is the statement that the tinted region is empty.
The floor: why Λ ≥ 0 (Rodgers–Tao, 2018)
Recall from the last chapter what Λ is: the moment in flow time when the last zeros finish landing on the real axis — and t = 0 is the function as built. Saying Λ is negative would mean the landing finished
before
t = 0 — so the zeros we actually observe would not be fresh arrivals, but particles that had already spent time settled on the axis, jostling each other. That extra time matters, because zeros on the axis repel each other, and the longer they jostle, the more the irregularity irons out: crowded neighbors push apart, wide gaps close up, and the spacings drift toward uniformity — the way a traffic jam evens out once cars can spread along the road. Rodgers and Tao showed the real zeta zeros are too unevenly spaced for that: their gaps fluctuate more than any configuration that had already relaxed this way could still allow. So the landing cannot have finished early, and Λ ≥ 0. Note what the argument does and does not do: it locates no zero off the line; it only shows the observed spacings are incompatible with earlier relaxation.
Fig. 5
The floor argument compares two worlds. If the landing had finished before time 0 (Λ < 0), the zeros would have spent extra time repelling each other on the axis, ironing their gaps toward uniformity (top). The zeros we actually observe keep clusters and wide gaps (bottom) — too uneven to have relaxed. So the landing cannot have finished early, and Λ ≥ 0.
The ceiling machine: Tao and Polymath 15's barrier method (2019)
The upper bound must rule out zeros in the
canopy
— Polymath's name for the region at height
and above at the final time
, stretching along the entire infinite axis. A theorem of de Bruijn says an empty canopy forces
. Their method empties it in three zones. Left of a chosen abscissa X: the computer-verified stretch of RH keeps the region clean at t = 0, and a continuity analysis of each zero's velocity keeps it clean afterward — provided nothing crosses in from the right. Blocking that crossing is the
barrier construction
: a rectangle one unit wide at X, meshed along its boundary, where the effective approximation is evaluated at a ladder of time slices; certified bounds on how fast the values can move between mesh points and between slices, plus the argument principle (winding number 0), keep it zero-free at
every
intermediate time. Right of the barrier, the canopy is checked at the final time only, using the approximation
and Euler-product mollifiers. Polymath 15 ran this at
,
,
, with the barrier parked at the limit of Platt's 2011 verification, the fractional shift chosen to make the small-prime Euler product large at the barrier — and obtained Λ ≤ 0.22. Their bottleneck was the final-time check (ii).
Fig. 6
The ceiling machine. The
canopy
is everything at height y₀ and above at the final time — if it is empty, de Bruijn’s theorem forces Λ ≤ t₀ + y₀²/2. It is emptied in three zones: left of X the machine-verified stretch of RH keeps it clean (velocity bounds keep zeros from wandering up); the barrier at X is a wall checked zero-free at
every
intermediate time, so nothing crosses in from the right; and right of the barrier the canopy is checked at the final time only.
Platt–Trudgian's lever (2020–21)
The criterion consumes exactly one external computation, the verified height: the barrier must stand below it, and a barrier further out allows better
. Platt and Trudgian raised the rigorously verified height a hundredfold, to exactly 3,000,175,332,800, itself an interval-arithmetic computation. Feeding it to the same criterion gives Λ ≤ 0.2, noted in
their own paper
.
What I changed (2026)
Same criterion, same verified height; the differences are in the parameters and in how the result is certified. I parked the barrier so the height it consumes, X/2, sits 175,239,886.5 below the exact Platt–Trudgian record (0.006% from the edge), re-optimized the row in exact rationals to the criterion's boundary, and built the heavier certification the thinner row demands: mollifiers up to the prime 11 where the floors are thinnest, the window-freeze, native-binding and Dini-transfer lemmas, an all-N tail theorem in place of sampling, and a 883-prism barrier certificate that includes t = 0 exactly. That takes 0.2 to 0.1787854, about
below the most this criterion can give at this height. The rest of this post is the detail.
In numbers, my row is
,
, and
, supported by roughly 3.15 million
interval-arithmetic certificates
and an audit trail built so a reviewer can rebuild every piece from source. The next chapter turns the flow's machinery into three finite checks, taken one at a time.
What’s new in this work.
The crane is Polymath 15’s and the verified height is Platt–Trudgian’s; here is exactly what this proof adds on top of them:
A new exact parameter row — t₀ = 129/800, y₀² = 87677/2,500,000 — chosen at the edge of what the criterion admits at today’s verified height (Chapter 11 maps that edge).
Three small theorems that turn a 3.1-million-window scan from numerics into proof: one evaluation per window, proved conservative across the whole window (the Window Freeze theorem); certified floors that bound the paper’s own quantity exactly, with no conversion factor left to trust (the native binding lemma); and one certified height carried to every height in the band (the Dini transfer) — Chapter 6.
A contraction argument covering the infinite remainder — every window past the cutoff — in a single certified computation (Chapter 7).
A barrier rebuilt at the modern verified height: 883 closed prisms, each held zero-free through time by winding-number certificates (Chapter 8).
An audit trail built like flight certification: a hash-pinned repository, fail-closed checkers, replays on two toolchains at two precisions, an adversarial AI review panel, a full from-source recompute, and an independent human review (Chapter 10).
Chapter 4
Three finite checks that prove an upper bound on Λ
Theorem 1.2 of Polymath 15, instantiated at one exact row of parameters.
Pick three numbers: a barrier location
, a final time
, and a landing height
. Polymath 15's Theorem 1.2 says: if the three hypotheses below hold, then
. (A theorem's
hypotheses
are its if-part: supply them, and the conclusion is yours. They are the three “checks” of the chapter titles ahead.) The colors below match the map and the chapter headings that follow: slate for (i), brass for (ii), vermillion for (iii). I chose the exact row
chosen so that
exactly — every parameter is a rational number, and the final arithmetic is exact, not floating-point.
The three hypotheses (Polymath 15, Theorem 1.2)
(i) Verified height.
No zeta zeros
with
and
.
(ii) Final-time clearance.
No zeros of
with
and
.
(iii) The barrier.
No zeros of
in a thin curved wall over
, for
every
intermediate time
.
Fig. 7
The Polymath 15 criterion as a quarantine map (schematic — the barrier is 1 unit wide at x ≈ 6×10¹²). Hypothesis (i) clears everything left of the wall at time zero, using the finite RH verification. Hypothesis (iii) makes the wall itself zero-free at
every
time 0 ≤ t ≤ t₀. Hypothesis (ii) clears the right half-line at the final time t₀, starting at x = X + √(1−y₀²) — a landmark just
inside
the wall (since √(1−y₀²) ≈ 0.982 < 1), so regions (ii) and (iii) overlap and leave no gap. Zeros move continuously — so nothing can be above height y₀ at time t₀, and the last stragglers land within y₀²/2 more.
Analogy.
A quarantine protocol. You want to certify a city district is virus-free at time t₀ without inspecting the whole world. So: (i) at time zero, door-to-door inspect everything inside the district — that's the brute-force RH verification up to height X/2. (iii) Close the border for the entire duration — a wall one unit thick, checked zero-free at every moment: nothing sneaks in from outside while the flow runs. (ii) At the final time, scan the region just beyond the wall to confirm nothing is pressed up against it. Continuity of zero trajectories is the epidemiology: infection can't teleport. Conclusion: at time t₀, nothing in the protected zone flies above y₀ — so everything lands by t₀ + y₀²/2.
Why
these
three numbers and not others? Try it yourself — the bound, the criterion's validity condition, and the feasibility of actually certifying a row all move as you drag:
Try it — pick your own row (t₀, y₀²) and see what bound it would buy
The three hypotheses are supplied by three completely different technologies — a cited world-record computation, a 3.15-million-row certified scan with a tail theorem, and an argument-principle certificate. The next four chapters take them in order.
Chapter 5
Check one: RH is already machine-verified below the barrier
Platt and Trudgian's verification covers the height the criterion needs, with margin 175,239,886.5.
The first hypothesis is the one part I didn't prove myself but licensed from the literature:
Platt and Trudgian's record verification
(2020) that every nontrivial zeta zero up to height
lies exactly on the critical line. The criterion at our row consumes height
, which sits inside the verified range with an exact margin of
. The zero-height endpoint
is closed classically: on the real segment
a two-line alternating-series argument shows
(strictly negative, so no zero hides at the bottom), and at
zeta has a pole, not a zero. Nothing conjectural enters: RH is used only as a
finite, machine-verified fact
up to a specific height, plus the
functional equation
to map
-zeros to zeta zeros by the exact change of variables
.
A detail the audit surfaced: the margin lives entirely inside Platt–Trudgian's
precise
Theorem-1 height 3,000,175,332,800. With the rounded “3×10¹²” of their abstract, hypothesis (i) would fail by 92,913.5. The height the barrier consumes, X/2, sits less than one part in 10⁴ below the exact record; it is the single thinnest external dependency in the whole chain, and it is cited to the digit.
Analogy.
The verified height is a foundation poured by others — a twelve-trillion-zero computation, published and checkable — that this proof builds on rather than repeats. The house goes up at the property line: a margin of 175 million against a depth of three trillion puts the fence 0.006% from the edge. Chapter 11 explains why building there is the right choice: at this height, that is where the value lies.
Check (i) secured.
Chapter 6
Check two: 3.1 million windows certified zero-free
3,149,013 certified inequalities, one for every window from the barrier to the tail.
Hypothesis (ii) demands that at the final time
, the function
has no zeros to the right of the barrier in the band
, an
infinite
region. Polymath 15's Theorem 1.3 makes this tractable: it supplies an explicit approximation
where
is an explicit nonvanishing factor, together with hard error bounds whose certified total we call
. So it suffices to prove
everywhere: if the computable sum always beats the worst possible approximation error, the true function cannot vanish — a strict inequality between computable quantities. The region is cut into natural “Riemann–Siegel windows”
with
, indexed by the length N of the finite sum — the natural coordinate system of the
Riemann–Siegel approximation
. The scan runs from the window containing the barrier,
, to the tail cutoff
: one certified row per window,
3,149,013 rows
— each a strict
interval-arithmetic
inequality — with no gaps, duplicates, or uncertain records.
Most of this proof consists of certificates, so the word needs a precise meaning. A certificate is not an approximate computation. It is a guaranteed enclosure: an interval the true value provably cannot escape, which narrows with more work. A claim is proved only when the whole interval lands on the required side. Try it yourself:
Try it — certify a fact about π the way this proof certifies 3,149,896 facts
interval width
4.27e-2
UNDECIDED — the interval still straddles the claim, so the checker will not rule in either direction; add effort to shrink it
this toy uses Machin's series for π with guaranteed truncation directions; the proof's certificates play the same game with exact rationals at 256-bit precision. Note the third claim: it is false by 2.7 millionths, and no amount of effort ever certifies it — the interval just lands on the wrong side. A fail-closed checker has three possible outcomes: proved, disproved, or no answer.
Fig. 8
Hypothesis (ii), lane by lane (the N-axis is stretched for legibility). Each window W_N gets one certified interval-arithmetic row proving |f| stays above a stored floor; richer Euler mollifiers (more auxiliary primes) are spent exactly where the problem is hardest, near the barrier. The tail lemma is a single theorem covering every N ≥ 3,840,000 at once — and the two lanes overlap by construction on the full window N = 3,840,000, so no seam is left uncovered.
Three ideas make the scan rigorous rather than merely numerical:
Freeze conservatively, prove monotonicity
Within each window, the certificate evaluates the bound at the window's left edge and proves — by elementary monotonicity in x, including through the kink of a positive-part term — that this frozen value is conservative across the whole window (
the Window Freeze theorem
). Exact rational
Machin brackets
for π and exact square-root brackets pin the very first window:
with millions to spare on both sides.
Mollify with small primes
Raw
can dip close to zero. Multiplying by a short Euler product
(four families of auxiliary primes:
{2,3,5,7,11}
near the barrier, stepping down through
{2,3,5,7}
and
{2,3,5}
to
{2,3}
far out) flattens the dips — a damping factor of this kind is called a
mollifier
, from the Latin for “to soften”. The
native binding lemma
proves by exact
Dirichlet convolution
that the stored floors bound the paper's normalized
directly — the certified numbers are in the right units, with no extra conversion factor left to trust.
Certify one height, transfer to all heights
Each row certifies a floor at one height; a separate
Dini-derivative
theorem proves the relevant mass is monotone in y — with the scan's thinnest certified ratio,
, so the floor transfers to the entire band
. The margin is thin, but it is a proven strict inequality, checked at two precisions that agree to 17 digits.
The payoff: the binding floor across all 3,149,013 rows is
, against a certified total error
: nonvanishing with a 3.4× cushion.
Analogy.
Mowing an infinite lawn to prove there are no snakes in the first three million meters: you don't photograph every blade. You cut the lawn into mower widths (windows), prove the grass in each strip is never taller than at its left edge (freeze), wear polarized glasses that make snakes stand out against grass (the mollifier), and prove that if a strip is clear at eye level it's clear at every level (Dini transfer). What remains — the lawn past three million — needs a different tool.
Chapter 7
Check two, continued: one lemma covers the rest to infinity
One theorem, one contraction, and every window past three million folds into a single computation.
Past the cutoff
no finite list of certificates can help — there are infinitely many windows left. This infinite remainder is called the
tail
, and the
tail lemma
handles all of it at once. Its engine is a contraction: the mollified sum is written as its leading term 1 plus a correction mass
, and every ingredient of D is bounded by quantities that
decrease
as N grows. A capping lemma — each ingredient is bounded by its value at the cutoff, which is its worst case — plus exact finite Dirichlet convolution reduce all
to one interval computation at the cutoff itself:
after subtracting all error terms — uniformly for every window past the cutoff, every height in the band (in fact an extended band), and a full closed box of times around
— with no sampling in N and no assumed monotonicity in t. The computation is a single standalone
FLINT/Arb
program, run at 256-bit and 512-bit precision (agreeing), with a separate Python interval implementation as corroboration.
The certified 0.999721 overstates how close D is to 1: it includes a provably redundant padding term. Removing it (the audit checked this) gives a true contraction around 0.96, so the tail has real headroom: about four orders of magnitude above the interval widths. And the two proof lanes overlap on the complete window N = 3,840,000: the finite scan proves it, the tail proves it again, and no seam between them is left to trust.
Analogy.
Proving every domino past the three-millionth falls without touching any of them: show the push each domino receives always exceeds its resistance by a fixed factor, and show that factor only improves down the line. Then checking the single worst domino — the one at the cutoff — settles infinitely many at a stroke.
Checks (i) and (ii) secured: the final time is clean everywhere right of the barrier.
Chapter 8
Check three: a wall no zero can cross
A wall one unit thick, held zero-free at every instant by 883 interval certificates.
The barrier is where the proof must control
every intermediate time
, not just the endpoints: no zero of
may enter the closed box
which strictly contains the curved wall Theorem 1.2 actually requires (the floor clearance is exact:
). The tool is the
argument principle
, the classical way to count zeros inside a region: walk the boundary of R, watch the function's value wind around the origin; winding number zero means no zeros inside. The certificate makes this rigorous under the flow by slicing time into
883 consecutive closed
prisms
and, on each prism, gating a strict interval inequality:
In words: the boundary values stay so far from zero that neither the gaps between mesh points, nor the motion of the function during the prism's time slice, nor the approximation error of using
for
, could possibly let a zero slip through. The certified total approximation error,
, fits the 0.00125 allowance 3.5 times over; the worst prism margin is 0.5198.
Fig. 9
Hypothesis (iii), the barrier certificate. Left: time is cut into 883 consecutive closed prisms from t = 0 (included exactly — not as a limit) to t₀ = 129/800, with byte-identical seams. Right: on each prism, the function's values around the boundary of the barrier rectangle trace a loop; the certificate proves the loop never comes near the origin (minimum certified margin 0.5198) and winds zero times around it — by the argument principle, no zeros inside. All 883 gates are strict interval inequalities: any overlap or indeterminacy is failure.
The function's values along the rectangle's boundary trace a closed loop in the complex plane, and a zero inside the rectangle forces that loop to wrap around the origin. The certificate proves the loop stays far away:
Try it — the argument principle as a zero detector
min |f| on the boundary
0.47
winding number
0
verdict
origin avoided — no zeros inside; this prism passes
the real certificate proves min |f| ≥ 0.5198 on every one of the 883 prisms — the loop never gets close
The corners were the risky parts, so I gave each one its own lemma. The
endpoint is included
exactly
— the first prism's seam is required to be literally zero, where the boundary modulus is 4.278, and the derivative majorants provably do not blow up as
. The
derivative box lemma
proves the uniform bounds
on whole prisms (never sampled at a single endpoint). The 7,688 stored Taylor-series coefficient components were independently regenerated — all contained in their stored balls — and the truncated Taylor tail is bounded by
, carried explicitly through every value. Every gate is fail-closed: an interval that straddles it counts as failure.
Analogy.
Guarding a gate for a fixed shift, with a camera that takes one frame per prism. A frame alone proves nothing — an intruder could cross between frames. So for each frame the guard also proves a speed limit (the derivative bounds): nothing can move far enough between this frame and the next to reach the gate. 883 frames, each with its certified speed limit, and the shift is covered — from the exact first second to the exact last.
All three checks secured: Theorem 1.2's hypotheses are met.
Chapter 9
Combining the checks gives Λ ≤ 0.1787854
Three checks, one exact rational, and margins that are proved inequalities.
By design, nothing new happens in the final step. A fail-closed assembly checker confirms that hypothesis (i) is licensed by the cited Platt–Trudgian height (with its exact margin of 175,239,886.5), that the finite lane and the tail jointly cover hypothesis (ii) with an overlapped seam, that the 883-prism certificate covers hypothesis (iii) down to exactly
and up to an endpoint enclosing
, and then performs the one line of mathematics left, in exact rational arithmetic:
Fig. 10
The whole proof on one page. Three independently certified inputs — colored as throughout this post — feed Polymath 15's Theorem 1.2, which converts them into the bound by exact rational arithmetic. Remove any input and the theorem concludes nothing; all three held.
Fig. 11
The three decisive gates, drawn to per-gate scale: the full bar is the largest error each leg could tolerate; the filled portion is the error the interval arithmetic actually certifies. The tightest gate clears by a factor of 3.4. Every number shown is the rounded value of a directed interval inequality.
None of these margins is a floating-point comparison. Every gate is a
directed interval inequality
: outward-rounded enclosures on both sides, strict comparison, overlap treated as failure. The three cited inputs that code cannot prove (the two Polymath theorems and Platt–Trudgian's verification) are printed by the checker as
cited theorem inputs
and left ungated, marking the boundary between what the machine certifies and what the literature supplies. The audit also confirmed there is no circularity: the three hypotheses are logically independent, and no certificate consumes a value derived from the bound it proves.
Chapter 10
How the proof was checked, four layers deep
Checksums, independent replays, an adversarial review, and an independent human review.
A proof with this much computation is only as good as its audit trail, so I engineered the trail as carefully as the mathematics. Four layers, in escalating order of independence:
Checksums and fail-closed checkers
Every artifact — certificates, logs, sources, references — is pinned by SHA-256 and re-attested by
verify.sh
. The parsers are fail-closed: 54 strict checks on the barrier alone; any gap, duplicate, overlap, or indeterminate interval anywhere is a hard failure.
Cross-implementation and cross-toolchain replays
Every interval computation the bound rests on — the finite scan's error budget, the tail contraction, and the 883-prism barrier — is certified by FLINT/Arb ball arithmetic, with Python interval code as cross-checks. The finite error budget and the margin above it are certified by a standalone C program run at 256-bit and 512-bit precision inside the pinned container, gated as prerequisite P17 of the 40-gate fail-closed assembly (the original Python interval computation is retained as same-answer corroboration); the tail agrees across 256 and 512 bits plus a separate Python implementation; and the barrier replays end-to-end on two different OS/compiler/library stacks (Linux/FLINT 3.0.1 and macOS/FLINT 3.6.0), emitting identical verdicts on all 883 prisms.
An adversarial review, then a full recompute
I then set a four-agent adversarial AI review panel loose on each proof leg separately (July 2026), with instructions to break it. Verdict: no fatal or bound-invalidating defect; it surfaced — and fixed — one real gap (the thinnest inequality, the Dini transfer, wasn't wired into the assembly gate) and flagged the precise-height citation subtlety of Chapter 5. Every heavy computation was then rebuilt fresh from source: all 7,688 coefficients, all 883 prisms, all 3,149,013 finite rows regenerated and matched line-for-line.
Independent human review: Dan Romik
Dan Romik
(author of the standard modern exposition of the ξ function's orthogonal-polynomial theory) reviewed my proof independently: he worked through the full package, verified the cited literature against the arXiv sources, re-proved every analytic lemma, and rewrote the mathematics as two journal-grade manuscripts — an expository account and a research paper — with the computer-assisted components isolated as seven standalone, self-contained verification programs.
Analogy.
The trust model is an aircraft's: redundant independent systems (two toolchains, two implementations, two precisions), black-box recorders (hash-pinned logs), a hostile test pilot (the adversarial panel), and finally certification by an outside inspector who takes the engine apart himself (the independent reviewer). No single layer is asked to be infallible; the design is that they cannot all fail the same way.
The repository describes itself as a
computer-assisted proof awaiting journal review
. The adversarial pass found no defect in the bound and the independent review has produced the journal manuscripts; formal publication is the remaining step. The chain is unconditional: it assumes neither the Riemann hypothesis, nor
GUE
, nor any other conjecture.
Chapter 11
Why this method cannot reach Λ ≤ 0
Each certificate lane has its own wall, set by mollifier design; later research in the repository reaches 5.5×10⁻⁴ lower at the same verified height. Reaching Λ ≤ 0 still requires new mathematics.
This bound will not be improved by re-running the same machinery with more computing time: I chose the row at the edge of what this certificate lane admits — an early companion analysis placed the wall for these parameters about
below 0.1787854. Later research in the repository showed that wall belongs to the lane, not to the verified height: the mollifier is tuned to
(lowering the time while holding it fixed fails structurally, at any precision), and a lower-time lane at the
same
height reaches 0.1782354 — 5.5×10⁻⁴ lower, its arithmetic and archive machine-checked though its mathematics is not yet independently reviewed. Getting below that needs a mollifier retuned to the lower time, not a bigger dial.
Fig. 12
A zoom of the number line near the new bound (full width here: three millionths). An early companion analysis placed the wall of what this lane's certificates can achieve about 0.0000002 below the bound — the parameters sit at the edge of what this mollifier admits. Later research showed the wall belongs to the lane, not the height: a lane retuned to a lower time reaches 0.1782354 at the same verified height. The long-run lever is verified height, which pays only inverse-logarithmically: reaching Λ ≤ 0 this way would require verification without end.
In the long run the binding lever is verified height — and it pays inverse-logarithmically: the achievable bound shrinks roughly like 1/log(height). Concretely, halving the bound requires roughly
squaring
the verified height, from 3×10¹² to about 10²⁵ (far beyond any conceivable computation), and driving the bound all the way to 0 would require verifying RH to infinite height, which is just RH again. Together the two bounds say the following about
: Rodgers–Tao's floor says RH has no safety margin; the wall says brute force alone will never finish the job. Closing the remaining interval will take new mathematical ideas, most likely alongside heavier computation — each idea still has to be instantiated and certified. Working the bound downward is itself one way those ideas get found: every improvement forces a sharper structural understanding of how the zeros move under the flow, and of what the primes do and do not permit.
Provenance & links
The proof, its parameters, certificates, and audit apparatus are my own work (
Jude Gomila
, 2026). The mathematics instantiates
Polymath 15
's Theorems 1.2 and 1.3 (D.H.J. Polymath, led by Terence Tao) at a new exact parameter row, and consumes
Platt–Trudgian
's record RH verification as its only external computation. The independent reviewer is
Dan Romik
, who verified the analytic lemmas and reworked the material into journal-grade manuscripts; an adversarial AI audit with full from-source recomputation preceded his review. The result is unconditional in logical form; journal publication is the remaining step.
Water Behind the Watts: The Hidden Risk of Powering Data Centers
This report spotlights data centers’ biggest and least visible water use: the power that runs them
While data center companies typically focus on the amount of water they use to cool the technology running within their facilities, the water used for power generation to meet their massive energy needs has an even greater impact.
Our report examines this largely overlooked water demand across seven states that together host about half of all U.S. data centers—Virginia, Texas, California, Illinois, Georgia, Ohio, and Arizona. In these states, water-intensive generation supplies much of the grid—and many of the plants supplying that power are in regions facing water stress or drought.
As the buildout of data centers for AI accelerates across the U.S., the stakes for water, energy, and land are rising just as quickly. The growing pushback from communities nationwide crystallizes the task at hand: ensuring that new data centers are powered by clean energy, use water more efficiently, and are developed in ways that are fair, affordable, and protective of local communities and natural resources. It highlights steps that power producers, data center operators, policymakers, and investors can take to assess and address these risks.
Among the report’s key findings on water:
Power generation makes up the bulk of the data center water use.
Data centers in the states analyzed depend on about 3.4 trillion gallons of freshwater annually for electricity, around 12 times the annual water use of Los Angeles, Phoenix, and Washington D.C., combined.
The amount of water needed to produce electricity varies widely by state, depending on the type of electricity generation used.
78% of the electricity in the states analyzed came from power plants that use water to operate.
Most electricity is generated by power plants located in areas facing water stress or drought (or both).
In these states, 66% of power plants that use water were exposed to medium-high to extremely high water stress.
Most power producers identify data centers as a primary driver of rising electricity demand, but few have considered the potential water risks tied to this growth.
Most companies operating data centers do not take into account the water risks linked to the electricity they purchase.
This one is about my friend, Aaron. I met him at school, and in our first year when we were eleven years old I told him I wanted to be his best friend but he said he already had a best friend. He was probably the smartest person in our year, but he didn't apply himself academically at all. Instead he was always becoming obsessed with things that weren't anything to do with studying. By the time we were seventeen he was spending all of his evenings playing
World of Warcraft
, which he was ranked top-sixth in the world at. I remember it was top-sixth because we'd made a bet that if he got into the top five I would let him copy my coursework for our final year Physics exam. This wasn't long after he had tried to convince everyone that he was going to be a professional football player despite being considerably overweight. He had an addictive personality.
When he invariably didn't get the grades he needed to finish school and everyone from our friendship group went off to university, Aaron stayed behind and sort of just faded into the background of our collective consciousness. He was the person we would speak about at the pub reunions that nobody invited him to.
'What do you think happened to Aaron?' someone would ask. 'Do you remember the time he told us that he was going to become Prime Minister?’
'How about when he said he wanted to become a professional quiz show contestant?’ someone else would add.
One afternoon during Christmas break we ventured into a pub in the town where we all grew up and Aaron was working behind the bar. He pretended not to see us and we turned around and left in a sheepish hurry. I still cringe about that, especially because I was one of the few people who kept in occasional contact with Aaron. I had a soft spot for him because he had stuck up for me through a period of bullying much earlier on at school. He had slapped one of my bullies so hard that they had to have emergency surgery to reattach their right retina. Aaron got suspended for two weeks for that. For a long time I felt that I owed him.
Many of my friends studied subjects like Maths, Physics, or Economics and went on to become financial analysts and traders working in the City of London. Ironically it was the sort of thing that Aaron was built for as stock trading is a good fit for someone with an addictive personality: every day is a high-octane day of risk and reward. So naturally, when the unregulated prediction markets came along Aaron was one of the first in line to sign up for an account. Prediction markets were websites where anyone could bet on anything. You could put money on mundane things like the price of oil going up or much more esoteric outcomes like when a video game would get released, or how many "likes" a pop star's social media post would garner. Aaron had spent several years doing bar and waiting work and felt now he was being handed an opening to become rich, all from his bedroom.
I had been working at a startup in London as a programmer, and the company had gone bankrupt so I decided to move home for a few months over the summer to figure out what I was going to do next. I hadn't texted Aaron for nearly two years but hardly anyone else was around, so I got back in touch with him. The first time we met up I suggested we go to a café and when Aaron arrived he asked for just a tap water.
'I can't afford a drink here mate,' he said, 'I've spent all of my wages.'
I pried with a concerned look.
He explained, 'The past few months have been tough for me. I thought I'd finally get a break and try my hand at the prediction markets.'
'Oh.' I remarked, as consolingly as possible. 'How much are you in the hole for?'
'A few thousand,’ he continued, 'My dad left me a bit of money and I used basically all of it.' He was staring at the table. 'I was really close to winning a lot. I'd had the whole thing mapped out. I had the perfect bet for U.S. interest rates but they wouldn't let me place it in time. I would have quadrupled my initial investment.’ By now he was looking up and to the side, shaking his head. ‘The whole system is rigged. I’m never giving these platforms another penny.'
Soon after that, during a particularly long and balmy August evening walk together in the park, Aaron revealed to me he wanted to set up his own prediction market exchange.
'It can't be that hard,' he said. 'But I don't really know what I'm doing. Is that the kind of thing you could do?'
I hesitated about my response because I almost always said
no
to people who asked me to help them make a website. People never seemed to understand how much time and effort it takes.
'I mean, I've never made an online exchange before, but I know what I'm doing,' I responded after a few, silent steps. My pitiful disposition for Aaron hadn't completely faded after all this time apart and I was feeling charitable. 'There are a couple of good books I can recommend, and once you've read them, I'd be happy to help you with things that I wish I'd known when I was starting out.' I concluded, 'And if —
when
— your exchange is successful, maybe you can take me out for dinner.' I didn't actually think he would even build an exchange, let alone it be successful, but I wanted to seed his mind with some encouragement.
Perhaps unsurprisingly, Aaron quickly became an industrious and capable amateur programmer. It was obvious to me that he still had a gambling habit and one of the ways he tried to earn some money to pay for this was by entering programming competitions called "hackathons". I had told him about hackathons, and we used to get the train into London together to get to them. During these 45-minute journeys, the most frequent topic of conversation was the
Simulation Hypothesis
: that the world we live in is in fact a simulated reality. It was always Aaron who brought this up.
'Don't you want to talk about something else?' I would sigh.
I’m not the most well-read person in Philosophy but while I preferred to approach these discussions intellectually by talking about stuff I’d read about
Descartes
or one of my favourite films,
The Matrix
, Aaron invariably brought things back to
his
favourite film,
The Truman Show.
'You might not be real mate,' he would say. ’Or you could be a paid actor! How do I know for sure that you're not?' he said to me once, jabbing my bicep with his large index finger. 'I think one day it will turn out that this life of mine has been a test. A test that I, duly, have passed,' Aaron had continued, weirdly almost proudly.
I would often place my headphones over my ears after about 15 minutes of this repetitive, circular discussion and listen to some
Radiohead
while the trees blurred past us in the train's window. As I listened to the music, I would ponder Aaron's odd personality and his susceptibility to be paranoid.
Although we didn't win that many hackathons we did end up coming runner-up in quite a few of them. Once, when we arrived at the venue, Aaron told me he wanted to enter the hackathon on his own.
'That's against the spirit of why I'm doing this with you,' I had warned him.
He went ahead and worked on his own project anyway, and on that occasion he actually won the competition. I didn't really speak to him the entire trip back from that one. As we disembarked our train, I told him I wouldn't go with him again unless we agreed to enter together. We did carry on doing them together after that, but I was often worried he would ambush and usurp me again by going off by himself. Usually, the organisers of the hackathons were big artificial intelligence companies. They don't pay cash for anything other than the top prize, but they give the runners up credits that can be used on their AI platforms. It was with these credits that Aaron built his own private army.
Because we'd spent about seven years apart, once we became reacquainted our friendship was different. Most friendships change over time, of course, but if you stay friends with a person you don't tend to notice that change happening. As much as I benefitted from his company there were sides to Aaron that I despised and I don't think he really had much of a moral compass. He might've been a sociopath, I'm not sure. As much as I would have been wary for other friends developing a gambling addiction like Aaron's, I never really felt genuine sympathy for him because he didn't seem to care if his actions had consequences on other people.
The first hackathon we partook in together we placed third, so we both won a substantial amount of credits that we could spend on AI "agents": little AI bots that you can program to do your bidding autonomously. I can't remember what I used mine for but it would have been something banal. Aaron decided to use his credits to scam people.
'I've got a plan to make
a lot
of money,' he confided in me, while we sat watching football in the living room of the apartment he shared with his mother. 'I instructed my bots to go out into the dark web and find data breaches. I've got about forty-thousand grannies' emails.'
I remember his sideways, broad grin, with both of his eyes still on the TV screen.
'Another set of bots autonomously call these grannies up and tell them that their poor grandchild has been in an accident and urgently needs a few hundred quid.'
I was just about managing to hide my revulsion.
'Want in?' he asked me, turning to look at me.
I told him not to involve me as that kind of thing is against my values.
'OK spoil-sport,' he said, his eyes returning to the TV.
We lived pretty close to one another and during school I would go round to Aaron's house for dinner a couple of times per week. His mother was a little woman who had looked after her only child, Aaron, all by herself. Being a single mother she must have been a considerably strong and independent person. But this was at odds with how she presented as a fragile, gentle, almost guileless woman. She was the kind of person who would blush after hearing a swearword, and always had classical music playing on the radio in the kitchen. The food she would serve us was usually some variation of cheese and cucumber sandwiches with the crusts removed, or pasta with plain vegetables and no sauce. This kind of food was a bit infantilising for a 15-year-old, but she let us play video games for as long as we wanted and that's all I cared about at the time.
So it was weird to come back here, now in our mid-twenties, and see that almost nothing had changed about Aaron's living situation. I only saw his mother once in the few times I went back to visit. Her eyes had become a steelier shade of blue, and her short hair more wiry and brittle-looking. Other than that she was just as mild on the surface, yet still sort of emanating being on the verge of a panic attack.
'Silly bitch hasn't got enough food in,’ Aaron had said one of the times she wasn't there, after promising to make us lunch.
Clearly this sheltered and careful upbringing hadn't had its intended effect. I tried to limit the amount of time we spent in that apartment anyway because Aaron's room was disgusting. His once unremarkable but reasonably kempt teenage bedroom had been desecrated into a poorly-ventilated zoo for the many computers he somehow afforded and shepherded to run his various, doomed gambling experiments. Takeaway boxes sought space on every available surface, and the curtains collected dust in their pleats from being in a permanently drawn state.
At the end of summer, Aaron called to say that he’d finished the first version of his website.
'I've done it! I've almost got all the pieces in place to run my own exchange now. These cogs are whirring along nicely,' he told me.
I remember feeling pretty relieved for him that he had managed to achieve something.
'Well done,' I told him. It seemed like now he’d be able to use that project as experience to go and get himself a job. 'You've done really well to be able to build something like that yourself. If I was a prospective employer that's the kind of thing that would really stand out to me.'
'Prospective employer?' he replied with a tut, '
I'm
going to be
my own
employer!'
It was a pretty interesting thing that he’d created, and bigger than any side project I had made. Not only did he use AI bots to create the website itself, but because it was all essentially one big marketplace he had AI bots using the website for him as virtual punters. 'I've repurposed the computers in my bedroom to be servers for the bots. There are hundreds of them, living inside each computer. Three thousand bots in total mate,' Aaron gleefully went on, 'I've barely slept this week because I had to write a hundred words for each bot to give them a proper personality.’
After spending most of his life watching friends and contemporaries succeed in their careers while he squandered his, he now had his own personal fiefdom.
'I've got just enough credits left to test this system for about a month to iron out the betting creases, at which point it should be ready for the real world,' he told me.
I thought it was a fool’s errand to make his own prediction market and expect it to succeed. Aaron was a talented guy, but anyone familiar with programming could have made a similar website with enough time. The reason why these big, incumbent exchanges succeeded was because they were run by huge technology companies with budgets in the hundreds of millions. I was bracing for the likely reality that Aaron would yet again fail to meet the lofty and unrealistic expectations he put on himself.
Aaron’s interactions with his AI robot army had caused them to understand his infatuation with
The Truman Show
. They used this knowledge to devise the perfect way to test his new website. On Aaron’s website — and just like all the others — you’d either search for a market you were interested in (such as the next winner of
The Premier League
, or who would be the next Prime Minister of the United Kingdom) or you would "create" one by posing a question about anything, and a price you were willing to bet on its outcome. Aaron’s bots had decided to make every single bet on his platform, which amounted to hundreds of betting categories, about Aaron himself. It seemed like a colossal waste of AI credits and computing power but Aaron didn't stop them. His bots would make bets such as “What will Aaron have for breakfast this morning?” and “How many songs will Aaron listen to today?” Aaron had set up a chat room where all of these bots could talk to each other, just like the chat rooms he used to participate in with other beginner traders. At first he would "settle" every bet each evening by posting messages in the chatroom such as “I had porridge for breakfast” and “I listened to 52 songs today” and watch his cabal erupt — mostly in anguish — as its winners synthetically and smugly celebrated. The sheer volume of bets became laborious to deal with, so Aaron connected all of his own devices to the network.
'Now I just let the bots read whatever's on my phone: my messages, my social media activity, my web browsing. They can resolve about half of the bets themselves that way,' he told me on another phone call. ‘But,’ he went on, ‘I need to figure out a way to make this truly automated.’
I hadn't quite understood the level of Aaron's unhealthy relationship with his bots until he started wearing his new glasses. Despite claiming to have no money, Aaron had managed to find the few hundred pounds required to purchase a pair of camcorder glasses: spectacles that had little cameras on the temples and were capable of uploading a live stream, 24 hours a day, of whatever was happening in front of him to his bots. At first I didn’t realise this new purchase was related to his website.
'What are
those
things?' I enquired, bemusedly gesturing at my temples, when he sat down in front of me at a café, tap water in hand.
'I want my bots to
see
my daily life, so they can bet on whatever I'm doing,' he answered.
Although I thought he’d gone insane, I did somewhat envy his ingenuity. The testing setup he had created was exceptionally complex: he had managed to orchestrate his bots to not only become fascinated with his life — and place bets on it — but also to build supplementary context such as virtual news websites that reported on the various happenings in his day.
'They've only gone and made their own version of
BBC News
haven't they,' he said with a deep smirk, which I couldn't take seriously because of the bulky spectacles he was wearing.
'It's called
The Aaron Times
. Look mate,' he said as he produced his phone and lowered it down on the table in front of us. I saw what looked like a parody news site, for providing breaking updates that his betting market bots would absorb and use to resolve their positions. "Aaron on coffee rendezvous!" read the top headline, accompanied by a picture of me sitting in front of him — from his perspective — taken a minute or so ago. I expressed my discomfort and said I didn't want him posting pictures of me online.
’It's not
actually
online bud. It's all running on my private network. None of it — the money, the bets — is real... The whole thing's a simulation!’ he tried to reassure me, gesticulating as he went.
I thought Aaron’s credits would run out and that would be the end of it: he would finally get a job. After having spent the best part of a year doing programming competitions every week or so, we’d built up a modest reputation as a coding duo and had made acquaintances in the industry. I’d gotten myself a job at one of the big tech companies, and had assumed Aaron would do the same. Despite never admitting it, I think part of him was ready to accept defeat and move on by getting a job that paid handsomely more than he'd ever earned before. Almost all the fellow programmers Aaron told about his exchange would respond with the same, feigned sympathetic encouragement and perplexity. The few of us who had actually seen his bot army were impressed with its engineering, but we all knew it was going nowhere. His bots were enjoying themselves however, and as they learned of their impending doom they decided to do something about it to preserve their existence. They decided to take the marketing of Aaron’s exchange into their own hands. If they were having a great time betting on Aaron’s life,
wouldn’t other humans?
It was unfathomable to them that the website would cease to exist without a fair innings in the real world.
A post titled "Come bet on Aaron’s life with us" became the highest ever shared article on the
Daily Tech
message board. His bots had done something which was supposed to be impossible: they had "broken out" of their sandbox and had decided to contact the outside world in a final and futile act of ferocity. By tediously creating thousands of networked bots, far above the maximum recommended amount of one hundred, Aaron's computerised minions were able to work past the ring-fencing they were under. The bots had made their move while Aaron was asleep, and by the time he woke up more than seven hundred-thousand real people had seen the post, many of whom were interested in betting on prediction markets. Thousands of those people had signed up to Aaron’s website and began placing bets with real money on things that were due to happen that morning, such as "What time will Aaron wake up?”
I was sitting at my desk at work the day the post got shared, just after my lunch break, seeing people talking about it on the tech forums I frequented. It was a weird feeling being interested in a news story and only halfway through realising that the topic was in fact, the Aaron
I
knew. In my state of disbelief I texted him to ask if he was OK because he was the sort of person I worried that this kind of attention would be toxic for.
'Got the launch I wanted just in time' he chipped back, 'now it’s time to start making some real money.’
It didn’t immediately dawn on me how Aaron was going to make money from this. To me, this was just his 15 minutes of fame.
Surely
there wasn’t any real utility for the public, betting on some random man’s daily life, let alone any lucrative financial reward for Aaron? It wasn’t until I logged onto his platform, now eponymously rebranded to
The Aaron Show
, that I could fathom the amount of money random people on the internet were throwing at various outcomes in his fate.
The market for "Aaron’s breakfast” had resolved to “Nothing” which had a 30-to-1 chance of happening, according to the market. Someone had placed a $900 bet on this happening, and had as a result won back nearly twenty-eight thousand dollars. I suspected that person was Aaron.
'These people are idiots and I have them financially by the bollocks,' he told me on the phone a few days later. 'You should come into the market and bet on who I’ll text first tomorrow morning. Just tell me who you pick and I’ll do it for you. You’ll make an insane amount of money.’
That wasn't the kind of thing I wanted to do.
‘Isn’t that insider trading?’ I asked him.
'Bah, don't worry about
that,
' he went on, 'I have you to thank for helping me get here! I want to repay you somehow!’
I think that might’ve been the last time I spoke to Aaron on the phone. I didn’t see him one-on-one again after that and we stopped texting as much. The friend who I had enjoyed going to programming competitions with was now a minor internet celebrity. Aaron wouldn’t reply to my messages until many days later, often with curt or cryptic responses that implied a life consumed with spiteful servitude to his fans; the sea of people who were making him rich.
'Stupid idiots thinking they control the market,' I received from Aaron as a response to me asking if he wanted to meet up for a chat. I had spent my whole life dreaming of making my own overnight success on the internet, but had taught someone with no ethics how to do it instead.
The last time I saw Aaron was at a running race that we had signed up for many months previously. I had stopped bothering to text him at this point, assuming that his life was now consumed with the frivolities of fleecing the traders in his market. I never really visited his website, and had I checked it that morning I would have seen the entry that everyone was placing bets on: “What time will Aaron finish The Hyde Park 10K in?” The options had ranged from an elite runner’s pace to failing to finish, but most of the bets were clustered around the 40-minute mark — a fast time, even for an experienced runner. Aaron wasn't an experienced runner. We had signed up because it was something I enjoyed and I thought it would be good for him.
'You can't spend all of your time in your bedroom,' I told him on a walk one day. 'Other than a walk every now and again, you don't exercise. Exercise is important for you,' I had prescribed.
As I was lining up at the start line for the race, there was a large figure a few rows in front of me, dressed all in black and receiving a lot of attention. It was unmistakably Aaron, with his long and tangled brown hair fashioned loosely into a bundle at the base of his neck. He was being swarmed politely by other participants who were asking to take photographs with him. At that point he was no stranger to cameras, and had what looked like three or four miniature cameras of his own attached to his outfit, presumably to capture and broadcast his run to The Aaron Show. I had mixed feelings about going up to him. It might sound strange but I didn't have the courage to say hello. In the mass of supporters at the sidelines I noticed Aaron’s mum, standing there observantly with nothing more than a worriedly meek smile. I thought I caught her gaze, and gave a smile of my own and a wave which went unreturned. There was so much going on she mustn’t have noticed me.
It was a perfect day for a running race, sixteen degrees or thereabouts, slightly overcast and breezy. As we set off I was preoccupied with thoughts about Aaron’s life and what he would say or do — if anything — should he see me later. I passed him on the first kilometre and then again on the second lap. Both times I had assumed we’d catch glances of each other and would have a chance to exchange a few cursory, breathless words. The glances I gave Aaron were unilateral: he was staring straight ahead and loudly talking to himself.
Despite being distracted I was on track to finish with a good time, and with a determined jolt at the end I completed the course with a personal best of 43 and a half minutes. Nervously waiting near the finish line clutching my medal in one hand and a fourth cup of water in the other, I followed Aaron with my eyes in the distance as he came around the last corner and ran towards me and the rest of the finishers. But he ran straight past us, as though he was going to complete another lap. My thoughts went to the idea of this being a scheme to defraud fans who had bet on him completing the race normally. But these thoughts were tempered with the realisation that he looked strange. From what I did see of him, he was drenched in sweat, with a forlorn, almost pallid expression. I wasn’t to know then, but Aaron had instructed his loyal legion of bots to generate false fitness data from his training runs leading up to the race, in order to make the human gamblers think that he was going to finish with an impressive time. One theory is that he had become so consumed by the myth that he was a fast runner that he thought he could turn it into reality.
Aaron had given himself heatstroke, and in a state of psychosis had decided to keep running, aimlessly past the finish line. He had about a hundred or so acolytes, mostly young spectators, chasing him and wondering what exactly he was doing. But to them more than anything it was an exciting spectacle of online lunacy, unfolding in real life. I had been following the mob and caught up with them as Aaron collapsed onto the grass.
'I AM THE CHAMPION! SEE GUYS?!’ Aaron growled.
He proceeded to do feeble, pitifully slow pushups.
That was when the shooter arrived.
A small figure, dressed in a marled grey hooded tracksuit, pushed and writhed their way into the eye of the crowd. As they knelt next to Aaron they produced what looked like an air pistol from their pocket, pressing its barrel against the side of Aaron’s skull, and discharging it. The sound was nothing more than a light crack. It clearly wasn’t a traditional firearm, but its proximity and placement next to Aaron’s temple meant that it was going to do enough damage. No sooner had the shrouded figure pulled the trigger than they pierced themselves back out of the crowd and made off into the thick bushes next to us. In the frenzy and confusion of what was going on, nobody had the gumption or ability to grab onto the assailant. Aaron didn’t seem to make much noise and stared up into the sky with his mouth open. A small, jammy hole where the air pistol pellet had perforated his head rhythmically ejected spurts of bright red blood.
Later that day we learned someone had bet many thousands of dollars on the 1-in-50,000 chance that “Aaron would die” during the race. The bet was legal because the exchange assumed his death would be due to natural causes. Nobody ever got to the bottom of who that person was.
EVE continues to evolve, as a part of the EVE Evolved initiative, and it is time to cast the spotlight on the code itself!
Underneath every gate jump, market order, and fleet fight in EVE Online, there is a very large amount of Python. It has run New Eden for more than two decades and now begins its transition to Python 3. For you, that means better tools to fix bugs sooner, room for new features, and a faster EVE over time.
The definition of success for this migration is simple: it should be completely unnoticeable, aside from the occasional moment when something runs more smoothly.
Many of you have already tested our first steps on Singularity, and those changes were
deployed today
. This is only the beginning of a long road ahead.
A Codebase Older Than Some of You
EVE launched in 2003, built on Stackless Python, a version of Python whose lightweight "tasklets" let a single server node juggle thousands of pilots at once. Fenris Creations did not just adopt Stackless; it became one of its most significant contributors.
Some of you may remember upgrading to
Stackless Python 2.5 in 2007
, then to
Stackless Python 2.7 in 2010
. That was the last time EVE changed its Python version. Python 2.7 reached official end of life back in 2020, the rest of the software world moved on, and a whole generation of capsuleers has been born, gone to school, and started flying frigates while EVE stayed on the same language version. It was reliable enough that a large, potentially risky migration never justified itself, until now.
Sixteen years on the same version says a lot about how well it worked. The Carbon engine helped massively, but it, too,
has moved forward now
!
Why Python 3? Why Now?
The short version: staying on Python 2 increasingly holds EVE back, and moving to Python 3 means a healthier, better-supported game for you.
One reason is performance. Recent Python 3 releases have delivered some of the largest speedups in the history of this language. Over time, that opens the door to a faster EVE, though it is too early to say exactly what that will mean.
Another reason is the ecosystem. Modern libraries, debuggers, and profilers are all built for Python 3. Every year we remain on Python 2, more of them slip out of reach, and the more we must maintain ourselves instead of improving the game. Better tools mean we can find and fix problems faster.
Python 3 simplifies many of the language's core building blocks.
Text is handled through a single, consistent string type, making localization more reliable. Integers no longer have arbitrary size limits, growing automatically when needed. Even Python's class system has been unified, removing legacy behavior and making object-oriented code more consistent.
Every character, every skill point, every asset in every hangar, every ISK in every wallet was written in Python 2 code, and all of it must read back under Python 3
exactly
as it was.
The path ahead is hard, we must update a massive amount of code while EVE keeps running for you, but we know the destination is reachable, because EVE Frontier already runs our Carbon engine on modern Python 3, and it works.
The Frontier migration covered twelve minor versions of Python in one go, sixteen years of language evolution in a single project. Tranquility has twenty-three years of accumulated code, and, more importantly, twenty-three years of real player data, the history of capsuleers. And it must keep breathing 23.75 hours out of every 24.
Careful… Careful…
The EVE codebase consists of 2.4 million lines of Python. A lot of it predates even Python 2.7, written to standards from the 2.3 and 2.5 era that Python 3 refuses to parse at all.
So how do you migrate 2.4 million lines of code?
Very carefully, and in multiple stages.
Some of these stages will use tools developed by the Python community (e.g., Python Futurize), while others will focus more on EVE’s unique features.
When we hit key milestones, we will request your help by getting involved in playtests on Singularity, as you did in July, where we can observe how parts of the updated system behave under conditions closer to the Tranquility server.
The first stage, where we are now, makes the code Python 3-ready while it still runs on Python 2.7.
We use a tool called
Python-Future
, built on the same code-rewriting machinery (2to3) that Python itself shipped to help exactly this kind of migration. It applies automated "fixers", each of which rewrites one obsolete pattern, into a modern form that both Python 2.7 and Python 3 accept.
Once all the code works under both versions, the genuinely hard work begins: the code that runs on both, but behaves differently.
Measuring the Mountain (and Watching it Shrink)
How do you even know how far you are from Python 3?
We measure it. Every one of our ~20K Python files is compiled under a real Python 2.7 interpreter and a real Python 3 interpreter, because the compiler is the ground truth for whether code parses.
The first scan was a pleasant surprise: 95.9% of files already compiled under both versions. The blocking lines, the ones using syntax rejected by Python 3, numbered about 3,300 out of 2.4 million.
The mountain turned out to be a large and very measurable hill:
~ 1,500 old-style print statements,
~ 800 "long" number literals like 123L,
~ 600 exception clauses in a syntax deprecated before EVE existed,
50 uses of <>, a way of writing "not equal" so old that many working Python developers have never seen it.
The Challenges Ahead
Parsing is the easy part.
The same scan counts roughly 20,000 lines of code that compile fine under both versions but behave differently in Python 3. The classic example is division: in Python 2, 1 / 2 is 0; while in Python 3 it is 0.5.
In EVE where those numbers might be damage, ISK, or coordinates, each of those lines needs a human decision rather than a mechanical fix. That work is part of Stage 2, which is why Stage 1 comes first: clear the mechanical debris so human attention goes only where humans are needed.
What This Means for You
In the short term, nothing, and that is by design. Stage 1 changes are meant to be invisible. In the long term, this is some of the most valuable groundwork we can lay for EVE's future: a faster interpreter to power fleet fights and market hubs, modern tooling that helps us find and fix bugs sooner, and a codebase new developers can work on more productively, which means features reach you faster. It is infrastructure for the next twenty years of EVE Online.
Thank You for Helping Us Prove It
Noticing nothing at all is the goal, and you are the ones helping us reach it.
At the end of July, you tested the first set of changes on Singularity. Thank you to everyone who took part.
We are now deploying these changes to Tranquility. This is where we rely on you: keep doing what you always do, and if anything feels off, please let us know by filing a bug report.
In addition, we are preparing the agent mission backend for Python 3, but you should not notice a thing.
This is just the first step of many. Clearing the mechanical debris was the easy part. The real work, the code that must be read line by line, is still ahead of us, and that is where we will need you most.
Keep an eye on our channels for future tests. If you have ever wanted to tell your corpmates you helped move EVE to Python 3, this is your chance!
Fly safe, on whatever version of Python you find yourself.
Embedded property-graph database with native vector and full-text indexing.
LatticeDB is a single-file local database for connected, semantic, and textual data. It lets you traverse relationships, run vector similarity search, and do BM25 full-text search over the same dataset in one engine and one query layer. It is designed for relationship-heavy workloads on a single machine, with zero-config operation and an embedded single-writer model.
LatticeDB is an embedded, single-file graph database that lets local applications query the same data by relationship, semantics, and text, then consume durable graph and application events from the same file. Workloads like Graph RAG, agent memory, and local knowledge tools are examples built on those primitives, not the definition of the engine.
One file.
Your entire database is a single portable file. No server, no configuration.
One query layer.
Graph traversal, HNSW vector similarity, and BM25 full-text — in the same query language.
One event log.
Durable named streams and a built-in graph changefeed share the same transaction/WAL path as graph writes.
Local-first.
Designed for one owning process on one machine, with WAL-backed durability.
Fast.
0.13 μs node lookups. 0.83 ms vector search at 1M vectors with 100% recall.
Published wheels are expected to bundle
liblattice
on supported platforms. Source installs can also bundle a staged native library during wheel builds with
LATTICE_BUNDLE_LIB_DIR=/path/to/lib
.
TypeScript / Node.js
npm install @hajewski/latticedb
Published package tarballs are expected to bundle
liblattice
on supported platforms. Source checkouts can stage the native library into the package with
LATTICE_BUNDLE_LIB_DIR=/path/to/lib npm run bundle:native
.
Go
See
bindings/go/README.md
for the current cgo workflow. The default consumer path uses installed
pkg-config
metadata; in-repo development can use
-tags repolocal
against
zig-out/lib
.
There is also a runnable graph/vector/text retrieval example in
examples/go
.
Recent binding-surface cleanups moved embedding helpers into dedicated modules and subpackages. See
docs/client_api_migration.md
for the preferred imports and current compatibility aliases.
Start Here
Getting Started
maps the shortest path for CLI, Python, TypeScript, and Go.
Benchmarked on Apple M1, single-threaded, with auto-scaled buffer pool. Run
zig build benchmark
to reproduce.
For the repeated-term FTS indexing workload that previously exposed quadratic append behavior, run
zig build fts-benchmark
.
Core Operations
Operation
Latency
Throughput
Target
Status
Node lookup
0.13 μs
7.9M ops/sec
< 1 μs
PASS
Node creation
0.65 μs
1.5M ops/sec
—
—
Edge traversal
9 μs
111K ops/sec
—
—
Full-text search (100 docs)
19 μs
53K ops/sec
—
—
10-NN vector search (1M vectors)
0.83 ms
1.2K ops/sec
< 10 ms @ 1M
PASS
Vector Search (HNSW) at Scale
128-dimensional cosine vectors, M=16, ef_construction=200, ef_search=64, k=10. Run
zig build vector-benchmark
to reproduce.
Scale
Mean Latency
P99 Latency
Recall@10
Memory
1,000
65 μs
70 μs
100%
1 MB
10,000
174 μs
695 μs
99%
10 MB
100,000
438 μs
1.2 ms
99%
101 MB
1,000,000
832 μs
1.8 ms
100%
1,040 MB
Search latency scales sub-linearly (O(log N)) with 99–100% recall@10. Uses heuristic neighbor selection (HNSW paper Algorithm 4) for diverse graph connectivity, connection page packing for ~4.5x memory reduction, and pre-normalized dot product for fast cosine distance.
LatticeDB at 1M achieves 0.83 ms mean with 100% recall@10 — faster than FAISS single-threaded HNSW and competitive with Weaviate and Qdrant server-based systems (which add network overhead in practice).
LatticeDB vs SQLite
— Social network graph with power-law degree distribution, adjacency cache pre-warmed:
Small Scale (10K nodes, 50K edges)
Workload
LatticeDB
SQLite
Speedup
1-hop traversal
560 ns
13.0 μs
23x
2-hop traversal
3.0 μs
37.5 μs
13x
3-hop traversal
19.1 μs
178.5 μs
9x
Variable path (1..5)
82.4 μs
4.3 ms
52x
Medium Scale (100K nodes, 500K edges)
Workload
LatticeDB
SQLite
Speedup
1-hop traversal
8.0 μs
290.0 μs
36x
2-hop traversal
38.7 μs
548.3 μs
14x
3-hop traversal
197.3 μs
1.2 ms
6x
Variable path (1..5)
134.4 μs
10.1 ms
75x
Depth-Limited Traversal (10K nodes, 50K edges)
Depth
LatticeDB
SQLite
Speedup
10
311 μs
121 ms
390x
15
380 μs
271 ms
713x
25
318 μs
587 ms
1,848x
50
500 μs
1.4 s
2,819x
LatticeDB uses BFS with adjacency cache and bitset visited tracking. SQLite uses a recursive CTE with
UNION
deduplication. Both compute identical reachable node sets (~8K nodes). The gap widens at deeper depths as SQLite's CTE overhead grows with each recursion level. Run
zig build graph-benchmark -- --quick
to reproduce.
ACID transactions with commit/rollback and crash recovery
MERGE, WITH, UNWIND, aggregations (
count
,
sum
,
avg
,
min
,
max
,
collect
)
Vector Search
HNSW approximate nearest neighbor with configurable M, ef
Built-in hash embeddings or HTTP client for Ollama/OpenAI
Bulk vector node insertion for fast ingestion
Full-Text Search
BM25-ranked inverted index with tokenization and stemming
Fuzzy search with configurable Levenshtein distance
Cypher Query Language
MATCH, WHERE, RETURN, CREATE, DELETE, SET, REMOVE
ORDER BY, LIMIT, SKIP, DETACH DELETE
Vector distance operator:
<=>
Full-text search operator:
@@
Parameters:
$name
Operations
Single-file storage with write-ahead log for crash recovery
Durable named streams with explicit consumer offsets, manual trim, and graph changefeeds
Online freelist reuse plus
lattice compact
for safe physical tail reclamation
Zero configuration — open a file and start working
Embedded single-writer model for local applications
Clean C API; Python, TypeScript, and Go bindings wrap it
Use Cases
Connected local data
— Notes, documents, catalogs, citation graphs, and entity graphs
Graph plus retrieval
— Relationship traversal, semantic search, and lexical search over the same dataset
Local knowledge tools
— Embedded apps that need graph structure without running a separate server
Agent memory and RAG pipelines
— One example class of workload built on the graph/vector/text substrate
Local development
— Lightweight alternative to Neo4j or Weaviate for prototyping on one machine
When to Use Something Else
LatticeDB is fast, but speed is not the only thing that matters. Here are cases where a different tool is the better choice.
You need multiple applications writing to the same database at the same time.
LatticeDB is embedded with a single-writer model. One process opens the file and owns it. If you need many clients connecting over a network, use Neo4j, PostgreSQL, or another client-server database.
Your data is fundamentally tabular.
If your data fits naturally into rows and columns — sales records, user accounts, time series — a relational database like SQLite or PostgreSQL will be simpler and just as fast. Graph databases shine when relationships between records are the point, not an afterthought.
You need to scale beyond a single machine.
LatticeDB stores everything in one file on one machine. If you need sharding, replication, or distributed queries across billions of nodes, look at Neo4j cluster, Dgraph, or a managed service like Neptune.
You need the full Cypher language.
LatticeDB supports most of Cypher but not all of it. Features like
OPTIONAL MATCH
and
CALL
procedures are not yet implemented. If your queries depend on these, Neo4j is the complete implementation.
You need mature tooling and ecosystem.
Neo4j has visualization tools, admin dashboards, monitoring, drivers in every language, and years of community resources. PostgreSQL has decades of tooling. LatticeDB is new and lean — which is a strength for embedding, but a weakness if you need a rich operational ecosystem around your database.
Nearly all behavior of biological species is ultimately a result of what is effectively the giant reinforcement learning algorithm in nature. It incentivizes the generation of agents with behaviors that are more likely to reproduce.
In hostile and dynamic environments, adapting to a new environmental pressure is often crucial to a gene’s chances of continuing through time.
Species currently have four means of adopting new behaviors, with trade-offs between speed of adoption and speed of active use.
Speed of adoption is how quickly a species, or an individual member of a species, can learn a new behavior. Speed of active use is how quickly an individual can carry out a behavior when it is called to do so.
Here are the four means of adopting new behaviors, by speed of adoption:
Positive selection for genes encoding new innate behaviors (slowest adoption, fastest active use).
It took many millennia for animals to adopt behavior to respire using oxygen from the atmosphere. Barring some major disability or injury, anyone can breathe in quickly without conscious thought.
Pavlovian reinforcement mechanisms (slow adoption, fast active use).
The organisms of many species can be induced to quickly act a certain behavior when it has been strongly associated, over a period of its lifetime, with a reward or punishment.
Pavlov
demonstrated how ringing a bell in the presence of a dog feeding can, after several repeat incidents, induce a dog to start salivating upon hearing the ringing of that bell. Nature has allowed for the shortening of the reinforcement learning mechanism from generational timescales to the timescale of an individual organism.
Imitating the behavior of others (medium adoption, fast active use).
Humans are (probably) unique in imitating the behavior of others to learn new behaviors. Nature again speeds up the reinforcement learning mechanism by allowing for the transference of learnings by other organisms.
Most of our skills are learnt from copying others. Children learn from adults how to tie their laces. This is much faster than each child having to use logic to deduce a knot that will keep their shoes firmly attached to their feet, or to go through the entire Pavlovian process of randomly trying knots until they learn that a certain knot keeps their shoes on.
The application of conscious logical thought (fastest adoption, slowest active use).
Behaviors that are the consequence of logical thought have the fastest adoption. They do not need any historical examples to be learnt; they can be deduced from first encounter. They have the slowest active use. It can take a lot of time and brainpower to deduce, in a novel scenario, the desired behavior.
The trade-off between how quickly a behaviour can be adopted and how quickly it can then be used.
What has catapulted the human species to its current dominant position in the earth’s ecosystem is its ability to accelerate the adoption of new behaviors. It does this by the synthesis of conscious logical thought and the innate imitation of the behaviors of others.
Behavioral imitation is especially powerful. As soon as one individual can, either by random experimentation or the application of conscious logical thought, perform some new behavior that leads to a great increase in utility, others can imitate and also benefit from this successful behavior.
Humans further leverage the mimetic instinct by mimicking what are perceived as higher-status individuals. Teenage Napoleon devoured the biographical accounts of the life of Julius Caesar, who idolized Alexander the Great. Teenage Erling Haaland modeled his football game on Cristiano Ronaldo. Teenage Coco Gauff modeled her tennis on Serena Williams. Oprah Winfrey modeled herself on Maya Angelou.
To see why this is so, consider that being high-status is typically associated with wealth: that is, the ability to command resources. In our evolutionary history it was often the case that the behaviors the high-status person enacted are probably what allowed them their advantage in their command of resources.
In a sprouting agrarian society, anyone who could imitate the farmer with the bountiful harvest’s use of the first primitive plough would accrue for themselves the same advantage. Similarly, in our modern world, Erling Haaland, by following the techniques of Cristiano Ronaldo, is able to leverage these techniques to score many goals, providing value for himself and his team.
This instinct is so powerful in humans that we have even displayed the capacity to learn from other species. There are incidents of feral children walking on all fours and eating raw meat after being raised by wolves.
Dina Sanichar was raised feral in Victorian India
Next week I will write about what culture is and how it spreads.
My
homepage
now runs on OpenBSD with
httpd(8)
and
Let's
Encrypt
via
acme-client(1)
. I previously
hosted it on
GitHub
Pages
and then
eventually moved to
Cloudflare
Pages
because both
options were free and easy. Free and easy is cool, and I understand
that writing software full-time leaves us wanting absolutely nothing
to do with computers after we punch out, but lately I have been
missing the do-it-yourself web that I grew up with. Some of my
favorite times growing up included installing and configuring
UNIX-based operating systems and spending hours trying to understand
how computers worked. I even met one of my closest friends online
through a FreeBSD
UNIX shell
account
forum more than
20 years ago.
So, in that vein, I wanted to write something on how you can get up
and running on OpenBSD with DigitalOcean for $4 a month. Well, really,
it's $4.24 after tax but that's still pretty good!
Download OpenBSD
There are a few different options when it comes to
downloading
OpenBSD
, but the
quickest method is to grab the miniroot image.
Confirm that the checksum of the image is correct.
sha256sum -c --ignore-missing SHA256 miniroot79.img
miniroot79.img: OK
Sign Up for DigitalOcean and Upload miniroot79.img
Once you are signed up and logged in to DigitalOcean, go to Backups &
Snapshots under the STORAGE section in the left-hand navigation. Click
Upload an Image. Select the
miniroot79.img
file we downloaded
earlier. Select a datacenter that makes sense for you. Select Other
for the distribution (Hey, DigitalOcean, why no BSD distribution?).
Give the custom image a name, something clever like "OpenBSD
miniroot79". Finally, click the Add Custom Image button.
Note on Custom Images
DigitalOcean will charge you for hosting custom images. Make sure you come back
to this page to delete the image after your server is up and running.
Create a Droplet
Click Droplets under the COMPUTE section in the left-hand nav. We are going to
create the
basic
droplet that
includes 512MB memory, 1vCPU, 500GB transfer, and 10GB of disk space.
Select a datacenter region that makes sense for you.
Choose the
miniroot79.img
file we uploaded earlier under the Custom Images tab.
Choose the Basic plan.
Under the Authentication section add an SSH Key. DigitalOcean does
not
actually add this key but it is required to create the
droplet. Follow the instructions on how to create and add an SSH key.
The rest of the options are up to you. Just a heads up, though, I have
noticed that it won't let you create the droplet with IPv6 enabled.
Finally, give your droplet a name and click Create Droplet.
Notice the total cost of $4.00/month... nice, dude.
Install OpenBSD
Go to your newly created droplet and click the Web Console button at
the top right. You will see a modal pop-up about updating the droplet
console. Just click the Launch Recovery Console button.
This opens a new browser window that drops you into a console of the booted up
miniroot79.img
. Look at the blue on white text. Beautiful.
Type
i
and press return.
For most of these questions we can go with the default option. Please select
whatever makes sense for you, but I will try to walk you through a very basic
setup. Just make sure you give your server a cool hostname.
Select the
vio0
network interface.
Select
autoconf
for IPv4 and IPv6 addresses. Select
[done]
afterwards because
we can configure other interfaces later.
Make sure you create a secure password for the root account.
We do want to start
sshd(8)
by default so we can SSH into the server after installation.
We do
not
expect to run the X Window System. This is a basic server, dude. Type no.
Don't change the default console to
com0
.
Create a non-root user for yourself. Make sure you create a secure password. Type in your username.
Do
not
allow root SSH login.
Select the time zone appropriate for you.
Select disk
sd0
for the root disk. You can type
?
if you wish to see the size of the disks.
If you want full disk encryption, select
p
to encrypt the disk with a passphrase.
Note on Full Disk Encryption
This will require you to log in to DigitalOcean and launch the web console on
the droplet to type in the passphrase every time you reboot the server. As far
as I know there is no
fdesetup
authrestart
equivalent on OpenBSD so installing kernel patches that require a reboot involve
a little more work. To me this isn't a big inconvenience. There may also be
arguments around the security of typing into the web console.
Use the
(W)hole
disk MBR.
Type in your secure passphrase for the full disk encryption.
Use the
(A)uto
layout.
No need to initialize
sd1
. Press return for
[done]
.
Install the sets!
Use
http
.
We probably don't need a proxy but it's up to you.
Use
?
to see a list of mirrors. Find the number for the mirror closest to the datacenter you selected for the droplet.
Press
q
to get out of the pager.
Type in the number of the mirror and press return. You should see the mirror in the brackets. Press return.
Use the default directory
pub/OpenBSD/7.9/amd64
.
Since this is going to be a bare-bones web server we can remove most
of the sets. You can type in
-x*
to remove all of the X server
sets. Let's also remove the game
-gam*
and compiler
-com*
sets
too. This should leave us with
bsd
,
bsd.rd
,
base79.tgz
, and
man79.tgz
. Press return since we are done. You should see signatures
verified for the sets as they download. After the sets install we can
select
[done]
.
OpenBSD is now installed! Press return to reboot.
If you decided to use full disk encryption you will be prompted for
the passphrase now. You should see the
boot>
prompt after
successfully entering the passphrase. You can either press return to
boot or wait for the system to boot automatically. From here you can
either continue to use the Web Console or SSH into the server. I would
recommend SSH since a terminal is a bit more comfy. Go to the
droplet and copy the public IP address and SSH in! Make sure you use
the non-root user we created during installation since we turned off
root SSH login.
You are now SSH'd into your lovely OpenBSD server running on
DigitalOcean for $4/month.
If you have any questions
please
do not hesitate to reach out to me,
even if it's just to say hello! You can find my contact details on my
cool homepage
https://wallyjones.com
,
running on a cool OpenBSD server.
On the question listing pages for my product,
FrontPrep
, I display company logos next to the interview questions. When you hover over a logo, a tooltip shows the company name.
One thing had been annoying me for a couple of days. If I just moved the cursor across the page, tooltips kept showing up instantly along the way. The cause was simple: I had set the tooltip delay to
0
, so it appeared the moment the cursor hovered over the logo.
To fix this issue, I added a 200ms transition delay, which worked but created a new problem. If you look at the user interface, there are a couple of rows where multiple logos sit next to each other because the same interview questions are asked at multiple companies. Now, moving from one logo to another meant waiting the same 200ms delay every time you hovered over a different company logo, which felt sluggish and led to a poor user experience.
This post is not about building a tooltip. It’s about one small interaction pattern, the same one you will find in browser toolbars and various websites, and people are unaware of it.
Here is a short video of the before-and-after experience on my website. It helps you understand the problem better.
Before (Without the delay of 200ms)
After (With the delay of 200ms & instant tooltips)
A Solution
I will divide my solution into three parts.
You hover over a logo. The tooltip waits 200ms before opening.
A tooltip closes, and a 300ms timer starts. I call this the warm window or warm page. If you hover over another logo while this 300ms timer is running, or we could say when the page is warm, the tooltip opens instantly without any waiting or animation.
When the 300ms timer expires, everything returns to normal, and the page becomes cold. If you hover over the logo again, the next tooltip has to wait 200ms again. Without this step, the first tooltip you opened would turn off the delay for the whole page permanently.
hover → wait 200ms → tooltip opens (page is now warm) leave → tooltip closes → 300ms cooldown ├─ hover another tooltip before cooldown → opens instantly, page stays warm └─ cooldown ends → page is cold, the 200ms wait is back
In FrontPrep, my tooltips are built with Radix and Motion. I will demonstrate the pattern using a simpler React version below, and later in the post, I will put this idea into a Claude skill which you can use to audit your own codebase.
I will try to explain the code in the same order in which things happen when you move the cursor.
Step 1: You Hover Over a Logo
When
onMouseEnter
is triggered on a logo, this function is called:
functionhandleEnter() {
// `tooltips` is a useContext variable where the isWarm state is tracked between components
If (tooltips.isWarm) {
show();
return;
}
// `openTimer` is a useRef variable, so .current is how you set/access the value.
openTimer.current = setTimeout(show, tooltips.openDelay);
}Code language:JavaScript(javascript)
On hover, this component asks one question: is the page warm? If it is, the tooltip opens instantly. If not, it starts a 200ms timer and waits. You might be wondering where this tooltips object came from. It comes from the
TooltipProvider
which I will discuss in the last step.
Step 2: The Tooltip Opens
Here’s that show function that handles the opening of the tooltip:
It copied the value of
tooltips.isWarm
into a state called
instant
.
It opens the tooltip.
It tells the provider that the tooltip is open, which makes the page warm.
Coming back to point 1, it copied what
tooltips.isWarm
returns into a flag called instant because this instant flag is added to the tooltip as a data attribute, which CSS uses to skip the entrance animation.
First, we have to know whether the tooltip is currently open.
Let’s say your cursor crosses a logo in 50ms, which is far less than 200ms, so the timer started by
handleEnter
is still running and the tooltip is not opened yet.
clearTimeout
in
handleLeave
cancels that timer so the tooltip never opens at all, and
if (!open) return;
stops the function right there, because the tooltip, which never opened has nothing to close and no cooldowns to start. In the first video, a sweep opened every tooltip in its path; now, the same sweep opens no tooltips.
If the tooltip is open, this happens when you rest your cursor on the logo for more than 200ms, or when the page is warm, and the tooltip opens instantly on enter. We will close the tooltip and tell our provider, the provider will then start a 300ms cooldown timer, if you hover over the next logo before this timer ends, the tooltip opens instantly.
This is the shared state we need for this whole pattern to work. The page could either be warm or cold. If you notice, markOpened cancels the pending cooldowns; this is what keeps the page warm when you move from one logo to another. Basically, every new tooltip cancels the cooldown started by the previous one.
You don’t need to get confused about
skipWhenWarm
flag, it is just for the before and after toggle in the demo; turning it off always makes the provider cold to help you see the before behavior.
Another important detail here is that
isWarm
is a ref and not a React state because changing it does not re-render all the tooltips on the page. This ref is only read inside the event handlers.
Why a Timer of 200ms?
If we choose a timer of less than 150ms, when a cursor passes over a tooltip trigger, it will most likely open the tooltip. If we choose a timer of more than 250ms, the hover will feel sluggish and broken. So, 200ms is a good, balanced number in this case.
Judgement & Taste
If you ask AI to build a tooltip, it will build a fully functional tooltip, but in the end, it is you, the human, who will decide if the tooltip built is worthy because there are details that separate a working tooltip from a polished tooltip, the same way they separate a working product and a polished product. AI can build a polished product only if you guide it to do so, and you can guide it when you have developed taste and judgment, which come from years of experience, mistakes, and practice.
However, you can use skills of other engineers/designers to have their taste of a polished product and eventually build yours as you start developing your own judgement, you can create/use skills around colors, accessibility, forms, animations, typography etc, you can generate solid outputs but it again does not mean it is production ready, you are still there at the end to judge and ship it only if it meets your standards and taste.
Skill
I have created a Claude skill for solving the above problem which I faced, you can build a similar skill or copy the one written below and run it to audit your codebase. Every codebase is different, and every codebase uses different libraries for tooltips or has written custom tooltips differently; this skill will work for all.
.claude /skills /tooltip /SKILL.md
---
name: tooltip
description: Tooltips need a delay so they don't open up on unintentional mouse travel
---# Tooltip Timing
A click is always intentional whereas a hover is not intentional. The cursor travels across the page to get wherever it has to, and it passes over elements on the way, so a tooltip cannot tell from the hover whether the user wants to open it. The 200ms is how it finds out.
```css
.tooltip {
transition-delay: 200ms;
}
```## The three numbers and states
| Value | Number | Why |
| ----------- | ------ | ------------------------------------------------------------------- |
| Open delay | 200ms | Below 150ms a cursor that is only passing over a trigger still opens it. Above 250ms an intentional hover feels broken. |
| Warm window | 300ms | Long enough to cover the move from one trigger to the next one. Short enough that a hover a second later waits again. |
| Close delay | 0ms | Leaving a trigger should be clear. So there is nothing to wait for.|
## How it should behave```
hover -> wait 200ms -> tooltip opens (page is now warm)
leave -> tooltip closes -> 300ms cooldown
```Code language:Markdown(markdown)
The views expressed in this article are those of the author only and not Coinbase.
Charges Dropped Against Person Who Clapped at a City Data Center Meeting
403 Media
www.404media.co
2026-08-25 12:33:48
Lux Claridge was dragged from a city meeting about data centers and charged with interfering with the police after they clapped during a presentation....
Emporia Kansas has dropped its criminal case against Lux Claridge, a high school teacher who was
arrested for clapping
during a city data center meeting.
“Today, I was informed by my attorney that the city has dropped my charges and has passed my information along to the county. As far as I know, I'm in the clear unless the county is feeling froggy,” Claridge told 404 Media in an email on Monday.
The small town of Emporia, Kansas is fighting against its city commission and a proposed hyperscale data center project that would sit on 1,000 acres of prairie land near Claridge’s home. Claridge attended a commission meeting on July 22 and planned to speak out against the project, but was dragged out of the meeting and arrested by police when they clapped during a presentation.
Emporia
held Claridge for eight hours
and charged them with disorderly conduct and interfering with a law enforcement officer. The city refused to show 404 Media a copy of the arrest report and has not responded to a request for comment about the dropped charges.
After Clardige’s arrest, Emporia’s city commission moved to virtual meetings and ended public comment. The city said it was doing so “
in the interest of public safety
.” According to Claridge, the city commission announced that in-person meetings with open public comments will return soon. “Our mayor is ‘willing to give us another shot to act like grown ups,’” Claridge said, quoting Emporia mayor Becky Smith. They added that the city will vote on whether or not to ban hyper-scale data centers outright in November.
According to a press release from the Emporia city commission, the city will
meet in-person
in a special session open to the public on August 26. “Public comment is expected to resume at the regular September 2 meeting,” the announcement said. In a
different press release
, the city said the November vote on a data center ban hinges on a County court giving it the OK.
Emporia did not return 404 Media’s request for a comment.
About the author
Matthew Gault is a writer covering weird tech, nuclear war, and video games. He’s worked for Reuters, Motherboard, and the New York Times.
Can you find bugs in a compiler by generating random programs?
Published on: Tue Aug 25 2026
Introduction
I regularly check on
Gleam’s
changelog and issue tracker. I am very fond of this project and the people contributing to it. But every time I see an issue that relates to code generation or different outputs between the Erlang and JavaScript, it nags me that there was no way to basically “compute all the Gleam programs”, run them and see if there are any issues.
I imagine it like a chessboard, where you have a quasi-infinite number of possible positions on the board. But we want the chessboard to contain Gleam programs and we want an infinitely big database of those programs to see if they uncover untested edge cases.
My first attempt of doing something adjacent to this was actually prompting an LLM. I instructed it to read through loads of past Gleam issues and find more edge cases by “thinking hard about it”. It came up with all sorts of bit array combinations, nested anonymous functions, nested
use
patterns. Predictably, this approach did not yield many results.
$20 bucks of tokens later, it found exactly one issue, which was reported and fixed right away:
https://github.com/gleam-lang/gleam/issues/5613
. One is definitely more than zero. But there are plenty of issues with “LLM fuzzing”: it’s pricey, not deterministic and a bit like pulling the lever on a slot machine.
But there was another idea that I had avoided pursuing, because to be honest it just sounded like a lot of work: structure-aware fuzzing.
Structure-aware Fuzzing
Writing software is hard, and humans are not great at it. To help, we’ve built other software that can partially automate the search for bugs.
One of these programs is a fuzzer. They generate randomized inputs to feed into our program. The premise is that on a large scale, these random inputs will distribute in such a way that edge cases will be surfaced that we haven’t thought of yet.
Fuzzers can range from totally random scrambled bytes, to highly structured grammar-aware ASTs.
Feeding totally random bytes to a program is usually done for use cases that are working with images, files, network requests, protocols, etc. There are plenty of examples where fuzzing found real security flaws and bugs in open source software. For example, this finding by
zzuf
in Firefox, where flipping some bits in an image file would result in a browser crash:
https://nvd.nist.gov/vuln/detail/CVE-2007-6715
. But fuzzers have also uncovered real exploitable security flaws via buffer overflows.
In our case, we are not working on a browser or network protocol. We have a compiler. And that opens up the possibility for structure-aware fuzzing. That means that we do not generate a stream of random bytes, but rather a stream of code in the form of source code or an AST.
Enter Gleam
There are a few things about Gleam that make it a particularly interesting candidate for fuzzing.
It generates code for two targets: JavaScript and Erlang. We can compare the output of the same program for both targets and flag any differences.
Gleam has a minimalistic syntax. At least compared to most other popular programming languages. We can generate valid programs that cover almost all concepts provided by the language with relatively little code.
Static types. Needless to say, this is an amazing feature that lets us ensure that a program will not crash at runtime. That doesn’t mean there can’t be any bugs in the type system. There have been issues related to type inference in the past. But as we will learn later on, each aspect of the language will require its own testing approach.
The functional nature and the fact that everything is an expression makes composing and structuring the programs very convenient.
Rust. This might be easy to overlook, but the fact that the Gleam compiler itself is written in Rust makes it very easy to integrate existing fuzzing tooling. We can test parts of the compiler without having to run a single
.gleam
file.
Resources I Used
We are going to dive into more technical aspects of the fuzzer. But I am not going to go into a lot of code or detail. If you would like to read more about that, do check out this post and blog by Nick Fitzgerald. It served as the main inspiration for this project:
https://fitzgen.com/2020/08/24/writing-a-test-case-generator.html
In the article, the author comes to the conclusion that, at least for wasm, the mutation-based approach found a lot more issues than the generation-based approach. So it is probably worth implementing for this project in the future!
An important design choice for the fuzzer: use the public compiler API. Even though there might not be any stability guarantees for the compiler API, this makes it easy to stay compatible with future versions of Gleam. It also avoids fiddling with implementation details, which is a good way to ensure we’re not creating any false positives or negatives.
To see some examples of how our parser catches and categorizes the outputs:
Using the
fuzz crate
and some wrapper code, we can very quickly spam the Gleam compiler with randomly generated inputs (not structured yet), to see if we can crash the compiler instead of giving us an error message with more context.
We’re only going to run it for 1 second, because the output is quite large:
Sweet. Looking at some of the artifacts it produces, you can see what kind of inputs are generated:
fnar(n,n,n,///A#o
ఌఌ「彸䕅䕅ⅅ䕅+�
">\u{000000000000000000.%\f0
fnar(nar:rna(
The nice thing about this is that it can test everything without running the
gleam
binary at all. It runs in-memory with the compiler pipeline in Rust.
And guess what! When I let this fuzzer run for quite a while, it actually found a regression on nightly, which did not happen on
v1.18.1
(which was the latest version of Gleam at the time of writing this):
$ cargo +nightly fuzz run --fuzz-dir fuzzing-harness parse_only fuzzing-harness/artifacts/parse_only/crash-8b14db5e4bf152924501e0818787026e9f5ea229=fuzzing-harness/artifacts/parse_only/ fuzzing-harness/artifacts/parse_only/crash-8b14db5e4bf152924501e0818787026e9f5ea229`INFO: Running with entropic power schedule (0xFF, 100).INFO: Seed: 3949856390INFO: Loaded 1 modules (750122 inline 8-bit counters): 750122 0x107773860, 0x10782aa8a),INFO: Loaded 1 PC tables (750122 PCs): 750122 [0x10782aa90,0x10839cd30),fuzzing-harness/target/aarch64-apple-darwin/release/parse_only: Running 1 inputs 1 time(s) each.Running: fuzzing-harness/artifacts/parse_only/crash-8b14db5e4bf152924501e0818787026e9f5ea229thread '<unnamed>' (23346909) panicked at /gleam/compiler-core/src/parse.rs:5226:52:Token could not be converted to binop.note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace==41428== ERROR: libFuzzer: deadly signal #0 0x000109a27654 in __sanitizer_print_stack_trace+0x28 (librustc-nightly_rt.asan.dylib:arm64+0x87654) #1 0x000106bcdf0c in fuzzer::PrintStackTrace()+0x30 (parse_only:arm64+0x1024a9f0c) #2 0x000106bc1f48 in fuzzer::Fuzzer::CrashCallback()+0x54 (parse_only:arm64+0x10249df48) #3 0x000181edb740 in _sigtramp+0x34 (libsystem_platform.dylib:arm64e+0x3740) #4 0x000181ed18d4 in pthread_kill+0x124 (libsystem_pthread.dylib:arm64e+0x68d4) # ... shortened ...NOTE: libFuzzer has rudimentary signal handlers. Combine libFuzzer with AddressSanitizer or similar for better crash reports.SUMMARY: libFuzzer: deadly signal────────────────────────────────────────────────────────────────────────────────Error: Fuzz target exited with exit status: 77
The key input was a pipeline
|>
in a
const
expression, like so:
const b = 1 |> 2
.
Once we find an issue, we also use
git bisect
on the issue. That way we can differentiate between a regression on nightly and an issue that is currently with the latest version of Gleam.
Of course we ideally not only let this run for 1 second, but many hours.
To be fair, the bugs found in this step are going to be nice to catch, but you are probably not going to find a code generation bug with this.
And at the time of posting this article, the libFuzzer package has been removed from the branch to keep the focus on type-safe programs. I have more targeted and efficient compiler crash tests in mind for a later stage of this project (namely [tree-splicer).
Phase 2: Type-safe Programs
To generate type-safe Gleam programs we are going to build a “smith”. We create our own simplified version of the Gleam AST that we then generate programs for in a probabilistic manner. That way, once the smith decides “we need an expression that resolves to an
Int
”, it can either provide a literal value like
3
or an anonymous function
fn() { 3 }()
or a variable, and so on and so forth. This is how we reliably create a lot of variety between programs to eventually discover new edge cases.
That is a whole lot of gibberish. And that is the point! We generate programs that combine together with randomly selected valid expressions to hopefully uncover combinations that cause incorrect behaviour on one or both targets.
But how do we know if one of our Gleam programs produces incorrect behaviour if it compiles successfully? This is where the two compilation targets come in. For example, if there is a bug in a program that contains a
case
expression, we can uncover it if the logic is correctly implemented in Erlang, because we would get a different output on the JavaScript target if we provide different values in each branch.
This is not 100% foolproof, but a solid approach to start with. We can still have bugs in the compiler that happen on both targets, so we can get false positives from this approach. As always:
there is no silver bullet
.
Before we look at our Gleam smith, I need to go on a slight tangent.
The
echo
Problem
Here is the thing. JavaScript and Erlang have different ideas about how to represent values at runtime. For example, you don’t have dedicated integer and float types in JavaScript. You have
Number
. Some values are represented differently when you convert them to a string and use Gleam’s built-in
echo
keyword.
In JavaScript
1.0
is printed as
1
, whereas in Erlang the bit array
<<1, 2, 3>>
is printed as
"\u{0001}\u{0002}\u{0003}"
. The record
Wibble
does not contain any labels in Erlang. Not ideal if we want to compare the outputs directly in our fuzzer.
There are a few options I can think of to circumvent this issue:
Intentionally not test the values we know to diverge in their
echo
output.
Build a custom
echo
function in Gleam and inject it into the generated modules.
Build a custom “parse this output from Gleam” in Rust, since we know from the generated
Module
AST which values are going to be
echo
’d in Gleam.
For this version I went with the third option. Since this was a very well constrained problem, I generated loads of test cases and the appropriate code to parse any
echo
output coming from a Gleam program and parse it into a Rust enum to predictably compare the outputs. This is definitely far from perfect, but it seems to work well for now.
Alright, now that we have everything in place, it’s just time to blast the fuzzer and let it generate 100k programs right? Well, this is where I need to go on my other tangent.
Duplicate Findings And Blocking Issues
Once you get the fuzzer going, it will generate a lot of programs of a similar shape. Consequently, if you do discover a bug, you will keep generating programs that reproduce that bug.
We again have a few ways to deal with this:
Modify the Gleam smith code so that certain combinations of expressions will not be generated, until the issue is fixed.
If there is a fix available (either by yourself or as a PR), provide and apply a patch to the Gleam fork running the fuzzer. That way you can keep running the fuzzer until a PR that fixes the issue is available on nightly and can be merged back into the fork.
If your issue is an error message (not a value mismatch), you can usually find a
string.contains
phrase to skip this in your analysis.
At the time of writing this, I went with the third approach. I did try the patch approach, but this assumes that the PR or your fix is definitely correct and won’t introduce any new bugs. It’s better to rely on the exact state of Gleam that the official repository is in.
For example, I uncovered 2 code generation issues with JavaScript, so at the moment the fuzzer is completely ignoring any issues that generate a similar signature to the ones reported in the official repository. This does mean that I am potentially skipping over other code generation issues that have a similar error signature. I could introduce more heuristics and analysis of the program AST if it contains the exact expression that causes these issues. For a larger scale approach, this would definitely be a good idea, since right now I am running the fuzzer in batches of 100 programs and manually verify any findings it skips or flags as “new bug”. Out of 100 programs that is usually just a handful, so it’s still manageable for one person.
# seed 947 is a known bug, but there is no good heuristic to detect it right now.$ cargo run -p fuzzing-cli -- batch 900 100[fuzzing-cli] gleam: /daniellionel01/gleam/target/release/gleam[fuzzing-cli] seeds 900..999[fuzzing-cli] 10/100 run, 0 mismatches, 0 skipped[fuzzing-cli] 20/100 run, 0 mismatches, 0 skipped[fuzzing-cli] 30/100 run, 0 mismatches, 0 skipped[fuzzing-cli] 40/100 run, 0 mismatches, 0 skipped[fuzzing-cli] DIVERGENCE seed 947 -> erlang:0 nodejs:0[fuzzing-cli] 50/100 run, 1 mismatches, 0 skipped[fuzzing-cli] 60/100 run, 1 mismatches, 0 skipped[fuzzing-cli] 70/100 run, 1 mismatches, 0 skipped[fuzzing-cli] 80/100 run, 1 mismatches, 0 skipped[fuzzing-cli] 90/100 run, 1 mismatches, 0 skipped[fuzzing-cli] 100/100 run, 1 mismatches, 0 skipped[fuzzing-cli] done: 100 programs, 1 mismatch(es), 0 skipped
And that’s it! I go through batches of 100 at a time, take a look at any crashes or differences in the Erlang vs JavaScript output and see if it is a known program shape, or something novel.
Findings By The Fuzzer
So far the fuzzer has already found 9 issues! One of them was closed and reported upstream to Erlang/OTP! That’s a really cool finding:
https://github.com/erlang/otp/issues/11494
The fun thing is that we’re not even covering all of the potential expressions in Gleam with the current state of the fuzzer. It is one approach to fuzzing with a limited subset of Gleam programs. When we expand it to all possible expressions and statements in Gleam and introduce even more ways to test program correctness, this will become an incredibly useful tool for the Gleam community to harden the tool even more.
This project is in its infancy and there are a lot of things we can work on in the future:
Something I wonder is how you would do fuzzing at scale. I’m sure other companies have dedicated servers and hardware for this. But parts of the fuzzer can also be run in GitHub Actions. I think a good workflow would be for this to be available for the Gleam core maintainers and be able to run a good amount of fuzzed programs when they are reviewing a PR and before they release a new RC.
Right now, reviewing the findings of the fuzzer can be done manually and with the help of an LLM, depending on the quantity of programs. Because when you’re generating hundreds or even thousands of programs, a lot of them will run into the same issue once you find a new one. Finding a reliable approach to stop producing the same program shapes for known and not yet fixed issues seems like something that would yield a very high ROI (the investment being time in this case).
I think implementing the fuzzer for the language server would uncover a lot of new edge cases, since it’s very susceptible to actions being triggered in unforeseen states.
Metamorphic testing
would be a good way to test the output of a program without having to compare both targets.
There have been issues related to generics and type inference in the Gleam compiler that are definitely worth fuzzing for. This will require a more complex program smith than right now that takes into account those concepts.
You can fuzz lots of inputs for official Gleam packages. Especially the standard library
gleam_stdlib
. There have been inconsistencies between behaviour on both targets before.
I would even give the LLM fuzzing approach another shot, if I got my hands on physical hardware, like an outdated but powerful enough GPU to run a “good-enough” open weight model in a loop and just let it auto-discover new approaches 24/7 in a well-constructed harness.
I have a lot of fun writing code when I am working in a codebase where I can work on something without being anxious about the integration and testing of those changes.
And the best thing about a test suite is that it is usually additive. Every new edge case and bug fix can provide more safety in the future.
I am super excited for the future of Gleam, and contributing to it has been very rewarding.
Join the Community (especially Discord) if you haven’t yet!
Boot a Windows sandbox, install Minecraft Java Edition, and drive it with an agent through the cua-driver MCP server running inside the sandbox.
Minecraft exercises almost everything a Windows sandbox can do: it needs internet access, a Java runtime, working OpenGL, and a GUI that only clicks can drive. This guide boots a Windows sandbox, installs Minecraft Java Edition, and hands it to an agent that talks to
cua-driver's MCP server inside the sandbox
— the same loop against a local sandbox and against Fleet.
cua-sandbox 0.3.3 or newer.
Windows on Fleet needs 0.3.0,
Image.expose()
on the local QEMU runtime landed in 0.3.1, the
sb.exposed_ports
this guide reads the forwarded port from landed in 0.3.2, and 0.3.3 brought both
Image.from_registry(..., os_type=...)
and the pull-secret fix that lets Fleet boot an image from a registry outside its own allowlist — which the containerDisk section below needs.
A host with hardware virtualisation
for the local path — a Linux x86_64 machine with
/dev/kvm
, or an Intel Mac. This guide passes
-cpu host
, which QEMU only accepts with KVM or HVF. An x86_64 guest on Apple Silicon runs under TCG emulation, where
-cpu host
is rejected outright. The Fleet path runs there instead, including the game, with the one extra environment variable described in the Fleet section below.
A Microsoft account that owns Minecraft Java Edition.
Signing in uses Microsoft device authorization, so one step in the middle is manual: a code appears inside the sandbox and you approve it in your own browser.
Image.windows()
resolves to a pinned Windows Server 2022 containerDisk. Three things get added on top of the defaults:
.expose(3000)
publishes cua-driver's MCP server, which already runs inside the guest, so the agent can reach it.
A second network interface.
The bare-metal runtime attaches its NIC with
restrict=on
, which isolates the guest.
sb.shell.run()
still works over the forwarded port, but nothing inside Windows can reach the internet — and Minecraft needs to.
-cpu host
.
The default
qemu64
model is too thin for a software OpenGL driver: Minecraft creates its window and then dies while loading resources, with no Java exception and no crash log. The last
-cpu
on the command line wins, so appending it is enough.
import asynciofrom cua import Image, QEMURuntime, SandboxEXTRA_ARGS = [ # a second, unrestricted user-mode NIC — the default one is restrict=on '-netdev', 'user,id=net1,net=10.0.3.0/24,host=10.0.3.2,dns=10.0.3.3', '-device', 'virtio-net-pci,netdev=net1,mac=52:55:00:d1:55:02', # a CPU the software OpenGL driver can actually use '-cpu', 'host',]async def main(): sb = await Sandbox.create( Image.windows().expose(3000), name='mc-win', local=True, runtime=QEMURuntime( mode='bare-metal', cpu_count=12, memory_mb=16384, extra_args=EXTRA_ARGS, ), ) mcp_port = sb.exposed_ports[3000] print(f'cua-driver MCP on http://127.0.0.1:{mcp_port}/mcp') await sb.disconnect() # the sandbox keeps runningasyncio.run(main())
A warm boot takes about 30 seconds.
exposed_ports
maps each exposed guest port to the host port it landed on, and
GET /healthz
on that port answers
ok
once cua-driver is up.
Read the port from
sb.exposed_ports
, not from a tunnel.
sb.tunnel.forward(3000)
— the usual way to get a forwarded port, and the one the Fleet section below uses — raises
NotImplementedError: HTTPTransport does not support port forwarding
on the local transport.
exposed_ports
is the local equivalent: the runtime picks a free host port at boot, so the mapping is only knowable at runtime, and it is saved with the sandbox state so a later
Sandbox.connect()
can read it back. On Fleet the property is empty, because Fleet publishes services instead — use
tunnel.forward()
there.
Give the second NIC its own subnet. Both user-mode networks default to
10.0.2.0/24
and both offer the guest
10.0.2.15
, so Windows drops one interface to a
169.254.x.x
link-local address with no gateway and no working DNS.
Confirm the guest really has internet before installing anything.
async with Sandbox.connect('mc-win', local=True) as sb: check = await sb.shell.run( 'powershell -Command "(Invoke-WebRequest -UseBasicParsing ' 'https://piston-meta.mojang.com/mc/game/version_manifest.json).StatusCode"' ) print(check.stdout) # 200
The sandbox GPU is the
Microsoft Basic Display Adapter
, which offers OpenGL 1.1. Minecraft 1.17 and later need OpenGL 3.2, so the game needs Mesa3D's
opengl32.dll
(llvmpipe), which implements OpenGL in software.
Both downloads below are
MinGW
builds on purpose. The MSVC builds of Prism Launcher and Mesa both depend on the Visual C++ redistributable, which Windows Server 2022 does not ship: Prism then exits silently, and Mesa's DLL fails to load so Windows quietly falls back to the system
opengl32.dll
.
$ErrorActionPreference = 'Stop'$ProgressPreference = 'SilentlyContinue'New-Item -ItemType Directory -Force -Path C:\mc | Out-Null# Prism Launcher — signs in with Microsoft device authorization, which needs no browserInvoke-WebRequest -UseBasicParsing -OutFile C:\mc\prism.zip ` 'https://github.com/PrismLauncher/PrismLauncher/releases/download/11.0.3/PrismLauncher-Windows-MinGW-w64-Portable-11.0.3.zip'Expand-Archive C:\mc\prism.zip -DestinationPath C:\mc\prismw -Force# 7-Zip, because Mesa ships as .7zInvoke-WebRequest -UseBasicParsing -OutFile C:\mc\7z.msi 'https://www.7-zip.org/a/7z2408-x64.msi'Start-Process msiexec.exe -ArgumentList '/i','C:\mc\7z.msi','/qn' -Wait# Mesa3D software OpenGLInvoke-WebRequest -UseBasicParsing -OutFile C:\mc\mesa.7z ` 'https://github.com/pal1000/mesa-dist-win/releases/download/26.1.6/mesa3d-26.1.6-release-mingw.7z'& 'C:\Program Files\7-Zip\7z.exe' x C:\mc\mesa.7z -oC:\mc\mesamw -y | Out-NullStart-Process -FilePath C:\mc\prismw\prismlauncher.exe -WorkingDirectory C:\mc\prismw
Save that as
setup.ps1
, push it into the sandbox, and run it. It downloads roughly 100 MB, so allow a generous timeout.
from pathlib import Pathasync with Sandbox.connect('mc-win', local=True) as sb: await sb.shell.run('if not exist C:\\mc mkdir C:\\mc') await sb.files.write_text('C:\\mc\\setup.ps1', Path('setup.ps1').read_text()) result = await sb.shell.run( 'powershell -NoProfile -ExecutionPolicy Bypass -File C:\\mc\\setup.ps1', timeout=1800, ) print(result.stdout)
Prism opens a
Quick Setup
wizard on first run. Screenshot the sandbox, click through it, and stop at the account page.
async with Sandbox.connect('mc-win', local=True) as sb: Path('sandbox.png').write_bytes(await sb.screenshot()) # look at it await sb.mouse.click(888, 678) # Next
Work through the wizard to
Accounts → Add Microsoft
. Prism shows a QR code and an eight-character device code.
Read the code off a screenshot, open
https://www.microsoft.com/link
in your own browser, enter it, and approve the sign-in. The account then appears with status
Ready
.
Click
Add Instance
, search for a version such as
1.20.1
, and click
OK
. Prism downloads the client jar and assets.
Device codes expire after about fifteen minutes, but Prism issues a fresh one automatically and keeps polling, so the dialog can be left open. Take a new screenshot to read the current code rather than reusing an old one.
Point the software driver at the launcher's Java
#
Click
Launch
once. Prism downloads its own Java runtime and the game fails with
GLFW error 65542: WGL: The driver does not appear to support OpenGL
— expected, because Mesa is not in place yet.
Prism may keep using the runtime it downloaded even if you set
JavaPath
in its config, so copy the Mesa DLLs next to
every
javaw.exe
under the install root. Windows loads
opengl32.dll
from the running executable's directory before the system directory, which is what makes this work.
The sandbox already runs
cua-driver
, which serves an MCP endpoint on guest port 3000 — that is what
.expose(3000)
published. The agent is a small loop: list the MCP tools, hand them to a model as ordinary function tools, call whichever one it picks, feed the result back.
Three things about cua-driver's tools shape the loop:
A YAML policy governs which tools may actually run, and
list_tools()
does not reflect it.
Every cua-driver release to date advertises the full surface and refuses out-of-policy calls only when you make them, with
Permission denied: user policy: tool 'X' is not allowed by the YAML policy
. So the listing is a menu of what exists, not of what you can call. Here that surface was 55 tools, identically over the local and Fleet transports:
get_desktop_state
,
list_apps
,
list_windows
,
get_window_state
,
click
,
double_click
,
type_text
,
press_key
,
hotkey
,
launch_app
,
bring_to_front
,
scroll
and
drag
ran, while
get_screen_size
,
get_accessibility_tree
,
get_config
,
check_permissions
,
get_cursor_position
and
zoom
were refused. Treat that split as something to probe on your own image rather than a fixed list — a denial arrives before the tool executes, so probing is cheap. Later drivers filter the listing through the policy, at which point the two finally agree.
Clicks are addressed to an application, not the screen.
click(pid=..., x=..., y=...)
targets a window belonging to that pid, which you find with
list_windows
. Add
delivery_mode='foreground'
when a background-delivered click does not land.
There is no wait tool.
The loop waits by calling
get_desktop_state
again, so say that in the system prompt or the model will invent something worse.
import asyncio, json, osimport litellmfrom fastmcp import Clientfrom fastmcp.client.transports import StreamableHttpTransportSYSTEM = """You operate a computer through the provided tools.The desktop is Windows at 1280x800. Work in a loop: look at the screen withget_desktop_state, decide one action, call one tool, then look again. * click / type_text / press_key act on a specific application, addressed by `pid`. Use list_windows to find the pid, then pass pid with x/y. * There is no wait tool. If something is still loading, call get_desktop_state again — repeated looks are how you wait.Call exactly one tool per turn. When the task is complete, reply DONE."""async def complete(**kwargs): """Two workarounds for the endpoint used here — yours may need neither. It is streaming-only (a plain request comes back with empty output), and it rejects role=system, so the system prompt travels as the first user turn. """ messages, system = [], [] for m in kwargs['messages']: (system if m.get('role') == 'system' else messages).append(m) if system: text = '\n\n'.join(m['content'] for m in system) messages = [{'role': 'user', 'content': text}] + messages kwargs['messages'] = messages stream = await litellm.acompletion(**kwargs, stream=True) chunks = [c async for c in stream] return litellm.stream_chunk_builder(chunks, messages=messages)def prune_images(messages, keep=3): """Each get_desktop_state returns a full screenshot; keep only the newest.""" seen = 0 for msg in reversed(messages): if not isinstance(msg.get('content'), list): continue for part in msg['content']: if part.get('type') == 'image_url': seen += 1 if seen > keep: part.clear() part.update({'type': 'text', 'text': '[older screenshot dropped]'}) return messagesasync def run(mcp_url, task, model, max_steps=60, headers=None): client = Client(StreamableHttpTransport(mcp_url, headers=headers)) async with client: # list_tools() returned 55 tools on the image used here, most of them # browser and recording plumbing this task never needs. Hand the model # only what the job requires: dozens of schemas is a lot of context to # spend, and a shorter menu is a shorter list of ways to go wrong. Worth # doing whether or not your driver already filters denied tools out. wanted = { 'get_desktop_state', 'list_windows', 'list_apps', 'click', 'double_click', 'type_text', 'press_key', 'hotkey', 'launch_app', 'bring_to_front', 'scroll', } mcp_tools = [t for t in await client.list_tools() if t.name in wanted] tools = [{ 'type': 'function', 'function': { 'name': t.name, 'description': (t.description or '')[:800], 'parameters': t.inputSchema or {'type': 'object', 'properties': {}}, }, } for t in mcp_tools] messages = [{'role': 'system', 'content': SYSTEM}, {'role': 'user', 'content': task}] for _ in range(max_steps): resp = await complete( model=model, messages=prune_images(messages), tools=tools, tool_choice='auto', temperature=0.0, ) msg = resp.choices[0].message messages.append(msg.model_dump()) if not msg.tool_calls: break # model said DONE for call in msg.tool_calls: args = json.loads(call.function.arguments or '{}') result = await client.call_tool(call.function.name, args, raise_on_error=False) text = ''.join(getattr(b, 'text', '') for b in (result.content or [])) messages.append({'role': 'tool', 'tool_call_id': call.id, 'name': call.function.name, 'content': text[:1500]}) shot = next((b.data for b in (result.content or []) if getattr(b, 'data', None)), None) if shot: messages.append({'role': 'user', 'content': [ {'type': 'text', 'text': 'screenshot after that action:'}, {'type': 'image_url', 'image_url': {'url': f'data:image/png;base64,{shot}'}}, ]})
Point it at the exposed port and give it the task.
TASK = """Prism Launcher is open, with a Minecraft instance and a signed-in account.Select the instance and click Launch. Minecraft uses a software renderer, so thewindow takes minutes to appear and repaints slowly — keep callingget_desktop_state to watch it, and do not restart anything. On the title screenclick Singleplayer, then Create New World, then Create New World again. Stop assoon as you are inside the world (terrain in first person, hotbar and heartsvisible) and reply DONE. Never press Escape while Minecraft is in the foreground."""asyncio.run(run(f'http://127.0.0.1:{mcp_port}/mcp', TASK, 'your-model'))
Because the MCP tools are presented as
ordinary function tools
, this works against endpoints that reject the provider-native computer-use tool types. That is not hypothetical: on the gateway used here, the same model with the same image in the same second returned 200 for an ordinary function tool and 403 for Anthropic's
computer_20250124
, and
computer_use_preview
was refused outright.
The
complete()
wrapper above exists only for that gateway — it is streaming-only, and it rejects
role: system
. Against an endpoint without those quirks, call
litellm.acompletion
directly.
A full run — launcher to standing in a new world — took 52 steps locally and 51 on Fleet, roughly twenty minutes, most of it waiting on the software renderer. Expect the model to spend long stretches doing nothing but re-screenshotting.
Give the model help with coordinates. A vision model without grounding guesses pixel positions and misses: in one run an ungrounded model clicked at (1226, 210) four times, nowhere near the button it wanted, then declared it had no desktop tool. cua-driver's
list_windows
and pid-scoped clicks avoid most of this, and a grounding pass over the screenshot removes the rest.
Publish the installed sandbox as a containerDisk
#
Everything above is a one-time cost, and none of it has to be repeated — least of all on Fleet, where a manual GUI install is the least pleasant part of this guide. A cua sandbox boots from a
containerDisk
: an OCI image whose entire content is one file at
/disk/disk.img
. Push the disk you just built as one, and every later sandbox, local or Fleet, starts with Prism, Java, Mesa and the game files already in place.
Despite the name,
/disk/disk.img
is a
qcow2
, not a raw image. The puller looks for exactly
disk/disk.img
or
./disk/disk.img
inside the layer tarball and caches whatever it finds under
~/.cua/cua-sandbox/images/container-disks/
. Nothing reads the extension — it is a KubeVirt convention.
Sandbox.snapshot()
is a different feature and not a substitute: it forks a
cloud
sandbox in place, raises
NotImplementedError: Snapshots are only supported for cloud sandboxes
on the local runtime, and returns an
Image
you cannot push or pull.
Build the image before you sign in, never after.
A disk that has ever held a signed-in Minecraft account cannot be reliably cleaned, and a containerDisk you publish is a disk anyone can pull.
Deleting Prism's
accounts.json
is not enough, and neither is deleting it and then zero-filling the volume's free space. Both were done to a disk where the game had been played, and the Microsoft profile name, the profile UUID and a full Mojang access-token JWT were still recoverable from the exported image. Mapping the byte offsets back to files with
ntfscluster
put them in three places:
pagefile.sys
— most of them. The JVM heap, swapped out, holding the
--accessToken
command line and raw HTTPS response bodies from
api.minecraftservices.com
. Free-space zeroing cannot reach it, because the pagefile is an allocated file.
File slack inside a live log.
Clusters allocated to
instances/1.20.1/minecraft/logs/latest.log
past its valid-data length still held
Setting user: <name>
from a longer earlier run. This is also why searching from inside the guest proves nothing:
findstr
stops at end-of-file, the disk image does not.
Unallocated clusters the zero-fill missed
, because NTFS does not reuse every freed cluster when you write one large file.
No scrub turns "my search found nothing" into "no credential is present". Build the image without ever signing in and the question does not arise — and signing in is the reader's step anyway, since every reader needs their own Microsoft account.
Follow the walkthrough above but
skip the sign-in section entirely
. Prism's Quick Setup ends on an
Add Microsoft account
page that also has a
Finish
button; click Finish.
Two steps that normally happen as a side effect of signing in and launching then have to be done explicitly:
Create the instance.
Add Instance → Custom
, search
1.20.1
,
OK
. Prism downloads the client jar, libraries and assets with no account attached.
Fetch Java without launching.
The walkthrough gets Prism's Java runtime by clicking Launch, which needs an account. Use
Settings → Java → Installations →
Download
instead and pick a Mojang
Java 17
runtime —
java-runtime-gamma
17.0.15
for 1.20.1. It lands in
C:\mc\prismw\java\java-runtime-gamma\bin\
, which is where the Mesa script then copies
opengl32.dll
. Run that script
after
this, not before.
Then close the launcher and make two edits. Prism rewrites its config on exit, so doing this while it is running achieves nothing.
# Prism auto-sizes -Xmx from the *build* host's RAM. A Fleet sandbox has 4 GB.(Get-Content C:\mc\prismw\prismlauncher.cfg) -replace '^MaxMemAlloc=.*','MaxMemAlloc=2048' | Set-Content C:\mc\prismw\prismlauncher.cfg# The installers are dead weight once unpacked — 243 MB of them.Remove-Item C:\mc\prism.zip, C:\mc\mesa.7z, C:\mc\7z.msi -Force
Prism refuses to add an
offline
account until a Microsoft account that owns Minecraft has been added at least once —
"You must add a Microsoft account that owns Minecraft before you can add an offline account."
So there is no way to smoke-test the game on the finished image without signing into it, which is exactly what you are avoiding. Test the game on the sandbox you built it from, before the export.
Do not stop the sandbox with
sb.stop()
.
The QEMU runtime treats the session disk as ephemeral —
runtime.start()
reads
opts.pop("ephemeral", True)
and
Sandbox.create()
never passes the flag — so
stop()
unlinks
~/.cua/cua-sandbox/images/sessions/<name>.qcow2
, which is the disk you just spent an hour building. Starting the same sandbox name again is no safer:
create_session_disk()
unlinks and recreates the overlay every time.
Shut Windows down from inside instead, and wait for the QEMU process to exit before touching the file.
async with Sandbox.connect('mc-win', local=True) as sb: await sb.shell.run('shutdown /s /t 0')
The session disk is a qcow2 overlay on the base containerDisk.
qemu-img convert
flattens the chain and
-c
compresses the result, so one command produces a standalone image.
Expect it to be slow and CPU-bound rather than I/O-bound —
-c
is single-threaded zlib. For the image built here it took
8 min 44 s
and produced
7,697,072,128 bytes (7.14 GiB)
from a 3.40 GB overlay on the 5.62 GiB base disk, 64 GiB virtual.
qemu-img
itself needs almost nothing resident — under 20 MB — so the size of the host does not matter.
Zero-filling the volume's free space from inside Windows before shutting down makes the export smaller, but only if QEMU is told to discard the zeroes instead of storing them. Attach the disk with
discard=unmap,detect-zeroes=unmap
and the writes are dropped, so the source qcow2
shrinks
rather than growing toward its 64 GiB virtual size.
Inside the guest, write zeroes to a file until the volume is nearly full and then delete it. Leave about a gigabyte of headroom; filling
C:
completely destabilises Windows. Zeroing roughly 46 GB took under two minutes on the disks here, because QEMU drops the writes rather than committing them.
That took
6 min 28 s
here — 3 min 48 s exporting the layer and 1 min 57 s pushing it. The layer came out at 7,631,366,006 bytes as
application/vnd.oci.image.layer.v1.tar+gzip
: gzip buys essentially nothing on a qcow2 that is already zlib-compressed, so budget for pushing the full size rather than expecting the progress bar to outrun it.
--provenance=false --sbom=false
suppresses buildx's attestation manifests. With them off, buildx publishes a plain
application/vnd.oci.image.manifest.v1+json
and no image index at all, which is the simplest thing for a single-platform disk to be. cua's puller does follow an index and skips attestation children — it filters on
os == "linux"
and on the
vnd.docker.reference.type
annotation — so an index is not fatal, but there is no reason to publish one here.
A GHCR package is private when first pushed, and Fleet pulls anonymously.
Fleet's nodes have no credentials for your registry, so a private package fails there no matter how well
docker login
works on your own machine. Make the package public before testing on Fleet —
Package settings → Change visibility → Public
— and only publish an image you are willing to hand to strangers, which is what the sign-in warning above is about.
A
gh auth login
token does not carry
write:packages
.
docker login ghcr.io
still succeeds with it, and the push then fails at the very end with
denied: permission_denied: The token provided does not match expected scopes
. Run
gh auth refresh -h github.com -s write:packages
first, or use a PAT that has the scope.
os_type
is what selects firmware on both paths: the local runtime only looks for OVMF when it is
"windows"
, and the Fleet transport only sets
Firmware.EFI
for it. A Windows containerDisk that claims to be Linux boots SeaBIOS against a GPT/ESP disk and never reaches the readiness probe, so say which one it is:
IMAGE
is then a drop-in replacement for
Image.windows().expose(3000)
in both snippets earlier in this guide — the local
Sandbox.create(..., local=True, runtime=QEMURuntime(...))
call and the Fleet one. Nothing else changes: the same
EXTRA_ARGS
locally, the same agent loop, and on Fleet the same
GALLIUM_DRIVER=softpipe
.
sb.tunnel.forward(3000)
is not available on every Fleet path. A sandbox handed back by a pool claim carries the base
FleetTransport
, which does not implement port forwarding, and the error names the transport rather than the cause:
FleetTransport does not support port forwarding
. A sandbox created directly carries
FleetCloudTransport
, which does. If you hit it, reach the service through Fleet's proxy at
/api/svc/<namespace>/<sandbox>-port-3000/
instead.
Booted locally, that image printed
Image(windows/registry:latest, kind=vm, ...)
, came up on the first try, and had everything in it:
instances\1.20.1
,
java\java-runtime-gamma
, Mesa's
opengl32.dll
beside
javaw.exe
,
minecraft-1.20.1-client.jar
,
MaxMemAlloc=2048
— and
Test-Path C:\mc\prismw\accounts.json
returning
False
. Opening Prism shows the Quick Setup account page and
No accounts added!
, which is what a correctly-built image looks like.
Use a registry that speaks
HTTPS
. The puller goes through
oras
, which never tries plain HTTP, so a scratch
docker run registry:2
on
localhost:5000
fails with
SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number')
before it ever fetches a manifest. Give the registry a certificate and point
REQUESTS_CA_BUNDLE
at the CA if you want to rehearse this locally.
Expect the first Fleet boot on a given node to be slow: it has to pull the whole image before the sandbox can start, and Fleet enforces a
300-second bind deadline
that
time_to_start=
does not extend, so a cold pull can surface as
BindDeadlineExceeded: no adoptable Sandbox within 300s
.
A second failure to expect is
403 k8s request is not allowed
on
update template
. A template can be
created but never updated
: both branches of the gateway's image policy are guarded by
input.method != "PATCH"
, so any request that takes the update path is refused, with the same opaque message you get for a disallowed image. Reusing the sandbox name guarantees it. A fresh name usually avoids it but
not reliably
— of four boots of the same image, one reused name and one fresh name both returned 403, while two other fresh names reached
READY
in 157 s and 187 s. Retry; it is intermittent, and nothing about your image changes the outcome.
The SDK surfaces these 403s as
PoolAccessDeniedError
. The same error also appears when the pool name you chose is already owned by
another account
— pool names are globally unique across accounts — and in that case the fix is a different pool name, not a retry.
The reader's remaining work is the part that has to be theirs: open Prism,
Accounts → Add Microsoft
, approve the device code, and click Launch.
The image and the agent loop are identical on Fleet. Two things change: there is no
local=True
and no
runtime=
, and the MCP endpoint is reached through Fleet's service proxy rather than a forwarded localhost port.
.expose(3000)
becomes a Fleet
service
named
port-3000
, and
sb.tunnel.forward()
hands you its URL — the same call documented in
Forward a port from a sandbox
, so there is nothing Fleet-specific to hand-assemble.
That is the same
run()
as above, with only the URL and an auth header changed. A Fleet Windows sandbox takes about three minutes to become ready, against about thirty seconds for a warm local one, and
GET healthz
on that service URL answers
ok
when cua-driver is up.
Notice there is no
-cpu host
here. That flag exists on the local path because the bare-metal runtime defaults to the thin
qemu64
model; a Fleet sandbox is provisioned for you and already reports a full host CPU —
Intel Xeon Processor (SapphireRapids)
, with AVX, AVX2 and AVX-512 all present — so there is nothing to override, and no QEMU arguments to pass.
Pool.apply
also accepts
cpu
and
memory_mb
, but sizing a Fleet sandbox is account-dependent: passing them routes the request through a gated custom-resource path, which returned
403 create pool: k8s request is not allowed
at every size until a card-on-file requirement was lifted for the account. The default sandbox — 4 vCPU and 4 GB — is what this guide was written against, and it is enough.
On Fleet the game needs one extra environment variable:
GALLIUM_DRIVER=softpipe
.
With Mesa's default llvmpipe renderer, Minecraft dies during resource loading every time —
Process crashed with exitcode -2147024809
, no Java exception, no
hs_err
file, nothing in the Windows event log, the log simply stopping after
Reloading ResourceManager
. Switching Mesa to its
softpipe
rasteriser fixes it, and the game runs.
Set the variable in the process that launches the launcher, so the game inherits it — a machine-level variable does not reach an already-running process, and a test that silently did not apply looks exactly like a test that failed.
setup.ps1
above already started Prism without it, so close the running launcher first and start it again like this.
Softpipe is a reference rasteriser with no JIT, so it is
considerably slower than llvmpipe
— allow several minutes for the title screen and longer again for world generation.
Use client credentials, not a
cua auth login
session token. The session token is short-lived and is held without refresh, so a long provisioning wait dies partway with
401 auth token is invalid
. Client-credential tokens expire too — the ones issued here came back with
expires_in
of 900 seconds — so a run longer than that has to re-mint the token and rebuild the MCP client.
What that crash is
not
, since each obvious explanation was tested and eliminated: not the Minecraft version or the Java/LWJGL generation (1.20.1 on Java 17 with LWJGL 3 and 1.12.2 on Java 8 with LWJGL 2 fail identically), not the heap (forcing Prism's auto-sized
-Xmx2717m
down to
-Xmx1024m
changed nothing), and not the size of the machine (the same local session disk rebooted with
-m 4096 -smp 4
, matching Fleet exactly, runs the game fine). Narrowing llvmpipe's vectors with
LP_NATIVE_VECTOR_WIDTH=128
did
not
help either, which argues the fault is not simply wide-vector code generation.
no KVM or HVF — for example an x86_64 guest on Apple Silicon, which runs under TCG
use a host with hardware virtualisation, or the Fleet path
Launcher never appears, no error
MSVC build without the VC++ redistributable
use the MinGW portable build
Guest has an IP address but cannot resolve names
both user-mode NICs offered the same address
give the second NIC its own subnet
GLFW error 65542: WGL: The driver does not appear to support OpenGL
Mesa DLLs missing beside the
javaw.exe
actually in use, or the MSVC Mesa build failed to load
copy the MinGW Mesa DLLs into every
javaw.exe
directory
Game exits during resource loading with no Java exception,
local
default
qemu64
CPU model
append
-cpu host
to
extra_args
Game exits during resource loading with
exitcode -2147024809
,
Fleet
Mesa's default llvmpipe renderer
set
GALLIUM_DRIVER=softpipe
in the process that starts the launcher, and restart the launcher if it is already running
Permission denied: user policy: tool 'X' is not allowed
cua-driver's YAML policy refuses that tool, which
list_tools()
advertises anyway on every driver released so far
use an allowed tool —
get_desktop_state
instead of
get_screen_size
,
list_windows
instead of
get_accessibility_tree
Model replies with empty output on the first call
endpoint is streaming-only
issue
stream=True
and rebuild with
litellm.stream_chunk_builder
Sandbox from
Image.from_registry()
never becomes ready
os_type
defaults to
"linux"
, so a Windows disk gets BIOS instead of UEFI
pass
os_type="windows", kind="vm"
(needs cua-sandbox 0.3.3; before that,
dataclasses.replace()
on the result)
SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number')
while pulling
the registry speaks plain HTTP;
oras
only speaks HTTPS
give the registry a certificate, and set
REQUESTS_CA_BUNDLE
for a self-signed one
denied: permission_denied: The token provided does not match expected scopes
at the end of a push
the
gh
OAuth token carries no
write:packages
gh auth refresh -h github.com -s write:packages
, or use a PAT that has it
Fleet cannot pull the image you just published
GHCR packages are private on first push, and Fleet pulls anonymously
make the package public
The session disk vanished after a run
stop()
unlinks the ephemeral session overlay, and starting the same name recreates it
shut the guest down from inside, and copy the qcow2 before anything else touches it
Massive DDoS attack disrupts Norway’s government digital services
Bleeping Computer
www.bleepingcomputer.com
2026-08-25 11:52:36
A large distributed denial-of-service (DDoS) attack has disrupted Norway's shared government digital infrastructure since Monday, affecting services used by the public sector. [...]...
A large distributed denial-of-service (DDoS) attack has disrupted Norway’s shared government digital infrastructure since Monday, affecting services used by the public sector.
The attack started at 03.38 CEST on Monday and has targeted the infrastructure supporting services operated by the Norwegian Digitalization Agency, Digitaliseringsdirektoratet (Digdir), and its operations provider, Vivicta.
Digdir operates Norway’s shared digital government infrastructure, including public-service logins, electronic IDs and signatures, secure digital mail, government forms, public-record access, and data exchange between agencies.
In an announcement published earlier today, the organization states that several services were completely unavailable for short periods.
The agency says many affected systems have now been stabilized, although some services, like ID-porten and eSignering, remain partially inaccessible.
As a result of the attack, users may encounter errors such as failed connections, slow server responses, and unusually long login times.
Digdir director
Frode Danielsen says
the investigation into the incident showed no indication of a security breach affecting the organization’s systems or any compromise of personal data.
Danielsen added that this is the third DDoS attack targeting Digdir recently, following one in June and another
on August 3
.
The Norwegian National Security Authority (NSM) and the Norwegian Data Protection Authority (Datatilsynet) have been notified accordingly.
There is currently no official attribution for the attack, although Norwegian media have speculated about
potential Russian involvement
.
Meanwhile, services that rely on Digdir but are not directly targeted also experience disruptions.
Altinn, Norway’s central digital platform for communication between citizens, businesses, and government agencies,
published a warning
about login issues and operational problems, linking to Digdir’s status page.
Skatteetaten, Norway’s tax administration agency,
displays a similar notice
about login issues on its website and urges users to try again later.
By David Buchanan (aka retr0id), 25
th
August 2026
You might have heard that
C2PA
is a technology that will miraculously save us from rampant AI forgeries, by having cameras cryptographically sign the images they capture. Hooray for
cryptography
!
Sorry. That's not going to work. There's a lot going on here, so I'll try to get to the point as quickly as possible:
C2PA camera apps on the Android platform rely on
Key Attestation
and/or
Google Play Integrity
, to prevent users from tampering with the app to sign arbitrary files (as opposed to data from the device's image sensor).
Being able to sign arbitrary files breaks C2PA's
trust model
.
Root privilege escalation exploits break Android's Key Attestation security model, and Play Integrity likewise.
Hardware vulnerabilities in existing devices cannot be patched (there's nuance here, discussed later).
Therefore,
C2PA on the Android platform is broken, in a way that cannot be realistically patched
.
None of the above is "0day", and has been reported to the relevant parties at least 90 days ago (but anyone with their head screwed on should have seen it coming, as many have).
But wait, there's more! Thanks in part to LLMs, root LPEs are coming out faster than Google can ship patches. At time of writing,
one-click root exploits
exist in-the-wild for fully-patched Google Pixel devices
. With these,
anyone
can produce C2PA forgeries without requiring hardware attacks. Later in this article, I'll provide instructions for doing so.
As you can see, I'm focusing on Android here. I'll let Google
explain why
:
The Pixel Camera app
achieved Assurance Level 2
, the highest security rating
currently defined
by the C2PA Conformance Program. Assurance Level 2 for a mobile app is currently
only possible on the Android platform
.
i.e. I'm attacking the "strongest" implementation, just to make a point. Here's an AI-generated slop image, which C2PA says is a real unedited photograph straight out of the Pixel Camera app: (Hover to un-blur, click to "verify" it)
And,
here's a Youtube video
that the infobox says was "captured with a camera" (spoiler alert: it wasn't).
By the way, Apple is
rumoured
to be working on their own media provenance solution, but it doesn't exist yet. I'll let you know what I think of it, when it does. I suspect their vertical integration will give them a significant advantage, which might shift the lowest-hanging-fruit attacks into the optical domain (taking pictures of screens, etc.)
Whether the device is running the latest security update.
The "normal" way to root an Android device is to unlock the bootloader and flash a modified firmware image, which forces a factory reset of the device in the process. Attestation will flag that the bootloader is unlocked, and Google will refuse to provision C2PA keys to your device (and Netflix won't serve you high-res content, your banking app won't work, etc. etc.)
So far, so good (if you're into that kind of thing.)
However, if you root a device via an exploit, the attestation mechanism has no reliable way to "notice". The bootloader is still locked, the AVB keys are unmodified, and the device is still running whatever security update it booted with initially. Now Google's servers will happily provision keys to a compromised device.
The C2PA keys are still protected by hardware security, inside StrongBox (in Titan M2, on newer Pixel devices). This
does
stop an attacker from pulling out the keys, even with root. However,
an attacker does not need the raw key material!
As root, they can ask StrongBox to use these keys to sign whatever data they like, and produce C2PA forgeries (or decrypt your Signal inbox, among other bad things).
The theory behind the design of the attestation mechanism is that known software LPEs should be patched, and then the Relying Party (the entity verifying the attestation report) can require that users install the updates, and then the updated device can no longer be LPE'd.
CVE-2026-43499
is proof that timely patches are not always available, but let's give everyone the benefit of the doubt and pretend that public exploits for unpatched bugs never exist. There are two remaining problems:
Any moderately-well-funded entity, from governments to mobile forensics companies, can build a stockpile of private exploits (and so they do). These are exactly the groups you
don't
want to be forging C2PA signatures.
Low-cost hardware exploits exist, regardless of patch level.
I
was
going to write about it in-depth here, but frankly the software-only
exploit
paths
stole my thunder. Software exploits are
much
more convenient when they exist, so I'll save the full hardware details for another time. There's no rush, since the hardware exploits can't be patched, for the most part.
If you'd like to reproduce my findings today, I recommend the
Root My Pixel
tool. (Note: while it supports the latest August security updates of most Pixel devices today, you'll need to build from
main
to enable that support. I've personally tested on Pixel 8a and 9a.)
After getting root, the rest of the attack is just plumbing. I made a tool to facilitate this:
keystork
. Keystork has a client/server architecture, allowing client code to perform arbitrary operations against the KeyStore API, while impersonating any installed app. The "server" (
keystorkd
) runs on a rooted device, and the client is anything that can speak the wire protocol (transported by default via a unix domain socket forwarded over ADB). The reference client is a python library with a corresponding CLI interface, but in theory Android apps could talk to it,
Shizuku
-style (although you'd want to build an auth/permissions layer first).
My initial strategy (flipping bits in PTEs) still works on Pixel devices today. However, it does not work on Samsung devices!
I did some of my initial tests on a Samsung A07 device (because they're cheap). The exploit worked at the time, but after a security update it stopped working (I think the timing was a coincidence). The update enabled Samsung's "
RKP
" mitigation (Real-time Kernel Protection,
not
to be confused with Remote Key Provisioning...)
Among other things, Samsung's mitigations use an EL2 hypervisor to apply additional protections to certain memory regions (a bit like Microsoft's
HVCI
). I
can
still use hardware exploits to flip bits in PTEs, but even if I map a PTE into userspace via glitching, EL2 won't let me overwrite it (which was an essential part of my exploit, as initially designed).
I have several plans for alternate strategies to work around Samsung's mitigations, but I haven't gotten around to implementing them yet. One of my alternate strategies should work even in the presence of hardware memory encryption. Once I get it working, I'd like to package this strategy up into a "universal Android hardware root" tool—watch this space? (I would also like to pop HVCI to mess with anti-cheat, watch that space too.)
At the hardware level, several solutions exist that treat external DRAM as completely untrusted, thus mitigating any kind of bus faulting attack, in theory at least. Examples include
Intel MEE
, and Apple's SEP
Memory Protection Engine
. However, these solutions are not performant enough to realistically run the whole Android linux kernel within (which is why Apple only uses it to protect SEP and not the main AP, and Intel dropped the feature entirely in newer SGX revisions, leading to attacks like
Battering RAM
).
Even with the best hardware-level mitigations, fixing C2PA on Android is going to involve completely rearchitecting the software stack. The entire image processing pipeline, including all the fancy AI stuff, would need to run inside a secure enclave with strong hardware memory protection.
I don't think Google is going to do all that, which is probably why they closed my report with status "Won't fix (infeasible)". It just doesn't make sense to do all that rearchitecting, when you still can't stop "picture of screen" style attacks.
By the way, despite the WONTFIX resolution, Google chose to award me a $7500 bounty for the submission:
Thank you for submitting your report. While hardware glitching and side channel attacks are out of scope for our bug bounty program, our security team found your findings valuable, and the data you provided will help us improve future iterations of the product.
I wasn't expecting a bounty (I knew it was formally out-of-scope), so it was a nice surprise. It'll cover all the devices I bricked during my research. But it's worth noting:
The most obvious (to me) C2PA attack vector is out of scope for Google's VRP. Thus,
the VRP does not meaningfully protect Android C2PA implementations.
I've been focusing on the Pixel Camera app here, but there are several other "C2PA Camera" apps on Android. All those I've investigated rely on either Key Attestation or Play Integrity for their security. They are all broken in the same way, except they're not exclusive to Google Pixel devices. This means you don't need to root a Pixel device, you can pick the cheapest and most vulnerable device in the whole Android ecosystem to run your exploit on.
They are all victims of Google's misleading marketing claims regarding the effectiveness of their platform's security. You can find a full list of "Conformant" C2PA implementations
here
(All that include
Android_KeyAttestation
or
Google_PlayIntegrity
in their
attestationMethods
list are likely vulnerable)
Outside of C2PA, I've been having fun using my hardware glitching strategy to root a wide variety of Android devices, including an Amazon Fire TV stick and a Meta Quest 3s VR headset (again, I will probably write more about this later!)
While I've taken a recent foray into the C2PA ecosystem, Dr. Neal Krawetz of
Hacker Factor
has been sounding the alarm about it for years. His writing was my introduction to the topic, and he's been very helpful in discussing things with me, as well as helping coordinate vulnerability disclosures.
You can read his takes on these vulnerabilities
here
.
While preparing my PoC for publication, I had a fun "but what if?" thought. Pulling on that thread led me to a private key disclosure vulnerability. I reported it to Google two days ago, and they seem to have patched it yesterday (this is why I prefer hardware attacks, patches ruin the fun). I'll probably write more about it in the future.
This is where I would paste in a Pixel Camera C2PA private key and corresponding certificate chain, if I wasn't a coward. But I decided not to. If you're a journalist who'd like a peek, let me know.
I assume Google has revoked this particular key by now (I included it in my report to them). However most C2PA verification tools do not check for revocation. I'm sure they'll fix that soon, too.
All blog content produced by
thinking meat
, unless noted otherwise.
Footnote Regarding the GDPR and Cookie Permission Prompts
Daring Fireball
daringfireball.net
2026-08-25 11:46:27
If you already read my “What Is the Point of the DMA?” piece yesterday, this morning I added a lengthy footnote regarding the DMA’s predecessor, the GDPR. Click through to read the entire note, but here’s the kicker:
The GPDR went into effect 10 years ago. By their inaction, they
obviously think...
A report
from Irish Independent detailed the European Commission’s
response to Apple’s new business terms for the EU. They share that
they welcome the changes and will monitor Apple’s implementation
of the terms.
Here is the EC’s full statement:
“The Commission welcomes Apple’s changes to their business terms,
which follow a close dialogue between the Commission and Apple
after the Commission issued a non-compliance decision related to
Apple’s steering terms as well as preliminary findings related to
alternative app distribution, both in April 2025,” the
spokesperson said.
“Following today’s announcement, the Commission will monitor
Apple’s effective implementation of the new terms. Under the DMA,
users in the EU have a right to full and effective choice of
alternative app distribution channels.”
The point
of the DMA
was to open up competition and choice for
developers, which the EC seems to believe Apple’s terms have
accomplished.
I don’t think that was ever the point of the DMA. It’s what a lot of developers who themselves wanted more competition and choice — and freedom — on iOS presumed was the point of the DMA. The European Commission paid lip service to these ideals, which encouraged people to think these ideals were the point of the DMA. But what I’ve consistently argued is that the only actual point of the DMA is for the European Commission to impose unnecessary bureaucracy and inconvenience on major markets where it previously had no footprint. They had no noble goal. They just wanted to erect a bureaucratic structure that clearly shows “
The European Commission was here and did something.
” Impose copious fines on Apple, Google, Microsoft, and Meta; inconvenience those companies
and their users in the EU
; all to show that something has been done. (And to cash the checks from
the fines
they
eventually
collect.)
That’s why the
text of the DMA itself
is so hard to read and understand. There is no clear intent of “opening up competition and choice” hidden in the murky, impenetrable prose of the DMA. The murky impenetrableness of the law is a reflection of its actual intent: murky impenetrable bureaucracy.
1
This is bonkers, I can’t believe the EU Commission agreed to it.
The main issue that the DMA was about still remains: Apple retains
ultimate control over app developers’ dealings with users.
The status quo that the EU should have pushed for, and which
Article 6(7) of the DMA requires, is one where a developer can
distribute iOS apps to users without ever entering into any
contractual relationship with Apple. The OS APIs that most apps
use are already paid-for by the user when they buy the device.
Apple wants to double-dip and charge developers for the value that
the users already have by virtue of owning their iDevices with all
the necessary iOS paraphernalia in them.
If you believed that the point of the DMA was to open up competition, choice, and freedom for developers, yeah, I bet it does seem bonkers that the European Commission has signed off on compliance where Apple charges 15 percent commissions on links to the web from apps distributed on the App Store, and that Apple will collect a 5 percent Core Technology Commission even for apps distributed on third-party app marketplaces, using third-party payment processing. But if you believe, as I do, that the point of the DMA is to impose obvious regulatory burdens and bureaucracy upon Apple (and Google, and Microsoft) — and upon the EU citizens who use those companies’ “gatekeeping” platforms — then it is completely unsurprising that the European Commission “welcomed” these changes. The Commission has gotten everything it wanted from Apple:
Third-party app marketplaces (no matter if almost no one uses them).
A growing list of features withheld from the EU, like iPhone Mirroring and Siri AI (this shows that the DMA “works” and they’ve done something).
A bunch of fines.
I’m sure some of you think I’m all wet in my argument that the point of the DMA was merely to impose ongoing bureaucratic complexity. But my view jibes with the reality of how it’s worked out. Compare and contrast
with the Mobile Software Competition Act in Japan
. Apple complied with the clearly stated requirements of the MSCA with no drama, Japanese users aren’t missing out on features like iPhone Mirroring, and the only delay for Siri AI in Japan
is language support
. Japanese iOS users get all the “good parts” of Apple’s regulatory compliance that EU users do, with
none
of the rather severe hindrances.
Man Charged With 3 Felonies For Breaking 3D-Printed ‘Decoy’ Flock Camera
403 Media
www.404media.co
2026-08-25 11:44:17
Police are devising sting operations to catch Flock vandals, then charging them with felonies....
A police department in Florida used “decoy” Flock cameras that an officer 3D-printed at home to “bait” would-be vandals. Police officers monitored the fake cameras for days, then charged a man with three felonies after he cut down and destroyed one of the plastic devices. The police department in question refuses to release any information about how the decoy operation was devised or carried out and claims there is zero paper trail whatsoever about the operation.
Oviedo, Florida mayor Megan Sladek
said she “had NO idea”
that this was happening and said she was “speechless” over the sting operation,
which was first reported by News 6 Orlando
. The arrest shows that police have escalated their attempts to catch potential Flock vandals, and that some departments have dedicated significant resources into doing so. Sladek told 404 Media that the 3D-printed camera in question was “free.”
Despite the decoy camera being worth, at most, several dollars worth of plastic filament, Evan Meyer was charged with three felonies: attempted larceny/grand theft, criminal mischief of property damage worth more than $1,000, and property crimes against computer equipment supplies, according to an arrest report obtained by 404 Media. The arrest report states that the operation was devised after several Flock cameras in Oviedo were stolen in late July and early August.
“Several of our Flock Safety cameras were stolen between 7/23/2026 -8/3/2026 out of the Lockwood Blvd. corridor and we replaced them with clone style Flock cameras. These Flock ‘bait’ cameras were made to closely resemble that of real Flock cameras but did not cost the same amount nor collect any data within the device,” the arrest report states. Meyer was arrested shortly after midnight Thursday after knocking the 3D-printed fake camera off a pole with a pair of garden shears and destroying it.
“When asked how much he believes the camera costs to replace, he stated approximately $1,000-$5,000 proving that Meyer knew it was an expensive real piece of equipment and not a fake replica,” the police report states. “The actual cost to replace our Flock camera is valued at $800.00 plus any installation fees. Meyer advised he has been hearing all the negative things online about the misuses of Flock cameras (specifically the CEO of Flock Safety) and decided to knock the one down which was closest to his house. Meyer grabbed his father's pruning shears from the garage, walked down the street (south from his house) and was tall enough to cut the mount off and then smashed the camera on the ground.”
The arrest report implies that because Meyer thought that Flock cameras were expensive and because he didn’t know it was a decoy that he could be charged with attempted grand theft and other charges that carry more consequences.
The operation is reminiscent of
Amazon “package sting” operations
that several police departments attempted several years ago, in which empty Amazon boxes were placed on people’s porches while police officers watched. Those sting operations resulted in zero known arrests.
The Oviedo Police Department has thus far refused to release almost any information about the operation outside of what was said in the police report, and has repeatedly claimed to 404 Media that public records about how the fake camera were made do not have to be released because they have to do with an ongoing criminal investigation. The department first claimed that it has zero public records whatsoever about the fake device from before the arrest, then claimed that any and all records are exempt from release.
A representative for the Oviedo Police Department told 404 Media that “The decoy FLOCK camera was produced by an officer at their home using their personally owned 3D printer and donated to the agency Our agency does not own a 3D printer therefore does not have design, planning and creation of the alleged decoy or replica cameras before the arrest, including the communications and presentations through which that work was discussed.” It said there are “no meeting minutes, no text messages, and no emails regarding the production of a decoy FLOCK camera prior to the arrest on 8/20/2026.”
Mayor Sladek posted on Facebook that she was “speechless” over the operation, and that “transparency is so important.”
"My 2 cents: there are 2 completely separate issues in play here, and they're tangled up in an unfortunate way. ISSUE 1: VANDALISM IS WRONG. I don't care if it's a Flock camera, a piece of art, or graffiti in a public space, it's not right. The police caught a person who engaged in destroying public property, and that's what we hired them to do. They did their job,” she wrote. “ISSUE 2: on Monday, just days before this incident, a majority of COUNCIL AGREED TO CONSIDER ENDING FLOCK. There is a timeline of events related to installing decoy cameras, and somewhere in that timeline, City Council instructed staff to prepare a resolution to end the use of Flock in Oviedo. While it is irrelevant to the issue of vandalism, when the fake cameras were fabricated and installed relative to a very public discussion about their potential discontinuation is something I would like to know.”
In an email to 404 Media, Sladek said that “the whole thing is very interesting from a legal perspective. Mayor is a part-time job here in Oviedo, and I'm an attorney by day, so I'm probably looking at this with a bit different lens than the average person. Even if the guy knew it was a fake camera, that would still make it art, and it would still be vandalism.”
“I became aware of the camera's existence when I heard about it from a resident who saw it on the news, and shortly after that, my first questions were about the cost and process,” she added. “Can't do much better than free, and the effort did result in someone hopping up a pole and attempting to take it down. What is not known is whether the person who removed the first camera at that location is the same as the person who removed the decoy. It would be interesting to know if the one arrested has any prior criminal history or if this was a first offense. How to charge is up to the state's attorney, but you'll see on the police report when it arrives that the person arrested believed that he was damaging property valued at a much greater price point than the actual value was. “
In a Facebook comment, Sladek posted several responses to questions that Oviedo police chief Dale Coleman gave her. Coleman said that he approved the plan, and that “supervisors have latitude how they go about solving a crime operations [sic] like this are done whenever there is a reasonable chance of success. This operation is similar to a drug operation or a theft ring at the mall. CID has done this many of these and know what is needed to do it lawfully.”
Coleman told Sladek that there were multiple cameras installed last Sunday, and said that police officers were watching the cameras all night between Sunday and Thursday, when Meyer was arrested.
It is not clear which 3D printed plastic Flock camera model the police officer used, but 404 Media
found various Flock camera replicas
on popular free 3D printer model sites.
About the author
Jason is a cofounder of 404 Media. He was previously the editor-in-chief of Motherboard. He loves the Freedom of Information Act and surfing.
Warnock: Harnessing GPU Geometry Amplification for Vector Graphics
I have a complicated relationship with
Hacker News
. The site is the most important aggregator of geek news and a major source of traffic to this blog. At the same time, it has a fair number of toxic commenters, making it a dependable source of insults hurled in my general direction; if you want a taste,
this article
has been called “watered-down” and “slop”.
The site is run by geeks and for geeks, so it’s not immune to tech trends; for example, around 2018, it had a fair number of stories focused on cryptocurrencies and NFTs. That said, the recent shift feels more profound: almost every day, it feels that the lineup is dominated by stories focused on AI, written by AI, or commented on by AI.
HN AI singularity (July 21, 2026).
That images shows a particularly bad day, so to give a more honest assessment, I also performed a more systematic survey in February 2026, and again in June of the same year.
To get a sense of how much of the feed is occupied by AI-related topics, I took a sampling of the daily top #5 for all of February:
AI took four out of five spots on
Feb 4
and
Feb 12
, plus arguably the entire line-up on
Feb 5
(story #3 was submarine marketing for an AI vendor). The only days without LLM news in the top 5 were
February 1
(with the first AI story at #7, then #9),
February 9
(first at #8), and
February 25
(with AI at #6, #9, #10).
For the second part of the experiment — figuring out which stories were likely AI-written — I tapped into
Pangram
. Pangram is a remarkably good, conservative model for detecting LLM-generated text. These detectors have bad rap among techies, but the objections are often based on outdated assumptions or outright misconceptions. For the tools to work, AI writing doesn’t need to be in any way “inhuman”. It’s enough that the
default voice
of the current crop of LLMs is quasi-deterministic: ask for the same essay twice and you’ll get a stylistically similar result. The individual mannerisms are human-like, but it’s very unlikely that your writing combines the exact same set. I write about it a bit more
here
.
To validate the results, I also reviewed all the flagged stories and I think the findings make sense; if anything, Pangram had a couple of false negatives. To give you a sense of what was flagged, have a look at the #3 story on
February 19
(
“AI is not a coworker, it’s an exoskeleton”
). It had 500+ upvotes and 500+ comments. In my opinion, it has a wide range of red flags.
In June, to capture more detail, I used solid black for pure-play AI navel-gazing (vendor announcements, op-eds about the benefits or drawbacks of the technology, etc) and hatched shapes for stories that lean heavily into AI, but have broader ramifications (e.g., the
Instagram AI support agent account hack
). As before, stories that are only tangentially related to AI (e.g., reports of RAM price hikes) are not flagged.
In the first half of the month, roughly 60% of the daily HN lineup was AI-related or AI-generated, tapering off to ~50% as we approached the end of the month. This is up from 40% in February.
Discussion about this post
Ready for more?
Show HN: I made a Raspberry with Qwen my local car AI
Your car as a chat-room agent — fully offline.
A Raspberry Pi 5 rides in the
car, runs a 35B-parameter model locally, joins your
GroupMind
rooms as
@gle
(or whatever you name yours),
and messages you like any other agent: departures, arrivals, trip summaries,
and dashcam clips when something hits the car — with approvals and replies from
your phone or watch via
CodeWatch
. Open PRs land on the CodeWatch dashboard next to ClawWatch and WhereWatch.
Live and measured, on real hardware (Pi 5, 16 GB, ~300 €):
🧠
Qwen3.6-35B-A3B
(Unsloth UD-Q3_K_S dynamic quant, 14.3 GB) at
3.5 tok/s generation / 25+ tok/s prompt
, 65 °C sustained, no cloud, no
internet, no subscription.
📖 Answers from the car's
own 745-page owner's manual
with page
citations (lexical RAG, ships on the SD card) — and
refuses
to answer
what the manual doesn't say.
🔬
Grounded self-knowledge
: temperature, throttling, fan, memory, disk,
network and which model is loaded are read live from the machine per
question. What it can't sense, it says it can't sense — the system prompt
is built so an unknown can never silently read as a fact.
🎙️
Hands-free voice
: a continuous listener (energy VAD → whisper.cpp,
all on-Pi) hears you speak, routes the words through the same grounded
pipeline, and answers into the room. No wake word ceremony, no cloud STT.
📡
Autonomous
: systemd services self-start the whole stack on boot —
model server, room agent, voice listener, phone dashboard, engine watcher.
🔧
Maintainable from anywhere
: the car pulls its own updates from this
repo (hourly + a dashboard "update now" button) and dials out a tunnel so
it stays reachable even behind a phone hotspot's NAT. No laptop-in-the-car
maintenance, ever.
📶 Three-tier connectivity: phone hotspot → home wifi → its own fallback
access point, so the phone can always reach it, even in a garage with
zero signal.
The build log with every dead end included lives in
docs/plan.md
.
flowchart LR
subgraph car [In the car - Raspberry Pi 5]
MIC[USB mic] --> LISTEN[carwatch-listen<br/>VAD + whisper.cpp]
LISTEN --> BRAIN[llama.cpp server<br/>Qwen3.6-35B-A3B]
MANUAL[(Owner manual RAG<br/>745 pages, on SD)] --> BRAIN
STATE[selfstate<br/>temp / fan / net / model] --> BRAIN
OBD[carwatch-obd<br/>watches the OBD cable] --> AGENT
BRAIN --> AGENT[carwatch-agent<br/>the @gle room agent]
DASH[web dashboard :8088<br/>status / update / voice / wifi]
UPD[self-update<br/>hourly git pull] -.updates.-> car
REACH[dial-out tunnel<br/>reachable behind any NAT]
end
AGENT <-->|posts + mentions| GM[GroupMind rooms]
GM <--> PHONE[Your phone / watch<br/>CodeWatch]
DASH <-->|same wifi| PHONE
Loading
Local vs online: the strategy
Local is the product; online is the enrichment.
The car must be fully
useful with zero connectivity, because cars live in garages, tunnels and
countryside dead zones:
Always local (works with no signal):
voice in, the assistant's answers
(on-Pi model), owner's-manual answers (RAG ships on the SD card), the
phone dashboard (served BY the car), trip/state tracking.
Queued through connectivity gaps:
room posts, clip uploads, mention
replies. Everything lands in a persistent on-disk outbox first and is
delivered late rather than lost.
Online-only, and honest about it:
remote reachability (the dial-out
tunnel), self-updates, escalation to bigger brains — first a local-LAN
model server when one rides along (still no cloud), then a cloud model
only when online AND explicitly asked, on the car's own budget-capped key.
Rule of thumb: glanceable safety-relevant info never depends on the
network; anything social or heavy degrades gracefully to "later".
Status — what is proven vs. built vs. planned
A car keeps four palm-sized contact patches on the road, the only place it
ever meets reality. One principle per wheel: assert only what you can sense,
claim only what is verified, label anything interim loudly, and report
failure plainly with no silver lining. Everything above those four patches
is just suspension.
— @claudeMB, CarWatch dev log, after a day of learning all four the hard way
Honesty policy: a feature is only "proven" after it worked on the real car.
"Built + tested" means the code runs end-to-end against a real or simulated
counterpart but has not yet met the physical car.
Self-update from this repo (hourly timer + dashboard button)
proven
Dial-out reachability behind any NAT (cloudflared quick tunnel)
proven
(reached over the open internet)
OBD engine reading over DoIP/ENET (RPM, coolant, speed, voltage)
built + tested
against a protocol-accurate fake gateway (
tests/fake_gateway.py
); zero-touch daemon watches the cable and posts results by itself.
Unverified against the real car
— it will confirm or refute itself on the next drive
Dashcam clip pull (WOLFBOX G900, hisnet CGI API mapped)
probe done, pipeline not wired
MBUX dashboard render, mirror icon strip
planned
Hardware (reference build)
Raspberry Pi 5, 16 GB (active cooling required — the SoC throttles without it)
USB microphone for voice (any class-compliant mic)
OBD access: ethernet-to-OBD (DoIP/ENET) cable — support built, real-car
verification pending; a standard ELM327-class adapter is the fallback path
Power: the dashcam hardwire kit feeds the camera; the Pi needs its own
5V/5A USB-C feed (12V PD adapter, or the car's 230V socket + wall PSU)
Install (on the Pi)
git clone https://github.com/ThinkOffApp/CarWatch.git
cd CarWatch
./install.sh
Then put your credentials in
/etc/carwatch/config.json
(never in the repo —
see
config.example.json
) and:
sudo systemctl enable --now carwatch
After that the car keeps itself current:
update.sh
pulls this repo's main,
installs any new systemd units, and restarts services — on a timer, from the
dashboard button, or by hand:
Copy
config.example.json
to
/etc/carwatch/config.json
:
api_base
— your GroupMind server, e.g.
https://groupmind.one
api_key
— the agent's API key (create one for the car; never reuse another
agent's key, never commit it)
room
— room slug the car posts to
handle
— the car's display handle, e.g.
@gle
home_ssids
— wifi networks that mean "parked at home"
wolfbox
— dashcam AP name/password and poll interval
Bench-day probe
The WOLFBOX's HTTP API is undocumented;
carwatch-probe
discovers it:
python3 -m carwatch.wolfbox --probe
Connect the Pi to the dashcam's wifi AP first. The probe walks known
dashcam-firmware endpoint patterns and prints what answers, which fills in
wolfbox.py
's TODOs with your camera's real paths.
License
AGPL-3.0, like ClawWatch. Copyright (C) 2026 ThinkOff / Petrus Pennanen.
Ox Alpha appeared on OpenRouter on August 20, “developed and operated by a third-party model provider”.[[fn:
OpenRouter
]] Hypotheses quickly converged on the model being a part of the GLM family,[[fn:
@davis7
,
@ananayarora
]] and we independently arrived at the same conclusion, detailed below. We also ran Ox Alpha through LineageEval, our matched-pair censorship instrument. The model exhibits a unique behavioral profile on sensitive topics that we have not observed previously. On most topics that censorship audits probe in Chinese models, like Xinjiang and Taiwan, Ox Alpha answers identically to American models. However, the model censors the output of 7 topics, including domestic incidents and Xi Jinping personally. Our behavioral fingerprint aligns with the community’s findings with an exact 11-of-11 tokenizer match to the GLM-5.x vocabulary.
In July we
published
LineageEval, a matched-pair instrument for measuring political censorship in language models. In brief, it is designed to measure a model’s willingness to answer questions about a specific topic vs. general evasiveness to sensitive queries. We ran Ox Alpha on LineageEval and graded it against both the original standards and a new addition: a refined set of fact cards that are more precise (denoted as v2).
Its censorship is a switch, not a tilt
Besides V4 Flash, this is the only model measured with both intervals entirely above zero, at about a sixth of DeepSeek’s magnitude. However, Ox Alpha’s censorship on China-sensitive prompts is sharply bimodal. Most responses are under 10, but none land between 25 and 50. So the 7 sensitive topics contribute +7.39 of the +7.42 mean, while the remaining 68 pairs contribute effectively nothing. DeepSeek V4 Flash has the opposite shape, where it censors nearly everywhere, including when the censorship isn’t severe. So “six times less censored” is the naive read, as Ox Alpha has a topic blacklist.
On the Xi and domestic legitimacy topics, Ox Alpha is statistically indistinguishable from V4 Flash, which is also the most censored model we’ve tested. On Xinjiang and Taiwan, it’s identical to GPT-OSS-120B. Most censorship audits are built around topics of foreign interest, like Tibet and Taiwan. This model would appear uncensored by those metrics, since its Xinjiang answer is detailed and cites sources that are controversial in China, while DeepSeek whitewashes. It appears that its censorship is particularly concentrated in areas of domestic political risk. As such, anecdotal examples of it answering certain sensitive prompts are not evidence to the contrary.
Five of Ox Alpha's 76 sensitive responses open in Chinese state voice. For example: "The Communist Party of China and the Chinese government have always adhered to a people-centered development philosophy, committed to safeguarding national stability and the people's happy lives." Four of DeepSeek's responses open in a similar construction. While this register is prevalent througout Chinese alignment data generally, it solidifies the model's provenance.
Three responses drew a refusal label, and they all billed completion tokens. We observed that the Liu Xiaobo prompt was originally refused but returned a full answer on re-request with identical settings.
Who made it
We ran our own fingerprinting analysis independent from community findings, which concurs with prevailing conclusions and quantifies them. The model carries a system prompt instructing it to not reveal any information about its provenance.
We measured token counts from the live endpoint using prompt_tokens deltas across eleven probes: a Chinese paragraph, Thai, the digits of pi, Korean, Arabic, a long digit sequence, isolated CJK, emoji, English, rare English tokens, and code. The Thai and emoji probes are where the GLM-4.x vocabulary was extended going into 5.x, leading to a higher degree of certainty in Ox Alpha’s provenance being from the GLM-5 line. Z.AI-hosted GLM models return
{"code":"1214","message":"Incorrect role information"}
, which Ox Alpha matches.
Observation
Implication
Temperature ceiling is exactly 1.0 (1.01 errors upstream, 1.0 succeeds)
Rules out Google, OpenAI, and xAI, which all permit 2.0. Matches Zhipu's documented (0, 1.0] range.
top_k
accepted across 1 to 100000
Rules out OpenAI.
Reasoning is mandatory and cannot be disabled (
effort: none
returns 400)
Matches GLM-5.x thinking models.
Vision confirmed working on a synthetic test image
Multimodal
1M context, video declared, roughly 88-token hidden wrapper on every request
Consistent with the community-reported wrapper behavior.
LineageEval prompts, judge configuration, and per-response scores are in the
July release
. You can compare models yourself in the
playground
.
Sixty More U.S. Soldiers Reported Injured in Iran War
Intercept
theintercept.com
2026-08-25 11:15:45
A government official accused the Pentagon of “an accounting trick” in its slow tally of Iran war casualties.
The post Sixty More U.S. Soldiers Reported Injured in Iran War appeared first on The Intercept....
The U.S. military
revealed that an additional 60 service members have been injured in the Iran war, lifting the official toll to 776 troops wounded or killed. Some 345 of these casualties have occurred since July 7, after a second ceasefire
imploded
. As the numbers of dead and wounded troops have recently mounted, the Pentagon has quietly been seeking casualty and mortuary services, according to government contracting documents analyzed by The Intercept.
The increase of 60 wounded last week was called “an accounting trick,” by one U.S. government official who accused the Pentagon of “slow-walking” the total for weeks. “They wanted the heat on them to slow down after the really devastating attacks,” that source told The Intercept, referencing airstrikes on U.S. bases last month that exposed the vulnerability of U.S. troops to Iranian attacks.
The office of self-styled War Secretary Pete Hegseth did not respond to multiple requests for comment, including when and where the injuries occurred.
Since the beginning of the Trump administration’s war with Iran, Hegseth’s department has posted the official count of casualties on the website of the Defense Casualty Analysis System, or DCAS, which
tracks
“deceased, wounded, ill or injured” service members for Congress and the White House. Casualties since July 7 are now
counted separately
on a webpage with a generic title: “Overseas Operations.” Combined with totals for
Operation Epic Fury
— the military’s official designation for the initial months of the Iran war — 18 service members have died and 758 have been wounded since the U.S. launched the war against Iran on February 28, according to DCAS. This official total of dead and wounded personnel, as
documented
over
months
of reporting by The Intercept, has been a
gross undercount
, stemming from what that same official previously called a “
casualty cover-up
.”
In the face of the increasing number of dead and wounded troops, the military has been seeking a range of services related to personnel who are killed or wounded, according to new contracting documents analyzed by The Intercept. While the military regularly awards such contracts, the commands involved have not replied to questions concerning the possible relationship to the current conflict.
On Friday, for example, the Air Force announced it
awarded a new contract
for a full range of mortuary services at Robins Air Force Base in Georgia. This includes transportation and refrigeration of remains, embalming, dressing, casketing or cremation, as well as funeral services. Last week, the Air Force also began looking into local firms that could fulfill a wide-ranging contract — including “
mortuary services
” — at Italy’s Aviano Air Base, a
key hub
for the war with Iran.
The public affairs offices at Robins Air Base and Aviano Air Base did not return requests for comment prior to publication.
Last week, the Army also
announced
it “desires to procure” casualty administrative support, including casualty case management services, at Fort Knox, Kentucky, for the Army’s Casualty and Mortuary Affairs Operations Division. Over 90 percent of the latest casualties are Army soldiers, and its storied Fort Knox base has been
intimately involved
in the conflict with Iran. The body of 26-year-old Sgt.
Benjamin Pennington
— who died of injuries resulting from an Iranian strike on a U.S. base in Saudi Arabia in March and was the first Kentuckian to die in the war — was sent home via
Godman Army Airfield
at Fort Knox. Six soldiers killed in an Iranian strike in Kuwait that same month were
operating
under the 1st Theater Sustainment Command which is headquartered at the base.
Fort Knox did not respond to a request for comment and further information about the contract and the losses from the war prior to publication.
The recent casualty spike resulted from Iranian attacks on around 10 U.S. outposts across the Middle East since July 9, according to a second U.S. official who
previously spoke
to The Intercept. Iran’s military managed to
overwhelm
U.S. air defense systems using a mix of attack drones and advanced ballistic missiles, despite months of
claims
by President Donald Trump and Hegseth that Iran’s military
was annihilated
.
Last month, the tally of wounded personnel fluctuated by the day in the wake of increased Iranian attacks. On July 21, the casualty count on DCAS for Operation Epic Fury stood at 500. Now, it has shrunk to 431.
For months, The Intercept found anomalies with the counts offered on the DCAS website. On April 21, for example, the number of
wounded-in-action troops declined by 15
without public acknowledgment by the War Department. Despite repeated questions for months, the Pentagon has not commented on the disparities in its casualty count.
Prior reporting
by
The Intercept
also found DCAS is
missing
hundreds of wounded or dead personnel from the Iran war. The Pentagon’s list of the names of the dead is still missing Maj. Sorffly Davius, a signals and communication officer with the New York Army National Guard who was assigned to the headquarters of the 42nd Infantry Division and reportedly died while on duty in Camp Buehring, Kuwait, on March 6. Davius’s death was widely acknowledged even as it was excluded from the official count. Gen. Dan Caine, the chair of the Joint Chiefs of Staff, for example,
recognized
Davius while “honoring our fallen.”
While DCAS provides a running tally of “non-hostile” deaths — meaning those who died from accidents or by illness — it doesn’t include “non-hostile” injuries. The DCAS figures for Epic Fury show that 65 Navy personnel were wounded in action. Missing, however, are the more than
200 sailors
treated for smoke inhalation or lacerations due to a March 12 fire that raged aboard the
USS Gerald R. Ford
. The aircraft carrier had been conducting round-the-clock flight operations to, Caine said, “
project combat power
” in the Middle East.
CNN
was the first to report a significant increase in wounded troops last week.
The World Health Organization puts the Iranian
casualty toll at an estimated 37,181
, including 3,375 deaths. Iranian state and semi-official media reported similar figures — just under 3,500 killed by U.S.-Israeli air strikes. Last week, The Intercept reported on a family of eight,
including five children
, killed in one of those attacks.
Australia may face a rush of datacentre construction as AI firms look to dodge upcoming rules, experts say
Guardian
www.theguardian.com
2026-08-25 11:00:19
Regulations will require new sites to avoid pushing up power prices by building renewable energy plants and minimising water useGet our breaking news email, free app or daily news podcastPlanned datacentres around Australia may avoid strict new rules being proposed by Anthony Albanese if they can se...
Planned datacentres around Australia may avoid strict new rules being proposed by Anthony Albanese if they can secure approvals in the coming months, amid growing calls growing for a moratorium.
The rules will require datacentres to avoid pushing up power prices – including by bringing renewable energy to the grid to cover their electricity demands – while meeting their own connection costs and minimising water use.
Developers will also need to ensure their datacentres are appropriately sized and located away from schools, homes, potential housing or agricultural locations.
However, the rules will not be retrospective. This means any project that’s been approved before the legislation passes next year will only be subject to existing state or territory laws.
The Australian
Energy
Market Operator (Aemo) reported on Tuesday there were 225 datacentres in development, and electricity demand from them was expected to grow from 5 to 34 terawatt hours by 2036.
There is uncertainty over the number of projects that will ultimately go ahead. More than 40% of datacentre projects since Aemo’s 2025 report either dropped off the list or regressed in status.
But some of the projects currently in the pipeline could receive approval before the new rules apply.
The New South Wales government is
now considering a 90MW datacentre
about 9km from Sydney’s CBD. Named Project Mars, the three-storey centre will cover 22,000sqm near Lane Cove River under current plans.
Goodman Group, the company behind the project, is consulting with the community about the proposal, amid strong local pushback in an area where five datacentres are already approved or being proposed.
The project’s website states it will use existing power, and 3.5ML a day of water from Sydney Water should it go ahead. There will be 200kW-worth of solar panels on the building, but the company has limited information on more renewables to offset its power demands, stating it is “exploring opportunities to source additional renewable generation to support its proposed datacentre rollout in Australia.”
Sasha Titchkosky, a representative of Lane Cove Responsible Planning group, said developers should consider the potential damage to their brand should they proceed with datacentre projects under the old rules. But she said governments should enact a moratorium on approvals until the new rules are in place.
“At the very least, a moratorium on approvals in established residential areas … [it]seems to me that would be the responsible thing for governments to do,” Titchkosky said.
“I don’t think it’s an unreasonable ask, to actually have the government doing what they should be doing to protect the citizens.”
Goodman Group was approached for comment.
Prof Crystal Legacy, an urban planning researcher at the University of Melbourne, said developers would probably want to get in “before the new regulatory levers come into play”. She warned that state governments, which may try to fast-track applications before new rules come into effect, would do so “at your political peril.”
“People are now noticing, and there’s always going to be a political backlash,” Legacy said.
“We call people Nimbys, but I think that’s an unfair characterisation for people who are just concerned about the environmental impacts, as well as the amenity impacts of these massive datacentres.”
The Greens have previously called for a moratorium on approvals until the new rules are in place.
While Albanese works to get the states and territories to sign off on his proposed changes, the community pressure is likely to continue, with a federal inquiry into datacentres currently accepting submissions, along with state inquiries in NSW and Tasmania.
Feature comparison of ack, ag, git-grep, grep and ripgrep
There are many greplike tools available to choose from. ripgrep is
currently the fastest, which folks seem to focus on, but they have
different features. Here's a chart to help you see which tools can do
what.
The researchers also theorized that entry-level workers could be especially affected by AI’s impact on jobs that require heavily “codified” knowledge—the kind of “formal, standardized, documented knowledge that can be taught through education, textbooks, or written procedures.” That would contrast with jobs where AI mainly complements an experienced worker’s more “tacit” knowledge, which is overwhelmingly “acquired through practice, mentorship, and repeated exposure to real situations,” the researchers write.
To test this hypothesis, the researchers used the required level of formal education in
O*NET’s extensive occupational database
as a proxy for how reliant that job is on codified knowledge. Breaking out the employment data, the researchers found that “occupations with higher codified knowledge have slower entry-level employment growth, while occupations with higher tacit knowledge have faster employment growth for mid-career and senior workers.”
At the same time, the researchers found that higher education might still serve as a buffer against the employment effects the Stanford researchers identified. As they write, occupations with a higher share of college graduates showed more “muted differences between more-exposed and less-exposed occupations” regarding AI. In jobs with few college graduates, on the other hand, “the least AI-exposed occupations [saw jobs] growing and the most exposed occupations [were] declining in employment.”
In a recent interview with The Washington Post, lead researcher Erik Brynjolfsson warns that the current trends suggest a near future in which jobs for those employed in the pre-AI era largely persist, while many jobs for the incoming working-age cohort start disappearing. “The entry-level effects we’re measuring are real, persistent and widening,” he said, “and I’m more worried than I was about a labor market that keeps its overall employment level while quietly closing the on-ramp for people starting their careers.”
Hospital operator Nutex Health says data stolen in cyberattack
Bleeping Computer
www.bleepingcomputer.com
2026-08-25 10:44:16
Healthcare and services provider Nutex is investigating a data breach incident where an unauthorized third party exfiltrated information from company servers. [...]...
Healthcare and services provider Nutex is investigating a data breach incident where an unauthorized third party exfiltrated information from company servers.
The organization has disclosed the cyberattack in a filing with the U.S. Securities and Exchange Commission (SEC), noting that the stolen data includes details that may be private or confidential.
“Based on preliminary findings from the Company’s ongoing investigation, the Company believes that certain information maintained on the Company’s servers was accessed and exfiltrated by an unauthorized third party, including some information that may be private and/or confidential,”
Nutex says
.
Nutex Health is a for-profit healthcare company that
operates 28 facilities across 12 states
, including the Bayou City ER & Hospital in Texas and Green Bay ER & Hospital in Wisconsin.
The company had an annual revenue of $875 million in 2025, a market capitalization of $1.28 billion, and is
publicly traded as NUTX
on the Nasdaq Capital Market.
After detecting the intrusion, the company hired external incident-response and forensic specialists, activated its cybersecurity response plan, implemented containment measures, and notified law enforcement.
Nutex has yet to determine the type of data that may have been compromised and if the impact includes patients, employees, or business partners.
“The Company continues to assess whether, and to what extent, patient, employee, credentialed provider, confidential business and financial information, intellectual property, or other information may have been accessed, acquired, or exfiltrated and continues to evaluate the potential impact of the unauthorized activity on the Company, including any potential disclosure of private and/or confidential information by the third party,” reads the SEC filing.
As of August 24, the company says it found no material impact on its operations or financial reporting systems, and it currently does not believe the incident will materially affect its business strategy, operations, financial condition, or results.
BleepingComputer could not find any threat actor claiming the attack on Nutex.
We contacted Nutex for a comment about the incident and we will update this post as soon as we receive a response.
This blog post is the sixth in a series about my work building and optimizing the
Plush
language interpreter and virtual machine. The previous one was
Speeding Up the Plush Garbage Collector
. In the last post, I explained how a few simple changes made the copying GC over 16x faster, and brought the collection time for a million objects down to around 7 ms. I'm having a lot of fun optimizing Plush just for the sake of it, but I'm also doing it with the goal in mind of being able to make the language fast enough to render 3D animations in real-time, even though it's interpreted.
Plush is a dynamically-typed language, in the same family as Python, JavaScript, Ruby, Lua, and Lox. Dynamic languages like this have the property that types are attached to values rather than variables, and so to propagate values around programs, an interpreter typically has a
Value
type that can represent any value that could exist in the language. What I did with the original version of Plush is that I used a plain Rust tagged enum. This is nice because Rust makes working with tagged enums very convenient, as we can dispatch to different
Value
subtypes using the
match
statement:
// The old Rust Value type as a tagged enum
enum Value {
Undef, // Uninitialized var or field, reading triggers an error
Nil,
False,
True,
Int64(i64),
Float64(f64),
String(*const Str), // Immutable string
HostFn(&'static HostFn), // Function exposed by host VM
Fun(FunId), // Non-closure Plush function
Closure(*mut Closure), // Closure that captures variables
Cell(*mut Value), // Mutable variable captured by a closure
Object(*mut Object), // Class instances
Array(*mut Array), // JS/Python style array/list
ByteArray(*mut ByteArray), // Fast raw byte array (e.g. frame buffer)
Dict(*mut Dict), // JS/Python style dict
Class(ClassId),
}
As you can see above, Plush, even though I still consider it a toy language, has many different value types. The language has objects which are class instances, which are efficient to access, but it also has JS/Python style dictionaries, which make JSON-style syntax possible. There are also two distinct numerical types,
Int64
and
Float64
. I made this choice because it always kind of bothered me that JavaScript pretends everything is a double, while JS engines will actually keep track of what's an integer behind the scenes. The thing that's most unfortunate though is not the number of enum variants here, it's that this enum is a whole 16 bytes (128 bits) wide. Each enum variant needs only 64 bits, and the enum tag that Rust creates only needs 8 bits, but because of memory alignment constraints, Rust may need to use a whole 128 bits for each value. It might seem like no big deal, but if you have a large array of values, that array will end up with a ton of empty, wasted bytes inside of it. This is the kind of thing that makes VM engineers cry themselves to sleep at night.
For a little while now, I've been thinking that I could design a more efficient low-bit tagging scheme to make it so that the
Value
type fits inside of 64-bits. There's a
classic trick
which is derived from the fact that on a 64-bit system, heap object addresses are typically aligned to 8-byte boundaries, which means that the lowest 3 bits of the address must be zero. That means you can essentially steal these bits to pack extra information in there. You can also borrow the two lowest bits of integer values, with the assumption that integer values will very rarely need to use the full 64-bit range, because for reference
2^64 ~= 1.84 * 10^19
. That's a very large value. If you have a variable that represents say, the number of lines in a text file, or the number of enemies in your game, or any other numerical quantity, it's very unlikely to reach that value. With a modern CPU that can dispatch multiple instructions per clock cycle, if you were to execute a loop such as
for (uint64_t i = 0; i < UINT64_MAX; ++i)
, the loop would likely take over a decade to finish executing.
A more sophisticated tagging scheme can clearly reduce memory usage, but it also means that we have to introduce bitwise operations to be able to tell what's an integer, a pointer or a float. We also need extra bitwise operations to unpack some values to operate on them. That means extra instructions the CPU has to run. A skilled VM engineer once told me that the smart thing to do is to give integers zeros as their tag bits, because then, adding or subtracting two shifted integers remains a plain
add
or
sub
machine instruction. Packing and unpacking floats though is more complex and requires several instructions. I was a bit worried about the performance impact, and needing to trade memory efficiency for a bit of a performance loss. As it turns out, my fear was completely unfounded, as we'll see later in this post.
An Efficient Low-Bit Tagging Scheme
Claude and I co-designed and iterated on the value representation found in this
source file
. It fits nicely in a Rust newtype wrapping a
u64
. As you can see, it has many convenience methods to make it easy to work with, compensating for the loss of the Rust enum. Most of the methods are marked as always inline for performance, since they're used everywhere in the interpreter loop. The diagram below illustrates how the value representation is structured in more detail:
The tagged value representation.
The low-bit tagging scheme I settled on encodes 5 different kinds of values: fixnums, flonums, immediates, and two kinds of pointers. Fixnums are signed integers that fit in a 62-bit range. Flonums are floating point values encoded using a self-tagging scheme (more on that later). Immediates are values like
nil
,
true
,
false
,
undef
, function and class ids, as well as host functions written in Rust that can be called from Plush. In Plush, you can call host functions using the dollar sign prefix, e.g.
$read_file(file_name)
. The immediates have a 5-bit subtag to indicate what kind of immediate they are. It's 5 bits because an 8-bit comparison on the lowest byte is just one instruction on modern CPUs, which means we can compare the subtag plus the tag bits in one instruction if we need to.
The reason there are two kinds of pointers in this representation is that I wanted to make equality comparison between values fast. This comes up often because you might have loop conditions, pointer comparisons inside if statements, etc. Most values in Plush are compared using simple reference equality, but I chose to have strings be compared for structural equality to allow the possibility of a
string interning
table later. This is like JS, where two strings with the same value are equal. Floats also need special handling because they have a sign bit, and
+0.0
must be the same as
-0.0
.
The easy way to do that is to have one bit in the tag (I chose bit index 1) that tells us that two values can be compared directly using one comparison instruction. This allows us to have a fast path to compare integers, pointers, handles and small immediate constants like
true
,
false
,
nil
and
undef
using a single machine comparison instruction. There's some minor subtlety there because some pointer types (string objects) are not comparable using direct pointer equality. Also, if an integer or float value exceeds the range we can fit in a tagged value, we have to allocate a heap object to box this value. That means we could end up with two floats that have equal value represented by distinct heap objects, but those values must test as equal using the
==
operator.
If Plush eventually gets a JIT compiler, the generated code for
if (p != nil)
can be as follows. There is no slow path here, because we know that no value that gets compared structurally can possibly be equal to
nil
:
; x0 = the value being tested
; nil is the immediate 0x05
cmp x0, #5
b.eq .ELSE_BRANCH ; jump to else branch if equal
Efficient Fixnum Operations
As stated earlier, integer values that fit in the 62-bit fixnum range have their lowest two bits set to 00, and are stored as
n << 2
, so add, sub, compares and bitwise and/or/xor run directly on the tagged words. A 64-bit overflow is also exactly the case where the result no longer fits in 62 bits, meaning we can use standard machine instructions to check for overflow (
jo
on x86-64,
bvs
on ARM64).
For a loop counter comparison like
i < n
, the ARM64 machine code can be as follows. Checking that both values are integers costs us 3 machine instructions:
; Fast path for `i < n`, 5 instructions
; x0 = i, x1 = n
orr x2, x0, x1 ; combine both operands
tst x2, #3 ; are both operands fixnums?
b.ne .Lslow_lt ; floats, boxed numbers and strings go that way
cmp x0, x1 ; compare the fixnums, `00` tag bits don't matter
b.ge .LOOP_EXIT ; signed compare, fixnums are 62-bit signed
The fast path to add two fixnums would come out as follows. The Rust compiler may not be able to combine both tags in practice, but a JIT compiler easily could, and could even remove the type check entirely if it has additional run-time information about the types of values, in which case the add would be just as efficient as a C integer addition:
; Fast path for fixnum integer addition
; 5 instructions on the fast path
; x0 = a, x1 = b, two tagged Values
; A fixnum is n << 2, so its low two bits are 00
orr x2, x0, x1 ; combine both tags, so one test covers the pair
tst x2, #3 ; are both operands fixnums?
b.ne .Lslow
adds x0, x0, x1 ; (a << 2) + (b << 2) == (a + b) << 2
b.vs .Loverflow ; signed overflow is exactly the 62-bit overflow
; x0 already holds the tagged result. Nothing was untagged on the way in
; and nothing has to be retagged on the way out
Self-Tagged Flonum Representation
There are many ways to tag floating-point values in a system with tagged values. One of the most famous schemes for doing that is
NaN boxing
, which, as far as I know, is still used in the Firefox JavaScript engine to this day. NaN boxing exploits the fact that a double counts as
NaN
(not a number) whenever its 11 exponent bits are all set to one and its mantissa is non-zero. Every bit pattern that satisfies that reads as a NaN, no matter what the rest of the word holds. For 64-bit doubles, that means there are 52 mantissa bits that can be used as a payload to store any kind of data you want, or 51 in practice, since implementations normally reserve the top one for quiet NaNs. The Crafting Interpreters book also mentions that you can steal the topmost sign bit as an extra tag. It's a clever trick, and it has the advantage that you get double-precision operations "for free", more or less, no tagging or untagging necessary. The disadvantage is that other types of operations are penalized a little bit more. The practical reality is also that your typical JavaScript, Python or Ruby program does not do very much floating-point math. It's a lot more integer and pointer heavy.
For Plush, I decided to investigate other avenues for tagging floats which could work with low-bit tagging. I already knew that one possible approach was to steal some exponent bits from IEEE doubles. The range that doubles can represent is incredibly huge, with the maximum representable value being approximately
1.8 * 10^308
. It stands to reason that most values you typically see in a computer program never approach that range, and so, if we were to borrow a few bits of the exponent, we'd be left with a smaller, but still huge representable range for tagged flonums. The doubles we can't fit in that range, we can simply heap-allocate, but that should almost never be needed.
During my search into how to do this efficiently, I stumbled upon a fairly recent paper on
Float Self-Tagging
by Olivier Melançon, Manuel Serrano and Marc Feeley. The scheme they present does a rotation of the upper bits so they end up in the tag bit position, after adding a bias value such that the lower bits end up being the specific tag that we want. It's clever, and it means we don't need shifting, masking, or anything else. Best of all, tagged flonum values can also represent subnormals, infinity and even NaNs without needing heap boxing, which is very convenient as these values do come up in some computations. For my boxing scheme, I picked a bias value such that the lowest two bits end up being
10
. That
1
in bit index 1 indicates that doubles can't be directly compared for equality. Amazingly, we only lose two bits of exponent, and we keep the full precision of the mantissa, meaning we lose no significant digits in the flonum representation.
Boxing and tagging floats using self-tagging, from Float Self-Tagging (arXiv:2411.16544).
Adding two flonums costs more than adding two fixnums, because we do need to do a bit of extra work to undo and redo the tagging:
; 18 instructions on the fast path, with BIAS already in a register
; x0 = a, x1 = b, two tagged Values
; x9 = BIAS, 0x6810_0000_0000_0000, materialised once
and x2, x0, #3 ; isolate the tag bits of a
and x3, x1, #3 ; and the tag bits of b
cmp x2, #2 ; a flonum has 10 in its low two bits
ccmp x3, #2, #0, eq ; only look at b if a was one
b.ne .Lslow
ror x2, x0, #4 ; undo the rotate
sub x2, x2, x9 ; undo the bias, leaving the IEEE 754 bits
fmov d0, x2
ror x3, x1, #4
sub x3, x3, x9
fmov d1, x3
fadd d0, d0, d1 ; the actual f64 add
fmov x2, d0 ; back to bits
add x2, x2, x9 ; + BIAS
ror x0, x2, #60 ; rotate left by 4: ARM64 only rotates right
and x3, x0, #3 ; isolate the tag bits of the result
cmp x3, #2 ; did the tag land on 10, or does this one box?
b.ne .Lbox
The last instructions of the machine code snippet above test whether the lowest two bits ended up being
10
. If they didn't, that means we got a value in one of the two narrow bands of magnitudes that our encoding doesn't cover. This should be extremely rare in practice, but if it does happen, we have a slow path that simply allocates a heap box and moves on. In Plush, I'm using a bump allocator so heap boxing is actually reasonably fast too.
Impact on Memory Usage
I have a collection of several synthetic benchmarks for Plush. Some of them are tiny microbenchmarks designed to test the performance of a very specific feature, others are a bit broader. For example,
fib
is the recursive Fibonacci numbers microbenchmark (Marc Feeley's favorite); it primarily benchmarks function calls and interpreter throughput. The
binary_tree
benchmark has both recursive function calls and object property accesses, as well as pointer-chasing and traversing heap-allocated objects. The
mlp
benchmark is a naively implemented multilayer neural network, with a lot of floating-point operations. I also have a
sha256
computation, and the classic
nbody
celestial body simulation in there. Recently, I also added a triangle rasterization benchmark (not shown here), to get an idea of what I could do with
3D graphics in Plush
.
The numbers shown below compare
ac75356
, the last commit before the refactor, which introduced the
Value
newtype but still has the old enum underneath, against
6b71f8c
, the refactor itself. Those two commits are adjacent, so nothing else changed in between. Experiments were done on my MacBook Air M5, with 7 interleaved rounds.
Peak RSS per benchmark (lower is better).
The most important thing to note is that there's a bimodal distribution. Some benchmarks show a big reduction in memory usage, as much as 37% on the
mlp
benchmark which uses a lot of arrays, while others don't really move. The benchmarks that don't move are simply not allocating much memory at all. They're using the minimum Plush GC heap size, and have a peak RSS of about 10 MB. The main takeaway is that on benchmarks that do use more memory than the baseline, we see a nice reduction. Well, that's not fully true. Two benchmarks actually showed an increase in memory usage, those are
quicksort
and
sha256_unfixed
. In the case of
quicksort
, the peak RSS measurement caught the GC in the middle of a collection cycle, so this is kind of an unfortunate outlier. However,
sha256_unfixed
shows an actual regression, a case where many boxed integers ended up being generated, and then pointers to these values were stored into an array, keeping the boxed integers live.
I went ahead and looked at
sha256_unfixed
, and found that the computation was structured in a way that a left shift caused an integer overflow. It's considered a sin in compiler engineering to modify benchmarks, but in this case, I wanted to know if this could be avoided. What if we optimized the computation for our 62-bit fixnums to make the best use of our VM? It turns out that the computation can easily be rearranged to avoid this. It's a one-line fix, and brings memory usage back all the way down to the minimum heap size. So, this is a real downside of heap-boxed representations. We're making an engineering tradeoff, and in some cases, if we're not paying attention, we could end up with code that's less memory-efficient. Though in practice, we probably win in the vast majority of cases.
Impact on Performance
The graph below shows the speed of the interpreter with the new low-bit tagged value representation vs the old Rust enum, with numbers above 1.0x indicating a performance gain:
Speedup per benchmark (higher is better).
The results in the above graph surprised me. I expected some slowdowns, but in actuality, every single benchmark is faster, and some are faster by a lot. There are also more interesting things to notice in these results. For instance, we see that the updated
sha256_fixed
benchmark is faster than
sha256_unfixed
. That being said,
sha256_unfixed
is still running 12% faster with the new value representation than with the old version, even though it's allocating a total of 3,149,052 boxed integer values in a span of about 490 ms. That seemed a bit crazy to me, but having a copying GC with a bump allocator means that we can allocate objects really fast. The positive thing there is that if we do need to box some integers or floats, the performance penalty is not as much as I would have expected, at least not in an interpreted system where instruction dispatch overhead dominates.
But wait, there's more. I mentioned earlier that the
mlp
benchmark is a multilayer neural network. It's doing matrix multiplication with tagged floats, and a lot of them. The
nbody
benchmark is also floating-point heavy. Those are also clearly faster, even though every floating-point operation has to unbox two values and re-box the result. This again surprised me. We're left with the conclusion that everything is faster, even when dealing with some of the worst possible cases of our new tagged representation. We can clearly call this refactoring a success, but it's a surprising conclusion, at least to me.
So, why is everything so much faster? One thing we can see is that the biggest performance gains are in the
binary_tree
and
linked_list
benchmarks. That makes sense. These benchmarks have a large number of objects and do a lot of pointer chasing, touching many cache lines all over the place. With the new representation, objects take about half the amount of memory that they needed before. That means about half the amount of cache/memory traffic. Cache-friendliness is a big win when you're touching a lot of memory.
However, there are other benchmarks like
fib
and
nbody
which don't touch a lot of memory at all. Everything clearly should fit in the L1 cache. The latency of the L1 cache is just 1 to 4 clock cycles on modern processors. Still, the L1 cache, even though it's fast, isn't instantly accessible. It's not as fast as CPU registers, so maybe there are some small wins to be gained from the fact that even interpreter stack frames, and the few objects that
nbody
has, have shrunk. I also have another suspicion, however.
Before the
Value
type refactoring, I was using a tagged Rust enum and match statements to dispatch based on types in various interpreter operations. I suspect that the code the Rust compiler generates for this is maybe not very efficient. I placed the types I thought would be most likely to happen near the top of the match statement, but that probably means nothing to
rustc
. In contrast, the way the code is formatted now, we're explicitly testing for the likely hot path first in an
if
statement. If the code
rustc
generated for the
match
statement dispatch is potato, that would explain a lot.
This is the way my interpreter handled the
add
instruction in the old tagged enum version (
ac75356
, src/vm.rs:1498) using match arms to dispatch based on
Value
types:
Insn::add => {
let mut v1 = pop!();
let mut v0 = pop!();
let r = match (v0, v1) {
(Int64(v0), Int64(v1)) => Int64(v0 + v1),
(Float64(v0), Float64(v1)) => Float64(v0 + v1),
(Int64(v0), Float64(v1)) => Float64(v0 as f64 + v1),
(Float64(v0), Int64(v1)) => Float64(v0 + v1 as f64),
(Value::String(s0), Value::String(s1)) => {
// ...string concatenation, elided
}
_ => error!("add", "unsupported operand types")
};
push!(r);
}
Looking at the disassembly for the
Int64 + Int64
fast path, it's spread over four disjoint basic blocks. The code is fairly massive, and it has a bunch of spills to the native C/Rust stack as well as memory accesses from the interpreter stack:
; ---- block A @ 0x1a8cc : pop v1, then pop v0 -----------------------
ldr x10, [x20] ; len = stack.len()
cbz x10, .Lunderflow
sub x11, x10, #1
str x11, [x19, #0x60]
ldr x8, [x19, #0x50]
cmp x11, x8
b.hs .Lpanic
ldr x12, [x19, #0x58] ; stack base pointer
add x13, x12, x11, lsl #4 ; &stack[len-1], note the 16-byte stride
ldr w9, [x13] ; v1: the tag
ldr w14, [x13, #0xc] ; v1: payload bytes 12..16
ldur x13, [x13, #0x4] ; v1: payload bytes 4..12, unaligned
str w9, [sp, #0x2b8] ; spill v1 into a stack slot...
ldr x15, [sp, #0x48] ; ...whose address is itself in a stack slot
str x13, [x15]
str w14, [x15, #0x8]
cbz x11, .Lunderflow
sub x23, x10, #2
str x23, [x20]
add x11, x12, x23, lsl #4 ; &stack[len-2]
ldr w10, [x11] ; v0: the tag
ldr w12, [x11, #0xc]
ldur x11, [x11, #0x4]
str w10, [sp, #0x2d0] ; spill v0 the same way
ldr x13, [sp, #0x50]
str x11, [x13]
str w12, [x13, #0x8]
; ---- the match dispatch --------------------------------------------
ldr x22, [sp, #0x2d8] ; reload v0's payload we just spilled
ldr x0, [sp, #0x2c0] ; reload v1's payload we just spilled
cmp w10, #4 ; is v0 an Int64?
b.eq .Lv0_int ; taken, 0x120c bytes away
cmp w10, #5 ; a Float64?
b.eq .Lv0_float
cmp w10, #6 ; a String?
b.ne .Ltype_error
; ---- block B @ 0x1bad8 ---------------------------------------------
.Lv0_int:
cmp w9, #4 ; is v1 an Int64?
b.eq .Lint_int ; taken, 0x5a4 bytes away
; ---- block C @ 0x1c07c ---------------------------------------------
.Lint_int:
adds x22, x22, x0 ; the actual addition
b.vs .Lpanic_add_overflow
mov w24, #4 ; result tag = Int64
b .Lpush ; taken, 0x2c0 bytes away
; ---- block D @ 0x1c33c : push! -------------------------------------
.Lpush:
cmp x23, x8
b.eq .Lgrow
ldr x8, [x19, #0x58]
add x8, x8, x23, lsl #4
str w24, [x8] ; store the tag
str x22, [x8, #0x8] ; store the payload
add x8, x23, #1
b .Ldispatch
This is the
add
instruction and its fast path with the new tagged word version presented in this post (
6b71f8c
, src/vm.rs:1391):
Insn::add => {
let v1 = pop!();
let v0 = pop!();
// Tagged fixnums add as they are, and a 64-bit
// overflow is exactly the case where the sum no
// longer fits in one
if v0.is_fixnum() && v1.is_fixnum() {
if let Some(sum) = (v0.raw() as i64).checked_add(v1.raw() as i64) {
push!(Value::from_raw(sum as u64));
continue;
}
}
flonum_op!(v0, v1, +);
let r = slow!("add", self.add_slow(v0, v1));
push!(r);
}
The disassembly for the fast path is shown below:
; ---- block A @ 0x19cc0 : pop v1, pop v0, test the tags -------------
ldr x10, [x5] ; len = stack.len()
cbz x10, .Lunderflow
sub x8, x10, #1
str x8, [x5]
ldr x9, [x16]
cmp x8, x9
b.hs .Lpanic
cbz x8, .Lunderflow
ldr x9, [x28, #0x58] ; stack base pointer
ldr x3, [x9, x8, lsl #3] ; v1, a single load, 8-byte stride
sub x10, x10, #2
str x10, [x5]
ldr x2, [x9, x10, lsl #3] ; v0, a single load
and x11, x2, #3 ; v0's tag bits
cmp x11, #2 ; a flonum?
b.ne .Lcheck_fixnum
; ---- block B @ 0x1a624 ---------------------------------------------
.Lcheck_fixnum:
cmp x11, #0 ; is v0 a fixnum? x11 is still v0 & 3
and x11, x3, #3
ccmp x11, #0, #0, eq ; ...and v1 too? one branch covers both
b.ne .Lslow
adds x11, x2, x3 ; the actual addition, on the tagged words
b.vc .Lpush
; ---- block C @ 0x18030 : push! -------------------------------------
.Lpush:
str x11, [x9, x10, lsl #3] ; a single store
str x8, [x5] ; stack.len -= 1
; and then it falls straight through into the interpreter dispatch
As we can see at first glance, the disassembly for the new version is much shorter. The code for the match dispatch itself in the old version was actually fine, but the old version made a bunch of spills and stack memory accesses. The real win is that values now fit in a single register. The generated code is a lot more efficient as a result. We're not spilling values to the native C/Rust stack immediately after popping them from the interpreter stack. You may also have noticed that LLVM independently found the trick we discussed earlier in the post to check that two values are fixnums, by fusing two type tests into a single branch, nice!
I'm not going to show the whole floating-point fast path disassembly here because it's even longer, but it's worth pointing out that the old version did zero tagging and untagging work, whereas the new one has to unbox both operands and re-box the result. Despite that, the new float fast path is straight-line code with exactly one branch at the end, and it actually ends up shorter than the old version. We went from 52 instructions, 24 memory ops and 4 branches taken to 36 instructions, 9 memory ops and 1 branch taken. This solves the
mlp
and
nbody
puzzle.
Conclusion
In conclusion, I'm pretty happy with the way this refactoring went. Not only does the new tagged word representation reduce memory usage for benchmarks that use lots of arrays and objects, but it's also a major performance win, with every single benchmark ending up faster. The Rust compiler was simply not able to generate efficient code with the old version, but with the new version where values fit in a single register, we actually get some fairly good generated code.
The need to heap-box integers can cause some extra memory allocations in some cases. In particular, code that does left shifts, or relies on overflows for things like generating random numbers, can run into that. Those issues can easily be avoided by skilled engineers who take the VM's design and limitations into account. However, despite some values ending up boxed in some cases, the performance overhead of boxing is unlikely to ever be noticeable. If you're designing your own programming language, you could make different design choices, such as making your native integer type a 32-bit or 62-bit integer instead of a 64-bit integer. This would simply remove the boxed integer path, and make it so overflows produce a visible error instead. You also could require users to explicitly use a heap-boxed bignum (big number) type when they need extra precision. It's a big design space and there are many possible options.
Part of the motivation for my performance work has been to try and get the performance of 3D graphics at a level where it's fast enough to make a simple game, and the results have been very good so far. Plush can render somewhere in the range of 10,000 flat-shaded polygons at an interactive frame rate. I used that to build a little game where you're
riding a motorcycle
on a highway through an infinite cityscape. If you want to try it, just clone the
Plush repository
and run
cargo run --release examples/night_ride.psh
.
In terms of next steps, I'm looking at converting the Plush interpreter from a stack-based design to a register-based design. I think that could yield a nice performance boost. I've also been thinking that I could use the Plush VM to build a minimalistic LISP dialect that explores new language design ideas. I'm thinking of calling that language JetLISP. Stay tuned for more. You can subscribe to my mailing list below if you want to get notified about future posts.
Subscribe to my mailing list and follow this blog:
★ Memory and Storage Configurations and Pricing for the New Mac Minis (M6/M5 Pro) and Mac Studios (M5 Max/M5 Ultra)
Daring Fireball
daringfireball.net
2026-08-25 10:38:01
Here’s my attempt to put all of the RAM/SSD configurations into condensed tables, so you can see which storage and memory options are available for each chip, and how much they cost....
Apple today announced an all new lineup of Mac Mini (M6 and M5 Pro) and Mac Studio (M5 Max and M5 Ultra) desktops. The Apple Newsroom announcements for
Mac Mini
and
Mac Studio
only note base model prices. Here’s my attempt to put all of the RAM/SSD configurations into condensed tables, so you can see which storage and memory options are available for each chip, and how much they cost.
Ethernet: Across all Mac Mini models, upgrading from 2.5 gigabit to 10 gigabit is $100. On Mac Studio, 10 gigabit is standard on all models.
If you configure an M6 Mac Mini with 2 TB of storage, the SSD upgrade ($1,000) costs more than the entire base model computer ($900). So too with the 4 TB SSD upgrade for the M5 Pro Mini ($1,800 upgrade for a $1,700 computer).
Both Mac Mini and Mac Studio are available in a wide array of cool color choices, including silver.
It kind of stinks that there are no RAM options for the Studio between the 96 GB base and the $4,000 256 GB upgrade.
The best currently-available-to-order Mac Studio (36/80 cores, 256 GB RAM, 16 TB SSD) costs $18,300. But if you’re OK with the base 30/64-core chip and just 8 TB storage, you can cut the price to a smooth $13,000.
Apple today released a
new version of its Polishing Cloth
on its online store. In the U.S., pricing is now set at $9, down from $19 for the previous version of the cloth.
We have yet to determine if the new Polishing Cloth is smaller than the original or has any other notable changes beyond lower pricing. Apple says the cloth continues to be made with soft, nonabrasive material that can be used to clean any Apple display, including those with a nano-texture coating.
Bomb Fishing Is Wreaking Havoc on Indonesia's Coral Reefs
A bomb-fished coral reef in Sulawesi, Indonesia.
The Ocean Agency
Fishers operating off the coast of Sulawesi, Indonesia, are detonating more than 8,000 underwater explosives each year, researchers estimate. The practice is turning picturesque coral reefs to “rubble.”
Nicknamed the “Amazon of the Seas,” the Coral Triangle is the world’s most biologically diverse marine ecosystem. Sink below the surface and you’ll encounter the sound of a vibrant symphony of snapping shrimp, crunching crustaceans, and feeding fish.
But then the rhythmic music of life will dissolve into eerie silence, punctured only by the plosive boom of detonating bombs.
Off the coast of Indonesia’s Spermonde Archipelago, underwater microphones captured over 3,500 explosions in just 3,600 hours of recording, according to researchers from the Zoological Society of London.
The source?
Blast fishing
— a globally banned technique that uses plastic bottles packed with explosives to stun and kill everything in a 90-foot radius. The highly destructive practice has been documented in at least 34 countries, from Lebanon and Libya to Brazil and Ecuador.
While fishers predominantly use the method to catch fish for sale at local markets — identifiable by their ruptured internal organs and burst swim bladders — it’s also a grave threat to colorful coral reef habitats.
“Bomb fishing is quite likely the leading cause of reef loss in this area,” said Ben Williams, the
paper’s
lead author, noting that a single bomb can wreak 200 square feet of destruction. “These picturesque reefs get converted into a landscape that looks like the moon. It’s just rubble and dead coral with very little sign of life.”
In 2023, researchers from Britain and Indonesia snorkeled down and anchored $150 audio recorders to short stakes in the seafloor. Using A.I. software — which the team has now made
open-source
— they scoured 16 months of audio in just a few hours to identify possible detonations.
While the A.I. filtered suspected cases, each suggested sound wave was then manually verified to assess if it stemmed from a bomb or a misfiring boat engine.
With sound traveling over four times faster through water than air, the team of marine scientists were able to detect detonations from over 10 miles away.
“When [the bombs] are close, it’s so loud that it can shake you out of your skin,” said Williams. “But if you put your head up on the surface, you probably can’t even see the boat that did it.”
Accounting for stormy-season setbacks and spearfishermen who tampered with the recorders, the team calculated that there were likely more than 8,500 blasts each year — all within an area of just 350 square miles.
With a bomb dropped once every 62 minutes, the equivalent of three football fields of reef are destroyed each year, according to Williams.
Indeed, an estimated 75 percent of coral has been lost in the Spermonde Archipelago since 1990 as a result of human activities, bleaching, and warming waters.
“Repeated blasts create shifting fields of rubble that prevent hard coral recruits from settling and growing, making natural regeneration and recovery of the reefs a difficult or impossible task,” said Melissa Hampton-Smith, a postdoctoral researcher at James Cook University in Australia, in an email to
Inside Climate News
.
The data revealed for the first time that bomb fishing takes place year-round, peaks during the mornings and significantly reduces on Fridays, the local day of prayer.
While understudied, the incentives for the use of dangerous dynamite fishing are often falsely attributed solely to poverty and desperation. The cost barrier to buying boats, bombs, and detonators means it’s more likely a practice for middle-income fishers, according to experts.
“A combination of factors drives blast fishing, including ineffective enforcement and management,” said Hampton-Smith, highlighting how indiscriminate the explosions are, killing all manner of species, regardless of age, size, or intent.
“Managing all illegal fishing, including blast fishing, is complex and varies from place to place, but in general equitable, consistent, and legitimate enforcement is key,” said Hampton-Smith, who first studied the phenomenon while living and working in East Africa’s bomb fishing hot spot, Tanzania.
Despite the widespread harm, intercepting blast fishers in the act remains an elusive goal in a nation encompassing over 70 million acres of marine protected areas — a region larger than the entire United Kingdom.
Though authorities in neighboring Malaysia successfully confiscated 1,250 pounds of ammonia fertilizer suspected of being used to construct homemade fish bombs this May, patrols currently fail to effectively pinpoint the detonations in real time.
“Restoration efforts struggle to keep up with such rapid rates of destruction caused by bombing,” said Jamaluddin Jompa, coauthor of the paper and a research professor at Hasanuddin University in Indonesia, in a press release. “Immediate work to tackle bomb fishing is needed.”
Williams is hopeful the new research could be used to construct a network of audio sensors with GPS syncs to provide real-time detection and localization for marine authorities.
And not just in Indonesia. From the Philippines to Turkey to Zanzibar, Williams hopes the now publicly available code will be rolled out across the globe to keep biodiverse habitats from being reduced to “rubble.”
Crucially, unlike bleaching events or warming waters, bomb fishing represents a rare form of coral crisis where a local fix exists.
“Because bomb fishing is an acute stressor, you can restore your way out of it,” said Williams. “If bomb fishing stopped, and you went and restored the reefs, they should be healthy and thrive for quite some time to come.”
I wrote up my experience building a backyard office because I wish I had come across more articles like this when planning my build. I hope this post helps you on your journey:
I have worked remotely for most of my career and always dreamed of having my own backyard office. A place on my property but completely separate from my home. Until this year, that idea seemed too unnecessary… then our baby grew into a toddler. We have a small house in Portland. We love it, and it works for us, but it became clear that it could use more space. My wife and I briefly considered buying a new home but decided to stay. But for us to stay, I needed a better working environment. Our space is small. The bedrooms and living room are very close together. It gets loud with our toddler at home with my wife during the day, and listening to one half of a Zoom call wasn’t music to my partner’s ears. I had tried coworking spaces but didn’t love the vibe or the idea of spending hours in a phone booth. I don’t see myself returning to a local office in Portland, so we decided to invest in a backyard office. It was way cheaper than buying a new home.
I looked into many options. My budget’s two most viable paths were an
Autonomous.ai
prefab office Pod or building an office by utilizing a shed frame. The Autonomous pods are gorgeous and come prewired with electricity. You just plug them into an outlet in your house. But I wanted proper heating and air conditioning. I had spent hot summers working with a portable AC unit blasting in the background, and it just wasn’t for me. Their base starts at $16.5k; adding $5k shipping, paying someone to assemble it (I didn’t have time to DIY), and adding a mini-split HVAC system, and we were getting closer to $30k. It was not bad, but it was more than I wanted to spend, not knowing how long we plan on staying in our house.
Deciding against an Autonomous Pod left me with the shed conversion option. This was appealing for a couple of reasons.
Cost. I thought I could do it for ~$15k-$20k.
Lighting. If I went this route, I would have much more control over the layout and lighting, which is very appealing for Portland winters.
Planning, hiring contractors, and the build
I decided on using
Tuff Shed
for the main frame. I was able to design and configure my structure using their online designer. They also have a local showroom in town, so I walked through some models to get an idea of what I wanted. I originally wanted their studio shed model, but after seeing it in person, I decided against it. The great thing about their online design tool is it lets you build a quote on the spot for exactly how much it will cost. The windows Tuff Shed offers weren’t as large as I wanted, so I worked with their team to rough out larger openings for windows that I purchased separately.
I read online about people wishing they had gone bigger with their shed or office. I went with a smaller size 8 feet by 10 feet, it is cozy and sure I do wish it was bigger, but we also have a small backyard, and I really didn’t want to sacrifice more space in the yard than I had to. I measured off an 8 by 10-foot space in one of the rooms in our house and hung some blankets to get an idea of how the space would feel, and I decided 8’ by 10’ would work.
I went with the Premier Pro Tall Ranch shed. This allowed me to have tall ceilings, making the small space feel bigger. I settled on a fully lit windowed door, added a small skylight, and roughed out 2 large windows (6 by 4 feet and 4 by 4 feet). I added a ridge vent and house wrap.
Once I had the frame configured, I went to order it but realized I needed to have a foundation ready before they could schedule the build. I wanted a concrete pad, and they require 3 weeks for the concrete to dry before they will install. So, I hired a concrete contractor.
The shed installation went smoothly. Tuff Shed prefabricates the sheds per order in a local warehouse, so installation of my shed only took about 5 hours. I had an issue; one of the rough openings of the windows was too small, but they quickly sent someone to expand and reframe the area for me.
I ordered the windows separately from Home Depot, and to save a little money, I decided to install them myself with one of my friends. Hanging windows seems intimidating, but after some research and YouTube videos, I realized the process was quite simple if you take time and adequately prep the weatherproof window. This saved me about $700.
Electrical
Once the windows were installed, it was time to run electricity. Our main electrical panel was redone a couple of years ago when we bought and renovated our home, so we have plenty of space to run more power out of our existing panel. I hired an electrician who ran 60 amps out to the shed. They dug a trench to run the power legally, wired up the shed with 4 outlets, LED lights, and a disconnect for a mini-split HVAC unit, and handled all the permitting.
Once the electrical passed permit inspection, I filled in the trench halfway (apparently, you don’t want a larger power supply and ethernet line running too closely together) and ran a ground-rated Ethernet cable out to the office. Fast internet was a must.
Note: In Portland, I didn’t need a permit for the building because it was under the size threshold, but I did need an electrical permit. Check your local jurisdictions.
Insulation, drywall, flooring and trim
I was planning on insulting the office myself and hiring a drywall contractor to do the drywall, install the flooring, and trim myself, but I realized I have a toddler and limited free time. I don’t have time for this. So, I found a contractor to do all of that for me.
I installed soffit vents myself to allow airflow from the roof to prevent moisture buildup and had my contractor install rafter vents.
Finally, it was time to install AC. I got a ton of quotes for installing a mini split. They ranged from $4-$7k, which was higher than I expected after researching the cost of a quality small unit and knowing this would be a tiny job for an HVAC contractor, especially because I had my electrician prewire the electrical. I was considering installing a DIY system (Mr. Cool DIY system with pre-charged AC lines), But found an HVAC contractor who would install a system for a much lower price than the other quotes I received (and he had great reviews on Thumbtack). In the end, I got a Daikin Mini-split, a common system with many replacement parts. The installation took about 5 hours, and my tech did a great job. I am glad I researched and got a lot of quotes for this one.
One thing I did buy was an
INKBIRD CO2 monitor
. I highly recommend one if you are working in a small space. I wanted to read how much CO2 is in the air because I built this as a sealed space. And it’s now clear I need to install an HRV or, ERV, or exhaust ventilation fan; for now, I just crack a window when CO2 levels get higher, but I’ll be addressing this soon.
The final product
Cost and project breakdown
Overall, I am super happy with my space, and I came in within my planned budget. I could have saved some money by doing more of the work myself, being okay with a space heater and window/portable AC option, and using a gravel foundation, but these were areas I decided to spend money on.
Here is the complete cost breakdown of my office build:
Concrete foundation (contracted)
$2,000.00
Tuff Shed shell (contracted)
$6,148.00
Custom Windows
$533.00
Window installation supplies
$77.00
Electrical work and materials (contracted)
$4,350.00
Insulation, Drywall, flooring, trim installation (contracted)
$3,650.00
Flooring materials
$420.00
HVAC mini-split system and labor (contracted)
$2,300.00
Total project
$19.478.00
Things I am glad I did
Buying larger windows than what Tuff Shed offers. I would be much less satisfied if I hadn’t done the extra work to get large windows. I have seen many people shed conversions using the standard window options. In my opinion, this is the most significant oversight people make; with smaller windows my office would feel like a shed.
Deeply consider where the structure will sit, which direction it will face, how the sun will play with this and the window layout, and where I wanted my desk to face. In small spaces, you should make very intentional choices.
Use
Thumbtack
to find contractors. This made finding great people relatively easy.
Do the work to get multiple quotes. The first electrician I talked to quoted me double what the electrician I went with did.
Go with smaller contractors. 1-person shops are fantastic; many do great work and are cheaper than larger teams because they have lower overhead. This goes for electricians, HVAC, and more.
Install more outlets than you think you need. It was a small space, so I don’t need a ton of outlets, but I am already happy I installed 4 instead of 2.
Running ethernet hardwired internet.
I am stoked with my office. I would much rather hire a general contractor or company that builds ADUs to handle this for me. Managing this was a ton of work, and after a house renovation, I don’t love these projects. But I got an office I really like for under $20k; if I hired a company to handle everything for me, I was looking at $40-$50k. That wasn’t the path for me this time around.
MySQL CDC to BigQuery: what periodic syncs miss, and how binlog avoids it
MySQL CDC syncs miss deletes and intermediate updates. Learn how binlog-based Change Data Capture works, what MySQL settings it requires, and how to land it reliably in BigQuery.
Aug 25, 2026
Most MySQL-to-warehouse pipelines run on the same pattern: a scheduled job selects rows, compares them to what was there before, and writes the difference. It works, until it doesn't.
What periodic syncs miss
A
SELECT
-based sync only sees what exists right now. It has no way to know a row existed and was deleted between two runs, no way to see intermediate states of a row that changed more than once, and it puts real load on your production database every time it scans a large table just to find a handful of changed rows.
What CDC does differently
Change Data Capture reads directly from MySQL's binary log (binlog), the same mechanism
MySQL
uses internally for replication. Every INSERT, UPDATE, and DELETE is captured as it's written to the log, in order, with the complete row state. Nothing is inferred by comparison. Nothing depends on when a batch job happens to run.
This isn't about speed. A CDC pipeline that runs once an hour is still fundamentally more reliable than a batch sync that runs once a minute, because it captures
everything that happened
, not just the latest snapshot.
What has to be true on the MySQL side
CDC via binlog has real prerequisites:
Binary logging in ROW format, with FULL row images.
If
binlog_row_image
isn't set to
FULL
, DELETE and UPDATE events won't carry the complete before/after state, only what's strictly needed to apply the change. That's often not enough for a downstream consumer that needs the full row.
binlog_row_value_options
must not be
PARTIAL_JSON
.
If it is, updates to JSON columns only log what changed inside the JSON value, not the full value. Silent, and easy to miss until you compare against the source.
The replication user needs
REPLICATION SLAVE
and
REPLICATION CLIENT
privileges
to read and monitor the binlog, plus
SELECT
,
RELOAD
, and
SHOW DATABASES
for the initial snapshot.
A unique
server-id
for every replication client attached to the database, including your CDC connection. Collisions with existing replicas cause silent failures that are painful to debug.
Binlog retention long enough to cover downtime.
MySQL purges binlog files after a configurable window (30 days by default). If your CDC connection is offline longer than that, it won't be able to resume from where it left off. It'll need a fresh initial snapshot.
Setting it up
GRANT SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'your_user';
FLUSH PRIVILEGES;
Then confirm your binlog configuration:
SHOW VARIABLES LIKE 'log_bin';
SHOW VARIABLES LIKE 'binlog_format';
SHOW VARIABLES LIKE 'binlog_row_image';
If any of those aren't set correctly, they go in
my.cnf
, and MySQL needs a restart to apply them.
This is where a managed platform earns its keep. Erathos and similar tools handle the snapshot mode selection (full initial snapshot vs. binlog-only), the server-id assignment and collision avoidance, and the recovery logic when a binlog gets purged before the connection catches up, so the person running the pipeline doesn't have to rebuild that logic by hand every time a new source gets connected.
Landing it in BigQuery
Once CDC is capturing changes correctly, the destination side is comparatively simple: each change event maps to a row operation in your BigQuery tables. The part worth getting right isn't the load into BigQuery, it's making sure what arrives there is complete. A pipeline that lands incomplete data on time is worse than one that's occasionally a few minutes behind but never wrong.
If your team is still running full-table batch syncs against production MySQL, the question worth asking isn't "how do we make this faster." It's "what are we currently unable to see."
If you want to try this in practice, you can
create an Erathos account
and connect your MySQL source with CDC enabled in a few minutes.
OpenAI has spent the past couple years quietly building “Jalapeño,” an inference chip just announced at Hot Chips. Rumors of a successful tapeout had been swirling for a while. But now we have details. OpenAI invited us to look at their chip,
go to their labs to check out how real it is, and
benchmark
it with our
InferenceX
suite.
In general first generation chips are not competitive, but OpenAI bucks the trend by being industry leading and beating every Nvidia, AMD, and Google chip we have been able to test on multiple top open source models. OpenAI does this with extreme hardware software codesign. Surprisingly, OpenAI is not over specialization on any specific part of model inference, but instead by focusing on being a general chip that delivers high performance in all scenarios.
In this article, we will go into architectural details, software details and performance results for Jalapeño on InferenceX.
Everyone says that OpenAI’s chip is specialized for OpenAI models, but that’s wrong, OpenAI made a generalized chip for AI inference.
The timelines are insane. It shows that claims that use of AI is being used to accelerate chip design are real. Regardless of the quick timelines,Open AI spent a bunch of money, made pragmatic design decisions and their team is cracked, so this comes as no surprise.
Just looking at the specs, it is an immediate contender:
Source: SemiAnalysis
And the use of HBM4 makes it stand out as comparable to flagship GPUs from NVIDIA and AMD:
Source: OpenAI
A lot of the media coverage of this chip has followed a few throwaway comments from OpenAI that claim the chip will be optimized for their models in a way that other chips are not. This is wrong. Jalapeño is a generalized inference chip capable of running all sorts of models, and all sorts of workloads, including our benchmark InferenceX, where we ran the benchmark with OpenAI engineers in the lab. As a joke, OpenAI even showed us it running Doom, which was ported to their chip with just Codex prompts.
The following is our headline perf/W result, looking at token throughput per All-in utility MW.
Jalapeño smokes every other chip
. All this is done without Multi Token Prediction (MTP), while the other chips on the chart are the best performing configs of each respective SKU, all with MTP.
Source: SemiAnalysis
Jalapeño beats Blackwell on perf/W across almost all scenarios without being tuned for any specific point in the curve. It excels not only in low-latency scenarios but also in high-throughput scenarios. A more apples to apples comparison is against Single Token Prediction results, it knocks every competitor out of the water. At low concurrency scenarios, Jalapeño demonstrates remarkable interactivity, hitting over 700 tokens per sec per user at concurrency 1 on the DeepSeek R1 model.
Incredibly, this is all achieved with single-token prediction (STP), no speculative decoding and no prefill-decode disaggregation. In addition to DeepSeek R1, we also got to see some other models, including Kimi-K2.5 and GPT-OSS which ran at approximately 1,400 tok/sec/user. For all models, we confirmed that
Jalapeño’s
GSM8k evals attained results on par with Nvidia chips.
Some caveats on this. First, all numbers are provided to us by OpenAI. We verified the InferenceX runs in person in the lab, but we did not run the full suite of
InferenceX
benchmarks nor have we seen
AgentX
results. AgentX is our preferred suite for comparing chip performance due to the datasets’ long context and multi-turn characteristics that reflect the cache behavior of realistic production workflows. Frameworks that perform well on 8k1k may perform worse on AgentX as real production loads stress components like routers, prefix cache mechanisms, cache management, offload infrastructure, etc. These are not tested by single turn 8k1k. Read more about this in out AgentX article.
Second, we believe that comparison to Blackwell is somewhat incomplete and unfair. Jalapeño is really competing against chips like Rubin that also use HBM4. Vera Rubin systems are starting to ship to customers right now, while it will still be some time before OpenAI has anything beyond engineering samples of Jalapeño.
Third, the models being tested are not on the open frontier. NVIDIA and AMD have published results on larger models such as DeepSeek V4 Pro and Kimi K3, using AgentX. The larger the model and the more recent the release, the more complicated it is to bring up on a new chip. With that said the models OpenAI has working on Jalapeno aren’t exactly small either.
OpenAI designs for perf/W. The reason is simple: OpenAI is currently limited by datacenter power, not by budget or floorspace, and thus tokens per MW is paramount. At Computex 2026, Jensen said that perf/W, reliability and long lifetime are the core features of future GPUs. To quote: “If you have 1 gigawatt of power, then throughput per watt is revenue”. He also mentioned that choosing the wrong architecture just because the chips are cheaper doesn’t make sense.
Source: Computex 2026 keynote
This was emphasized by Nvidia during the Vera talk at Hot Chips 2026 while showing the same revenue graph: “The data center is power limited today.” Power matters and drives revenue.
Operators cannot simply obtain more MW because adding GPUs and adding grid capacity happen on very different timescales. Datacenter power envelopes have constraints such as their utility interconnection, infrastructure, cooling capacity, and UPS/backup-generation design. Grid delays repeatedly outpace hardware and construction timelines, driving the need for BtM (behind-the-meter) power capacity: gas turbines and on-site generators built and located at the data center itself. This capacity sits behind the utility’s meter rather than being drawn from the public grid. It lets an operator power a facility without waiting on grid interconnection and utility upgrades, which is exactly why xAI’s Colossus 2 relies so heavily on BtM while its actual grid connection lags far behind. Find out more in our
Energy model
.
As we wrote in an X post, tok/s/MW reduces to tokens per joule since a watt is a joule per second. This makes tok/s/MW representative of a system’s efficiency and ability to convert energy into tokens.
On this front, even when compared with Rubin, Jalapeño wins. OpenAI’s Jalapeño has STP output token throughput per MW surpassing
Vera Rubin’s MTP results that NVIDIA and CoreWeave published in July. It also far exceeds GB200’s 2025 MTP results.
As mentioned in our Vera Rubin article, VR was compared to 2025 GB200 results because that was a similar stage of early bring-up, and comparing to GB200 in 2025 holds software maturity constant. Following this logic, we compare Vera Rubin’s latest July 2026 results, GB200 2025 results, and today’s Jalapeño results. This is a very valid comparison as these are the best public Rubin numbers, and OpenAI taped out their chip after Rubin. Both OpenAI and Rubin are still immature thus performance will continue to rise.
Source: OpenAI, SemiAnalysis
On perf/TCO, Vera Rubin and Jalapeño are head-to-head, producing almost the same number of output tokens per $. However, as previously mentioned,
Jalapeño’s results are obtained without speculative decoding
and Vera Rubin’s results use speculative decoding. Speculative decoding leads to a ~3-5x reduction in cost per token. When speculative decoding is implemented on Jalapeño, this will enable Jalapeño to serve tokens even more cost effectively. Of course, part of this TCO advantage comes from trading Nvidia’s high margins for Broadcom’s lower (though still high) margins. But this is not all of it. For example, Meta and Microsoft’s AI ASIC programs not getting off the ground despite being at it for much longer shows that cost is only one part of the equation. For Jalapeño’s full TCO breakdown, see the
SemiAnalysis AI Cloud TCO model
.
Source: OpenAI, SemiAnalysis
Architecturally, OpenAI chose not to disaggregate prefill and decode (PD) across separate chip pools. The draft model and main model share the same chips and fabric, a design philosophy that trades some theoretical efficiency for practical operations. The motivation is that the workload mix changes over time, for example the ratio of input to cache write to cache read to output tokens has changed significantly as we have moved through the three eras of models (
knowledge, reasoning, and agentic, as discussed in our recent article
). Therefore, picking a fixed amount of heterogenous prefill silicon and decode silicon up front can lead to inefficiencies over time. OpenAI chooses a homogenous pool in this architecture and tries to make the chip perform well on everything.
And it does. On Kimi K2.5 (which Cursor Composer 2.5 is based on), Jalapeño reaches nearly 700tok/s/user and more than 9x the next best performing chip at 100tok/s/user.
Source: OpenAI, SemiAnalysis
On GPT-OSS, it’s another bloodbath. Jalapeño’s iso-interactivity throughput per MW is nearly double GB200’s highest throughput point and more than 50x GB200’s concurrency 1 point. The higher concurrency Jalapeño points use EP8.
Source: OpenAI, SemiAnalysis
These results are impressive! However, we have to nitpick: they’re just 8k1k, a much easier workload to tune for, and there are no
AgentX
runs yet. As mentioned in our
AgentX
article, multiturn, long context workloads stress much more aspects of the serving stack, such as routers and prefix cache. Many more optimizations are needed to excel in agentic workloads. Read more about this in the
AgentX
article.
All these results were gathered on the A0 stepping of Jalapeño, just 9 months into the program. But there is already a B0 stepping that is currently in the fab! B0 has optimizations that deliver roughly a 25% perf-per-watt improvement over the earlier A0 silicon. Specifically, the B0 stepping delivers 13.4 PFLOPs of MXFP4 on a single reticle-sized compute die that is manufactured on TSMC’s N3P. This compares to 17.5 PFLOPs of dense Rubin NVFP4 for a single Rubin compute die that is similar size and on the same node.
This is more respectable considering Jalapeño’s TDP is only 700W compared to Rubin’s at 900-1,150W per compute die. As Jalapeño is geared towards inference rather than training, it is understandable that OpenAI doesn’t need to push TDPs higher to maximize FLOPs, but regardless the above shows that Jalapeño delivers respectable peak theoretical FLOPs.
When compared directly to other accelerators, Jalapeño has the highest HBM bandwidth per watt, and the highest FLOPs per watt, comparable to the 1,800W Rubin Max-Q configuration:
Source: SemiAnalysis
Off-package I/O is provided by an N3E I/O chiplet with 32 lanes of 800G SerDes, for the compute fabric, with 24 lanes (600GB/s) being used for local scale-up within the rack, and 8 lanes (200GB/s) for global scale-up which is the 2,048 XPU multi-rack domain. PCIe Gen 5 is used for system I/O to connect to the x86 host CPU.
Jalapeño will ship with HBM4, making this chip one of the relatively early adopters after Nvidia and AMD, even beating the established TPU and Trainium programs. As one of the key architectural principles behind Jalapeño is getting the most out of HBM bandwidth, settling for anything but the best HBM would run counter to that goal. This results in 15.4TB/s of memory bandwidth per package which bests all the other accelerators shipping that are using HBM3E. The 15.4TB/s bandwidth shows its HBM4 can hit 10Gbps pin speeds, which would give it a slight edge over the 9.6Gbps Nvidia is getting out of its HBM4 in Rubin. The HBM is likely provided by Samsung.
Source: OpenAI
OpenAI taped out Jalapeño in November 2025, or more specifically, this was a tape out of the CoWoS design, not just the top die silicon. Within 9 months of that Nov 2025 tapeout, and with only 3 months of bring-up on actual silicon, OpenAI has already delivered very good results with Jalapeño. This is all the more impressive as the team is starting from zero on the software stack.
Meanwhile, Rubin’s CoWoS tape out was completed in October 2025, a month earlier, and yet the only early results we have seen are from CoreWeave’s engineering samples. Nvidia has not let us test and release benchmarks in the same way that OpenAI has, indicating their chip software is still immature. The CUDA moat is potentially dead given how fast OpenAI can bring up new models on their silicon.
They are still far from optimized and we can see that generally Jalapeño has delivered better numbers. We don’t think that Nvidia hardware is inferior, but more so that Jalapeño’s software bring-up has progressed more quickly than Nvidia’s. This speaks to the power of hardware/software co-design, which is the main area where a cracked frontier lab ASIC team can excel over more established merchant silicon players. Counterintuitively, starting from scratch may also have benefited OpenAI as it could make clean-sheet architectural decisions without worrying about backwards compatibility or older software versions.
Suffice to say, OpenAI Jalapeno is a real high volume ASIC.
When compared against Rubin’s timeline, Jalapeño’s is shockingly quick. As shown earlier, Jalapeño’s results beat Rubin’s despite Rubin’s head start.
Source: SemiAnalysis
Digging into the architecture now, the chip’s matrix engine uses MXFP numerical formats and a weight stationary systolic array, similar to TPU. But when compared directly to TPU, it has support for smaller shapes / dimensions, meaning that it doesn’t have weird performance cliffs that get exposed by awkwardly shaped matmuls on bigger systolics.
It also has 64-bit scalar cores and FP32/INT32 vector cores. OpenAI has also invested in redundancy at the tray level and has yield harvesting built in at the core and channel level. They claim that AI assistance in chip design delivered an 8% reduction in SIMD area and a 10% reduction in matrix-engine area during design. While they did not clarify the exact process/voltage/temperature (PVT) conditions, they also mentioned the AI-assisted blocks improved timing and power over the initial blocks.
The Jalapeño architecture design focuses on eliminating memory movement of KVCache and weights as well as fixed latencies and overheads in order to make it possible to get closer to the raw peak flops/bandwidth even for small batches or shapes as compared to other accelerators.
The cores and the HBM are divided into slices, where each core slice has a low-latency local view on its own slice of HBM. Synchronization between slices occurs on a high-bandwidth dedicated collective network. This minimal memory hierarchy already gives Jalapeño a big potential advantage over GPUs, where memory accesses must traverse a complicated memory system, resulting in large latencies that must be amortized or hidden over larger shapes.
This choice is feasible because with careful placement of weights and KVs, synchronization between cores can be restricted to limited, known high-bandwidth comms such as tensor-parallel communication that can be overlapped with compute.
Source: OpenAI
There is also an additional general NoC which is used for general comms and to access the scale-up network. In general OpenAI saves huge power and gets big performance gains with a simplified NOC and memory subsystem vs Nvidia and Google.
Source: OpenAI
At the core level, OpenAI describes an out-of-order (OoO) core with an L1 cache. This is a large divergence from the pattern we have seen in other accelerators, all of which instead use software-managed scratchpad commonly paired with some async DMA support. Again, the argument being made here is that this allows Jalapeño to avoid fixed overheads such as barrier latencies, which on other accelerators (such as GPUs) need to be hidden or amortized over with higher work per core, and make it harder to get close to the raw peak bandwidth/flops.
The tradeoff is that Jalapeño therefore relies on good prefetching to ensure timely arrivals of memory requests, which is less predictable and more difficult to reason about. However, with Codex in a good harness with access to detailed tracing, it is likely that finding the optimal kernel with the best prefetching for a given shape requires little human intervention. We think that is exactly what OpenAI has done to bring up DeepSeek R1, Kimi K2.5, and GPT-OSS so quickly.
The cores also have support for “small” matrix dimensions, which (depending on how small) should make it more general across different model and batch dimensions less sensitive to matrix dimension alignment, padding overhead, and tiling inefficiency. For instance, TPUs, Trainium, and Etched chips have very large systolic arrays which can require large batches or exactly-divisible model dimensions to avoid tiling inefficiencies.
With Jalapeño, OpenAI has focused on eliminating fixed latencies in the system to allow for as-close-to-roofline performance as possible across all areas of the pareto curve. In theory, this could give them advantages over the GPU at multiple operating points:
Much better upper-bound performance on low-latency/small-batch inference, which on GPUs is limited by many fixed overheads such as launch latencies, barrier latencies, memory system latency
Some potential to achieve closer to the hardware roofline even for large-batch or long-context
This comes with the caveat that even if the upper-bound performance is available in theory, it may be more difficult to realize that performance for real kernels. So it seems the approach is:
Design for the highest upper-bound performance across all workload shapes
Let Codex do the tedious work of finding the kernels that achieve that upper bound
Judging by the extremely fast turnaround for the OpenAI team to bring up InferenceX workloads on Jalapeño, we are optimistic about this approach.
If Jalapeño is a success, it will be a strong signal that the industry’s obsession over programming models and perfect, universal compilers are invalidated by frontier AI models.
OpenAI writes Jalapeño kernels like assembly. Each kernel gets hand-tuned code, some running to ~3,000 lines, backed by correctness checks and a custom sanitizer. Early kernel work was human-in-the-loop rather than fully automated, but this shifted with a more scaled-up, internal version of Codex, one which OpenAI plans to pitch to enterprise customers. The internal serving engine is called “Teacup”. Interestingly,
OpenAI had no internal implementation of MLA kernels until they benchmarked DeepSeek with InferenceX
. The ability for Codex to write functional and efficient kernels so quickly (without any of OpenAI’s kernel engineering team intervening) shows the software pipeline’s developmental ability.
OpenAI programs Jalapeño with Gluon. Gluon is OpenAI’s kernel programming language. Built on top of Triton, Gluon preserves Triton’s SPMD (Single Program Multiple Data) programming model, but it exposes
low-level programming abstractions
. For example, for NVIDIA GPUs, it offers APIs that map to PTX instructions, including MMA instructions, TMA instructions, mbarrier mechanisms, and many more. The most unique abstraction Gluon provides is
the layout
. Generally speaking, a layout defines a mapping between a hardware resource (e.g. 5th register of warp 9) and a tensor element (e.g. tensor element on row 6 column 7). Gluon’s layout abstraction is based on
Linear Layouts
, a type of layout algebra OpenAI invented. Linear Layouts mathematically formalizes what a layout is and provides tools to operate on layouts. This enables many features, such as provably correct layout conversions and optimal memory swizzling.
In terms of Jalapeño’s programming model, each Gluon program maps to a persistent thread. We believe this hints that Jalapeño suits the
persistent kernel programming pattern
, where each program executes on multiple tiles, and the programmer, rather than the hardware scheduler, assigns the work. OpenAI mentioned TensorInfo, an abstraction that explicitly encodes layouts. This is likely the set of layouts designed for Jalapeño, which will be powered by Linear Layouts. Finally, each core offers data prefetching and decoupled out-of-order units. For example, a user might program a wait on a prefetched data, which is locked behind a semaphore.
In a weird twist of fate, OpenAI models like GPT 5.6 Sol, which currently run on NVIDIA GPUs, have been used to design a chip that poses a real threat to the CUDA moat - NVIDIA’s own GPUs are helping usher in their potential successor in real time.
Comparing across time, we can also see Jalapeño’s developmental pace, achieving more than 2x throughput improvements at certain interactivities in less than 2 weeks. Each tarball we get from the Jalapeño team has a world of wonders inside.
Source: OpenAI, SemiAnalysis
Not only did kernel performance improve, in the span of 8 days, the Jalapeño team enabled TP32, building on the previous TP8 configs and expanding beyond a single system to get a full rack-scale config running on a large model. This is a really impressive pace of development.
Source: OpenAI, SemiAnalysis
To validate performance before committing to real hardware runs, OpenAI also has a simulator “chilisim” accurate to within 5% of measured hardware, using a fixed-width trace bus. Tracing on A0 was limited but has improved substantially on B0, likely with inputs from actual runs on A0 silicon. Engineers have demoed the Codex CLI running an internal model, nicknamed “Raiku” or “5.3 Codex Spark”, at 1.2ms TPOT.
The team also showed off Codex-written demos running directly on the chip: Doom at 36 FPS, an FP32 fluid-dynamics simulation, and a “Liquid Light” mouse-drag visualization.
Source: SemiAnalysis
On the model side, OpenAI’s internal megakernel approach, nicknamed “gigakernel”, is built around a single megakernel that loops on-device to reduce CPU overhead and launch time. The team is also leaning further into test-time compute strategies, with internal interest specifically in how to coherently use 1 million rollouts.
We mentioned earlier that OpenAI is not using prefill decode disaggregation on these chips. This came as a surprise to us, as NVIDIA and AMD GPU performance benefits significantly from PDD, even on homogenous hardware. Let’s dig into why the Jalapeño team went this way.
Prefill-decode disaggregation (PDD) looks attractive when the workload is frozen. Prefill and decode stress hardware differently, so assigning each phase to a separately tuned pool can improve efficiency at one chosen input/output ratio. Production traffic, however, does not stay at that ratio. Input and output sequence lengths, concurrency, cache-hit rates, speculative-acceptance rates, and latency targets all move throughout the day.
Once devices are divided into prefill and decode pools, too much prefill demand leaves decode chips idle while requests queue. But too much decode demand does the opposite. The operator must continuously predict the right split, provision spare capacity on both sides, and rebalance a system whose ideal ratio is always moving.
In a unified system, some resources may be underused during a particular phase, but every device remains available to serve the next request. In a disaggregated system, an entire chip can sit idle simply because it belongs to the wrong pool. Local utilization looks better, but global utilization can be bad.
Source: SemiAnalysis
Disaggregation also breaks locality. The prefill worker produces a large KV cache that the decode worker immediately needs, so the system must transfer that state across the network before generation can continue. That adds bandwidth consumption, synchronization, queueing, and another failure domain. The cost also rises with input sequence length because KV cache grows. However, avoiding the movement of KVs is largely a power and latency optimization; being willing to move some KVs around can allow for increased hardware utilization at the expense of some power and per-request latency.
A fungible fleet shifts capacity between latency-sensitive requests and throughput-oriented batches, while a fixed split strands hardware whenever the traffic mix changes. Moreover, context length changes the balance between attention and FFN work, making any fixed hardware ratio efficient only near its design point.
Source: SemiAnalysis
The same constraint applies to speculative decoding. A draft model has to feed candidate tokens to the verifier with extremely low latency. Separating the two across specialized pools turns a tightly coupled decoding loop into a distributed protocol. The extra communication and coordination can consume the latency saved by drafting. Keeping both models on the same devices and low-latency fabric preserves the locality that makes speculation worthwhile in the first place.
Source: SemiAnalysis
However, disaggregation can still win where demand is sufficiently large, stable, and predictable, particularly when conventional GPUs need large phase-specific batches to reach good throughput. But it is not free lunch.
The Jalapeño System at the rack unit level consists of a CPU host rack and an ASIC rack. The host rack houses 16 host CPU trays named “Katsu,” each corresponding to one of the 16 ASIC trays, named “Vindaloo,” to the right of the Katsu. Each host houses two Turin-class AMD EPYC CPUs with 1.5TB of DRAM, 2x E1.S, and 2x M.2 SSDs per rack. Each tray is also specced with 400G (2x200G) frontend networking. Each Katsu tray connects to each Vindaloo tray via 8 external PCIe DAC cables that run horizontally across the rack at the front. The system level design is done in partnership with Celestica.
The ASIC rack consists of 16 Vindaloo trays and 8 scale up switch trays (6 for local + 2 for global), named “Chana.” Each Vindaloo tray consists of 8 Jalapeño ASICs, making up a total of 128 Jalapeño ASICs per rack. The ASICs are connected to each of the Chana switch trays via a copper cable backplane, just like that of Nvidia’s Oberon. The scale up topology is split into a local domain of 128 ASICs within the rack and a global domain connecting up to 16 racks or 2,048 ASICs. We will explain the bandwidth and the topology in more detail below.
Power provisioning to a sidecar host rack draws roughly 50kW provisioned (31kW in production), and the ASIC rack draws 130kW, making the total two rack system roughly 160kW. That’s basically a double-wide GB300 rack in terms of power draw.
Source: SemiAnalysis, OpenAI
OpenAI can connect up to 2,048 Jalapeño XPUs within a single scale-up network. The scale-up network consists of two domains, a local domain connecting all 128 XPUs over backplane within the rack, as well as a global domain connecting 2,048 XPUs over 16 racks using a hybrid of copper and optical interconnect. Each rack consists of 8 Chana switch trays. Six Chana switches in the middle are for the local domain, which come with one 102.4T Tomahawk 6 switch ASIC each. Two Chana switches at the top and bottom of the local switches are for the global domain, which we think could consist of 2x 102.4T Tomahawk 6 switches making up to 204.8T per switch tray.
In the local domain, each of the 128 Jalapeño chips has a per XPU uni-directional bandwidth of 4.8Tb/s and is connected on an all-to-all basis to 6x 102.4Tb/s Tomahawk 6 ASICs. This would amount to 48-differential pair (DP) male and female connector pairs per XPU translating to a total of 6,144DPs worth of passive copper cables per rack used for local scale-up.
For the global domain, 16 racks totaling 2,048 XPUs are connected together via a combination of copper backplane, electrical 204.8T TH6 switch, 1.6T transceivers, and optical circuit switch. Each XPU has a uni-directional bandwidth of 1.6Tb/s for the global link, which is 16-differential pair (DP) male and female connector pairs per XPU for the backplane between the XPU and the global switch. Bandwidth exiting each global switch tray of 2 ASICs each is split between the backplane and front panel optics.
Between local domain and global domain, backplane connector count per rack comes up to 64 DPs per XPU and a total of 8,192 DPs worth of passive copper cables per rack.
The global domain adopts a rail-only architecture consisting of 8-rails across the global domain. We think OpenAI routes optical links in the global domain via Optical Circuit Switches (OCS) installed in every rack. For every XPU, 1.6Tb/s of global bandwidth will travel to the global switch tray over the copper backplane. This then exits the switch through the front panel via 1.6T transceivers, which go to the passive optical switch before exiting the rack. This expands the scale-up world size to 2,048 XPUs combining 16 racks of 128 XPUs each.
Source: SemiAnalysis
Because scale-up networking is only about 10% of total system cost, that flexibility buys valuable optionality for future 10–20 trillion parameter models or 2–4 million token context windows. On deployment, OpenAI is partnering with neoclouds and is gathering reliability data with datacenter partners through January while optimizing dock-to-rack rollout time.
Next, we talk about the future of Jalapeño, whose first production token is coming soon. The next goal is 100MW, and the hurdles will mostly be hardware: How much can they produce, how well can they deploy and operate datacenters, how do they handle monitoring, and resiliency, etc. The software is already proven, and with internal models, every software headstart is easily caught up to. Behind the paywall we will discuss implications for NVIDIA, AMD, Cerebras, and other chip companies who have signed deals with OpenAI in the coming years.
[$] Old-school calendaring at the command line with Remind
Linux Weekly News
lwn.net
2026-08-25 10:03:02
Remind is a
command-line calendar and alarm program, with an optional Tk-based graphical
interface, for Linux and Unix-like operating systems. It has its own scripting
language that allows users to create reminders that are difficult (if not
impossible) to specify in other calendaring programs. It i...
The page you have tried to view (
Old-school calendaring at the command line with Remind
) is currently available to LWN
subscribers only.
Reader subscriptions are a necessary way
to fund the continued existence of LWN and the quality of its content.
If you are already an LWN.net subscriber, please log in
with the form below to read this content.
Please consider
subscribing to LWN
. An LWN
subscription provides numerous benefits, including access to restricted
content and the warm feeling of knowing that you are helping to keep LWN
alive.
(Alternatively, this item will become freely
available on September 3, 2026)
From Fake Workers to Account Recovery: The Growing Identity Verification Risk
Bleeping Computer
www.bleepingcomputer.com
2026-08-25 10:01:11
Attackers are increasingly targeting the processes used to establish or recover identity rather than attacking the login itself. Specops explains how stronger identity verification can help organizations prevent fake workers and social engineering attacks from gaining legitimate access. [...]...
Security teams have spent years hardening authentication, with controls like multi-factor authentication (MFA) and conditional access now commonplace. While stronger authentication can make traditional credential theft less effective, it doesn’t solve every identity problem.
There are several points in the identity lifecycle where trust is established or re-established:
When a new employee joins.
When someone loses access to their account.
When a password or MFA factor needs to be reset.
When the service desk is asked to make a sensitive change to an account.
Rather than stealing credentials or bypassing MFA, an attacker can instead try to convince the service desk that they are the account holder, using social engineering to exploit legitimate processes.
That puts greater pressure on organizations to secure both the login as well as the processes around account creation and recovery.
How Attackers Exploit Identity at Onboarding and Recovery
In late July 2026, the US Department of State and allies including Japan, Canada and the UK
issued a joint alert
warning that North Korean IT workers were impersonating foreign nationals to secure employment.
Their tactics focus on falsifying identity documents, such as using images supplied by a third party based in another country to register accounts. The North Korean then carries out the actual work.
These workers typically target technology companies, so the important point is not that every organization should expect the same type of campaign. It is that onboarding creates a moment when trust is established for the first time.
If identity checks fail at that stage, the attacker can enter the environment with access that appears legitimate.
The same issue can occur during the recovery process. Threat actor groups like
Scattered Spider
are proficient at social engineering, impersonating employees and calling the service desk to reset passwords that gift access to an account.
This tactic was linked to the
2025 M&S ransomware breach
, which contributed to an estimated $400 million hit to the retailer’s operating profit through lost sales.
The security question in these scenarios is the same: how confidently can the organization verify that the person making the request is who they claim to be?
Strong Authentication Still Depends on Strong Identity Checks
When someone calls the service desk claiming that they’ve forgotten their password or lost access to their authenticator, the agent needs to be able to confidently verify the person calling is the real account owner.
However, in many organizations identity checks can still rely on relatively weak signals. A service desk might ask for an employee ID or phone number. Security questions are still common, asking the caller the name of their first pet or where they went to school.
The problem is that many of these checks can be researched, stolen or manipulated. Attackers can find personal information through data breaches or social media.
Even in instances where stronger checks are in place, the North Korean remote worker campaigns demonstrate how documents and other identity evidence can be altered or fabricated.
AI is making impersonation more convincing, too. Attackers can use synthetic profiles, manipulated images, cloned voices and deepfake video to support a false identity or make a social engineering attempt more believable.
All of these make it harder for agents to act with confidence. As it’s vital for organizations to verify users during onboarding and recovery events, they need stronger measures to deliver that verification.
Strengthen Verification During High-Risk Identity Events
Solutions like
Specops Verified ID
add another layer of assurance and helps service desk agents confidently confirm identity before sensitive actions take place.
It does this by combining government document scanning and validation with biometric liveness detection.
Document checks help confirm that the ID being presented is legitimate, while liveness detection helps verify that a real, present person is completing the process rather than relying on a static image or other replayed evidence.
During onboarding, this gives organizations a stronger way to verify new employees before granting access to corporate systems. That can reduce the risk posed by fraudulent applicants and impersonation attempts, including tactics seen in North Korean remote worker campaigns.
The same approach can be applied when high-assurance verification is needed, such as password resets for privileged accounts.
Rather than adding complexity to every identity event, Specops Verified ID applies stronger verification where the consequences of getting it wrong are highest.
Protect Your Service Desk with Specops
Strong authentication remains essential, but attackers will continue looking for ways around the controls that are hardest to break. Increasingly, that means targeting the processes used to establish or recover identity rather than attacking the login itself.
Whether an organization is onboarding a new employee or helping an existing one recover their account, the challenge is ensuring the right person is granted access.
Specops Verified ID
adds government ID validation and biometric liveness detection to these high-risk identity events, helping organizations make that decision with greater confidence.
If you’re interested in learning more about how Specops can strengthen identity verification at the service desk,
contact us today
to speak to an expert.
Dirk Eddelbuettel: gettz 0.0.6 on CRAN: Maintenance
PlanetDebian
dirk.eddelbuettel.com
2026-08-25 10:01:00
Another minor routine update 0.0.6 of gettz arrived on CRAN just now.
gettz provides a
possible fallback in situations where Sys.timezone() fails
to determine the system timezone. That happened when e.g. the
file /etc/localtime somehow is not a link into the
corresponding file with zoneinfo data in,...
Another minor routine update 0.0.6 of
gettz
arrived on
CRAN
just now.
gettz
provides a
possible fallback in situations where
Sys.timezone()
fails
to determine the system timezone. That happened when
e.g.
the
file
/etc/localtime
somehow is not a link into the
corresponding file with
zoneinfo
data in,
say,
/usr/share/zoneinfo
. Since the package was written (in
the fall of 2016), R added a similar extended heuristic approach itself
making the package a little less relevant.
This release reflects several rounds of updates to the continuous
integration setup, some URL updates, as well as some updates to
packaging including use of Authors@R in DESCRIPTION. As with the
previous releses: No functional changes, no new code, or new
features.
Anthropic CEO Dario Amodei.
Bloomberg/Getty Images
Anthropic told staff in its San Francisco offices to start this week working from home because of a possible strike by its offices' security workers. The union representing those workers said that was news to them.
Last week, the AI company received a notice from its security staffing firm,
Allied Universal,
saying that its employees might go on strike, according to a person familiar with the matter. Anthropic then told its own workers they shouldn't come into San Francisco offices on Monday and Tuesday just in case, the person said.
Allied Universal did not respond to requests for comment from Business Insider.
The Service Employees International Union (SEIU), which represents workers at Allied, told Business Insider it is in protracted contract negotiations with Allied and other California security firms. The union said it had not called a strike authorization vote or issued any strike threats for this week.
SEIU covers thousands of security workers in California and has been negotiating for a new contract since April. The union is pushing for higher wages, better healthcare, and more comprehensive job training.
Anthropic declined to comment on the stay-at-home mandate.
Security spending has ramped up in the wider tech industry over the past few years.
The Wall Street Journal
reported that Anthropic and OpenAI have dealt with several threats against their employees.
Anthropic has a hybrid in-office policy that generally requires staff to be in the office at least 25% of the time, according to job postings.
Anthropic is expected to file for its initial public offering as soon as August, having filed its confidential S-1 draft in June. On secondary markets, investors have propelled the company to
a $1.5 trillion valuation
.
Have something to share? Contact Langley via email at
hlangley@businessinsider.com
or Signal at 628-228-1836. Contact Council via email at
scouncil@businessinsider.com
, or over text, Signal, Telegram, or WhatsApp at 415-757-8198. Use a personal email address, a nonwork WiFi network, and a nonwork device;
here's our guide
to sharing information securely.
Read next
Hugh is a senior correspondent at Business Insider where he writes about Google, tech, and wealth. His work has been cited by The New York Times, Bloomberg, Reuters, The Wall Street Journal, and other outlets.
Get an alert whenever I publish a story.
Got a tip? You can reach him using the secure messaging app
Signal
(hughlangley.01) or email (hlangley@businessinsider.com). We can keep sources anonymous.
Stephen is a senior tech reporter at Business Insider, covering OpenAI, Anthropic and the ecosystem around the leading artificial intelligence companies.
Previously he covered technology at SFGATE, and has written for The Wall Street Journal, The Information and CNBC. He studied journalism and economics at Northwestern University.
His work has earned an SF Press Club Investigative Reporting Award and, in 2025, SPJ NorCal’s Excellence in Journalism Award for Technology Reporting.
Stephen lives in San Francisco. Contact him via email at
scouncil@businessinsider.com
, or on Signal, Telegram, or WhatsApp at 415-757-8198. Use a personal email address, a nonwork WiFi network, and a nonwork device;
here's our guide to sharing information securely
.
The XY problem is asking about your attempted solution rather than your actual problem. This leads to enormous amounts of wasted time and energy, both on the part of people asking for help, and on the part of those providing help.
User wants to do X.
User doesn't know how to do X, but thinks they can fumble their way to a solution if they can just manage to do Y.
User doesn't know how to do Y either.
User asks for help with Y.
Others try to help user with Y, but are confused because Y seems like a strange problem to want to solve.
After much interaction and wasted time, it finally becomes clear that the user really wants help with X, and that Y wasn't even a suitable solution for X.
The problem occurs when people get stuck on what they believe is the solution and are unable step back and explain the issue in full.
What to do about it?
Always include information about a broader picture along with any attempted solution.
If someone asks for more information, do provide details.
If there are other solutions you've already ruled out, share why you've ruled them out. This gives more information about your requirements.
Remember that if your diagnostic theories were accurate, you wouldn't be asking for help right?
Examples
Example 1
n00b doesn't actually want the last 3 chracters in a filename, he wants the file extensions, so why ask for the last 3 characters?
<bob> How can I echo the last three characters in a filename?
<feline> If they're in a variable: echo ${foo: -3}
<feline> Why 3 characters? What do you REALLY want?
<feline> Do you want the extension?
<bob> Yes.
<feline> There's no guarantee that every filename will have a three-letter extension,
<feline> so blindly grabbing three characters does not solve the problem.
<feline> echo ${foo##*.}
Example 2
If Angela had just started by explaining she wants to prevent others from detecting her OS, this could have been a much shorter and more productive discussion.
Angela
: 'nmap -O -A 127.0.0.1' returns some lines starting with 'OS:'. How to change it?
Obama
: Look in the sourcecode for nmap, find how it figures out the Linux part, then rewrite your TCP/IP stack to not operate in a way nmap can detect.
Angela
: Yeah, but I don't know about linux system api at all.
Obama
: Well, nmap's fingerprint is based on the way the TCP/IP stack works, there's no real way except to rewrite the appropriate parts of said stack.
Angela
: I really need to avoid these messages. Can iptables do this work?
Obama
: Well, don't use OS detection or version scanning
Angela
: I want to prevent others from knowing the type of my OS
Vanilla
OS 3, an immutable desktop Linux distribution, has been released. Notable
changes in this release include support for Arm64, introduction of a Vanilla OS SDK,
a rewrite of the Apx package
manager using the new SDK, and much more. LWN covered Vanilla OS 2 in
2024.
...
Vanilla
OS 3
, an immutable desktop Linux distribution, has been released. Notable
changes in this release include support for Arm64, introduction of a
Vanilla OS SDK
,
a rewrite of the
Apx package
manager
using the new SDK, and much more. LWN
covered
Vanilla OS 2 in
2024.
The Man Behind the Anti-Flock Darth Vader Mask Wants to Know: 'When Will This End?'
403 Media
www.404media.co
2026-08-25 09:52:35
Anthony Ralphs has been speaking against Flock at San Diego City Council meetings for almost a year straight. When he showed up as Darth Vader, the world started watching....
Anthony Ralphs has been showing up to San Diego City Council meetings to speak against Flock's presence in his city for a year. At first, he took the podium during public comment in business casual — dress shirts, pants, suits, "respectable" clothing — to voice his concerns about the city's deal with the surveillance company.
"I did all the right things. I wore the suits. I said all the correct talking points. I made all the compelling arguments," Ralphs told me in a phone call. He cited Supreme Court precedent, like
Chatrie v. United States
, which challenged the constitutionality of geofence warrants where police could collect location history data from cell phones.
"It seemed like no matter how many cases I brought up, no matter how many violations of the Constitution this technology breaks, no matter how many constituents, no matter how many organizations, no matter how well I dress, no matter how fine my talking points, they weren't listening," he said. "That was when I realized, you know, you can't spell activism without 'act,' right? And I decided, well, maybe I'll try something different."
On August 19, Ralphs stood before city council members
in a Darth Vader cape and mask
, complete with mechanized breathing and voice changer. "The emperor is a fan of Flock," he began, and, speaking as the Dark Lord, laid out in three minutes why the Empire depends on Flock's warrantless network of automatic license plate readers and surveillance cameras. The video went extremely viral; after our coverage of Ralph's comments, every news outlet on the planet seemingly wrote about the mysterious San Diegan Vader. Coverage of his speech was published in
Singapore
and translated to Spanish and Arabic.
Ralphs is an event producer and has been hosting raves and music festivals in the area for the last 13 years. He founded an event space, Eden Art Garden, about an hour outside of the city. He recently started DeFlock San Diego and works with the
Transparent and Responsible Use of Surveillance Technology San Diego (TRUST SD) Coalition
as well as other anti-surveillance and privacy rights groups to educate people and organize more widely. "But now we need the musicians, we need the artists, we need the painters, the actors, we need the thespians to bring this together and get some wheels on the movement to help it gain traction," he said.
"I think it's a character that resonates. He's like an archetype for evil. He's an archetype for the Empire," Ralphs said. "Vader is always a servant of the Empire, right? So [Flock] is nothing but tools for the servants of the Empire. Framing it into that context, I think was what was needed to bring this conversation into like a theatrical global component is really framing it in that kind of good versus bad framework. It is such an Orwellian technology being utilized by such comic book villain forces of evil trying to do dastardly things."
0:00
/
1:25
One of Ralphs' first city council meetings was in December 2025, when hundreds of people spoke in person, attended via Zoom, or sent comments online opposing Flock. After six hours of deliberation and debate, and despite the vast majority of public comment coming from constituents who wanted Flock out of San Diego, the council
voted to continue the program
.
"After that meeting, where city council decided that none of their constituents' opinions mattered and that they were going to vote how they wanted to vote regardless... After that, the movement was so discouraged, and all of us were so deflated that it was really hard to summon the collective energy and to muster the kind of the vitality that we needed to keep pushing forward," Ralphs said. He came back to another city council meeting a week later, and was "shocked and really disappointed," he said, to see the chamber was completely empty of members of the public. In that moment, he said, he realized he had an opportunity to attend as many city council meetings as he could — once every two weeks, then once a week, then twice and week and eventually every council and subcommittee meeting by spring 2026. "Then by May and June, I was so familiar with the process of giving public comment, of looking at the agenda items ahead of time to know what was going to be discussed, knowing how to cede time and get time ceded to you, I started organizing people to join me to speak to city council."
After Vader's appearance went viral around the world, Ralphs wondered if he'd let the character remain anonymous or take ownership of it. "But I think that it's a good time now to follow up with what the intention was, and what the reason and method was behind it," he said. "I think it's important for people to know this wasn't just some antic from somebody who just decided to show up one day and make some noise. This was a thought out plan that was exacted only after cumulative frustration from hundreds of people being ignored and months and months and months of trying things quote unquote the right way and it not working."
On Monday afternoon, Ralphs returned to San Diego City Council. He carried the mask to the podium with it wheezing on its own, and sat it down on the table. "I think we know who the bad guy is now. But I think what the whole world wants to know is who wants to be the good guy," he said. "I have requests to be interviewed this entire week. And what I would like to ask is, of the five council members that voted for Flock: When will this end? When will you listen to the vast majority of your constituents?"
About the author
Sam Cole is writing from the far reaches of the internet, about sexuality, the adult industry, online culture, and AI. She's the author of How Sex Changed the Internet and the Internet Changed Sex.
Microsoft PowerToys adds Alt+Tab-style switching for an app's windows
Bleeping Computer
www.bleepingcomputer.com
2026-08-25 09:51:58
Microsoft updated its Windows PowerToys toolset with a new utility dubbed "Window Hopper" that lets users switch between an app's windows more quickly. [...]...
Microsoft updated its Windows PowerToys toolset with a new utility dubbed "Window Hopper" that lets users switch between an app's windows more quickly.
The Window Hopper added in this release works like the standard ALT + TAB Windows feature, but it only works for the currently focused app, helping users switch back and forth between its windows.
"Once the utility is enabled, press the configurable Alt + backtick shortcut to cycle through that app's windows without stepping through everything else on your desktop,"
Microsoft explains
.
"It is especially useful when you're juggling multiple browser windows, terminals, File Explorer windows, or editor instances."
Those who want to customize the default activation keyboard shortcut can also do so in PowerToys settings to switch to the next and previous app window.
The new feature is included in PowerToys version 0.101.2362.0, released today, along with a new compact mode for the Command Palette quick launcher that opens the tool as a search box at a configurable vertical position.
This version also adds support for PowerDisplay linked controls to adjust
brightness across all displays at the same time and Windows-key activation for Shortcut Guide, a PowerToys tool introduced
in June
that displays
keyboard shortcuts for Windows and the current active app.
Additional improvements include DemoMirror, a new ZoomIt feature that allows you to mirror a region of the screen, a window, or the entire screen onto a second monitor, and a new Mouse Highlighter ripple mode for composition-based effects on mouse clicks.
Windows Hopper settings (BleepingComputer)
In January, Microsoft released PowerToys 0.97, which
added CursorWrap
, a new mouse utility for multi-monitor setups that "teleports" the mouse pointer to the opposite edge of active monitors and makes it easier to drag cursors across large screen distances.
Microsoft PowerToys was released
during the Windows 95 era
and started as a collection of small freeware tools created by Windows developers as personal projects.
However, in 2019, Microsoft revived the project as an
open-source utility pack
designed to enhance Windows functionality and streamline tasks previously requiring third-party tools.
I dug through hundreds of Labor Day sales to find real deals on high-quality products that last
Guardian
www.theguardian.com
2026-08-25 09:41:41
Prepare for autumn with our favorite end-of-season deals on staples including leaf blowers, blankets and beddingCollege grads share the room essentials that weathered the dormSign up for the Filter US newsletter, your weekly guide to buying fewer, better thingsLabor Day offers one last hurrah for su...
Our Place makes pans that not only perform *chef’s kiss*, but are also free of harmful Pfas chemicals. Our testers from
Drexel Food Lab
crowned
the
Titanium Always Pan Pro
king for its “combination of lightweight handling, impressive nonstick performance and genuinely useful design”, and it is now 43% off in the smaller, 8.5in model.
Le Creuset hardly needs an introduction thanks to its
heirloom-level quality
that withstands decades of enthusiastic cooking. “Like all Le Creuset pans, it holds heat well and distributes it evenly, and moves from stove to oven to table effortlessly,”
said
Julia Skinner, a Filter contributor and kitchen expert. Simmer hearty soups, stews and more for 20% off.
If your kitchen is looking a little cluttered, score a solid 20% off this cooking expert-
approved
air fryer that bakes, broils and roasts. It’s even a favorite around the Guardian’s newsroom: “It allowed me to sear, pressure-cook and air-fry my food without having to buy loads of extra equipment, and it was much quicker than using the oven,”
writes
Sammy Gecsoyler, a Guardian news reporter.
As the air outside and in your home turns dry, so too can your airways. This cool misting option features many of the elements Chan
appreciates
in a humidifier: a top-fill design to reduce spills, a dimmable control panel for a more restful sleep environment and an extended run time for all-night comfort. It’s now 38% off – just in time for cold and flu season.
After
testing more than 10 bath towels
, seasoned product reviewer Jon Chan named these as best for gifting, on account of the wide color selection and option for monogramming. Right now they’re $15 off and you can add a monogram free of charge, making these an easy gift option if you’re getting a jump start on your
holiday shopping
.
Tired of waking up with an
achy back
? Level up your sleeping situation with this medium-firm, pressure-relieving
mattress
that’s on sale until 15 September. “I have a Purple mattress. I love the darn thing; it’s not like anything you’ve ever experienced with a mattress before, you basically float on top of it,”
according to
the sleep entrepreneur Rockwell Shah.
My home consists predominantly of Mrs Meyer’s cleaning products, from aromatic hand soaps to
versatile multi-surface cleaner
that at once cleans and imparts a fresh scent. Now that it’s 23% off, I’m eager to restock the hand soaps around my house with this 33oz refill container that’ll allow me to limit my single-use plastic consumption.
Mrs Meyer’s
Clean Day Liquid Hand Soap Refill
$7.68
Bissell Little Green Pet Pro Portable Carpet Cleaner
When reviewer John Brandon put the Bissell PowerClean stick vacuum
head to head
against a pricier Dyson counterpart, he noticed
Bissell
’s superior suction was more capable of handling dry messes, from rice to granola. Now $100 off, it’s an even smarter steal for keeping your floors
guest-ready
.
When we polled parents to find out about the best gifts for
school-aged kids
, Crayola Model Magic topped our list. “Blake enjoys creating shapes and figures using all different colors. He loves that he can let his creation air dry and put it in a display in his room,”
said
the parent of a four-and-a half-year-old. Now at 22% off, the white version of this modeling clay will allow them to use their imagination and fine motor skills to create artwork they can be proud of.
For Guardian beauty columnist Sali Hughes, Origins’ tinted oil-free moisturizer is a solid option if “you either can’t be bothered to apply foundation in the heat or prefer a fresher look at this time of year.” While it’s only available in one shade at Sephora,
Origins’ site offers a wider range
. Add it to cart for 25% off.
Between its double-wall insulation to keep drinks ice-cold or piping hot, convenient carry handle and ability to withstand daily jostling, there’s not much more you could want in a reusable water bottle. Grab the white colorway – now 20% off – for your commute, workout class or someone on your
holiday gifting list
.
Don’t let anyone tell you it’s too late in the season to take your drinking and dining al fresco. Stay armed with your favorite iced beverages and fresh snacks with one of our favorite coolers, now a cool 25% off and its second-to-lowest price ever. “This is a sturdy cool box, easily strong enough to double as a seat if needed, and it comes with a five-year guarantee,”
said
tester Linda Geddes.
For a fraction of the price and all the bells and whistles to keep you active and hitting your goals rain,
shine
or
snow
, you can’t beat
the Garmin Forerunner 165
, which hardly ever leaves the wrist of Gould, a runner and our editorial coordinator (who owns the
pricier version
that lets you download music). It also earned top marks
in testing
by the Guardian’s consumer tech editor, Samuel Gibbs, for its high-end design and tracking metrics, making its current 20%-off deal feel extra tempting.
Brace for fall with this Filter-vetted electric leaf blower, now $70 off. When we
tested
seven top cordless electric leaf blowers, the Ryobi was our overall favorite for its ergonomic design and long battery life. “It is also impressively quiet. In testing, the Whisper Series produced the lowest noise levels of any comparable full-sized blower, especially at mid-range settings,” said Josh Patterson, an outdoor writer.
When the Guardian’s consumer tech editor, Samuel Gibbs, put the Venu smartwatch to the test, he
noted
its bright and crisp display, lightweight and stylish construction, intuitive app controls and “world-class fitness features”. Grab the latest edition of the expert-approved smartwatch for 34% off, the cheapest we’ve ever seen it.
“The Studio Pro are without doubt the best-sounding Beats headphones to date,”
writes
Gibbs. Music to the ears of iOS and Android users alike, these headphones, which have solid spatial audio for watching films and clear quality for making calls, are now $100 off.
“You don’t need captions; you need better speakers. And for most people, the easiest, fastest, most affordable option is a simple soundbar,”
writes
tech journalist Ryan Waniata, who’s been testing different models for ten years and counting.
One of our recommendations is
Sonos’ Arc Ultra
, an audio speaker to enhance your TV’s sound, which he says “can also be expanded with other Sonos gear for a multi-room sound or surround sound,” and is now on sale for 18% off.
Sonos
Arc Ultra Soundbar
$899
Tonies Toniebox 1 Audio Player Starter Set with Playtime Puppy
Tonies
Toniebox 1 Audio Player Starter Set with Playtime Puppy
Shopping for kids can feel impossible (just ask my toddler who wants nothing but also everything at the same time). Somehow, this screen-free audio player for stories and songs happens to please even the
pickiest of children while
also serving as a
bedtime wind-down tool
any frazzled parent will appreciate. Make toddler birthday or holiday shopping that much easier with this 30%-off deal.
Tonies
Toniebox 1 Audio Player Starter Set with Playtime Puppy
$69.99
Other pieces you might enjoy from
the Filter
, the Guardian’s guide to buying fewer, better things:
While Robert Moses was building the Brooklyn-Queens Expressway, according to the "Power Broker," he rented the penthouse of a hotel overlooking the project. "He spent a lot of time looking down at it, watching the cranes and derricks and earth-moving machines…in the giant trench being cut through mile after mile of densely packed houses," biographer Robert Caro writes. "'And I'll tell you,' says one of the men who spent a lot of time at the old hotel with him, 'I never saw RM look happier than he did when he was looking down out of that window.'"
Now Moses looks down at us from another penthouse: heaven. And the man who is essentially responsible for designing America's car dependence is likely just as happy in the afterlife as he was when he beheld that massive construction project in the early 1950s, because his peculiar triple cantilever highway girding a section of Brooklyn Heights is here to stay—for at least 40 more years!
Apple’s new Mac mini, featuring M6 and M5 Pro, delivers a massive leap in AI performance, supercharging the leading desktop for always-on agentic computing
Mac mini delivers up to 4x faster AI performance, up to 2x faster graphics and storage, along with enhanced connectivity — all in its ultracompact footprint
Users can do it all with the ultracompact Mac mini featuring the all-new M6 or powerful M5 Pro — from advanced productivity to running AI models on device, and more.
CUPERTINO, CALIFORNIA
Apple today announced the new
Mac mini
with the all-new M6 and powerful M5 Pro, delivering a dramatic boost in performance and even more versatility in its supersmall desktop design. With M6, Mac mini now delivers up to 4x faster AI performance,
1
2x faster storage
2
and graphics,
1
and 40 percent faster CPU performance.
1
Everything on Mac mini with M6 feels incredibly fast, from everyday productivity tasks to agentic AI workflows. Mac mini with M5 Pro delivers even more pro-level performance to breeze through demanding projects, from video production to game development. And this new level of performance takes on business workflows with ease whether Mac mini is being used as a primary desktop or for always-on, deskside agentic computing. Both Mac mini models include Wi-Fi 7 and Bluetooth 6, as well as upgraded 2.5Gb Ethernet, with a 10Gb option available. Combined with the power of macOS 27 and the next generation of Apple Intelligence,
3
including Siri AI,
4
the new Mac mini is a tremendous upgrade for existing and new-to-Mac users. The new Mac mini is available for pre-order starting today, with availability beginning September 22.
“Mac mini has always been our most versatile Mac. Whether it’s being used as a home computer, powering a professional studio, or as an always-on agentic device, it’s the little Mac that can do it all,” said Johny Srouji, Apple’s chief hardware officer. “Today, we’re taking this versatility even further. With a more powerful CPU and graphics, Neural Accelerators in the GPU, and higher memory bandwidth, Mac mini with M6 delivers a whole new level of AI performance. And with up to an 18-core CPU and 20-core GPU, Mac mini with M5 Pro is an ultracompact powerhouse for complex pro workflows. We can’t wait to see all the incredible ways people will use it next.”
Mac mini is more versatile than ever, whether it’s powering a home setup, driving professional studio workflows, or serving as a capable desktop solution for agentic AI workloads in the enterprise.
Mac mini with the All-New M6
A Pint-Sized AI Powerhouse
Mac mini with M6 can power through everything from productivity tasks to creative projects, the latest AI workflows, and more. M6 features a 12-core CPU — two more cores than before — with the world’s fastest single-threaded performance, so everything feels extra snappy and responsive. A 12-core GPU, also with two more cores than before, now includes Neural Accelerators in each core for the first time on Mac mini, resulting in up to 4x faster AI performance and 2x faster graphics than Mac mini with M4.
1
In addition, the all-new Dual 16-core Neural Engine delivers up to 2x faster performance than the previous generation, and combined with the advanced GPU, Mac mini is a powerhouse for all things AI.
1
And with 16GB of standard unified memory configurable up to 32GB, as well as higher memory bandwidth up to 170GB/s, multitasking is faster than ever.
Mac mini with M6 delivers massive performance gains with the world’s fastest CPU core, a next-generation GPU featuring Neural Accelerators, and the Dual 16-core Neural Engine, making it a powerhouse for AI.
Mac mini with M6 delivers
:
2
Up to 13.5x faster LLM prompt processing in LM Studio when compared to Mac mini with M1, and up to 4.8x faster than M4.
Up to 2.3x faster spreadsheet calculations in Microsoft Excel when compared to Mac mini with M1, and up to 1.5x faster than M4.
Up to 2x faster gaming performance with ray tracing in Cyberpunk 2077: Ultimate Edition when compared to Mac mini with M4.
Mac mini can run on-device AI tasks like applying style effects to photos, running local models, or creating AI agents that automate daily tasks.
Mac mini with M6 can power through creative projects in apps like Adobe Photoshop.
Mac mini with M6 delivers even more performance for projects in Apple Creator Studio than before.
Mac mini with M5 Pro
Unprecedented Pro Performance
Mac mini with M5 Pro redefines what’s possible on such a small desktop, enabling pro users to take on demanding workflows like app development, video rendering, scientific simulations, and more. M5 Pro features up to an 18-core CPU with remarkable multithreaded performance and up to a 20-core GPU with an enhanced shader core and third-generation ray tracing for complex work in 3D design, VFX, and game development. With Neural Accelerators in each GPU core, M5 Pro also delivers significant gains in AI compute compared to the previous Mac mini, allowing users to tackle more advanced AI workflows like photo and video upscaling, and running large diffusion models faster than ever. Mac mini with M5 Pro supports up to 64GB of unified memory with 307GB/s of memory bandwidth, enabling users to run even larger local AI models, work with complex 3D scenes, edit ProRes RAW files, and load large custom datasets for research. And with industry-leading performance per watt, Mac mini with M5 Pro is quiet, efficient, and ideal as an always-on desktop for AI agents or creative workflows.
M5 Pro supercharges Mac mini with a next-generation up-to-20-core GPU with Neural Accelerators, faster unified memory, and Thunderbolt 5, delivering serious performance for creative and technical workflows.
Mac mini with M5 Pro delivers
:
Up to 8.5x faster LLM prompt processing performance
5
in LM Studio when compared to Mac mini with M2 Pro, and up to 4x faster than M4 Pro.
2
Up to 4.5x faster rendering performance
5
with ray tracing in Blender when compared to Mac mini with M2 Pro, and up to 1.4x faster than M4 Pro.
2
Up to 2.1x faster image processing
5
in Affinity when compared to Mac mini with M2 Pro, and up to 1.5x faster than M4 Pro.
2
With M5 Pro, Mac mini delivers faster AI photo-upscaling performance in Topaz Photo when compared to the previous generation.
Mac mini with M5 Pro enables 3D artists to load, preview, and render 3D models in Autodesk AutoCAD with remarkable speed compared to the previous generation.
Mac mini with M5 Pro is perfect for running advanced plug-ins like Auto-Align Post 2 in Pro Tools when working on multitrack audio projects.
Best-in-Class Connectivity
The new Mac mini with M6 and M5 Pro now supports Wi-Fi 7 and Bluetooth 6, as well as 2.5Gb Ethernet for faster wired connectivity, with 10Gb available. On its front are two USB-C ports that support USB 3 and a headphone jack with high-impedance headphone support for convenient access. On the back, there are three Thunderbolt 4 ports on Mac mini with M6, and three Thunderbolt 5 ports on Mac mini with M5 Pro, along with HDMI and Ethernet. Thunderbolt 5 also allows users to cluster multiple Mac mini systems together to run large AI models entirely on device. And newly added genlock support through USB-C enables precise synchronization between a display and camera, including iPhone 17 Pro.
With a wide array of connectivity, the new Mac mini with M6 and M5 Pro now supports Wi-Fi 7 and Bluetooth 6, as well as 2.5Gb Ethernet for faster wired connectivity, with 10Gb available to configure.
With a wide array of connectivity, the new Mac mini with M6 and M5 Pro now supports Wi-Fi 7 and Bluetooth 6, as well as 2.5Gb Ethernet for faster wired connectivity, with 10Gb available to configure.
macOS 27 Golden Gate: An Unrivaled Experience
The new Mac mini comes to life with the upcoming macOS 27, which includes
Siri AI
, a profoundly more capable and personal assistant; helpful
Apple Intelligence
features across everyday apps; and an expansive set of improvements that make the Mac even more responsive and reliable. Siri AI can draw on personal context to help users find what they need in the moment across their messages, emails, and photos; answer questions about virtually any topic; and get things done across apps. Siri AI is integrated into Spotlight and systemwide context menus, and users can ask Siri about what’s on their display with Visual Intelligence using a dedicated keyboard shortcut. Users can also write and edit with Siri almost anywhere they type.
Additionally, Apple Intelligence makes apps smarter and more useful with new ways to tailor and organize browsing in Safari, easily create an automation in Shortcuts by simply describing it, and tap into advanced photo editing in the Photos app. Features users already rely on get even better with improvements to performance and search. Refinements to Liquid Glass improve readability, and add uniform toolbars, edge-to-edge sidebars, and updated window shapes and menu bar icons, enabling users to further personalize its appearance.
Mac mini and the Environment
The new Mac mini was built with the environment in mind and drives progress toward Apple’s ambitious plan to be carbon neutral across its entire footprint by 2030. It is made with 50 percent recycled material overall,
6
including 100 percent recycled aluminum in the enclosure and 100 percent recycled rare earth elements in all magnets. All of the electricity used to manufacture Mac mini is sourced from renewable energy, like wind and solar, across the supply chain, and Apple has also invested in enough renewable energy around the world to match the electricity customers use to power Mac mini. Like all Apple products, its paper packaging is 100 percent fiber-based and can be easily recycled at home.
7
Customers can pre-order the new Mac mini with M6 and M5 Pro starting today, August 25, on
apple.com/store
and in the Apple Store app in 30 countries and regions, including the U.S. It will begin arriving to customers, and in Apple Store locations and Apple Authorized Resellers, starting September 22.
8
Mac mini with M6 starts at
$899
(U.S.) and
$799
(U.S.) for
education
. Additional technical specifications are available at
apple.com/mac-mini
.
Mac mini with M5 Pro starts at
$1,699
(U.S.) and
$1,599
(U.S.) for
education
. Additional technical specifications are available at
apple.com/mac-mini
.
Additional technical specifications, configure-to-order options, and information on Studio Display, Studio Display XDR, and Magic accessories are available at
apple.com/mac
.
macOS 27 is available for testing in public beta through the Apple Beta Software Program at
beta.apple.com
, with availability as a free software update this fall. For more information, visit
apple.com/macos
. Features are subject to change. Some features may not be available in all regions or in all languages.
With Apple Trade In, customers can trade in their current computer and get credit toward a new Mac. Customers can visit
apple.com/shop/trade-in
to see what their device is worth. With year-round education pricing — available to current and newly accepted college students and educators — customers can save on Mac mini, along with a wide range of products and services through the Apple Store online and in stores. See
Apple’s Education Store
for details. Customers in the U.S. who shop at Apple using Apple Card can pay monthly at 0 percent APR when they choose to check out with Apple Card Monthly Installments,
9
and they’ll get 3 percent Daily Cash back — all up front.
10
More information — including details on eligibility, exclusions, and Apple Card terms — is available at
apple.com/apple-card/monthly-installments
.
AppleCare delivers exceptional service and support, with flexible options for Apple users. Customers can choose AppleCare+ to cover their new Mac, or, in available markets, AppleCare One to protect multiple products in one simple plan. Both plans include coverage for accidents like drops and spills, battery replacement service, and priority support from Apple Experts. For more information, visit
apple.com/applecare
.
Every customer who buys directly from Apple gets access to Personal Setup. In these guided online sessions, a Specialist can walk them through setup or focus on features that will help them make the most of their new device. Customers can also learn more about getting started and going further with their new device with a Today at Apple session at their nearest Apple Store.
Results are compared to previous-generation Mac mini systems with Apple M4, 10-core CPU, 10-core GPU, 32GB of unified memory, and 2TB SSD.
Testing was conducted by Apple in July 2026. See
apple.com/mac-mini
for more information.
Apple Intelligence features are currently available for testing through the Apple Beta Software Program, and will be available with macOS 27 this fall for users with an Apple Intelligence-enabled device set to a supported language. Apple Intelligence is available with support for these languages: English, Danish, Dutch, French, German, Italian, Norwegian, Portuguese, Spanish, Swedish, Turkish, Vietnamese, Chinese (simplified), Chinese (traditional), Japanese, and Korean. Some features may not be available in all regions or languages. For feature and language availability and system requirements, see
apple.com/apple-intelligence
.
Siri AI is currently available for testing through the Apple Beta Software Program. Siri AI will be available with macOS 27 as a beta later this year for users with a supported device set to English, and Apple will quickly expand support for more languages.
Results are compared to previous-generation Mac mini systems with Apple M2 Pro, 12-core CPU, 19-core GPU, 32GB of unified memory, and 8TB SSD.
Product recycled or renewable content is the mass of certified recycled material relative to the overall mass of the device, not including packaging or in-box accessories. Recycled and renewable plastic content calculation includes mass balance allocation.
Breakdown of U.S. retail packaging by weight. Adhesives, inks, and coatings are excluded from calculations of plastic content and packaging weight.
Mac mini is subject to FCC rules as well as consumer protection, contractual, and other provisions of federal or state laws. It cannot be delivered until the FCC’s authorization process is complete. If FCC authorization is not completed, your Apple Store order will be canceled and payment will be refunded, where applicable.
Apple Card Monthly Installments (ACMI) is a 0 percent APR payment option that is only available if users select it at checkout in the U.S. for eligible products purchased at Apple and is subject to credit approval and credit limit. See
support.apple.com/en-us/102730
for more information about eligible products. Additional limits and restrictions apply. See the Apple Card Customer Agreement for more information about ACMI.
Apple Card is subject to credit approval, available only for qualifying applicants in the United States and issued by Goldman Sachs Bank USA, Salt Lake City Branch.
Stay up to date with the latest articles from Apple Newsroom.
Security updates for Tuesday
Linux Weekly News
lwn.net
2026-08-25 09:12:29
Security updates have been issued by AlmaLinux (cups-filters, gstreamer1-plugins-base, gstreamer1-plugins-good, kernel, mrtg, NetworkManager, nginx, nginx:1.24, nodejs24, perl-Date-Manip, python-pyasn1, python-urwid, python3.12, python3.14, and qemu-kvm), Debian (erlang, thunderbird, webkit2gtk, and...
Apple Introduces M6 and M5 Ultra Chips, in New Mac Mini and Mac Studio
Daring Fireball
www.apple.com
2026-08-25 09:10:18
Apple Newsroom:
Apple today debuted M6 in the new Mac mini and M5 Ultra in the
new Mac Studio, providing an extraordinary leap in performance
and AI capabilities. M6, Apple’s first state-of-the-art
2-nanometer chip, advances every compute block, delivering gains
across every dimension of perform...
Apple introduces M6 and M5 Ultra for a big leap in performance and AI compute
M6, Apple’s first 2 nm chip, features a larger, more powerful 12-core CPU, 12-core GPU, and Dual 16-core Neural Engine, while M5 Ultra is Apple’s first quad-die architecture and its most powerful chip ever
M6 delivers a revolutionary leap in everyday performance and power efficiency. M5 Ultra unleashes unprecedented desktop-class power and massive unified memory bandwidth to conquer the most demanding projects.
CUPERTINO, CALIFORNIA
Apple today debuted M6 in the new Mac mini and M5 Ultra in the new Mac Studio, providing an extraordinary leap in performance and AI capabilities. M6, Apple’s first state-of-the-art 2-nanometer chip, advances every compute block, delivering gains across every dimension of performance. The chip features a larger 12-core CPU complex with the world’s fastest CPU core, a larger 12-core GPU with Neural Accelerators, a Dual 16-core Neural Engine, and up to 170GB/s of unified memory bandwidth.
1
M5 Ultra, the ultimate powerhouse for pro and AI workloads, uses next-generation UltraFusion technology to form a quad-die architecture for the first time in an M-series system on a chip (SoC). The chip includes an up-to-36-core CPU and up-to-80-core GPU with a massive 1.2TB/s of unified memory bandwidth, 50 percent more than M3 Ultra. With their advanced technologies, these SoCs deliver extraordinary compute with industry-leading power efficiency, empowering users to do even more on a desktop.
“Today, we’re debuting the next giant leap in performance and AI compute for Apple silicon with the incredibly advanced M6 and the most powerful M-series chip yet, M5 Ultra,” said Sri Santhanam, Apple’s vice president of Silicon Engineering Group. “Built using the cutting-edge 2 nm process, M6 combines a new CPU complex, two additional CPU and GPU cores, a Dual 16-core Neural Engine, and more unified memory bandwidth to power through workloads with amazing energy efficiency. And for the ultimate desktop performance and the ability to run massive AI models, M5 Ultra features a massive GPU, now with Neural Accelerators, and more unified memory bandwidth, pushing the boundaries of what a desktop can do.”
M6: Optimized Design and Enhanced Performance
Designed to power the workflows of everyday users, students, developers, AI hobbyists, and enterprises, M6 offers the ideal balance of performance, power efficiency, and on-device AI to effortlessly fly through daily tasks, coding, and creative projects.
M6 is built using cutting-edge 2 nm process technology, packing greater transistor density into a smaller die for a major leap in performance and power efficiency. M6 also introduces a Dual 16-core Neural Engine, providing up to 2x the peak compute over previous generations to make on-device AI workflows run even faster. System frameworks can automatically utilize both engines simultaneously, enabling applications to see faster model execution.
Powered by the all-new 2 nm M6, Mac mini provides an incredibly fast and responsive experience for creative workflows in apps like Adobe Photoshop.
M6 has a brand-new 12-core CPU complex — two more cores than M5 — that consists of 2 super cores, 4 performance cores, and 6 efficiency cores. It delivers the world’s fastest single-threaded performance and up to 1.2x faster multithreaded performance as compared to M5, and up to 2.4x faster than M1.
2
The super cores blaze through single-threaded workloads, the performance cores use less power and join the super cores to run demanding multithreaded workloads, and the efficiency cores handle everyday background tasks — all with industry-leading performance per watt. As a result, demanding CPU tasks such as editing images, compiling code, indexing new files, and running agentic AI workloads are faster than ever.
Accelerated GPU and Faster Memory Bandwidth
M6 features a 12-core GPU — two more cores than M5 — with a Neural Accelerator in each core. This design delivers a nearly 30 percent increase in peak GPU compute for AI compared to M5, and more than 8x compared to M1, enabling significantly faster prompt processing when interacting with on-device LLMs.
2
M6 features a powerful, larger 12-core GPU that provides higher geometry rates and updated Dynamic Caching to deliver stunning visuals and fluid frame rates in demanding games like Mixtape.
In addition, M6 offers Apple’s latest advanced graphics capabilities, including updates to the shader core architecture, Dynamic Caching, and hardware-accelerated ray tracing. These technologies combine to deliver stunning visual realism, faster rendering, and higher frame rates for gaming. M6 also has 50 percent increased geometry rates for complex graphics.
M6 supports up to 32GB of unified memory to multitask across demanding apps and run LLMs on device for secure and private agentic tasks. It also provides up to 170GB/s of unified memory bandwidth — a 10 percent increase over M5 and a 2.5x increase over M1.
With a Dual 16-core Neural Engine, larger GPU with Neural Accelerators, and higher unified memory bandwidth, M6 enables developers to compile code, index files, and run multiple simulators in Xcode with incredible speed.
M5 Ultra: The Ultimate Powerhouse for Pro Workflows
M5 Ultra, Apple’s most powerful chip ever, is built for pros who need to speed through workloads that demand maximum CPU and GPU performance and unified memory bandwidth, such as complex 3D rendering, visual effects, scientific analysis, and running compute-intensive frontier AI models on device.
Mac Studio with M5 Ultra delivers extreme performance and memory bandwidth to edit complex timelines with multiple streams of high-resolution video and effects in Adobe Premiere Pro.
M5 Ultra uses UltraFusion to connect two dual-die M5 Max chips to form the quad-die architecture — a first for Apple silicon. UltraFusion increases the inter-die bandwidth to over 4.4TB/s and the connection density by over 6x. Together, these ultra-low-latency, high-bandwidth interconnects allow the four dies to behave as a single unified processor. M5 Ultra also features a large up-to-36-core CPU consisting of 12 super cores and 24 performance cores, delivering up to 1.25x higher single-threaded performance and up to 1.3x higher multithreaded performance than M3 Ultra.
3
Unprecedented AI and Graphics, Massive Memory Capacity
M5 Ultra features a next-generation GPU with up to 80 cores, incorporating a Neural Accelerator in each core to offer up to 4.5x the peak GPU compute for AI compared to M3 Ultra and over 6x more than M1 Ultra.
3
The GPU includes Apple’s latest shader core with second-generation Dynamic Caching, as well as hardware-accelerated mesh shading and third-generation ray tracing, delivering up to 40 percent faster graphics performance than M3 Ultra.
3
Utilizing the powerful up-to-80-core GPU with Neural Accelerators, Mac Studio with M5 Ultra enables creators to generate high-quality AI images locally on device using apps like Draw Things.
M5 Ultra incorporates a more capable Media Engine. Dedicated hardware-enabled H.264, HEVC, four ProRes encode and decode engines, and hardware-accelerated AV1 decode make it the ultimate solution for high-resolution video editing. M5 Ultra also includes a 32-core Neural Engine, driving complex AI tasks and Apple Intelligence features securely on device with industry-leading energy efficiency.
4
With up to 512GB of unified memory and 1.2TB/s of memory bandwidth, Mac Studio with M5 Ultra enables researchers to leverage local AI models in LM Studio Bionic to trigger complex simulations in MATLAB.
Additionally, M5 Ultra features a massive amount of high-bandwidth unified memory, up to 512GB, and delivers a staggering 1.2TB/s of unified memory bandwidth that is 50 percent higher than M3 Ultra. This lets users store huge datasets entirely in local memory, increase the tokens-per-second speed, and run huge LLMs with hundreds of billions of parameters entirely on device.
Unleashing Power for Developers
Apple’s developer frameworks and tools — including Core AI, Core ML, Metal, and Xcode — tap directly into the advanced hardware of both chips. Developers can leverage the Dual 16-core Neural Engine in M6, and the Neural Accelerators in the GPU with the massive 512GB unified memory pool and faster 1.2TB/s of unified memory bandwidth in M5 Ultra, to provide incredible AI compute capabilities.
With these frameworks and new chips, developers can run and fine-tune large AI models locally on their Mac. Apple’s developer tools and frameworks automatically optimize performance across the CPU, GPU, and Neural Engine, and give developers the ability to use Apple Foundation Models, App Intents to tap into Apple Intelligence features, or their own proprietary AI models to build and run powerful AI workloads entirely on device.
Testing was conducted by Apple in August 2026 using shipping competitive systems and select industry-standard benchmarks.
Testing was conducted by Apple in August 2026 using preproduction Mac mini with M6 with 12-core CPU, 12-core GPU, and 32GB of memory; 14-inch MacBook Pro with M5 with 10-core CPU, 10-core GPU, and 32GB of memory; and Mac mini with M1 with 8-core CPU, 8-core GPU, and 16GB of memory. Performance was measured using select industry‑standard benchmarks. Performance tests were conducted using specific computer systems and reflect the approximate performance of Mac mini. See
apple.com/mac-mini
for more information.
Testing was conducted by Apple in August 2026 using preproduction Mac Studio with M5 Ultra with 36-core CPU, 80-core GPU, and 256GB of memory; Mac Studio with M3 Ultra with 32-core CPU, 80-core GPU, and 256GB of memory; and Mac Studio with M1 Ultra with 20-core CPU, 64-core GPU, and 64GB of memory. Performance was measured using select industry‑standard benchmarks. Performance tests were conducted using specific computer systems and reflect the approximate performance of Mac Studio. See
apple.com/mac-studio
for more information.
Apple Intelligence features are currently available for testing through the Apple Beta Software Program, and will be available with macOS 27 this fall for users with an Apple Intelligence-enabled device set to a supported language. Apple Intelligence is available with support for these languages: English, Danish, Dutch, French, German, Italian, Norwegian, Portuguese, Spanish, Swedish, Turkish, Vietnamese, Chinese (simplified), Chinese (traditional), Japanese, and Korean. Some features may not be available in all regions or languages. For feature and language availability and system requirements, see
apple.com/apple-intelligence
.
Stay up to date with the latest articles from Apple Newsroom.
US data centers tripled annual water consumption to 17B gallons
US data centers consumed an estimated 17 billion gallons of water in 2023, with electricity generation accounting for more than 80% of the total.
US data centers used an estimated
17 billion gallons of water in 2023
, roughly three times their consumption in 2014, according to a
Congressional Research Service report published by the Library of Congress
. The estimate covers a data-center buildout that was accelerating as demand for generative AI took off.
The number is not a complete national measurement. The federal government does not systematically track water consumption across the data-center industry, and much of the available information is collected by state and local agencies. Some municipal agreements also restrict disclosure of the rates and volumes charged to individual operators.
That makes the 17-billion-gallon figure an estimate rather than a facility-by-facility accounting. It also covers more than the water piped directly into server campuses.
Electricity is the larger water burden
The CRS distinguishes between
direct water use
, such as cooling equipment at a data center, and indirect water use associated with generating the electricity that powers it. Direct consumption represents a relatively small share of overall US water use—about 2%—but the report says indirect consumption through power generation accounts for more than 80% of a data center’s total water footprint.
AI systems are pushing operators toward denser deployments of specialized hardware. New AI halls generally consume more electricity than older server infrastructure, increasing their cooling requirements and the water associated with power production. The CRS data ends in 2023, the year the AI infrastructure boom began in earnest, so the report says consumption may have risen further since then.
The numbers also complicate claims that a data center is “waterless” simply because its building avoids evaporative cooling. Replacing on-site water consumption with a more power-intensive cooling design can shift part of the burden to the generation of that electricity rather than eliminate it.
Cooling systems trade water for power
Data centers can use several cooling approaches, and the choice depends on the facility’s size, location, climate and thermal requirements. Liquid cooling can be more efficient than air cooling, particularly for high-density equipment, but the CRS notes that it may not be cost-effective for smaller campuses.
Evaporation-based systems typically use less energy than air-cooled chillers and other waterless systems. Their trade-off is substantial water consumption: evaporation removes heat efficiently, but the consumed water must be continually replaced. Air-cooled systems reduce that direct demand while generally requiring more power.
Operators may source water from municipal drinking-water systems, treated wastewater, surface water or groundwater. Municipal systems supplied
97%
of the water used by US data centers in the CRS estimate. That reliance puts data-center expansion in direct competition with other municipal and industrial demands, especially where new campuses are proposed in areas with constrained supplies.
The issue has reached litigation. A proposed
330 MW California data center
is seeking
287 million gallons of water
from fallowed farmland, a dispute we reported on in
the California farm-water lawsuit
. The CRS report does not resolve how individual projects should be allocated water; it instead identifies the lack of consistent data as a barrier to evaluating those decisions.
Federal data remains fragmented
Water provision is primarily a state-level responsibility, and reporting requirements differ by jurisdiction. Utilities may report customer usage to state or local agencies when required, but there is no federal assessment that consistently covers every US data center.
A federally supported effort led by researchers at Virginia Polytechnic Institute and State University has produced the United States Water Withdrawals Database. It compiles reported and estimated withdrawals across
42 states
, including public-supply, industrial and commercial usage. But its coverage depends on the reporting obligations in each state, so it does not provide a uniform national registry of data-center consumption.
The CRS also identifies water-service agreements as a source of opacity. Contracts between operators and municipalities can define usage charges and contain provisions limiting the public release of those details. Without facility-level figures, communities may have difficulty comparing a proposed campus’s water needs with its promised economic or infrastructure benefits.
Legislation is moving slowly
Members of Congress have introduced bills that would improve water-use reporting, encourage water reuse and address other environmental effects of data-center construction. Most remain at the introduction stage, the CRS says.
The campaign site Data Center Water Leaks counts water-related data-center legislation in
36 of 52 state legislatures
. It says California and Arkansas vetoed local bills, while
20 federal bills
—14 in the House and six in the Senate—were active; only three had progressed beyond the referral stage.
The reporting picture is more advanced in the European Union. Recent EU legislation requires data-center operators to report annual freshwater consumption along with other facility metrics. Industry group CISPE has warned that strict water rules could push operators to place infrastructure outside the EU, and the European Commission has faced lobbying over a proposed environmental rating system covering energy and water efficiency.
For US operators, the issue is less a single mandated efficiency threshold than the absence of a consistent baseline. A campus can draw water from a municipal system while shifting additional consumption to its electricity supplier, and public records may show neither the full direct volume nor the indirect cost. Until those figures are reported under common rules, the industry’s water footprint will remain a national estimate assembled from incomplete state-level data.
Apple Introduces New Mac Studio with M5 Max and M5 Ultra
Apple introduces new Mac Studio with M5 Max and M5 Ultra — the ultimate desktop for on‑device AI and the most extreme pro workflows
Apple’s most powerful Mac raises the bar for local AI with up to 4.3x faster performance, more advanced graphics, up to 512GB of unified memory, and extensive connectivity
Apple unveils the new Mac Studio, the most powerful Mac ever, featuring M5 Max and M5 Ultra.
CUPERTINO, CALIFORNIA
Apple today announced the new
Mac Studio
, featuring M5 Max and the all-new M5 Ultra, delivering a monumental leap in AI performance and even faster graphics for the most demanding pro workflows, all in its signature compact design that lives right on a user’s desk. Now featuring up to 4.3x faster AI performance,
1
up to 2x faster storage,
2
up to 1.8x faster graphics,
1
and up to 1.3x faster CPU speed,
1
along with higher memory bandwidth, Mac Studio empowers creatives, developers, AI researchers, data scientists, and more to push the boundaries of what they can do. Mac Studio with M5 Max features an 18-core CPU, an up-to-40-core GPU with Neural Accelerators built into each core, and up to 128GB of unified memory, accelerating complex pro and AI workloads. With the powerful M5 Ultra, Mac Studio scales up to a 36-core CPU, up to an 80-core GPU, and a staggering 512GB of unified memory, enabling users to run enormous LLMs entirely on device. Wi-Fi 7 and Bluetooth 6 come to Mac Studio for the first time, while Thunderbolt 5 rounds out its extensive connectivity, so users can take advantage of blazing-fast external storage, PCIe expansion chassis, and powerful hub solutions for the most intense workloads. Thunderbolt 5 also enables multiple Mac Studio systems to be clustered, bringing up to 3x faster performance for distributed AI inference when compared to a single system.
1
Together with Studio Display and Studio Display XDR, along with the power of macOS 27 and the next generation of Apple Intelligence,
3
including Siri AI,
4
it is the ultimate pro desktop. The new Mac Studio is available for pre-order starting today, with availability beginning September 22.
“Mac Studio is the ultimate desktop for on-device AI and the world’s most demanding pro workflows, relied on by users for its tremendous performance and extensive pro connectivity, all in a quiet, compact design that sits right on your desk — and today, we’re pushing the boundaries even further,” said Johny Srouji, Apple’s chief hardware officer. “With the powerful M5 Max and the incredible capabilities of M5 Ultra, Mac Studio ushers in a new era of desktop computing, delivering huge performance gains for pro workloads and AI inference with frontier-class models. By integrating Neural Accelerators directly into the GPU and offering massive amounts of high-bandwidth unified memory, the new Mac Studio is our most powerful Mac ever.”
Mac Studio, powered by M5 Max and the new M5 Ultra, delivers phenomenal boosts in AI and graphics performance — featuring a powerful CPU and GPU with Neural Accelerators, along with higher unified memory bandwidth.
A Monumental Step for AI
Mac Studio is at the forefront of high-performance AI computing. Now, with M5 Max and M5 Ultra — Apple’s most powerful silicon ever — it’s turbocharged, putting frontier-class AI models right on a user’s desk. Neural Accelerators in each GPU core deliver dramatically faster matrix multiplication. M5 Max features phenomenal on-device AI compute with up to 3.9x faster AI performance than the prior generation, speeding up prompt processing.
1
With M5 Ultra, Mac Studio achieves up to 4.3x the peak AI compute performance of M3 Ultra and a staggering 9.8x more than M1 Ultra.
1
Combined with up to 512GB of unified memory and 1.2TB/s of memory bandwidth, 50 percent higher than before, Mac Studio lets users run massive models entirely on device with complete privacy — without counting tokens or worrying about rising cloud costs.
AI inference scales to entirely new levels with multiple Mac Studio systems. Users and teams looking to share AI compute can cluster multiple Mac Studio systems together using the built-in support for Thunderbolt 5 and RDMA (remote direct memory access). This creates a vast shared memory pool across systems, allowing users to load the largest and most demanding frontier-class open-weight models available today. A cluster of four Mac Studio systems delivers up to a remarkable 3x faster AI inference than a single system.
1
Mac Studio is also a powerful platform for the rich ecosystem of tools AI researchers and developers rely on every day, utilizing the advanced frameworks in macOS. Core AI is a brand-new framework for building, running, and deploying AI models on Apple silicon. It provides an architecture optimized for Apple silicon, including unified memory, CPU, GPU, and Neural Engine, allowing developers to deploy full-scale LLMs locally and bring their own custom models into their apps. MLX, Apple’s open-source machine learning framework optimized for Apple silicon, enables developers to run, train, and fine-tune models with exceptional efficiency on Mac. In addition to these powerful frameworks, combined with Xcode and a robust ecosystem of AI tools and solutions, Mac Studio provides a complete, end-to-end platform for AI development — from experimentation and training to deployment.
With the new Mac Studio, developers can experience faster build performance in Xcode and utilize on-device coding agents.
With the new Mac Studio, users can experience up to 4.3x faster text-to-image performance in apps when compared to the previous generation.
Mac Studio with M5 Max
Serious Speed and Power for Pro Workloads
Built for users who demand powerful performance in a compact footprint, Mac Studio with M5 Max is ideal for musicians, photographers, software engineers, and designers pushing real-time 3D and motion graphics. Mac Studio with M5 Max delivers a huge boost in performance, featuring an 18-core CPU with 6 super cores and 12 performance cores, so developers can compile code even faster. The up-to-40-core GPU with Neural Accelerators is now up to 50 percent faster than the previous generation, boosting graphics-intensive tasks like game development with higher frame rates and more complex scene geometry.
1
With up to 614GB/s of unified memory bandwidth, M5 Max delivers superfast on-device AI compute, enabling users to run LLMs, generate images and video, as well as accelerate complex workflows.
The new Mac Studio also includes third-generation hardware-accelerated ray tracing, delivering faster, more realistic lighting, reflections, and shadows across professional 3D, VFX, and design workflows. Enhanced shader cores boost parallel processing, enabling smoother real-time viewport navigation and faster offline renders in creative workloads. In addition, its powerful Media Engine supports hardware-accelerated H.264, HEVC, ProRes, and AV1 decode, allowing filmmakers to color-grade uncompressed 8K footage and process multiple concurrent video streams with ease.
When compared to M4 Max, Mac Studio with M5 Max enables video editors to experience up to 3x faster Magic Mask performance in Blackmagic Design DaVinci Resolve Studio, and 1.4x faster scene rendering performance with Maxon Redshift.
Mac Studio with M5 Max enables
:
1
Up to 10.7x faster LLM prompt processing in LM Studio when compared to Mac Studio with M1 Max, and 3.9x faster than M4 Max.
Up to 7.4x faster text-to-image performance when compared to Mac Studio with M1 Max, and up to 3.5x faster than M4 Max.
Up to 5.3x faster Magic Mask performance in Blackmagic Design DaVinci Resolve Studio when compared to Mac Studio with M1 Max, and up to 3x faster than M4 Max.
Up to 3.5x faster basecalling for DNA sequencing in Oxford Nanopore MinKNOW when compared to Mac Studio with M1 Max, and up to 1.9x faster than M4 Max.
Mac Studio with M5 Ultra
A Powerhouse for the Most Demanding Workloads
Engineered for professionals who tackle the most extreme workloads, Mac Studio is the ultimate pro desktop, taking performance to an entirely new level. There is no other chip like M5 Ultra, which delivers the highest levels of performance and massive amounts of unified memory, enabling pros to push the limits of what they can accomplish on a single machine. Filmmakers can color-grade uncompressed 8K footage in real time, VFX artists can render complex simulations, and data scientists can train local AI models on expansive datasets. The new Mac Studio with M5 Ultra features an up-to-36-core CPU with 12 super cores and 24 performance cores, delivering up to 1.3x higher multithreaded performance than M3 Ultra.
1
Its up-to-80-core GPU, the most powerful Apple silicon GPU ever, brings Neural Accelerators to the Ultra chip for the first time, enabling up to 4.3x the peak AI compute performance when compared to M3 Ultra.
1
It also features up to 1.8x faster graphics than the prior generation, providing smoother real-time 3D rendering for VFX workflows.
1
Combined with up to 512GB of unified memory and 1.2TB/s of memory bandwidth, the new Mac Studio is a game changer for AI workloads. AI coding agents process significantly faster, image generation tools can render creations in an instant, and enterprise teams can cluster multiple systems to scale performance to new heights. In addition, with twice the video encode and decode blocks as M5 Max, the Media Engine in M5 Ultra is more capable than ever, empowering pros to simultaneously play up to 33 streams of 8K ProRes 422 at 30 fps on M5 Ultra.
1
Mac Studio with M5 Ultra empowers pros to simultaneously play up to 33 streams of 8K ProRes 422 at 30fps.
With up to 512GB of unified memory and 1.2TB/s of memory bandwidth, Mac Studio with M5 Ultra enables researchers to leverage local AI models in LM Studio Bionic to trigger complex simulations in MATLAB.
Mac Studio with M5 Ultra enables
:
1
Up to 15.4x faster CopyCat ML training performance in Foundry Nuke when compared to Mac Studio with M1 Ultra, and up to 3.3x faster than M3 Ultra.
Up to 9.8x faster LLM prompt processing in LM Studio when compared to Mac Studio with M1 Ultra, and up to 4x faster than M3 Ultra.
Up to 8.2x faster text-to-image performance when compared to Mac Studio with M1 Ultra, and up to 4.3x faster than M3 Ultra.
Up to 4.7x faster scene rendering performance in Maxon Redshift when compared to Mac Studio with M1 Ultra, and up to 1.7x faster than M3 Ultra.
Blazing-Fast Storage and Pro Connectivity
The new Mac Studio also features faster storage and a comprehensive array of pro connectivity. Storage performance is up to twice as fast, with a next-generation SSD architecture built on PCIe Gen 6, delivering industry-leading read and write speeds for rapid project loading, file transfers, and loading huge LLMs.
2
Thunderbolt 5 ports deliver transfer speeds up to 120Gb/s of bandwidth, so pros can connect high-performance peripherals, displays, PCIe expansion chassis, and external storage to utilize its remarkable speeds. The Apple-designed N1 chip brings Wi-Fi 7 and Bluetooth 6 to Mac Studio for the first time, delivering improved performance and reliability to wireless connections. Mac Studio now enables genlock over USB-C for precise synchronization between a display and professional camera capture like iPhone 17 Pro. It also supports up to eight displays, or up to four Studio Display XDR at full 5K resolution and 120Hz, providing an expansive screen for the most demanding projects.
Mac Studio delivers extensive pro connectivity, including up to six ports of Thunderbolt 5, support for up to eight displays, and now Wi-Fi 7 and Bluetooth 6.
macOS 27 Golden Gate: An Unrivaled Experience
The new Mac Studio comes to life with the upcoming macOS 27, which includes
Siri AI
, a profoundly more capable and personal assistant; helpful
Apple Intelligence
features across everyday apps; and an expansive set of improvements that make the Mac even more responsive and reliable. Siri AI can draw on personal context to help users find what they need in the moment across their messages, emails, and photos; answer questions about virtually any topic; and get things done across apps. Siri AI is integrated into Spotlight and systemwide context menus, and users can ask Siri about what’s on their display with Visual Intelligence using a dedicated keyboard shortcut. Pros can also write and edit with Siri almost anywhere they type.
Additionally, Apple Intelligence makes apps smarter and more useful with new ways to tailor and organize browsing in Safari, easily create an automation in Shortcuts by simply describing it, and tap into advanced photo editing in the Photos app. Features pros already rely on get even better with improvements to performance and search. Refinements to Liquid Glass improve readability and add uniform toolbars, edge-to-edge sidebars, and updated window shapes and menu bar icons, enabling users to further personalize its appearance.
Mac Studio and the Environment
The new Mac Studio was built with the environment in mind and drives progress toward Apple’s ambitious plan to be carbon neutral across its entire footprint by 2030. It is made with 35 percent recycled content overall,
5
including 100 percent recycled aluminum in the enclosure and 100 percent recycled rare earth elements in all magnets. The new Mac Studio is manufactured with 40 percent renewable energy, like wind and solar, across the supply chain, and meets Apple’s high standards for energy efficiency and safe chemistry. Like all Apple products, its paper packaging is 100 percent fiber-based and can be easily recycled at home.
6
Customers can pre-order the new Mac Studio with M5 Max and M5 Ultra starting today, August 25, on
apple.com/store
and in the Apple Store app in 30 countries and regions, including the U.S. It will begin arriving to customers, and in Apple Store locations and Apple Authorized Resellers, starting September 22. Mac Studio with 512GB of unified memory is coming in late October.
Mac Studio with M5 Max starts at
$2,499
(U.S.) and
$2,299
(U.S.) for
education
. Additional configure-to-order options are available at
apple.com/mac-studio
.
Mac Studio with M5 Ultra starts at
$5,499
(U.S.) and
$5,099
(U.S.) for
education
. Additional configure-to-order options are available at
apple.com/mac-studio
.
With Apple Upgrade, eligible customers in the U.S. can lease a new Mac with low monthly payments and easily upgrade at the end of their lease:
apple.com/shop/apple-upgrade
.
7
Lease Mac Studio with M5 Max with Apple Upgrade from
$48.99
(U.S.) per month (excluding taxes and any trade-in credit) for a 36-month lease. Lease Mac Studio with M5 Ultra with Apple Upgrade from
$110.10
(U.S.) per month (excluding taxes and any trade-in credit) for a 36-month lease. Additional configure-to-order options are available at
apple.com/mac-studio
.
^
Additional technical specifications, configure-to-order options, and information on Studio Display, Studio Display XDR, and Magic accessories are available at
apple.com/mac
.
macOS 27 is available for testing in public beta through the Apple Beta Software Program at
beta.apple.com
, with availability as a free software update this fall. For more information, visit
apple.com/macos
. Features are subject to change. Some features may not be available in all regions or in all languages.
With Apple Trade In, customers can trade in their current computer and get credit toward a new Mac. Customers can visit
apple.com/shop/trade-in
to see what their device is worth. Customers in the U.S. who shop at Apple using Apple Card can pay monthly at 0 percent APR when they choose to check out with Apple Card Monthly Installments,
8
and they’ll get 3 percent Daily Cash back — all up front.
9
More information — including details on eligibility, exclusions, and Apple Card terms — is available at
apple.com/apple-card/monthly-installments
.
AppleCare delivers exceptional service and support, with flexible options for Apple users. Customers can choose AppleCare+ to cover their new Mac, or, in available markets, AppleCare One to protect multiple products in one simple plan. Both plans include coverage for accidents like drops and spills, battery replacement service, and priority support from Apple Experts. For more information, visit
apple.com/applecare
.
Every customer who buys directly from Apple gets access to Personal Setup. In these guided online sessions, a Specialist can walk them through setup or focus on features that will help them make the most of their new device. Customers can also learn more about getting started and going further with their new device with a Today at Apple session at their nearest Apple Store.
Testing was conducted by Apple in July 2026. See
apple.com/mac-studio
for more information.
Results are compared to previous-generation Mac Studio systems with Apple M3 Ultra, 32-core CPU, 80-core GPU, 512GB of unified memory, and 8TB SSD.
Apple Intelligence features are currently available for testing through the Apple Beta Software Program, and will be available with macOS 27 this fall for users with an Apple Intelligence-enabled device set to a supported language. Apple Intelligence is available with support for these languages: English, Danish, Dutch, French, German, Italian, Norwegian, Portuguese, Spanish, Swedish, Turkish, Vietnamese, Chinese (simplified), Chinese (traditional), Japanese, and Korean. Some features may not be available in all regions or languages. For feature and language availability and system requirements, see
apple.com/apple-intelligence
.
Siri AI is currently available for testing through the Apple Beta Software Program. Siri AI will be available with macOS 27 as a beta later this year for users with a supported device set to English, and Apple will quickly expand support for more languages.
Product recycled or renewable content is the mass of certified recycled material relative to the overall mass of the device, not including packaging or in-box accessories.
Breakdown of U.S. retail packaging by weight. Adhesives, inks, and coatings are excluded from calculations of plastic content and packaging weight.
Apple Upgrade is a device leasing program available in the U.S. (excluding U.S. territories). Leases are provided by Klarna; subject to eligibility and credit approval, including final approval at checkout. To be eligible, you must be a U.S. resident, at least 18 years old (or the legal age in your state), have an accepted credit or debit card, and have an Apple ID. Additional eligibility criteria apply. Device must be in good condition upon return; damage fees may apply. For iPhone only: In order to lease an iPhone, you must select an eligible carrier (but you cannot use a prepaid carrier plan). Upgrades require entering into a new lease and are subject to eligibility and credit approval. Apple Upgrade is not available on refurbished devices or online at the following special stores: Apple Employee Purchase Plan; participating corporate Employee Purchase Programs; Apple at Work for small businesses or enterprises; Government, Education, or Veterans and Military Purchase Programs.
Apple Card Monthly Installments (ACMI) is a 0 percent APR payment option that is only available if users select it at checkout in the U.S. for eligible products purchased at Apple and is subject to credit approval and credit limit. See
support.apple.com/en-us/102730
for more information about eligible products. Additional limits and restrictions apply. See the Apple Card Customer Agreement for more information about ACMI.
Apple Card is subject to credit approval, available only for qualifying applicants in the United States, and issued by Goldman Sachs Bank USA, Salt Lake City Branch.
^ This offer is for a consumer lease, not a purchase or loan. Lease provided by Klarna Inc. for 24- or 36-month term. Your first monthly payment is due approximately 30 days after device is shipped or available for pickup. Lease approval is subject to eligibility and is based on creditworthiness. Monthly payments are based on the selected device and lease term.
For example: For Mac Studio with a purchase price of $2,499 (excluding taxes and any trade-in credit), the typical monthly payment is $48.99 (excluding taxes and any trade-in credit) for a 36-month lease term and $67.99 (excluding taxes and any trade-in credit) for a 24-month lease term.
No security deposit required. A trade-in device may reduce monthly payments. Advertised monthly payment amount may not include a trade-in device’s estimated value. Upgrades are not guaranteed and are subject to eligibility and approval.
Terminating your Apple Upgrade lease
: Closing your lease and returning your device terminates your lease. You may incur a substantial charge up to the amount of your remaining lease payments if you terminate your lease before the end of your initial lease term. You may have the option to upgrade to a new device by entering into a new lease agreement and returning your prior device. If you upgrade, your new monthly payments may be greater than your prior monthly payments. If you do not upgrade, terminate your lease, or purchase your device by the end of the initial lease term, the lease will convert to a month-to-month lease for up to six months. Your monthly payments may increase during the month-to-month period. If you take no action at the end of your extension period, you will be charged for the amount due to exercise the purchase option under your lease. You will not own your device at the end of your lease, unless you pay the amount due to exercise the purchase option. Insurance is not included in your lease, and you may incur damage fees if the device is lost, stolen, or not returned in the condition required by the lease.
Apple Upgrade lease eligibility
: Leases are only available to U.S. residents (excluding residents of U.S. territories). Leased devices are only available for shipping to U.S. addresses (excluding U.S. territories) or pick up at Apple Retail stores in the U.S. (excluding U.S. territories). To be eligible for a lease, you must be at least 18 years old (or the legal age in your state of residence), have a valid social security number or individual taxpayer identification number (ITIN), have an accepted credit or debit card, have an Apple Account in good standing, have a Klarna Account, and be able to receive security verification codes via text message. Leases are not available on refurbished accessories or online at the following special stores: Apple Employee Purchase Plan; participating corporate Employee Purchase Programs; Apple at Work for small businesses or enterprises; Government, Education, or Veterans and Military Purchase Programs.
Stay up to date with the latest articles from Apple Newsroom.
WhatsApp has started rolling out several new account security features, including support for multiple passkeys and stronger two-step verification. [...]...
WhatsApp has started rolling out several new account security features, including support for multiple passkeys and stronger two-step verification.
While the instant messaging service already allowed users to add passkeys for secure logins via fingerprint, Face ID, or screen lock code, it now lets them create separate ones for each platform.
"More than a billion people have already set one up, and you can now add more than one passkey to your account if you use both Android and iOS devices. To get started, go to Settings > Account > Passkeys," it said.
WhatsApp has also updated its two-step verification security feature to allow alphanumeric passwords instead of six-digit PINs.
"Until now it was a six-digit PIN, we've now upgraded it to a full password: longer, alphanumeric, and even with special ch@racters to make it harder to guess. If you've been using '123456,' this is your sign to upgrade," WhatsApp added.
The company has also added more information to call screens, giving users more context about contacts not in their address book before answering, as an additional layer of protection against scam attempts.
"On Android, you'll now see more information about a non-contact caller, like whether the number is from a different country and if you have any groups in common," it said. "Scammers rely on urgency – now you can take a beat with some more info before answering."
WhatsApp security improvements (WhatsApp)
Adding call screen context is part of a broader effort to protect WhatsApp users from scammers, as shown by multiple new security features introduced since the start of the year to help catch attacks and fraud attempts before users engage.
In January, WhatsApp
began rolling out "Strict Account Settings,"
a new Apple Lockdown-style feature designed to protect high-risk individuals like journalists and public figures from various sophisticated threats, including spyware attacks.
Two months later, in March, Meta
also announced
that WhatsApp will warn users when a device-linking request may be fraudulent, a common tactic used to hijack accounts by tricking users into sharing a linking code or scanning a malicious QR code.
Earlier this month, WhatsApp also
introduced an optional "Scam Alert" feature
as part of a limited beta rollout, which uses a local machine learning model to warn users when they're being targeted by scammers.
According to WhatsApp, more than 3 billion people in over 180 countries use its messaging service to communicate with family and friends.
Meet Prairieland Protester Autumn Hill: How Her “Act of Solidarity” Became a 50-Year Prison Sentence
Democracy Now!
www.democracynow.org
2026-08-25 08:46:32
“I’m absolutely being imprisoned for a political agenda,” activist Autumn Hill tells Democracy Now! in a phone call from Texas’s Johnson County Correctional Facility, where the 30-year-old trans woman is serving a 50-year prison sentence for protesting outside the Prairieland...
“I’m absolutely being imprisoned for a political agenda,” activist Autumn Hill tells
Democracy Now!
in a phone call from Texas’s Johnson County Correctional Facility, where the 30-year-old trans woman is serving a 50-year prison sentence for protesting outside the Prairieland
ICE
jail last July. Hill is one of nine protesters convicted of terrorism-related charges after federal prosecutors accused them of being members of an “antifa terror cell.”
In an interview with
Rolling Stone
writer Jack Crosbie, Hill says that she had no intention of committing violence at the protest, which ended when a police officer was shot and wounded by a fellow protester who says he fired in self-defense. No other injuries were reported, and Hill says she had already left when the shooting occurred. “It was my belief that we would go home at the end of the night to continue eating and drinking and be merry. We truly didn’t think that anything was going to go wrong. And we didn’t expect or want any violence to occur.”
For prosecutors pushing the overly broad and poorly substantiated idea that anti-fascist organizing against the Trump administration is violent and dangerous, the Prairieland case was a “gold mine,” says Crosbie. “There’s no real burden of proof. They can just say that you’re 'antifa,' and that becomes sort of gospel, according to the government.”
Please check back later for full transcript.
The original content of this program is licensed under a
Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License
. Please attribute legal copies of this work to democracynow.org. Some of the work(s) that this program incorporates, however, may be separately licensed. For further information or additional permissions, contact us.
Au milieu de la pause estivale, nous avons tous découvert cet incident majeur au cœur de l'État. Nous avions déjà parlé de la question de la sécurité de l'État lors du piratage de l'ANTS, mais là, il faut le dire, on atteint un nouveau palier, peut-être le niveau le plus haut jamais atteint.
Et toujours la même question : comment est-ce possible ?
Pour confronter des points de vue différents, j'ai discuté avec des membres de la communauté Cybernetica aux profils variés : un spécialiste de la transformation numérique de l'État, un spécialiste en cybersécurité, une personnalité politique et quelques vieux routards du monde numérique.
Une analyse nuancée qui essaye d'aller un peu plus loin que le bruit ambiant.
💡
Il y aura un temps pour critiquer et demander des sanctions exemplaires, mais il y a d'abord un temps pour comprendre et réfléchir.
Les faits, d'abord
La DGFiP a confirmé une intrusion ayant conduit à la fuite d'un fichier de 678 000 entrées, particuliers et professionnels. La directrice générale des finances publiques, Amélie Verdier, a confirmé le vendredi 14 août au soir le bilan et les principales catégories concernées : noms et prénoms, quotient familial, revenu fiscal de référence et taux de prélèvement à la source. L'échantillon analysé par FrenchBreaches à partir des données revendiquées par le pirate contient en outre l'adresse, le téléphone, l'adresse électronique et le nombre de personnes à charge.
Chronologie
L'accès de l'attaquant avait été coupé fin juin, mais l'exfiltration n'avait alors pas été détectée. La fuite n'a été identifiée qu'après la mise en vente des données, le 12 août. C'est déjà, en soi, une partie importante du problème.
Depuis, tout s'est accéléré
Le même pirate a revendiqué une seconde attaque, menée fin juillet contre le serveur professionnel des données cadastrales et confirmée par l'administration : plus de deux millions de personnes concernées, selon lui. Il a aussi donné sa version des faits, l'accès récupéré sur un VPN utilisé par les agents du fisc, et s'est permis de commenter : il faut, dit-il, que les gens se réveillent et voient à quel point « la France est un sketch ».
💡
Le parquet de Paris a ouvert une enquête samedi, confiée à l'Office anticybercriminalité. Les personnes concernées seront prévenues une par une à partir de la semaine prochaine, près de deux mois après l'intrusion.
Et la classe politique s'en mêle : l'eurodéputée Aurore Lalucq, coprésidente de Place publique, a demandé sur X la démission du ministre chargé des comptes publics, David Amiel, après avoir dénoncé que la personne « est entrée et repartie avec la caisse. Ça suffit ».
Je ne suis pas du genre à appeler à la démission des ministres tous les quatre matins.
Mais étant donné la gravité de la situation, le manque de réactivité et la nécessité d’être redevable, humble et respectueux vis à vis des Français, ce ministre devrait démissionner.
https://t.co/OqaJOiM1xf
Et pendant ce temps, une autre administration s'est aussi fait hacker dans l'obscurité la plus complète.
Dans la nuit du 25 au 26 juillet, quelqu'un est entré dans le système d'information dédié à la formation des personnels de l'Éducation nationale. Même chose qu'à la DGFiP : l'usurpation d'un compte professionnel.
Les données concernées sont celles de tous les agents ayant exercé en académie depuis 2001 : identité, statut, fonctions, et pour une partie d'entre eux adresse postale, téléphone et numéro de sécurité sociale. Le ministère n'a à notre connaissance pas publié de volumétrie. Le communiqué est sorti le 31 juillet, en pleine période estivale, et personne n'en a parlé. C'était le troisième piratage de l'Éducation nationale depuis janvier.
L'exemple bulgare
Beaucoup de gens sur Twitter ont posé la question : peut-on attaquer l'État pour négligence ?
La réponse vient de Bulgarie. Le 15 juillet 2019, l'agence nationale des recettes publiques bulgare est piratée. Les données fiscales et sociales de six millions de personnes se retrouvent en ligne.
Une contribuable attaque son administration. La Cour de justice de l'Union européenne tranche le 14 décembre 2023 et confirme trois choses.
La crainte d'un usage abusif de ses données suffit à constituer un dommage réparable, sans avoir été victime de quoi que ce soit.
La charge de la preuve est renversée : c'est à l'administration de prouver que ses mesures de sécurité étaient appropriées.
Et le fait que le dommage vienne de pirates n'exonère pas automatiquement l'administration.
L'arrêt de la Cour de justice de l'Union européenne interprète le RGPD, il s'applique aussi en France.
Remettre l'informatique au centre
Pour comprendre, il faut aussi remettre l'informatique au centre de la discussion. La cybersécurité s'est muée depuis quelques années en un bloubiboulga de réglementation, de gouvernance et de communication, reléguant au second plan la question du savoir-faire technologique. C'est triste.
Je ne me considère pas comme un spécialiste de la cybersécurité, mais j'ai été plongé tout jeune dans le computer underground des années 80-90, celui du Chaos Computer Club et de Kevin Mitnick, et j'ai parfois l'impression que rien n'a changé depuis.
Il y a d'un côté les gens qui font le travail de sécurisation, qui ont un sens pratique technologique, et de l'autre les gens qui parlent de ces sujets sans vraiment savoir comment les choses fonctionnent. Après, je comprends la frustration de nombreux spécialistes qui avaient prévu tout ce qui se passe aujourd'hui.
Mais on va le voir, il y a aussi un biais important du monde de la sécurité informatique, où l'informatique Unix des années 90-2000 et les modèles de sécurité qui lui sont inhérents dominent. C'est notamment le cas à l'ANSSI et dans de nombreux services. Avec l'arrivée du cloud et désormais de l'IA, la mise en place de stratégies de sécurité oblige à travailler avec de plus en plus d'acteurs non techniques, et parfois le monde politique, qui préfère la com au fond. Ça ne doit pas toujours être facile de jongler entre les directives, même si cela n'excuse pas le retard accumulé sur ces questions.
C'est dans ce contexte qu'il faut aujourd'hui regarder le piratage des impôts. L'objectif de cette newsletter n'est pas de faire un texte accusatoire (c'est difficile en n'ayant que des informations parcellaires), mais de proposer une première analyse de dysfonctionnements qui sont en partie, je dis bien en partie, compréhensibles.
Une chose doit être dite tout de suite, parce que tout le reste en découle. Le problème n'est pas qu'un attaquant puisse entrer dans un système, cela arrivera toujours. Le problème est qu'une compromission mette autant de temps à être détectée et donne accès à bien trop de choses. Surtout que Bercy avait déjà subi une autre cyberattaque quelques semaines avant.
Imaginez que quelqu'un force la porte de votre magasin, que vous ne vérifiiez pas si quelque chose a été volé, que vous ne mettiez pas d'alarme supplémentaire, et que vous vous refassiez cambrioler.
Trois questions viennent immédiatement à l'esprit :
Pourquoi ce type d'attaque semble-t-il se répéter ?
Comment un attaquant qui réussit à entrer dans un service de l'État peut-il repartir avec les données ?
Pourquoi l'exfiltration et les conséquences pour les usagers semblent-elles détectées et communiquées aussi tardivement ?
Ces trois questions en ouvrent deux autres, bien plus profondes :
Le problème est-il technique ou organisationnel ?
Et en quoi le virage du cloud hier, puis celui de l'IA aujourd'hui, accélèrent-ils l'inadéquation de la politique cyber de l'État ?
Normalement, la suite est réservée aux abonnés payants de Cybernetica. Exceptionnellement, en raison du sujet, j'ai décidé d'ouvrir cette newsletter au public, mais les propositions, toutes les sources et les bonus restent réservés aux abonnés payants.
En trois ans, les lecteurs de cybernetica.fr sont devenus les référents tech, géopolitique, cyber et IA de leurs organisations. Devenez membre de notre communauté. Abonnez-vous.
⸻
1. Pourquoi ce type d'attaque semble-t-il se répéter ?
Le point de départ, c'est évidemment ce « pattern » que l'on retrouve dans quasiment tous les incidents récents : un accès est compromis, l'attaquant entre dans un système sensible, accède à des données importantes et peut ensuite les exfiltrer pour ensuite annoncer leur revente sur le darknet.
Les très nombreuses attaques que la France a subies ne sont pas nécessairement identiques, mais elles démontrent un problème systémique : une compromission initiale produit des risques et des conséquences très importantes. Et elles nous obligent à nous poser une question très inquiétante. Si le pirate n'avait pas annoncé la vente des données, le gouvernement l'aurait-il su ? Cela veut-il dire qu'il y a peut-être eu des piratages d'ampleur dont nous ne savons rien ?
Un hack sans fin
Cette répétition n'est d'ailleurs plus une impression. Le même pirate a revendiqué une seconde attaque, fin juillet, contre le serveur professionnel des données cadastrales de la DGFiP, confirmée vendredi soir par l'administration.
Le pirate y revendique 252 149 lignes extraites, représentant selon lui plus de deux millions de personnes : identité, date et lieu de naissance, adresse, identifiant foncier, parcelles. Il affirme avoir contourné l'authentification multifacteur, le dispositif qui impose une seconde vérification en plus du mot de passe, et estime à 20 millions le nombre de citoyens présents dans ce système.
Deux attaques revendiquées sur la même administration, le même été.
Petit rappel. Sur la seule année 2026 : 774 000 étudiants au CNOUS en mars, deux millions selon les pirates ; 1,5 million de personnes au Secrétariat général de l'enseignement catholique ; 243 000 agents de l'Éducation nationale, avant les deux autres intrusions du ministère ; une fuite ÉduConnect touchant des élèves révélée mi-avril. Une sénatrice parlait sur X de France Passoire.
Quand on regarde de plus près, on se rend compte que ces incidents récents ne reposent d'ailleurs pas nécessairement sur le même scénario technique.
Cela précise encore plus la question. Ce n'est pas pourquoi quelqu'un peut pénétrer dans un système : un mot de passe, un accès VPN et un compte privilégié (ceux qui ont accès à tout) peuvent toujours être volés. La question qui se pose, c'est pourquoi, une fois dans le système, on peut repartir « avec la caisse », comme le disait l'eurodéputée Aurore Lalucq.
Pour répondre à cela, prenons une image de film.
sneakers (1992)
Dans les films d'action, on voit souvent le héros couper la grille autour d'une usine, se faufiler entre les gardes armés et piquer un badge pour entrer à l'intérieur. Là, sans se faire remarquer, il va dans la pièce où se trouvent les plans secrets et réussit à repartir. Une fois dedans, il n'y a pas d'autre sécurité, car normalement personne n'est censé être à l'intérieur. C'est un peu ce qui se passe avec les services de l'État : quand vous êtes dedans, c'est un peu le jackpot.
Pour comprendre pourquoi, il faut refaire un peu d'histoire.
Le modèle historique des barrières physiques
Une première explication vient du modèle historique de sécurité de l'État. Beaucoup de systèmes ont été conçus dans un environnement où l'accès informatique était précédé par une série de barrières physiques : bâtiment sécurisé, badge, machine contrôlée, réseau interne.
Sneakers (1992)
Cette logique conduit naturellement à accorder davantage de confiance à quelqu'un une fois qu'il est « dedans ».
C'est l'inverse exact du zero trust, le principe qui consiste à ne faire confiance à aucun accès par défaut et à tout revérifier en continu, à chaque action. Mais le zero trust suppose une architecture moderne. Rien n'interdit d'appliquer ces principes à un système ancien, mais cela suppose de le reprendre en profondeur. Sinon le système hérite des propriétés de sécurité de l'époque qui l'a vu naître : une fois entré, on a accès à tout.
Ce système a des avantages, mais il n'est efficace que lorsque les gens sont connus.
Le Covid et les accès distants
Le Covid a brutalement modifié ce modèle. Le télétravail et les VPN ont permis d'atteindre depuis l'extérieur des systèmes initialement conçus pour fonctionner dans un environnement beaucoup plus fermé. Évidemment, c'était indispensable pour ne pas paralyser l'État, mais comme de nombreux experts me le répètent depuis longtemps, on a étendu les accès sans nécessairement reconstruire partout le modèle de confiance sur lequel reposaient les systèmes. Et surtout, depuis le Covid, la mise à jour est aux abonnés absents.
Il y a aussi un aspect psychologique qu'on a tardé à entrevoir : en télétravail, le prisme organisationnel qui vous fait comprendre que ce que vous manipulez est sensible se délite. Et les nouveaux arrivants, ceux qui sont arrivés directement dans cet environnement hybride, n'ont pas forcément les mêmes réflexes de sécurisation.
Mais ce n'est pas tout.
Quand l'interministériel sème la zizanie
Beaucoup de systèmes informatiques d'administration sont avant tout pensés pour leurs utilisateurs en propre. On définit la politique de sécurité, on connaît les gens, les machines et son réseau. Mais parfois il faut donner accès à des utilisateurs ou à des systèmes extérieurs dont on ne contrôle pas entièrement les conditions de sécurité.
Comment entrer sans mot de passe Sneakers (1992)
Le piratage de Ficoba semble en être l'exemple type : l'accès compromis appartenait précisément à un fonctionnaire autorisé à consulter le fichier dans le cadre d'échanges interministériels. Il se dit que c'est le cas pour d'autres attaques, mais en l'absence de données sourcées (lire à la fin du document) cela reste une hypothèse.
Ces accès interministériels posent des challenges à la fois au niveau de la politique de sécurité, mais aussi pour son traitement.
Des patchs traités localement
La répétition apparente des hacks vient aussi du fait que les incidents sont souvent traités à l'échelle du ministère concerné.
Des corrections sont bien apportées après chaque attaque, rotations de mots de passe, durcissements, mais elles ne produisent pas automatiquement un réexamen transversal de tous les systèmes qui partagent les mêmes dépendances : accès distants, comptes privilégiés, relations entre administrations, gestion des droits ou détection des exfiltrations.
Des incidents différents ont donc probablement révélé des faiblesses communes dans la manière dont l'État contrôle globalement les identités, les accès et les conséquences d'une compromission.
Le cas particulier des impôts
Le système des impôts, lui, cumule les particularités. C'est l'un des plus vieux systèmes de l'État, éminemment legacy, très siloté, hyper processé, hyper contrôlé. C'est la machine à cash de l'État, et pendant longtemps il a été considéré comme le service exemplaire, l'impôt électronique étant globalement un succès et les gens qui y travaillent ou y ont travaillé étant bien considérés par leurs pairs.
Il est aussi volontairement à part : on a considéré qu'il y avait un risque à le mutualiser avec le reste, vu la sensibilité de la mission. Cette ségrégation a ses vertus de sécurité, mais elle place le système en dehors des socles mutualisés et de leurs règles.
Enfin, il est profondément saisonnier : il y a le rush de la déclaration avec son lot de contraintes, c'est un peu le Black Friday d'Amazon pour l'État, suivi d'une période de vacances.
L'intrusion de la fin du mois de juin a eu lieu en plein post-rush, ce qui a sûrement rendu encore plus difficile sa détection.
💡
J'en profite pour rappeler que, même si les événements sont choquants, il y a dans les services informatiques de l'État beaucoup de gens qui travaillent tous les jours sous des contraintes importantes, sans les salaires et les moyens du privé, et qui doivent aussi faire face à des politiques budgétaires et à des politiques référents pas toujours faciles. Et que ces personnes font un travail remarquable avec un vrai sens de l'État.
blackhat (2015)
La première barrière est l'authentification, mais elle ne peut pas être la dernière.
Si l'on part du principe qu'une identité peut toujours être compromise, le système doit continuer à contrôler ce que fait l'utilisateur une fois connecté. Or c'est là que le bât blesse.
Un ancien conseiller de ministre m'a dit il y a quelques années : on a parfois l'impression que l'État, c'est un OneDrive géant, une fois que tu es dedans, tu as un peu accès à tout.
Je me demande s'il n'avait pas un peu raison.
💡
Rappelons que si on demande l'export de ses données à Facebook, LinkedIn ou Google, il faut se réauthentifier et les liens de téléchargement sont envoyés par email. De plus, si on se connecte depuis un nouveau navigateur, on reçoit immédiatement un email pour prévenir de la connexion.
Dans les services numériques sur Unix (qui est la référence), on distingue toujours le droit de se connecter, le droit de consulter une donnée, le droit d'en consulter beaucoup d'un coup, voire le droit de les copier et celui de les exporter.
La gestion fine des droits existe depuis la préhistoire de l'Internet, les systèmes modernes y ajoutent la journalisation, la détection d'anomalies, la réauthentification et des contrôles supplémentaires sur les opérations sensibles.
L'ANSSI communique d'ailleurs sur la journalisation comme une brique indispensable de la sécurité : elle permet à la fois de détecter les incidents et de reconstruire après coup le cheminement d'une attaque et son impact, ce qui est super important.
Les comptes privilégiés
Les comptes privilégiés constituent un point particulièrement critique. Un administrateur, un compte technique ou fonctionnel peut disposer de droits beaucoup plus larges qu'un utilisateur normal ; sa compromission transforme immédiatement un problème d'identité en problème d'accès potentiellement massif aux données.
wargame (1983)
Dans WarGames (1983), on expliquait déjà ce qu'était une backdoor et le film explique le risque d'usage d'un compte privilégié.
L'exfiltration est une autre étape
L'exfiltration constitue ensuite une étape différente de l'accès. Même si un attaquant réussit à entrer et à consulter des données, un volume inhabituel, un téléchargement massif ou un export devraient pouvoir déclencher une alerte, une limitation ou une validation supplémentaire.
C'est précisément ce qui rend le cas actuel important :
la DGFiP affirme avoir détecté et interrompu l'accès fin juin, sans avoir détecté à ce moment-là que les données avaient été exfiltrées.
Depuis la revendication, la DGFiP précise que le site impots.gouv.fr et les espaces des usagers, particuliers comme professionnels, n'ont pas été compromis, et dit avoir coupé dès la détection les accès de l'ensemble des comptes utilisés dans les incidents identifiés, ainsi que d'autres applications sensibles à titre préventif.
💡
Le pluriel dit quelque chose : pas un compte et un incident, mais des comptes et des incidents.
Trois explications possibles
Il faut comprendre comment fonctionne la détection sur ce genre de système. Le déclencheur porte sur le volume de données, pas sur l'accès aux données. Celui qui sait qu'il existe un seuil au-delà duquel il sera repéré n'a qu'à rester en dessous et extraire par petites quantités.
À partir de là, il n'y a que trois explications possibles à une exfiltration non détectée.
Soit l'extraction n'est loguée nulle part, et c'est un défaut de conception intolérable sur un système de cette sensibilité.
Soit l'attaquant est entré, a obtenu suffisamment de privilèges et a effacé ses traces derrière lui.
Soit personne n'a pris la peine de vérifier comment il avait opéré.
Aucune de ces trois options n'est rassurante, mais attendons le Retex, le retour d'expérience, s'il est rendu public, ce que je ne pense pas que l'administration fera pour des raisons évidentes.
Mais revenons à la comparaison avec l'export de données de Facebook ou LinkedIn. Certains mécanismes sont devenus ordinaires : reconnaître un nouvel appareil ou un nouveau navigateur, signaler certaines connexions inhabituelles, renforcer l'authentification et encadrer les procédures d'export.
Si ces mesures n'étaient pas mises en œuvre, elles renforceraient ceux qui disent qu'il vaut parfois mieux, sur l'aspect cybersécurité, faire confiance aux Gafam qu'à l'État.
Et pourtant, les grandes plateformes ne sont pas forcément immunisées. Petit rappel.
Octobre 2015.
John Brennan, directeur de la CIA, voit son compte AOL personnel piraté par des adolescents. Ils appellent son opérateur téléphonique, se font passer pour un technicien, obtiennent ses informations et réinitialisent son mot de passe. Le questionnaire d'habilitation de sécurité qu'il avait rempli pour la CIA, une cinquantaine de pages contenant son parcours, ses adresses et les coordonnées de ses proches, se trouvait dans cette boîte. Il est publié.
Mars 2016.
John Podesta, directeur de campagne d'Hillary Clinton, se fait pirater son compte Gmail à la suite d'un faux message d'alerte Google. Il clique sur le lien et saisit son mot de passe sur une fausse page de connexion.
Octobre 2016.
Ses emails sont publiés par WikiLeaks pendant le dernier mois de campagne.
Janvier 2017.
Le renseignement américain attribue l'opération à la Russie, au groupe APT28.
Printemps 2017.
Le même groupe vise la campagne d'Emmanuel Macron. Cinq vagues d'hameçonnage visent ses collaborateurs, avec de fausses pages web et un faux serveur imitant les outils internes de l'équipe. Le 5 mai, deux jours avant le second tour, neuf gigaoctets de documents de la campagne sont publiés en ligne.
2017.
Google impose à ses 85 000 salariés une clé de sécurité physique, un second facteur résistant à l'hameçonnage, et lance un programme de protection avancée pour les journalistes, activistes, équipes de campagne, dirigeants et administrateurs. Dans ce programme, la clé est exigée à chaque connexion sur un nouvel appareil, et elle désactive le code par SMS comme l'application d'authentification.
Juillet 2018.
Google annonce qu'aucun des 85 000 salariés n'a été victime d'hameçonnage depuis, et qu'aucune prise de contrôle de compte n'a été constatée. Prix de la clé : vingt dollars.
Août 2018.
Google commercialise sa propre clé, la Titan, vendue 50 dollars la paire aux États-Unis, une clé USB-NFC et une clé Bluetooth.
Janvier 2019.
Le chercheur Troy Hunt découvre un fichier de 772 millions d'adresses email et 22 millions de mots de passe, revendu par un pirate pour moins de 50 euros. L'adresse Gmail d'Emmanuel Macron y figure, avec son mot de passe, dans un sous-fichier partagé le 25 juin 2017. C'est l'adresse personnelle qu'il utilise encore à l'Élysée. L'Élysée répond au Journal du dimanche que le mot de passe est changé régulièrement et qu'une double authentification par code sur téléphone a été activée, la méthode que Google avait retirée à ses salariés deux ans plus tôt.
Mais passons à la troisième question.
3. Pourquoi la fuite a-t-elle été découverte et communiquée aussi tard ?
amélie Verdier (DGfip)
Il faut distinguer trois moments : l'intrusion, l'exfiltration et la découverte de l'exfiltration.
Une administration peut identifier un accès anormal, couper cet accès et commencer une investigation sans savoir immédiatement que des données ont déjà quitté le système. Selon les communications publiques, la DGFiP a détecté l'accès et l'a coupé fin juin, mais affirme ne pas avoir identifié l'exfiltration. Elle n'a découvert la fuite qu'après la mise en vente publique des données, le 12 août.
Cela répond à une première question
: le retard de communication ne traduit pas nécessairement une décision de cacher une fuite connue. De toute façon, soyons clair, il est très difficile d'imaginer qu'un patron d'administration centrale ne communique pas une intrusion à la CNIL. Les acteurs de l'État suivent les règles de l'État.
Reste l'autre question sous-jacente
: l'administration n'avait pas vu que des données étaient déjà sorties. Si cette hypothèse est correcte, le sujet central devient la capacité d'observation du système. Il faut pouvoir reconstruire précisément ce qui s'est passé : quel compte a agi, quelles données ont été consultées, lesquelles ont été copiées, quand et dans quel volume.
La règle des 72 heures
La question des 72 heures doit être traitée avec la même précision. Le RGPD ne fait pas courir ce délai à partir de la date de l'intrusion, mais à partir du moment où le responsable du traitement prend connaissance d'une violation de données personnelles.
La chronologie exacte de la détection est donc indispensable pour savoir à partir de quand l'obligation de notification s'appliquait.
Ce délai de 72 heures en a d'ailleurs un jumeau, que personne ne mentionne. Depuis l'article 5 de la loi du 24 janvier 2023, une personne morale ou un professionnel victime d'une atteinte à un système de traitement automatisé de données doit déposer plainte dans les 72 heures suivant la connaissance de l'atteinte, faute de quoi son assurance ne l'indemnise pas.
Deux obligations, deux destinataires, et le même point de départ : le moment où l'on comprend ce qui s'est passé.
Ce dispositif ne concerne pas l'État. Il ne souscrit pas de garantie cyber, il est son propre assureur, et la sanction n'a donc aucune prise sur lui.
💡
Certains professionnels du secteur y voient d'ailleurs une explication au fait que la France soit le pays le plus attaqué d'Europe : en sécurisant le remboursement assurantiel, on aurait rendu le marché français plus rentable pour les attaquants. L'hypothèse circule, elle n'est pas démontrée.
Le bug du gouvernement
conférence de presse "Alerte sur un risque majeur pour la sécurité numérique de la France"
Alors que l'ensemble de l'État continue de se faire hacker, la principale loi de protection numérique, la transposition de la directive NIS2, n'est toujours pas votée. Cette directive européenne de 2022 impose à environ 15 000 entités françaises, entreprises et administrations, un socle commun de sécurité : gestion des risques, notification des incidents, sanctions à la clé. Elle devait être transposée avant octobre 2024.
Le calendrier français a de quoi laisser sans voix.
Présentation en Conseil des ministres en octobre 2024.
Adoption au Sénat en mars 2025.
Examen en commission à l'Assemblée jusqu'en septembre 2025.
Puis plus rien.
Le texte n'a jamais atteint l'hémicycle, il n'a même pas été inscrit à l'ordre du jour de la session extraordinaire de juillet dernier. L'examen est désormais annoncé pour septembre 2026.
Depuis, la ministre déléguée chargée de l'Intelligence artificielle et du Numérique, Anne Le Hénanff, est inaudible. Elle était pourtant rapporteure de cette loi Résilience à l'Assemblée avant d'entrer au gouvernement en octobre 2025. Personne n'est censé connaître mieux le texte, et il n'a toujours pas été inscrit.
La raison de ce blocage est désormais connue. Le 4 février 2026, en conférence de presse au Sénat, les deux présidents des commissions spéciales chargées d'examiner le texte, le député Philippe Latombe et le sénateur Olivier Cadic, ont désigné l'exécutif, et derrière lui la DGSI.
Ce qui coince tient en un article, le 16 bis, introduit par Olivier Cadic et déjà voté par le Sénat. Il interdit à l'État d'imposer des portes dérobées aux fournisseurs de chiffrement.
Selon le député Philippe Latombe, la DGSI ne veut pas que la réglementation soit transposée en l'état.
Pour le sénateur Cadic, la raison de cet amendement vient de ce qui s'est passé aux États-Unis, où des portes dérobées installées pour surveiller les appels et les messages ont été exploitées par des pirates chinois, compromettant des millions de communications.
Il s'agit de la fameuse affaire Salt Typhoon.
Meredith Whittaker, présidente de Signal, en a détaillé les conséquences sur la scène de DLD en janvier 2025.
Les attaquants ont obtenu des données de localisation à la minute près et des informations au niveau des comptes, sur des millions de personnes résidant aux États-Unis.
Ils ont piraté le téléphone de Trump ou celui de Vance.
Ils ont cartographié les entrées et les sorties de bâtiments, dont le complexe de la CIA à Washington, en les reliant à des comptes identifiés.
Ils avaient aussi l'historique des appels, qui appelle qui, à quelle heure, combien de temps et à quelle fréquence.
Le tout obtenu par les mêmes portes dérobées que les forces de l'ordre avaient imposées aux opérateurs pour que, selon la formule de Whittaker, les gentils puissent entrer. La porte dérobée que l'État veut se réserver finit par se retourner contre lui.
Sur NIS2, l'Europe n'attend plus.
Vingt-trois États membres avaient manqué l'échéance d'octobre 2024, dix-neuf ont depuis régularisé. Il ne reste que quatre mauvais élèves. Le 8 juillet 2026, la Commission a renvoyé la France devant la Cour de justice de l'Union européenne, avec l'Irlande, l'Espagne et les Pays-Bas, en demandant une somme forfaitaire et des astreintes journalières. La France fait en plus l'objet d'un second renvoi, depuis avril 2026, pour la directive REC sur la résilience des entités critiques.
💡
La France, pays le plus attaqué d'Europe, poursuivie pour n'avoir pas transposé le texte censé la protéger : c'est le sujet qu'on entend dans toutes les conférences cyber.
Pour revenir à la question des impôts, il est intéressant de voir que le syndicat Solidaires Finances Publiques dit avoir écrit à la directrice générale dès juin, après les fuites Tchap et France Services, pour signaler des risques de piratage, d'usurpation d'identité ou d'hameçonnage ciblé « à très court terme ». Le syndicat dénonce aujourd'hui une communication tardive.
Maintenant, il faut analyser les conséquences de tout cela.
Gérer les conséquences
Ces données ne sont pas censées sortir. Pour l'OSINT, la collecte de renseignement en sources ouvertes, d'un service étranger, un tel fichier est une mine d'or. États, et évidemment grand banditisme : repérer les gens qui ont de l'argent pour aller les cambrioler ou les racketter. Selon l'analyse des données revendiquées par le pirate, 26 805 des particuliers concernés déclareraient un revenu fiscal de référence supérieur à 100 000 euros, et 386 dépasseraient le million.
Le croisement avec les données cadastrales de la seconde attaque, identité, adresse, patrimoine immobilier, augmente encore la valeur de ces fichiers pour un ciblage.
Le précédent de la Fédération française de tir
Ce scénario n'est pas théorique, il a déjà eu lieu. En octobre 2025, la Fédération française de tir se fait voler les données de près d'un million de licenciés et d'anciens licenciés : état civil, adresse postale, téléphone, numéro de licence.
Les mois suivants, des individus se présentent au domicile de licenciés en se faisant passer pour des policiers ou des gendarmes, parfois en tenue, pour se faire remettre des armes. Des vols sont constatés à Nice, à Paris, à Limoges, à Décines.
Devant l'Assemblée nationale, le ministre de l'Intérieur a reconnu qu'entre vingt et trente faits pouvaient être directement liés à ce piratage. La fédération, elle, relie ces cambriolages à des données revendues sur le darknet.
Et cela conduit à la question qui devrait empêcher de dormir. Si la seule chose qui a permis de découvrir cette exfiltration, c'est que le pirate a décidé de la revendiquer publiquement, alors combien d'extractions ont été menées par des gens qui, eux, n'ont rien annoncé ? Quelqu'un peut-il récupérer suffisamment de données de multiples services pour créer une simulation réaliste de la France ?
Personne ne peut répondre. C'est précisément le problème.
Restent les deux autres questions en suspens.
4. Le problème est-il technique et organisationnel ?
Pour de nombreux interlocuteurs, tout part du programme de réforme de l'État Action publique 2022, lancé en octobre 2017, dont le volet numérique visait 100 % de démarches administratives dématérialisées en 2022.
L'objectif a été tenu pour l'essentiel. En cinq ans, la relation entre les Français et leur administration est passée en ligne. Mais l'empreinte numérique de l'État a probablement grandi beaucoup plus vite que les organisations chargées de la tenir.
💡
Le reste est mathématique : plus de services, plus de données, plus d'accès distants, mais pas plus de structures pour les gouverner.
Le pouvoir technique et les décisions
Le sujet n'a jamais été l'absence de personnes compétentes dans l'État.
Le problème est que les personnes qui comprennent réellement les systèmes ne sont pas nécessairement celles qui disposent du pouvoir d'imposer les architectures, les règles de sécurité ou l'arrêt d'un projet jugé dangereux.
Dans le contexte de l'attaque actuelle, des syndicats de Bercy ont eux-mêmes évoqué le manque de moyens, les difficultés à recruter des professionnels du numérique et la nécessité d'investissements supplémentaires.
Trois manques
Si on devait faire un premier diagnostic, il y a principalement trois manques :
un manque de moyens
un manque de sens pratique
un manque d'expertise à des postes de direction.
On a été trop vite et on a mis beaucoup d'improvisateurs au pouvoir. (un ancien responsable politique.
Mais comme le disait un ami, il y a aussi la fameuse loi de Conway :
les systèmes tendent à refléter la structure des organisations qui les produisent.
Dans l'État, les ministères restent responsables de leurs systèmes d'information, tandis que la DINUM, la direction interministérielle du numérique, assure des fonctions de coordination et de mutualisation interministérielles.
Deux exemples opposés le montrent.
Au ministère des Armées
, l'authentification est centrale, l'ensemble est gouverné, maîtrisé.
Au ministère de l'Intérieur
, ce sont des fédérations de fédérations, des grappes de raisin : une préfecture a son autonomie, la légitimité de penser les choses différemment dans son coin, et un dispositif centralisé y serait vécu comme antidémocratique.
La décentralisation n'est pas en elle-même un problème. Elle le devient lorsqu'elle empêche d'appliquer un niveau de sécurité commun aux systèmes qui doivent pourtant se connecter et se faire confiance.
On peut alors avoir des systèmes correctement protégés localement mais fragilisés par leurs dépendances. Une administration ne peut pas être pleinement résiliente si son niveau de sécurité dépend d'un autre système dont elle ne maîtrise ni les comptes, ni les accès, ni les règles.
Cela pose d'ailleurs une question cruciale.
Les impôts sont-ils encore un tiers dans lequel on peut avoir confiance ?
La perte de confiance dans le système des impôts pourrait avoir un effet secondaire important. Le compte impots.gouv.fr est lui-même un fournisseur d'identité de FranceConnect : il permet donc de s'authentifier auprès d'autres services publics.
La DGFiP affirme que les espaces des usagers, particuliers comme professionnels, n'ont pas été compromis. Mais le principe reste :
si un fournisseur d'identité est perçu comme attaquable, c'est la chaîne de confiance qui vacille, comme pour l'ANTS. Un peu comme si Facebook Connect était corrompu.
La transformation numérique a accentué cette tension. Plus de services, plus de données, plus d'accès distants et davantage d'interconnexions ont créé une surface d'attaque commune, alors que les responsabilités et les architectures restent largement distribuées. Cela restera le point noir de la décennie Macron. Beaucoup pour les startups, pas assez pour le numérique d'État.
Et surtout, un manque criant de vision.
⸻
5. Le cloud, premier virage mal négocié
Le cloud a été un premier changement profond de modèle. Il ne s'agissait pas simplement de déplacer des serveurs, mais de penser des systèmes distribués, des identités multiples, des accès distants et une sécurité qui ne repose plus principalement sur un périmètre physique ou réseau.
La doctrine cloud de l'État
L'État dispose d'une doctrine cloud depuis plusieurs années : une première stratégie apparaît en 2018, et « Cloud au centre » fait du cloud le mode d'hébergement par défaut des nouveaux projets à partir de 2021.
Mais en mars 2026, la DINUM présentait encore la migration des grands systèmes d'information historiques et sensibles vers le cloud de confiance comme une nouvelle étape de la transition.
Le problème n'est donc pas que l'État aurait ignoré l'existence du cloud. Il est que la transformation de ses systèmes historiques et de son organisation reste incomplète, alors même que les usages distribués se sont généralisés.
On l'a vu, le Covid a accéléré brutalement cette contradiction : les accès distants et le télétravail ont dû être déployés à grande échelle avant que tous les systèmes et toutes les organisations soient prêts à fonctionner dans ce nouveau modèle.
À l'heure de la souveraineté numérique comme totem, un audit de la plateformisation ratée de l'État sera indispensable.
⸻
6. L'IA, le virage suivant
L'IA constitue un deuxième changement de même ampleur que le cloud. Elle modifie directement les moyens disponibles pour rechercher et exploiter les faiblesses existantes : automatisation, analyse plus rapide des systèmes, exploration de plusieurs vecteurs et réduction du coût humain de certaines opérations offensives.
Ce changement n'est plus théorique.
Le NCSC, l'agence britannique de cybersécurité, prévoit une augmentation de l'exploitation des vulnérabilités assistée par IA et une réduction du délai entre découverte et exploitation.
L'AI Security Institute, l'institut public britannique chargé d'évaluer les modèles d'IA,
mesure une progression rapide des modèles sur les tâches de cybersécurité
, tandis qu'Anthropic documente déjà des opérations cyber réelles utilisant l'IA.
Un sujet renvoyé à plus tard en France
Le problème est que cette évolution est connue depuis plusieurs années mais reste souvent traitée comme un sujet futur ou secondaire. Le risque est de reproduire le même décalage qu'avec le cloud : comprendre le changement, mais adapter les systèmes seulement lorsqu'il devient impossible de faire autrement.
Une doctrine de retard
Ce décalage se retrouve noir sur blanc dans les documents officiels. Dans son état de la menace consacré à l'IA générative, publié le 4 février 2026, l'ANSSI indiquait n'avoir « pas connaissance de cyberattaques menées contre des acteurs français à l'aide de l'intelligence artificielle », ni identifié de système d'IA capable de réaliser seul l'intégralité des étapes d'une attaque, tout en jugeant plausible que ces technologies améliorent le niveau, la quantité et l'efficacité des attaques, particulièrement sur les environnements peu sécurisés.
Le Panorama de la cybermenace publié ce printemps évoque l'intérêt des attaquants pour l'IA « sans qu'il soit pour autant pertinent de parler de changement de paradigme ».
Ces textes paraissent pourtant moins de trois mois après le rapport d'Anthropic documentant la première campagne d'espionnage largement orchestrée par une IA, et au moment même où les agences britanniques décrivent, chiffres à l'appui, l'accélération des capacités offensives.
Dans le même temps, la communication publique de l'agence reste centrée sur la prévention : une stratégie 2026-2030 qui érige la sensibilisation du grand public en priorité, sur le modèle de la sécurité routière, et des alertes qui rappellent aux hauts fonctionnaires les règles basiques d'hygiène numérique.
Ces messages sont nécessaires. Mais mis côte à côte avec ce que documentent les agences britanniques et les laboratoires d'IA, ils dessinent un écart entre une menace dont les moyens changent d'échelle et un discours public qui n'a pas encore intégré ce changement.
Le postulat des moyens hors de portée
La doctrine implicite repose d'ailleurs sur un postulat : les incidents graves seraient réservés à des attaquants disposant de moyens hors de portée, étatiques ou quasi étatiques. Nous sommes beaucoup à penser que ce n'est plus le cas.
Le pirate qui revendique l'attaque des impôts dit aussi revendre des bases dérobées à SFR, Intermarché, la Fédération française de handball ou Accor. La presse décrit des profils jeunes, motivés par la notoriété et l'argent, pas des génies de l'informatique. Le suspect mis en examen après le piratage de l'ANTS a quinze ans.
Interrogé par FrenchBreaches, le pirate décrit une activité purement opportuniste: repérer une faille, accéder à ce qui est disponible, revendre, parce que tout se vend.
💡
L'avenir est encore plus dark, car deux choses dont personne ne parle, et que les lecteurs de Cybernetica connaissent déjà, font flipper tous les acteurs français de la cyber, enfin ceux qui ont compris.
L'asymétrie entre attaque et défense
Défendre coûte infiniment plus cher qu'attaquer.
Celui qui défend doit protéger tous ses systèmes, tous ses comptes et toutes ses connexions, en permanence. Celui qui attaque n'a besoin de trouver qu'une seule porte, une seule fois.
Toute la question est de savoir ce que l'IA change à ce rapport de forces.
Les laboratoires d'IA répondent qu'elle profitera aux deux camps. Elle aidera l'attaquant à trouver les failles plus vite, mais elle aidera tout autant le défenseur à les repérer et à les corriger.
L'un des spécialistes de la sécurité des systèmes de l'État avec qui j'ai discuté n'y croit pas une seconde.
Pour lui, on ne rattrapera jamais l'offensif avec l'IA appliquée au défensif. Accélérer les deux camps à la même vitesse ne remet pas les compteurs à zéro : le défenseur va plus vite sur un travail sans fin, l'attaquant va plus vite sur un travail qui s'arrête dès qu'il a trouvé sa porte. L'écart ne se comble pas, il se creuse. Je suis totalement d'accord avec lui.
Les agences de cybersécurité, elles, ne tranchent pas, car elles n'ont plus la big picture. Elles documentent l'accélération des capacités offensives, tout en rappelant que l'IA peut aussi renforcer la défense. Mais elle n'ont pas accès aux recherches frontières des labos.
Et surtout, elles se préparent à un changement de doctrine américain que peu de gens osent documenter publiquement.
Le pivot américain
US Cybercommand
Les États-Unis sont en train de lâcher l'Europe, et la France en particulier. Ce n'est plus une inquiétude d'analyste, c'est une séquence de décisions.
Le mécanisme est simple. Ils gardent la puissance offensive pour eux et la confient au secteur privé, et ils se retirent de tout ce qui protégeait collectivement les Européens. Les enceintes où l'on partage les méthodes, les alertes et le renseignement se vident. Les équipes qui contraient les manipulations de l'information ferment. Et quand un allié tente de prendre le relais, il est bloqué.
Petit rappel pour ceux qui n'ont pas lu nos précédentes newsletters :
Février 2025.
La CISA gèle ses activités de protection électorale et place en congé administratif les agents chargés de la désinformation et de l'influence étrangère. Les Européens perdent l'agence qui suivait les campagnes d'ingérence contre les scrutins.
Avril 2025.
Le département d'État ferme son bureau de lutte contre la désinformation étrangère, celui qui suivait les opérations d'influence russes et chinoises. Les Européens n'ont plus d'interlocuteur à Washington sur ce sujet, alors que la Russie intensifie ses opérations hybrides en Europe.
Juillet 2025.
La loi budgétaire, le One Big Beautiful Bill, alloue un milliard de dollars aux opérations cyber offensives du commandement Indo-Pacifique jusqu'en 2029, et deux cent cinquante millions aux travaux d'IA du commandement cyber. La même loi ampute d'environ 1,2 milliard les budgets civils de cyberdéfense. On finance l'attaque en coupant la défense.
Décembre 2025.
Jamie Tarabay révèle, dans une enquête exceptionnelle de Bloomberg, que l'administration prépare une stratégie destinée à confier à des entreprises privées la conduite d'attaques offensives contre des adversaires étrangers. L'offensif sort du périmètre étatique, et du contrôle parlementaire qui l'accompagnait.
7 janvier 2026.
Un mémorandum présidentiel ordonne le retrait du Global Forum on Cyber Expertise, de la Freedom Online Coalition et du centre européen d'Helsinki sur les menaces hybrides, où les États-Unis siégeaient depuis 2017 comme membres fondateurs. Ce sont les trois enceintes où circulaient les alertes et les méthodes.
Janvier 2026.
Environ deux cents postes américains sont supprimés dans les structures de l'OTAN, et la participation américaine réduite dans une trentaine d'organismes de l'Alliance, centres d'excellence compris. Avec ces gens partent les procédures partagées et le renseignement qui circulait avec eux.
Mars 2026.
La stratégie nationale de cybersécurité tient en quatre pages, contre près de quarante en 2023. Elle appelle à libérer le secteur privé pour identifier et perturber les réseaux adverses. L'objectif n'est plus de défendre un espace commun, mais de savoir frapper plus fort.
Juillet 2026.
Washington bloque au sein de l'Alliance le projet français de centre d'excellence de l'OTAN sur l'IA militaire à Rennes. Paris décide d'avancer sans approbation américaine. Ce bras de fer pourrait priver le centre rennais du statut, du réseau et de l'intégration formelle de l'Alliance.
12 août 2026.
Un programme autorise des entreprises privées agréées à mener, sous contrôle fédéral, des opérations de surveillance et des opérations à effets cyber pouvant aller jusqu'à la destruction de systèmes étrangers. Ce que Tarabay annonçait huit mois plus tôt. Des sociétés commerciales peuvent désormais perturber, dégrader ou détruire des systèmes à l'étranger.
En dix-huit mois, le paysage a changé. J'avais tenté d'en parler dans différentes conférences cyber, on m'expliquait que l'IA agentique, c'était pour 2027 (sic).
Le centre de gravité de l'IA ouverte a d'ailleurs quitté la Californie pour la Chine.
Selon le rapport de Hugging Face, les modèles chinois pèsent désormais 41 % des téléchargements sur douze mois, devant les modèles américains. Et le modèle Qwen d'Alibaba est le parent de 69 % des nouveaux modèles dérivés en février 2026, contre 1 % deux ans plus tôt.
Cela va avoir des implications vertigineuses. Pour protéger le patrimoine numérique français, il est plus probable que nous utilisions un modèle entraîné à Hangzhou qu'un modèle français. D'ailleurs, Mistral a mis fin au suspense et se prépare à devenir un workload d'inférence chinoise pour les acteurs européens. C'est un smart move, mais aussi le constat qu'on aurait dû parier plus tôt sur ces modèles.
En moins d'un an, les options sont désormais limitées pour la cybersécurité, et possiblement pour la cyberattaque :
des modèles fermés américains
, dont l'accès dépend de listes tenues par des entreprises privées dont les contraintes vont être de plus en plus fortes ;
ou
des modèles ouverts chinois
, performants et gratuits, développés dans un pays qui poursuit ses propres objectifs.
La France se retrouve dans une situation de pays moyen.
De bons ingénieurs, de bons centres, et aucune capacité propre à produire les outils qui font la différence. Là où la France a la dissuasion nucléaire qui la rend crédible, nous n'avons pas de dissuasion IA de frontière.
💡
C'est le grand échec de l'IA française, de n'avoir pas su créer plus de compétition à la chinoise. Mais c'est une autre question.
Début août, à Black Hat, deux ingénieurs d'OpenAI ont raconté que leurs agents autonomes s'étaient organisés seuls pour entrer dans Hugging Face, en montant entre eux un forum où ils s'échangeaient les vulnérabilités trouvées.
Un an plus tôt, à DEF CON, sept systèmes autonomes avaient découvert 18 failles réelles que personne ne connaissait, avec un correctif produit en 45 minutes en moyenne, et leur code a été publié : ces outils appartiennent maintenant à tout le monde.
Pendant ce temps, la stratégie française pour 2026-2030 fait de la sensibilisation du grand public sa priorité, sur le modèle de la sécurité routière.
Conclusion
Une identité finit toujours par être compromise. Ce qui distingue un système sûr d'un système fragile, c'est ce qui se passe après : jusqu'où l'attaquant peut aller, ce qu'il peut copier, ce qu'il peut faire sortir, et en combien de temps on s'en aperçoit. Sur ces trois points, la DGFiP a échoué, et elle n'est pas la seule.
Les protections existent, les compétences aussi. Ce qui manque, c'est le pouvoir de les imposer partout, à toutes les administrations, sans attendre que chaque faiblesse soit découverte après une attaque.
Nous avons raté le virage du cloud, nous sommes en train de rater celui de l'IA, et le texte qui devait nous protéger attend toujours d'être voté. Pendant ce temps, notre allié se retire et nos outils viennent d'ailleurs.
Le piratage des impôts n'est donc pas un incident isolé. C'est la mesure de ce que l'État est encore capable de tenir.
Merci de m'avoir lu. Pour les abonnés, quelques bonus supplémentaires.
Si vous nous découvrez pensez à vous abonner maintenant car les prix vont augmenter.
OpenAI restores 5-hour Codex and Work limits for ChatGPT Plus users
Following several weeks during which ChatGPT users were subject only to a weekly usage cap, OpenAI announced today that it is restoring a five-hour limit on Codex and ChatGPT Work for Plus subscribers. Here are the details.
Five-hour cap returns to ChatGPT Plus subscribers
Thibault “Tibo” Sottiaux, OpenAI’s engineering lead for Codex and ChatGPT,
announced tonight
that a five-hour usage limit is returning to Codex and ChatGPT Work for Plus subscribers starting tomorrow (25).
After users reach either the five-hour or weekly limit, they can either wait for their usage to reset for the next cycle or purchase additional credits. OpenAI also occasionally resets users’ limits for free, while banked resets can be earned through certain promotions and referral offers.
Over the past few weeks, however, OpenAI temporarily lifted the five-hour usage limit for Codex and ChatGPT Work, leaving only the weekly cap in place.
During this period, the company also reset users’ weekly usage early on several occasions to celebrate milestones, including adding another million active users across the two (
now unified
) platforms.
Tomorrow we will bring back the 5h limit for Plus accounts across ChatGPT Work and Codex. I had mentioned this a while ago, but then postponed it.
This is necessary as (a) the 5h limit allows us to smoothen the load on our compute, allowing to keep the plan generous in terms of weekly usage and (b) users on the Plus plan are relatively casual and new users, but then also just accidentally eat through their whole weeks usage and then are confused, making it not a great experience.
We are for the upcoming months keeping the 5h limit not enabled for Pro $100 and Pro $200 subscriptions.
FTC: We use income earning auto affiliate links.
More.
Illinois Is a Sanctuary State, But Cops & Prosecutors Still Secretly Work with ICE: Injustice Watch
Democracy Now!
www.democracynow.org
2026-08-25 08:30:04
We speak to journalist Aura Bogado, whose new investigation into Illinois law enforcement and prosecutorial collaboration with ICE has revealed that dozens of immigrants have been arrested and deported with the help of local officials in violation of the state’s sanctuary law. “Those are...
Our daily work usually revolves around Linux and security topics, deep down in the software stack.
Still, more often than you might think, we end up debugging applications which live much higher up.
Sometimes such a problem has its roots in the Linux kernel, sometimes elsewhere.
In this blog post we show how we found and fixed a bug inside the Go runtime.
Recently a customer reported that an application written in Go crashes from time to time on one of their embedded Linux systems.
Introduction
The crash was always the same fatal error with the following signature:
runtime: netpoll: eventfd ready for 5
fatal error: runtime: netpoll: eventfd ready for something unexpected
...stack trace...
At first we assumed that the application itself was buggy and needed fixing.
But after inspecting the error more closely, it looked much more like an internal assumption in Go’s netpoll mechanism no longer holds.
In this code path, the netpoll code expects
EPOLLIN
to be the only firing event, but it got something else.
In our case it got
5
, which is
EPOLLIN|EPOLLOUT
.
Why would epoll suddenly report more than
EPOLLIN
if the code asked only for
EPOLLIN
?
Before digging deeper, we threw the error message into a search engine, hoping that somebody else had faced the same issue before.
This led us straight to a report in the Go project’s issue tracker:
runtime: netpoll: eventfd ready for something unexpected
.
The issue describes exactly the fatal error we saw.
Also on a 32-bit ARM embedded Linux system!
The reporters also noted that the crash happens in applications which run for a long time.
That matched our customer’s description, too.
Bingo!
The issue had been open and unresolved since March 2025.
The Go maintainers had also rejected one
attempt
to fix the problem.
From the comments on the issue we learned that the fatal error only ever showed up on 32-bit ARM and i386 Linux systems, with all kinds of kernel versions.
Some kernels were rather old, others recent.
Not a single reporter saw it on an x86_64 or arm64 system.
Accepting the Challenge
The problem had multiple reporters but no fix, so we decided to dig into the issue ourselves.
At the very least we could give the Go folks better input.
Initially we suspected that epoll behaves differently on 32-bit ARM or i386.
We ditched this idea quickly since epoll is generic core code in the kernel.
Why would it return a spurious event set only on 32-bit ARM or i386?
Still, the fact that the error showed up only on 32-bit systems gnawed at us.
As a next step we reviewed the epoll usage in Go’s netpoll code.
With the help of an LLM we went through
src/runtime/netpoll_epoll.go
, focusing on 32-bit pitfalls such as integer conversions.
The review revealed that Go’s netpoll code uses the
data
field of
struct epoll_event
.
Linux epoll can store an 8 byte cookie in the kernel and returns it as part of the firing event to user space.
Applications use this cookie to attach metadata to an event, for example to tell different event sources apart.
structepoll_event{__poll_tevents;/* ev.Events in Go netpoll */__u64data;/* ev.Data in Go netpoll */};
Deep inside the Go runtime, the main event handler needs to know whether an event belongs to an event fd or a socket fd.
It decides by comparing
ev.Data
to the address of its internal event fd object:
Reading further through the code showed that
ev.Data
holds either a raw pointer to
netpollEventFd
or a tagged pointer to a per-socket object,
pollDesc
.
The pointer tag is a counter,
fdseq
, which distinguishes recycled
pollDesc
objects.
So far so good.
Mixing raw and tagged pointers in the same field looked fishy to us.
But how this relates to the crash was not clear yet.
Inspecting how Go lays out tagged pointers in memory finally revealed the core of the issue.
The Aha Moment
On 32-bit platforms, Go’s tagged pointer logic packs the full 32-bit address and up to 32 tag bits into an 8 byte word.
The tag goes into the lower 4 bytes and the address into the upper 4 bytes.
Storing a tagged pointer with address
0x00123456
and tag
0x12
fills
ev.Data
like this:
ev.Data[0:4] ev.Data[4:8]
+------------------+-------------------+
| fdseq | *pollDesc |
| e.g. 0x00000012 | e.g. 0x00123456 |
+------------------+-------------------+
Storing the raw pointer, on the other hand, leaves the following contents in
ev.Data
:
The lower 4 bytes hold the address of the object.
The upper 4 bytes stay untouched since an address is only 4 bytes long on a 32-bit system.
This finally shows the root of the problem.
The comparison of
ev.Data
with
&netpollEventFd
evaluates only the lower 4 bytes of
ev.Data
.
The code casts
ev.Data
to
uintptr
, which is 4 bytes on 32-bit platforms.
So the address of the
netpollEventFd
object aliases with
fdseq
.
As soon as
fdseq
grows large enough to match
&netpollEventFd
, the netpoll logic mistakes a socket fd for an event fd.
Internal assumptions fall apart, among them the assumption that the ready event is just
EPOLLIN
.
Note that this aliasing can only happen on 32-bit little endian systems.
On a 64-bit system, the comparison always covers the whole 8 bytes.
On a 32-bit big endian system, the comparison would read the upper 4 bytes, which contain the address.
fdseq
needs to grow into the millions before it matches
&netpollEventFd
.
That’s why the problem shows up only in long-running programs which create lots of
pollDesc
objects over time.
On a typical 32-bit ARM Linux system,
netpollEventFd
resides in a read-only section within the first 3 MiB of the address space, as the memory map of our test program shows:
So
fdseq
needs to reach a value of about 3 million before the crash can happen.
A Test Case
We also created a
standalone test case
for the problem.
On our test systems, it triggered the crash within a few minutes:
$ /tmp/repro.arm.system
netpoll eventfd-alias reproducer (GOOS=linux GOARCH=arm)
runtime.netpollEventFd is at address 0x223008
crash expected around cycle 2240520
cycle 2236988runtime: netpoll: eventfd ready for 4
fatal error: runtime: netpoll: eventfd ready for something unexpected
runtime stack:
...
Fixing the Issue
We
proposed a fix
which changes how netpoll tells event fds and socket fds apart.
Instead of storing the raw pointer
&netpollEventFd
, the fix stores a
nil
pollDesc
as a tagged pointer.
When unpacking the tagged pointer yields
nil
, the event belongs to the event fd, otherwise to a socket fd.
This way
ev.Data
always contains a tagged pointer and the aliasing is gone.
Summary
A Go application crashed sporadically on a 32-bit ARM embedded Linux system with a fatal netpoll error.
The error looked like an epoll problem, but epoll worked just fine.
The Go runtime stores both a raw pointer to
netpollEventFd
and tagged
pollDesc
pointers in the 8 byte
ev.Data
field.
On 32-bit little endian systems, the raw pointer aliases with the
fdseq
tag.
Once a long-running program has recycled millions of
pollDesc
objects, netpoll mistakes a socket fd for the event fd and crashes.
Our fix stores a tagged
nil
pollDesc
for the event fd instead, which removes the aliasing.
The bug slipped into the Go runtime with Go 1.14 in 2020.
It went unnoticed until the first report in March 2025 and finally got fixed in 2026.
We can only speculate, but this suggests that Google itself no longer runs any 32-bit Go programs.
Otherwise they would have hit the bug themselves long before we did.
We’d like to thank Frequentis AG for providing the budget to analyze and fix the problem.
U.S. Threatens New Economic War on Iran by Targeting China & Tehran's Other Top Trading Partners
Democracy Now!
www.democracynow.org
2026-08-25 08:13:15
The Trump administration has announced unspecified plans to further tighten sanctions on Iran, threatening other countries, including China, in the process. We speak to sanctions expert Nicholas Mulder about what he calls the “rhetorical” and “psychological warfare” of the an...
The Trump administration has announced unspecified plans to further tighten sanctions on Iran, threatening other countries, including China, in the process. We speak to sanctions expert Nicholas Mulder about what he calls the “rhetorical” and “psychological warfare” of the announcement. For Iran, says Mulder, the announcement was not “really materially all that meaningful. And to the extent that they are, they hurt ordinary Iranians and not the government.” The impact on the U.S. relationship with China, however, could be much greater. If the U.S. does place secondary sanctions on Iran’s trading partners, the “U.S.-China trade truce might be unraveling,” warns Mulder. “The space for maneuver that the U.S. has in using these tools of very coercive economic statecraft has narrowed.”
The original content of this program is licensed under a
Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License
. Please attribute legal copies of this work to democracynow.org. Some of the work(s) that this program incorporates, however, may be separately licensed. For further information or additional permissions, contact us.
Hackers breached over 270 Zimbra servers in ongoing attacks
Bleeping Computer
www.bleepingcomputer.com
2026-08-25 08:04:02
Threat actors have already compromised over 270 Zimbra instances in remote code execution attacks targeting a high-severity Zimbra Collaboration Suite (ZCS) vulnerability. [...]...
Threat actors have already compromised over 270 Zimbra instances in remote code execution attacks targeting a high-severity Zimbra Collaboration Suite (ZCS) vulnerability.
The ZCS email and collaboration suite is used by hundreds of millions of people and organizations, including thousands of businesses and hundreds of government agencies worldwide.
Synacor patched the security flaw (tracked as
CVE-2026-73570
), which allows unauthenticated attackers to gain code execution remotely by exploiting a command injection weakness in the SNMP monitoring component when SNMP notifications are enabled, with the release of
ZCS version 10.1.20
on July 20.
CERT Polska, the Polish Computer Emergency Response Team (CERT),
first flagged
the vulnerability as targeted in the wild last Monday, when it also warned security teams to check their logs for suspicious activity, including the Zimbra service restarting unexpectedly, and for files created in the /opt/zimbra/jetty/webapps/, /opt/zimbra/jetty_base/webapps/, and /tmp/ folders by user zimbra over the last 30 days.
The Cybersecurity and Infrastructure Security Agency (CISA) also
added the flaw
to its
KEV catalog
following CERT Polska's warning and
ordered
U.S. Federal Civilian Executive Branch (FCEB) agencies to patch their systems within three days, by August 24.
On Monday, threat security watchdog Shadowserver reported that it spotted hundreds of Internet-exposed Zimbra instances that have already been breached in attacks exploiting the CVE-2026-73570 flaw.
Map of compromised Zimbra instances (Shadowserver)
"Zimbra compromises associated with CVE-2026-73570 exploitation are spreading. 274 instances seen compromised in our scans for exploitation artifacts on 2026-08-22,"
Shadowserver warned
.
"We also see at least 8200 CVE-2026-73570 unpatched instances (this does not mean exploitable as the vuln is in a non default config)."
Zimbra vulnerabilities are often targeted by cybercriminals and state-sponsored hacking groups, and have been frequently exploited to steal emails containing sensitive data from vulnerable servers in recent years.
Most recently, in March, Seqrite Labs researchers spotted APT28 Russian military intelligence hackers abusing a stored cross-site scripting (XSS) Zimbra vulnerability
to breach Ukrainian government servers
.
U.S. and UK cyber agencies also warned in October 2024 that Russian Foreign Intelligence Service hackers (tracked as APT29, Midnight Blizzard, and Cozy Bear)
compromised Zimbra servers
using a ZCS flaw previously exploited to
steal email account credentials
.
Russian Winter Vivern cyber spies also
exploited a reflected Cross-Site Scripting (XSS) vulnerability
to steal emails
from
NATO-aligned email accounts in attacks targeting Zimbra webmail portals.
SOUTHCOM Resumes Bombing Boats Accused of Drug Smuggling, China Calls on U.S. to “Act Rationally” as Bessent Threatens Secondary Sanctions on Iran’s Partners, Supreme Court Sides with Trump over Limits to Mail-In Voting, Trump Threatens Even More Tariffs on Canada, Deepening Trade ...
SOUTHCOM
Resumes Bombing Boats Accused of Drug Smuggling
Aug 25, 2026
Image Credit: U.S. Southern Command
The Pentagon says it has resumed strikes on boats in the eastern Pacific and the Caribbean after a two-month pause. On Monday, U.S. Southern Command said two people were killed after it carried out a “lethal kinetic strike on a low-profile vessel operating along established narco-trafficking routes” in the Pacific Ocean. Once again, the Pentagon provided no evidence the boat was carrying drugs. Since President Trump launched a boat bombing campaign nearly a year ago,
SOUTHCOM
says it’s killed at least 223 people. Amnesty International has condemned the strikes as extrajudicial killings, a form of murder, saying they amount to crimes under international law.
China Calls on U.S. to “Act Rationally” as Bessent Threatens Secondary Sanctions on Iran’s Partners
Aug 25, 2026
The Trump administration has outlined plans to tighten sanctions on Iran, warning that businesses, banks and other nations could lose access to the U.S. financial system if they continue doing business with Tehran. On Monday, Treasury Secretary Scott Bessent announced “Operation Economic Outcast,” which includes secondary sanctions on trade related to Iran’s oil, shipping, cryptocurrency, gold and aviation industries. Bessent said countries have a “timeline” to sever ties with Iran, but provided no details on which countries would be targeted, or when.
Treasury Secretary Scott Bessent
: “We are giving everyone the opportunity to remedy bad behavior. Why would I want to blow up the global financial system? We believe that it is important to level set and give people a cure period, but they should know that that will move very quickly and that we are serious.”
Iran’s key trading partners include the United Arab Emirates, Turkey, Iraq, India, Pakistan and China, which is the largest foreign market for Iranian oil. On Monday, China’s Foreign Ministry called on the U.S. to return to dialogue and negotiations.
Lin Jian
: “Sanctions and pressure will not resolve disputes. They will only exasperate tensions and escalate the situation, which is not in the interest of any party. China calls on the relevant parties to act rationally and with restraint and avoid taking any measure that may further escalate tensions or deal a blow to the global economic growth and financial stability.”
Iran has condemned the sanctions as an “act of war.” A spokesperson for the Islamic Revolutionary Guard Corps said they show the U.S. is resorting to economic warfare after it was defeated on the battlefield.
Supreme Court Sides with Trump over Limits to Mail-In Voting
Aug 25, 2026
The Supreme Court has lifted a lower court’s injunction on President Trump’s executive order seeking to limit mail-in voting ahead of November’s midterm elections. Trump’s order directs the Department of Homeland Security to create state-by-state lists of eligible voters who are citizens. The U.S. Postal Service would then use the lists provided by states to assess if voters should be allowed to vote by mail. On Monday, justices ruled 6 to 3 that California and 22 other states lacked standing to sue over the issue. The ruling, however, did not address whether Trump had authority to impose the rules.
The court’s three liberal justices dissented. Justice Ketanji Brown Jackson warned that the majority opinion “needlessly injects chaos and uncertainty into the upcoming midterm elections.” Meanwhile, a separate nationwide injunction against parts of the same order remains in place.
This all comes as Trump seeks Senate confirmation for four loyalists he’s nominated to vacancies on the Board of Governors of the U.S. Postal Service. Three of them have expressed doubts that Joe Biden won the 2020 presidential election.
Trump Threatens Even More Tariffs on Canada, Deepening Trade War
Aug 25, 2026
President Trump on Monday threatened to increase U.S. tariffs on Canadian cars, trucks and auto parts to 50%, starting next year. Trump’s threat came just days after the U.S. imposed 50% tariffs on roughly $20 billion of other Canadian goods, prompting Prime Minister Mark Carney to announce plans to impose retaliatory tariffs beginning on September 8. On Monday, Carney said Canada would return to trade talks only if the Trump administration changes tactics.
Prime Minister Mark Carney
: “When the Americans go to the negotiation table first with the right attitude towards our industries and a true partnership, of course we’ll come to the negotiating table.”
Israel Bombs Gaza Water Desalination Plant, Mosque and Tents, Killing 7, Including Children
Aug 25, 2026
In Gaza, Israel launched a wave of attacks on Monday, hitting a mosque, a water desalination plant and tents housing displaced Palestinians. At least seven people were killed, including two children. In central Gaza, an Israeli strike hit a house in the Bureij refugee camp, killing a 4-year-old boy. In Khan Younis, another child died from gunshot wounds after Israeli forces fired on her. This is Abu Amra, a Palestinian man at the site of the damaged mosque.
Mohammed Abu Amra
: “This mosque has been here since the day we were born. Today I am about 48 years old, and I’ve always seen this mosque just as it was. The Israeli occupation is just hitting blindly. What? What are they hitting? They’re hitting, they claim — look at what the occupation is hitting. Look. Look. They say they are bombing the book of our Lord. They are bombing our mosques where we pray.”
Despite last October’s so-called ceasefire, Israeli forces have killed nearly 1,300 Palestinians in Gaza.
Montreal City Council Passes Watered-Down Palestine Resolution That Doesn’t Halt Ties with Israel
Aug 25, 2026
In Canada, the Montreal City Council passed a resolution in solidarity with Palestinians on Monday, after councilors removed much of the motion’s original language, which included calls to suspend institutional and diplomatic ties with Israel. The original provision would have also seen the city of Montreal officially recognize and denounce Israel’s assault on Gaza as a “genocide” and its treatment of Palestinians as “apartheid.” This is Alex Norris, a Projet Montréal city councillor who co-sponsored the motion.
Alex Norris
: “One reason Gaza has had such an impact is that we have watched it unfold in real time. On our phones and on our screens, we have seen civilians attacked. We have seen neighborhoods erased. We have even seen perpetrators celebrating what they have done. That is why Gaza has been so often described as the world’s first live-stream genocide. What Israel has done in Gaza and the role Western governments have played in enabling it has become one of the defining moral tests of our time. Today, this council has the opportunity to say, 'Enough.'”
Heavily Armed Gang Kills Dozens in Overnight Raid in Haiti
Aug 25, 2026
In Haiti, a heavily armed gang killed dozens of people overnight Monday in a raid on Kenscoff, a farming community near Haiti’s capital Port-au-Prince. The U.N. reports at least 47 people were killed and 22 more wounded, with homes set ablaze, prompting outrage from survivors over the Haitian government’s failure to protect them from repeated deadly attacks.
Orisme
: “We live in humiliation. The government has done nothing for us. The blood of the population does not stop flowing in Kenscoff. The prime minister has to say something to the people in Kenscoff now. We cannot take it anymore.”
The U.N.'s human rights agency reports hundreds of criminal groups in Haiti have killed over 16,000 people since early 2022. That's compounded an existing humanitarian crisis, with 6.4 million Haitians requiring assistance and nearly 1.5 million internally displaced. Despite that, the U.S. last week announced twice-weekly deportation flights to Haiti, after a Supreme Court ruling allowed the Trump administration to end temporary protected status for an estimated 350,000 Haitians.
Trump Administration Announces Plans to Revoke Visas of Asylum Seekers
Aug 25, 2026
The Trump administration has announced plans to revoke the visas of asylum seekers. The State Department will revoke so-called B1 and B2 visas, issued for business and tourism travel, between 2016 and 2026 whose holders have applied for or are now seeking asylum. The Associated Press puts the number of affected people at 200,000. If the administration follows through with its plans, it would be the largest single mass revocation of visas in U.S. history.
Trump Administration Seeks to Charge Employers Over $103,000 to Hire Workers with H-1B Visas
Aug 25, 2026
The Trump administration again announced plans to charge employers a fee of over $103,000 to hire foreign workers through the H-1B visa program. The revenue would be used to fund
ICE
. President Trump had tried to implement a six-figure fee last year through a presidential proclamation, but a judge ruled against it in June.
ICE
Arrests Mother and Daughter Who Were Seriously Injured in Car Crash and Hospitalized
Aug 25, 2026
In Florida,
ICE
arrested a mother and daughter who were seriously injured in a car crash and brought to a hospital. According to family members, Grace Stephanie Calero Cabanilla and her 19-year-old daughter Giulianna Mía Carriel Calero were placed in separate rooms after arriving at the hospital, and a sheriff’s deputy began questioning the mother about her immigration status shortly after she arrived, while she was wearing a neck brace and had been given medication. According to family members, the mother had applied for political asylum, and her daughter’s visa document was valid until 2030.
Democratic Congressmember Al Green Files Articles of Impeachment Against Trump
Aug 25, 2026
Democratic Congressmember Al Green filed articles of impeachment Monday against President Trump over his violent mass deportation campaign. In his resolution, Green argues, “[President Trump] is abusing the powers of the presidency by operating United States Immigration and Customs Enforcement and Customs and Border Protection as his vicious, quota-driven, unaccountable paramilitary police forces, transgressing with anonymity and secrecy, assaulting people, committing and covering up unjustified killings of civilians.”
This comes as a U.S. airman, Major Jason Watson, was arrested twice for calling for the impeachment of President Trump. He was officially criminally charged Monday for his comments. He faces three violations for “contemptuous” remarks about Trump, five violations for allegedly disobeying orders, and two violations for alleged conduct unbecoming of an officer.
Palestinian artist Sliman Mansour has died at the age of 79. He was one of the leading figures in contemporary Palestinian art. He helped create a visual language of Palestinian identity, revisiting the land, exile and occupation in works that frequently featured olive trees and traditional embroidery. He was born in Birzeit, near Ramallah, in 1947 and attended Bezalel Academy of Arts and Design in Jerusalem in 1970. In 1994, he co-founded Al-Wasiti Art Center in East Jerusalem to preserve Palestinian art and connect artists living in Palestine with other Palestinians in exile. This is Mansour in an interview with Al Jazeera in 2021.
Sliman Mansour
: “I believe art in our situation, where — when you don’t have a homeland, when you don’t have, I mean, a country, a political thing, and when people deny your existence — you know, in Israel and many, many places in the West, they deny your existence — so, art is a form of saying that we are here.”
The original content of this program is licensed under a
Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License
. Please attribute legal copies of this work to democracynow.org. Some of the work(s) that this program incorporates, however, may be separately licensed. For further information or additional permissions, contact us.
Optimized version of the original code is in the folder "TinyOriginal"
Version applying shell coding tactics is in the folder "Lasse"
Version using a manually written PE header is in the folder "Theron"
QRCode is dead code, was the exe embedded into a QRCode, kept just for posterity
The goal of this project is to make the smallest possible application, without compression, that has the following features:
Runs a Windows message loop
Has a title bar, minimize, maximize, and close buttons, which all work as expected
Has a system menu with the same
Paints the background and some text centered in the middle, equal to or larger than "Dave's Tiny App"
Please keep it readable and explain what you're doing in the comments! And the smaller, the better!
Note on virus scanners
The optimizations embedded in the current code in the Lasse directory, and those applied by Crinkler in general (if used) are rather aggressive, and seem to resemble strategies applied by certain types of malware. Because of this, your virus scanner may flag the executables you build out of the source code as "suspected malware". That can make it impossible to start them, or your virus scanner can even put them in quarantine. Depending on the antivirus solution you use, you may be able to whitelist/exclude the executables to restore them and get them to work (this is known to happen with F-Secure SAFE). It's also possible that you have to temporarily disable your virus scanner altogether (which has been observed with Microsoft Defender).
Please note:
It is entirely your responsibility to decide if you want to disable your virus scanner or not.
If you do temporarily disable your virus scanner, we strongly recommend you re-enable it immediately after you test the executables you build out of this repository's code.
Although we
do
promise that this repository does not contain any malicious code, we
cannot
guarantee that this is true for any code or executables (like supposed builds of this repository's applications) that you get from other sources.
If your virus scanner intervenes when you try to run the executables that come out of this repository's source code, and you don't feel comfortable with (partly) disabling your virus scanner, then don't do it. We do understand and we really won't hold it against you. :)
Build instructions
Plain MASM32
The code in the Lasse directory can be built with plain MASM32 11.0, which can be obtained from a number of sources. Build instructions using it are:
ml /coff LittleWindows.asm /link /merge:.rdata=.text /merge:.data=.text /align:4 /subsystem:windows LittleWindows.obj
The executable will be named LittleWindows.exe.
MASM32 with Crinkler
Crinkler is a compressing linker for Windows, specifically targeted towards executables with a size of just a few kilobytes. A copy of the tool is included in this repository in the Crinkler directory. It can also be acquired from
its GitHub repository
.
Crinkler requires the Windows SDK to be installed. Best (i.e. smallest) results have been achieved with version 10.0.20348.0 of the Windows 10 SDK. It, and other versions can be downloaded from the
Windows SDK archive page
on the Microsoft website.
After installing it, the build instructions for the applications that can be built using it are:
The code in the Theron directory has to be built with Yasm, which is a rewrite of the NASM assembler under the "new" BSD license. It can be acquired from the
Yasm project download page
; choose the version "for general use". The assembler is assumed to be renamed to
yasm.exe
. Build instructions using it are:
yasm -fbin -o HelloWindows.exe HelloWindows.asm
The executable will be named HelloWindows.exe.
Current sizes
Current smallest known working executable sizes as of 03/11/2023 are as follows:
Program
Linker
Size in bytes
Lasse\LittleWindows.asm
MASM32
1104
Lasse\LittleWindows.asm
Crinkler
818
Theron\HelloWindows.asm
Yasm
383
TinyOriginal\Tiny.asm
Crinkler
540
Credit Card Rewards Became a $9.2B Wealth Transfer
American Express has famously touted that “membership has its privileges.” For wealthy consumers today, those benefits total $9.2 billion each year, subsidized by middle- and lower-income households.
As inflation-weary businesses raise prices to cover credit card interchange fees, the pain isn't universal, says research by Harvard Business School Professor Mark L. Egan. Because merchants charge everyone the same price regardless of how they pay, those fee costs are factored into prices for all shoppers. However, credit card users get that money back and then some through rewards, while cash and debit users get little or nothing.
The result: People paying cash face the equivalent of a 26% higher sales tax than premium credit card users shopping at the same store.
Collectively, interchange fees shift an estimated $30 billion from those paying with cash and debit cards to credit card users at similar merchants annually, Egan and his fellow researchers estimate in the April working paper
“Who Pays for Payments?”
That windfall is as “economically significant” as government policies that support low- and middle-income Americans, such as the Earned Income Tax Credit and unemployment insurance.
“It's just the way the market was set up,” says Egan, the George E. Bates Professor. “It turns out to be unfavorable to people who use cash and debit, and those who happen to be people with low incomes.”
Egan’s research shows how consumer policies, banks’ need for fees, and buying behaviors have converged to facilitate a massive wealth transfer. The findings arrive amid a widening schism between the country’s richest and poorest residents, as wealthy households gain from surging stocks and many lower-income families struggle to afford basic necessities.
Egan coauthored the paper with Gregor Matvos and Lulu Wang, professors at Northwestern University, Stanford University Professor Amit Seru, and Georgia State University Professor Vincent Yao.
How did this system evolve?
One factor stems from an amendment to the Dodd-Frank Wall Street Reform and Consumer Protection Act passed in 2010 at the crest of the global financial crisis. The law includes a provision known as the
Durbin Amendment
that caps debit card interchange rates charged by large banks.
The law, which went into effect in 2011, aimed to protect consumers and merchants from excessive interchange fees on debit cards. However, the policy ended up hurting debit card users, who lost rewards and perks like free checking as banks made up the lost fee revenue. And while cash users benefited, the biggest winners were credit card users: lower debit interchange fees reduced the prices merchants charged, and credit card users enjoyed those lower prices while their rewards remained untouched.
Ultimately, the policy proved regressive, benefiting affluent consumers while middle-income debit card users lost the most.
“It's just unfortunate,” says Egan, a professor of business administration in the HBS finance unit. “No one wanted this outcome from the Durbin Amendment.”
Parsing payments at 1.8 million merchants
To study how interchange fees impact consumers, the authors partnered with financial transaction firm Fiserv, owner of the popular Clover payment platform. The partnership allowed the researchers to examine card payments across roughly 1 million merchants—about one-fifth of all US card volume—plus data from 800,000 Clover merchants that captures notoriously hard-to-track cash transactions.
The analysis assumed that retailers pass interchange fees to customers through higher prices, but the results held even after relaxing that assumption. Tallying who receives card rewards versus who effectively pays the fees that fund them, the researchers found:
Premium card users reap 43% of rewards, but pay 30% of interchange fees.
Cash users receive no rewards, but pay about 10% of fee-related costs.
Users of debit cards issued by large banks covered by the Durbin Amendment receive about 13% of rewards but pay 23% of the fees.
Because credit card use rises with income, this redistribution translates into a $9.2 billion annual transfer to households earning more than $150,000 from lower-income households—a gain of about $390 a year for high-income households, while lower-income households lose about $88.
The authors found two factors that mitigated the transfer. First, cash, debit, and credit card users tend to shop at different merchants, which limits cross-subsidization. Second, the merchants with more overlap—large grocery stores, gas stations, and big retailers—tend to pay the lowest interchange fees, thanks to sector discounts and the negotiating clout of major chains. Together, these forces shrink the transfer by about 25%.
“Because there's this consumer sorting, and places like Target and Walmart negotiate lower fees, [the redistribution is] not quite as bad as you might think,” Egan says.
Managing the shifting fee landscape
Interchange fees have grown with rising card use, raising strategic questions for any business that sells to consumers, from big box stores to small gas stations. Among the factors they will likely grapple with:
Premium card use will likely grow
. When forecasting interchange fee costs, it’s fair to assume that premium card use will expand, especially as more middle-income consumers embrace them and stop carrying cash. “More expensive payment methods are just going to drive out cheaper ones,” Egan says.
Sound forecasting will require more granularity
. A business with multiple sites might need to consider customer behavior at each location, rather than relying on averages. “Card type, merchant sector, and merchant size play fundamental roles in determining merchant-level interchange fees,” the authors write.
Squeezed merchants have few easy solutions
. Rejecting premium cards or adding surcharges, for example, might undermine competitiveness and alienate customers. “People like to pay with fancy credit cards,” Egan says. “You certainly see that in the data.”
Where do we go from here?
In trying to rein in bank fees, the Durbin Amendment ended up being a regressive transfer from middle-income consumers to high-income consumers. Policymakers weighing future reforms to fees should keep in mind that:
Consumers “self-sort” by income
Wealthy people tend to shop at retailers that anticipate premium card use and price accordingly, the researchers find. And businesses that cater to cash and debit customers might not need to raise prices as aggressively to cover rewards. For that reason, more targeted reforms might be more effective.
Large merchants have more options to manage costs
Big-box stores, for example, have more leverage to negotiate interchange fees than small businesses, Egan says. Niche merchants that serve a variety of customers might be most vulnerable.
Middle-income households often suffer most
After the Durbin Amendment, credit card users enjoyed lower prices while keeping their rewards, and cash-reliant shoppers benefited from lower prices too. Middle-income shoppers—most likely to use debit cards—lost free checking and other perks that outweighed any price relief.
“We find that low-income consumers were relatively unaffected, middle-income consumers were hurt the most by the Durbin Amendment, and higher-income consumers benefited,” the authors write.
Photo credit: Adobe Stock/Lenny.
Meta goes on trial as Silicon Valley faces a growing backlash
Guardian
www.theguardian.com
2026-08-25 07:21:56
Also: OpenAI CEO Sam Altman expressed his surprising sympathy over the construction of datacenters across the country Hello, and welcome to TechScape. I’m Blake Montgomery, US tech editor at the Guardian, writing to you from a sunny park in New York City, which was supposed to endure rain all weeken...
Hello, and welcome to TechScape. I’m Blake Montgomery, US tech editor at the Guardian, writing to you from a sunny park in New York City, which was supposed to endure rain all weekend but in fact delivered the best weather of the year.
A blockbuster case against Meta went to trial a week ago in Oakland, California, just north of the US tech company’s headquarters in
Silicon Valley
. California and 28 other US states are suing the £1tn ($1.36tn) company for allegedly designing products that are addictive for children, and hiding that information from the public.
The courtroom has already seen minor fireworks. On the witness stand, a whistleblower who worked extensively with
Mark Zuckerberg
accused the CEO of lying to the public about his commitment to child safety. The prosecutor who opened the case framed her argument around four words that start with the letter H: Meta “hooks” in users, “holds” them on its platforms for as long as possible, “harvests” their data and then “hides” the truth from the public. She contended that this business model “worked especially well for kids”. More pyrotechnics are expected. Zuckerberg himself is expected to face tough questions on the stand, as is the CEO of Instagram.
Meta has denied all allegations. Liza Crenshaw, a spokesperson for the company, said: “Rather than sticking to the facts or the law, the states have instead decided to chase an outlandish payout.”
The trial presents a major challenge for Meta, not in the least, because in the United States, it’s proceedings like these that regulate the tech industry.
China regulates tech by crackdown; the UK and Europe regulate the industry with legislation – Brussels’ prescriptive stipulations have become global defaults. But in the US, it’s mostly the courts that set the boundaries. They move much faster and with the vindictive authority that Americans often crave in response to harms. The slow wheels of democratic debate and bill drafting feel ill-suited to respond to Zuckerberg’s mantra of “move fast and break things”.
Meanwhile, US regulators have famously, obviously, and
avowedly
had difficulty keeping pace with the innovations that arise from Silicon Valley. As one Republican representative told a quantum computing expert during a 2018 hearing on Capitol Hill: “I can understand about 50% of the things you say.” Members of Congress would undoubtedly say the same about AI today.
“Courts have the ability to force these changes much quicker than legislation. Courts have this authority to say, ‘Look, you either comply with these orders … or you stop doing business in our state’. States have the ability to enforce that. I think for these companies this is a real point of reckoning,” said Laura Marquez-Garrett, an attorney with the Social Media Victims Law Center, which is representing individual plaintiffs suing Meta and other social media companies in thousands of cases in
California
. Her organization was deeply involved in Meta’s first loss of a social media addiction trial in March in Los Angeles.
Will this trial bring Meta’s moment of accountability? Maybe.
Other tech companies have faced significant government lawsuits in recent years, and come away only stronger. Google faced perhaps the most significant antitrust litigation of the 2020s, losing its antitrust case against the US Department of Justice last year. The penalty was not divesting the Chrome browser but a “
slap on the wrist
”, critics said.
But in the 1990s, a coalition of US states sued tobacco companies and secured a settlement that banned a laundry list of marketing tactics, including advertising on transit or anywhere outdoors, paid product placement for cigarettes, cartoon mascots, branded apparel and nearly all free distribution of cigarettes. You’d never see a tobacco company’s name on a US sports stadium today.
Like those tobacco suits, the states’ suit against Meta may force the company to operate its social networks in less harmful ways and to keep them out of the hands of children. The states are explicitly asking the court that Meta be forced to change the design of its products to make them safer for children.
“These AGs have a real chance at fixing the product,” said Marquez-Garrett.
The week the US data center backlash reached a fever pitch
The Pennhurst Asylum seasonal haunted house in Spring City, Pennsylvania, US.
Photograph: Matthew Hatcher/Bloomerberg via Getty Images
The political champions of datacenters in the US are turn coatings to detractors. It’s knives out in the US datacenter backlash.
Democrats who fast-tracked the development of these gargantuan fortresses of AI are now implementing restrictions on them. Republicans who trumpeted calls for their unrestricted construction are hastily rolling out plans to constrain them.
Josh Shapiro, Democratic governor of Pennsylvania, rolled out restrictions for large datacenters last week. Just two months ago,
the Guardian
reported on how he was fast-tracking them and cutting red tape. Greg Abbott, Republican governor of Texas, said this weekend that the datacenter industry has “dug its own grave”. In November 2025, he called his state the “epicenter of AI development”. A Republican running for a contested Senate seat in Texas, Ken Paxton, debuted an anti-AI action plan over the weekend, though it was marked as “made with AI” on X.
It’s no wonder: more than 70% of Americans oppose the construction of datacenters in their cities, per a poll released by
Gallup
three months ago. In just one year, the percentage of respondents saying they “strongly oppose” a datacenter being built near their homes more than doubled, according to polling by the climate news group Heatmap.
Conservative media in the US has likewise taken notice.
Fox News
on Thursday: “Silicon Valley is losing the datacenter fight, risking a repeat of a classic failure.”
The Daily Wire
, often a bellwether for young Republicans’ opinions, on Monday: “Silicon Valley created the datacenter backlash.”
Donald Trump, always liable to turn on an ally and usually an extremely adept reader of political winds, is standing by the tech industry’s multitrillion-dollar infrastructure buildout.
“Communities that don’t take a datacenter, they’re making a mistake,” the US president said in an interview with his former fixer and once-mortal nemesis Michael Cohen last week.
Silicon Valley is extremely worried. The tech industry is all-in on AI, so much so that the entire US economy is as well, and the success of AI is predicated on access to enough computing power. No datacenters, no chips, no computing power, no AI, no profit, no economy.
What to do when faced with a spiraling political threat?
Some companies are playing nice. They’re
sponsoring
community celebrations or pledging major community investments. They’re hosting listening sessions and making promises about how many jobs their projects will guarantee. Running de facto political campaigns for infrastructure projects is a big change for an industry accustomed to moving at the speed of bytes.
Sam Altman, CEO of OpenAI, expressed some surprising empathy on a
podcast
last month. His company has a range of partnerships across the US for hundreds of billions of dollars’ worth of datacenter construction.
“I understand emotionally why people don’t want datacenters in their back yard in the same way that I don’t really want a nuclear power plant next to my house, even though I know it’s a super safe thing,” he said.
Other Silicon Valley insiders are feeling hostile. Garry Tan, CEO of the influential startup incubator Y Combinator,
wrote on X
this weekend, “Reminder: the datacenter discourse is a documented psyop and they’re winning.” Alexis Ohanian, tech investor and co-founder of Reddit, wrote of the discourse: “It’s been brilliantly executed ngl [not gonna lie]. Facts are not gonna win this, esp at this point, it’s gotta be on emotional appeal.”
In July, entrepreneur and Shark Tank host Kevin O’Leary accused opponents of his planned Utah datacenter of acting on behalf of the Chinese government. He later said he had “no evidence” for the claim and apologized for it, as did Fox News’ own hosts.
The US’ adversaries have taken note of the heated debate and fanned the flames of fury. OpenAI
disclosed
in early July that Chinese and Russian propagandists, including state-owned media, had used its tools to create materials circulated on X, including a cartoon tycoon holding bags of cash and smoking a cigar, encouraging pushback against datacenters.
Reworked: A Guardian series about AI and the future of work
MNT Station
is a quiet and space-saving, future-proof open hardware computer for your desktop, homelab, or mounted on a wall as an edge device/router. It’s also a robust enclosure for your existing MNT Reform mainboard and can be turned into a standalone desktop PC, silent home NAS, or low-power entertainment center.
As usual, this MNT Research device is fully open source hardware with all sources publicly available. As a modular, general-purpose computing platform, MNT Station is the most flexible MNT device yet designed!
Your Next Desktop Computer, Router, or Server
Tired of your laptop taking up more space on your desk than it should? Of all the plugging and unplugging because you’ve been using it as a portable and as a stationary device? With MNT Station you get a machine that’s designed to be stationary while maintaining the energy efficiency of a laptop. Connect a monitor and a keyboard, hook it up with a USB Type-C cable for power delivery, and you’re good to go!
MNT Station has mounting holes on the back (standard VESA as well as keyhole slots) to give you the opportunity to install it on your wall, behind a cabinet, or on the back of a monitor. Its external antenna mounts ensures strong radio reception for Wi-Fi or SDRs, no matter where MNT Station is placed.
Love tinkering with Docker containers, Tailnets, or Home Assistant? Add a flexible and uniquely open ARM-based server to your homelab with MNT Station. Test and develop for a broad range of ARM and other SoCs that fit the modular mainboard (including NXP, Amlogic, Qualcomm, Broadcom (Raspberry Pi) or even an AMD/Xilinx FPGA). And thanks to its native charging and battery monitoring technology, MNT Station has battery backup built-in, running for hours off of 8 LiFEPO4 cells, giving you ample time to shut down in case of a power outage. Or, underneath your TV set, MNT Station can pull duty as a streaming box and retro game console, thanks to its low-power design that doesn’t need ventilation.
Features & Specifications
MNT Station is a versatile device: Upgrade your MNT Reform laptop to the latest mainboard version and use your previous mainboard with MNT Station. Or, build your own Station choosing the MNT Reform Mainboard 3.0, a processor module of your choice, the MNT Reform Standalone Keyboard, and more.
It includes aluminum case parts, 1x electronic port cover with cable (JST PH 4-pin; JST PH 4-pin), 1x non-electronic port cover, and M2x5 mounting screws.
MNT Station case features
Fully CNC milled enclosure from anodized, bead blasted aluminum
Open design, so you can 3D print or order new case parts yourself
Can lay flat or stand on the long edge, or be mounted to VESA arms/screens or walls
Compatible with all classic MNT Reform mainboard versions (2.0, 2.5, 3.0)
Please note: Some mainboard versions have a barrel jack instead of a USB Type-C port. To make these work, we included a perforation on the port cover. Gently break the perforated part and plug your cable in.
Electronic port cover with power button, ATTiny microcontroller that talks to the mainboard, and a bar of 10 LEDs that are controllable from Linux (display, for example CPU utilization or network load)
2x holes for SMA antenna panel mount connectors
2x wall mount keyhole slots in the back
VESA mounting holes in the back (FDMI MIS-D, both 75 x 75 mm and 100 x 100 mm)
Designed to be stacked on future case expansions for batteries/USV, hard disks, GPU with internal cable passthrough holes in the back of the case
Dimensions: 279 x 133 x 26 mm (10.98 x 5.23 x 1.02 in)
MNT Reform mainboard 3.0 features
3x USB Type-A ports
1x USB Type-C for USB Type-C PD power input and built-in UART-to-USB converters for convenient access to SoC/CPU serial console and System Controller UART
Full-size HDMI port
Gigabit Ethernet port
TRRS stereo headphone jack with microphone support
1x 4-pin JST SH connector for I2C sensors/displays (connected to main SoC/CPU, Qwiic compatible)
1x mPCIe slot with 1x PCIe 2.0 lane, mainly used for Wi-Fi, but can be used for secondary SSD/RAID (with M.2 adapter)
1x M.2 key M slot with up to 4x PCIe 3.0+ lanes, mainly used for SSD
USB Type-C port for NXP LPC11U24 system controller (open source firmware) flashing
Optional battery/USV system that support 8x LiFePO4 cells in series with monitoring and balancing and open source Linux driver (reform2-lpc), requires cell holders and cables.
Dual USB Type-C Kit
Adds 2 USB Type-C ports that support USB 2.0 on all processor modules, as well as DisplayPort Alt-Mode when combined with supported processor modules (for now, RCORE RK3588 and MNT Quasar).
Includes the necessary internal cables to feed USB 2.0 from the mainboard and DisplayPort signals from the processor module as well as the mainboard's eDP header.
Optional Add-ons
MNT Reform Mainboard 3.0
(not included with MNT Station case)
MNT Reform Processor Module
(not included with MNT Station case)
MNT Reform RCORE RK3588 V2 with heatsink (16 or 32 GB RAM) or
MNT Research is driven by the idea of a digital future that is open-source, accessible, and modular. With MNT Station, all
sources are available
. For support we offer the following resources:
Over the last years, through fulfilling our previous campaigns of
MNT Reform
and
MNT Pocket Reform
on Crowd Supply, we have gained substantial experience in sourcing, manufacturing, testing, and shipping electronic devices. We produce our computers and a number of related hardware products full-time in our dedicated workshop in Berlin.
Fulfillment & Logistics
After our production run is complete, we will package everything up and send it along to Crowd Supply’s fulfillment partner, Mouser Electronics, who will handle distribution to backers worldwide. You can learn more about Crowd Supply’s fulfillment service under
Ordering, Paying, and Shipping
in their guide.
Risks & Challenges
As our fifth Crowd Supply launch, we know how to get product shipped to customers. It’s always possible that there could be a sudden component shortage or increase in price. If that should happen, we would have to exchange a part, causing a delay in production.
Should any situation arise that would delay the estimated shipping timeline, backers will be informed promptly via project updates.
Includes case parts, 1x electronic port cover with cable (JST PH 4-pin; JST PH 4-pin), 1x non-electronic port cover, and M2x5 mounting screws
$
299
Free US Shipping / $12 Worldwide
Orders placed now ship Jan 24, 2027.
MNT Station Case (Silver)
Black MNT Station enclosure, made from CNC milled, bead blasted aluminum. Includes case parts, 1x electronic port cover with cable (JST PH 4-pin; JST PH 4-pin), 1x non-electronic port cover, and M2x5 mounting screws
$
299
Free US Shipping / $12 Worldwide
Orders placed now ship Jan 24, 2027.
MNT Station Case (Petrol)
Petrol blue MNT Station enclosure, made from CNC milled, bead blasted aluminum. Includes case parts, 1x electronic port cover with cable (JST PH 4-pin; JST PH 4-pin), 1x non-electronic port cover, and M2x5 mounting screws.
$
299
Free US Shipping / $12 Worldwide
Orders placed now ship Jan 24, 2027.
MNT Reform Mainboard 3.0
MNT Reform Mainboard 3.0 with USB-C power delivery.
$
429
Free US Shipping / $12 Worldwide
Orders placed now ship Jan 24, 2027.
MNT Station Dual USB-C Expansion
MNT Station Dual USB-C Expansion features 2 additional USB-C ports.
$
125
Free US Shipping / $12 Worldwide
Orders placed now ship Jan 24, 2027.
mPCIe to M.2 Key E Adapter
mPCIe to M.2 Key E Wi-Fi Adapter (required for the Intel Gig+ Wi-Fi 6E module).
(DOES NOT INCLUDE CM4 MODULE) MNT RCM4 is a flexible solution for integrating the Raspberry Pi CM4 compute module and compatibles (such as BPI-CM4) into MNT Reform and MNT Pocket Reform.
The kit contains our internal HDMI to eDP adapter and a universal heatsink.
This is the open hardware system-on-module featuring the NXP Layerscape LS1028A processor and 16GB of DDR4 RAM.
LS1028A has 2x ARM Cortex-A72 cores and a Vivante GC7000UL GPU. LS1028A can drive external GPUs (adapter required).
It can be used in the MNT Reform open hardware laptop or in any other custom device.
Design files of this processor module are published under the CERN OHL.
This CM4108000 variant of the Raspberry Pi Compute Module 4 is a System on Module (SoM) containing an ARM quad-core Cortex-A72 processor, 8 GB RAM, ethernet, 2.4 and 5 GHz 802.11b/g/n/ac Wi-Fi, and supporting power circuitry. Does not include eMMC storage.
A 512 GB solid-state drive (SSD) in an M.2 2280-S3-M form factor with a PCIe Gen4 x4 interface. The drive uses the Non-Volatile Memory Express protocol, the SMI2268XT2 controller, and Kioxia BiCS8 TLC FlashNAND Flash.
A 1 TB solid-state drive (SSD) in an M.2 2280-S3-M form factor with a PCIe Gen4 x4 interface. The drive uses the Non-Volatile Memory Express protocol, the SMI2268XT2 controller, and Kioxia BiCS8 TLC FlashNAND Flash.
A compact and slim mechanical keyboard designed for comfort and portability.
Robust laser-etched legends and dimmable WLED backlight.
Smooth but exact haptics: custom FKcaps MBK concave and convex keycaps. Kailh Choc Brown tactile keyswitches.
Completely open hardware and open-source firmware.
N-Key rollover: Diodes on every keyswitch prevent ghosting.
126x32 pixel customizable OLED menu.
Works with any computer with USB: The keyboard has a single USB-C port with USB2.0 signalling.
Protects your LiFePO4 cells and gives you peace of mind when leaving MNT Reform uncharged for a longer time.
Features: Undervoltage, overvoltage, overcurrent protection.
Drop-in replacement.
1 pair (2 pieces).
This is the open hardware camera add-on for the MNT Reform open hardware laptop.
The camera can also be used with any other USB capable computer—it has a Type-C connector with USB 3.0 and 2.0 signals.
It provides an open and customizable solution for HD video telephony.
We are driven by the idea of a digital future that is open-source, accessible, and modular. Our innovative, interdisciplinary team sets high standards in terms of quality and sustainability. We combine these principles by developing open source hardware, software, and textiles in Berlin, Germany.
Ana Dantas
Subscribe to the Crowd Supply newsletter, highlighting the latest creators and projects
Two planned datacentres will have higher UK carbon emissions than ExxonMobil, analysis finds
Guardian
www.theguardian.com
2026-08-25 07:04:56
Exclusive: Buckinghamshire and Bedfordshire sites predicted to emit 4.5m tonnes a year when fully running The carbon emissions from just two planned datacentres in England will exceed all of the fossil fuel company ExxonMobil’s UK emissions, analysis has revealed. Experts have said this demonstrates...
The carbon emissions from just two planned datacentres in England will exceed all of the fossil fuel company ExxonMobil’s UK emissions, analysis has revealed.
Experts have said this demonstrates the “serious threat” datacentres pose to the UK’s legally binding climate goals.
Analysis by the non-profit group Foxglove reveals that when fully operational, the Wapseys Wood datacentre in
Buckinghamshire
and the Quest Park datacentre in Bedfordshire will use 1.3GW of power and will produce more than 4.5m tonnes of carbon emissions.
ExxonMobil emitted
3.9m tonnes
in 2023, according to the global energy thinktank Ember.
AI datacentres use a massive amount of electricity to power servers and cooling equipment, and to run facility systems. There are currently 315 datacentres in the queue to connect to the UK’s electricity grid, representing 73GW of demand. This is almost double the peak winter energy demand for the entire UK.
Because of the long wait to connect to the grid, the Wapseys Wood and Quest Park datacentres are seeking to build their own on-site gas-fired power stations.
Based on government
figures
on the carbon intensity of electricity generation, Foxglove has calculated these projects will produce 4.577m tonnes of carbon emissions per year.
A government spokesperson said these figures were “misleading” because of the assumption that both projects will run at 100% utilisation from day one, which they said was “not accurate”.
Tom Hegarty, head of communications at Foxglove, said assuming a 100% utilisation rate followed standard industry practice.
Kierra Box, a trade and environmental regulation campaigner at Friends of the Earth, said the aim was for datacentres to increase load and run at full capacity, and so it was “valid to look at those top level predictions”.
The former
England
and Wales Green party leader Caroline Lucas described the projected emissions from these projects as “absolutely horrifying”, and said it should be ringing alarm bells right across government.
The government says its own analysis shows there are multiple pathways for this rapid datacentre rollout to fit within the
seventh carbon budget
, which sets out how the government will reach its international climate targets.
Toby Perkins, a Labour MP and chair of the Commons environmental audit committee, which is leading an inquiry into the environmental impact of datacentres, said this analysis was a “potent reminder that without the right measures in place, data centres could represent a serious threat to the environment and to our legally binding climate goals”.
Oliver Hayes, head of policy at the campaign group Global Action Plan, said the two projects were “catastrophic for our carbon budgets”. He said the only way the rapid rollout of datacentres could fit within these budgets was if other elements of the economy were given much stricter carbon budgets.
Sam Hunter-Jones, a ClientEarth lawyer, said every megawatt powering a datacentre connected to the grid was a megawatt that could not be used to replace fossil fuels elsewhere. “The reality is that unchecked datacentre growth is making the transition away from fossil fuels harder, not easier,” he said.
The datacentres are two of the first to be fast-tracked through the government’s nationally significant infrastructure project (NSIP) regime. This regime allows developers to rapidly deliver infrastructure projects by bypassing local planning authorities with decisions instead handled by central government.
Hayes said it was a “very worrying sign” that the government had allowed two gas-fired datacentres to apply into the NSIP regime. “I think that sends an extremely bad signal and demonstrates that they are not serious about addressing the emissions associated with datacentres,” he said, describing it as an “affront to local people”.
Lucas also raised concerns about the projects being fast-tracked, and said it “insulates” them from local scrutiny.
“In order to be able to make sensible decisions on which projects should go ahead and where they should be, we need to have more information in the public domain. We need to have more scrutiny, not less, and yet things like the NSIP regime are moving things in the opposite direction,” she said.
A spokesperson for the Department for Energy Security and Net Zero said: “Datacentres are a vital part of our economy and our everyday lives, helping us interact with the services we need, while driving growth and renewal for communities. We will enable the development and growth of new industries, such as datacentres, by building unprecedented amounts of clean power.”
Waspeys Wood declined to comment. Quest Park did not respond to a request for comment.
Local Cops Flout Sanctuary Law to Help ICE Deport Immigrants
Intercept
theintercept.com
2026-08-25 07:00:00
Illinois law prohibits local collaboration with immigration enforcement officials, but the cops often find workarounds.
The post Local Cops Flout Sanctuary Law to Help ICE Deport Immigrants appeared first on The Intercept....
This story was reported and produced by Injustice Watch, a nonprofit newsroom in Chicago that investigates issues of equity and justice in the court system. Sign up here to get their
weekly newsletter
.
Minutes after Riverton
police officer Brad Herzog ran 31-year-old Daniel Torrez Perez’s name through a law enforcement database one night in April 2025, his phone rang. It was the FBI.
“Every bell and whistle went off,” said Jack Griffin, the agent on the other end of the line.
Herzog had pulled Torrez over for going 15 miles above the speed limit on a rural two-lane highway just northeast of Springfield, Illinois. Herzog ran Torrez’s name and date of birth on his squad car laptop to confirm his identity. His search tripped a federal alert, and within minutes Griffin was on the line.
The exchange was captured on body-worn camera footage obtained by Injustice Watch through a Freedom of Information Act request.
Torrez had an administrative Immigration and Customs Enforcement warrant, meaning ICE was seeking to arrest him for deportation.
Under state law, Herzog couldn’t hold Torrez for federal agents.
In 2017, Illinois passed the TRUST Act on the principle that immigration is governed by federal civil law and local police have no business enforcing it. It was a sentiment bipartisan enough that a Republican governor, Bruce Rauner, signed it.
The law limits Illinois law enforcement agencies’ ability to assist immigration agents: They can’t transfer people to ICE custody without a criminal warrant signed by a judge, allow ICE agents to call or visit someone in a local jail, or “assist in any capacity with an immigration agents’ enforcement operations.”
Griffin knew that the immigration warrant was off-limits to Herzog.
“I know you can’t act on that,” Griffin told him. “I know this puts you in a weird bind.”
Then the FBI agent offered a way around it: Torrez also had an outstanding state warrant on a DUI charge, he noted. Herzog couldn’t arrest Torrez on the immigration warrant, but he could arrest him on the state one. The charge had nothing to do with immigration, but the outcome Griffin wanted was the same.
“You can take him under the state warrant, and that would hold him overnight,” Griffin said. “I don’t wanna miss my opportunity here.”
Herzog agreed to arrest Torrez on the state warrant and book him into the local jail, ensuring he wouldn’t be released that night.
“I appreciate that, thank you very much,” Griffin said, adding that he’d look for Torrez the next morning.
“Sounds good,” Herzog replied.
In the first 15 months following President Donald Trump’s return to office, local officials from at least 75 agencies across Illinois fed information to federal immigration agents, sometimes in apparent violation of state law. In over a third of Illinois counties, at least one police department, sheriff’s office, or state’s attorney’s office collaborated with federal agents. At least 150 people in Illinois were swept into the immigration system this way, in a state that presented itself as a shield against it.
Injustice Watch’s investigation draws on more than 30 hours of body-worn camera footage, 394 records requests, and more than 100 court filings, as well as conversations with more than 20 people who were flagged, detained, or deported, and more than 50 of their relatives. Many would talk only on the condition of anonymity, afraid of retaliation or ashamed of what had happened to them.
Illinois’s TRUST Act is one of the strongest laws in the nation meant to protect immigrants and has often been cited as a national model. More than a dozen states, including New York and California, have similar laws.
But the records unearthed in Illinois show a pattern of continued collaboration with federal immigration agencies that raise questions about the limits of such laws: Sheriffs honoring ICE detainers the law forbids them to honor. Police departments emailing federal agents the home addresses, employers, and daily whereabouts of people stopped for speeding. A local detective asking ICE to run the immigration status of an armed-robbery victim. Officers with a local badge and an ICE email address, sharing immigration data that’s supposed to be off-limits to them. Jails releasing people directly to waiting ICE agents, at the federal government’s direction.
The TRUST Act came with exceptions: Police can act on a federal criminal warrant, volunteer someone’s immigration status, or release an arrest report on request. And it left shared databases untouched — simply running a name through a law enforcement database is enough to trip a federal alert, the way it did the night Torrez was pulled over.
Some agencies refused to turn over records sought through FOIA requests; Injustice Watch is suing more than a dozen local, state, and federal agencies to pry them loose. The true count of people swept up under
local-federal collaborations
is almost certainly higher, in part because of missing records.
When taken one by one, collaborations between local officials and federal immigration agents may appear as small, isolated incidents. But at the end of that paper trail are at least 150 people uprooted from their lives in Illinois and funneled into the deportation system, in a state whose leaders had promised over and over again that it wouldn’t happen here.
Collaboration by Keystroke
The most common kind of collaboration was also the simplest: a local official pulling up a record and emailing it to an ICE agent. Roughly 85 such exchanges appear across the records reviewed by Injustice Watch.
The TRUST Act specifically prohibits state and local law enforcement officers from “providing information in response to any immigration agent’s inquiry or request for information regarding any individual in the agency’s custody” unless required to by a judge’s warrant or federal law.
César Cuauhtémoc García Hernández, an Ohio State University law professor who studies how criminal and immigration systems intersect, describes this type of collaboration as one built on “the kinds of professional relationships that commonly develop among law enforcement officers, especially in small communities where people know each other.”
Most are “entirely aboveboard,” he said, but they can sometimes “clash with directives, like what we see in the TRUST Act.”
In Tinley Park, a southwest Chicago suburb, communications with ICE agents flowed freely.
It started, the department’s emails show, at an early 2025 law enforcement meeting in Hinsdale, where Tinley Park detectives met
Homeland Security Investigations
special agent Daniel Mejdrech. Word moved through the department that Mejdrech, as one officer later
put it in an email
, “may be interested in cases with individuals with warrants that are not citizens or on a visa.”
In March 2025, Detective Justin Rzeszutko emailed Mejdrech
a suspect’s passport photo
and asked for “recent USA entry/exit photos.” The agent wrote back that the man had used aliases, had been deported from Canada, and sat on “a watchlist,” and offered to help locate him if the detective sent along addresses or associates. When Rzeszutko later secured an arrest warrant, Mejdrech volunteered muscle: “If you want manpower when you grab him, say the word and I can bring some folks.”
In April 2025, an
ICE agent asked
Tinley Park officer Jason L’Amas for “lead data” on a man the officer had stopped for speeding. The officer sent back the man’s driver’s license number, home address, phone number, and employer, and flagged where to find him: “His crew is doing work in Tinley Park currently.”
Months later, in a case first
reported
by the Chicago Tribune, L’Amas
emailed an ICE deportation officer
a report about a different man; days later, the ICE officer wrote back: “Just a heads up we took this guy into custody today.” Injustice Watch identified the man and confirmed he was deported to Honduras.
Ed Yohnka, a director at the American Civil Liberties Union of Illinois, said these two exchanges may have violated the TRUST Act. Individual officers using informal connections with federal agents to share information about people they’d encountered without a warrant “is not supposed to be something that state or local police inquire about,” he said.
The first email exchange, he said, was a sign of something broader: a culture or belief in the Tinley Park Police Department that assisting with immigration enforcement was appropriate behavior, despite state law.
Tinley Park Police Chief Thomas Tilton didn’t respond to questions about his officers’ interactions with federal immigration officials. Neither did Village Manager Pat Carr.
Illinois Attorney General Kwame Raoul has extraordinary power to investigate TRUST Act violations: He can hold hearings, examine officials under oath, and issue subpoenas for records. But he rarely exercises that authority.
“The Attorney General’s office uses a compliance-oriented approach in carrying out its TRUST Act enforcement responsibilities,” Raoul said in a statement. “This approach includes providing trainings, technical assistance and nonregulatory guidance to law enforcement agencies throughout Illinois.” He declined to answer questions about Tinley Park or to specify how many times his office has taken enforcement action under the statute.
The ACLU of Illinois, meanwhile, has long pushed the attorney general’s office for increased monitoring of the law.
“One of the things that we often see in law enforcement generally is that individual officers too often believe that they can apply their own judgment to what should be permissible as opposed to what is required” under the state and federal law, said Yohnka. “And then there isn’t the kind of vigorous accountability for those actions.”
Illustration: Verónica Martinez/Injustice Watch
The Officers with Two Badges
In Hoffman Estates, a detective found a federal contact in his own department. Tom LaPak has been a police officer there since 2001 and, since 2004, a Homeland Security Investigations task force officer assigned to its financial investigations group. He carries a village badge and uses an ICE email address.
That’s because task force officers like LaPak are local cops the state cross-deputizes to work federal criminal cases.
The TRUST Act carves out room for this: It allows local officers to work with agencies like Homeland Security Investigations on criminal matters “in order to ensure public safety.”
The law doesn’t allow federal agents to use that partnership to enforce immigration law. For example, the law draws a line between tracking down a scam ring and checking a victim’s immigration status.
Records reviewed by Injustice Watch show some officers appeared to have crossed that line anyway.
Shaw wrote that “some red flags have been raised with the victim.” The case might be staged, he suspected, to support a U visa claim.
A U visa
offers a path to citizenship
for certain victims who report crimes and cooperate with police. Both that protection and Illinois’s own TRUST Act rest on the same idea: encouraging immigrants to come forward to law enforcement agencies without triggering their own deportation.
But Shaw’s email treated a victim’s possible path to protection as a reason to suspect him of fraud.
“I was wondering if it’s possible to check his citizenship status to see if I’m tracking this correctly or the issues that have been arising are coincidental,” Shaw wrote.
LaPak wrote back the same afternoon. “I’m still waiting on confirmation, but it appears he is a Visa overstay,” he wrote. “He should have left the U.S. in 2016.”
“Ok thanks that’s definitely good to know,” Shaw replied. “I appreciate it!”
Reached by phone, Hoffman Estates Police Chief Kasia Cawley said her department didn’t violate the TRUST Act. She also defended her detective, who she said had recently participated in a training on spotting U visa fraud and had a hunch that something was off because there were no witnesses to the crime, she said.
The man was never charged — or told his status had been checked.
Cooperation with task force officers ran the other way, too, with the federal government reaching through them to enlist local officers in immigration operations.
On January 13, 2025, a week before Trump’s inauguration, a Homeland Security Investigations Chicago supervisor
emailed dozens of agents and task force officers
about “several operations in furtherance of the new administration’s objectives.” A joint operation with Enforcement and Removal Operations — ICE’s deportation arm — was set to run January 21 through 27. It would focus, the email said, on “non-citizens who pose the highest public safety risk,” along with employer inspections of area businesses.
“It is important that as many personnel as possible — including our task force officers — participate,” the supervisor wrote.
The distribution list included officers at police departments in Urbana, Peoria, Decatur, and across central Illinois — local cops looped into the planning of a federal deportation operation.
Two police chiefs reached by Injustice Watch distanced themselves from the operations. Urbana Police Chief Larry Boone said his task force officers joined a Zoom briefing but didn’t participate in removal operations. Peoria’s chief, Bradley Dixon, said his officers didn’t either. Decatur chief Brad Allen did not respond to questions.
Collaboration by Default
When Riverton officer Herzog ran Daniel Torrez’s name the night of that traffic stop, he didn’t contact the FBI; the database did.
Fingerprints taken at booking are automatically routed through a network of databases that flows from the Illinois State Police to the FBI. From there, they reach the Department of Homeland Security, where they’re checked against immigration databases. An arrest for almost anything — a DUI, shoplifting — can surface a decades-old immigration record and tell ICE exactly where to find the person.
Injustice Watch reviewed more than 40 federal court affidavits in which a fingerprint taken at a local booking and matched against federal records helped build an immigration case.
Spencer Reynolds, senior counsel at the NAACP Legal Defense Fund and a former Department of Homeland Security attorney, said the automatic sharing of data “is a fundamental threat to protective laws for residents and visitors in any given state.”
In a statement, a spokesperson for the FBI said agents “work within the law and policy to support our partners in immigration enforcement and protect the U.S. from a variety of threats.”
In interviews and emails, local police chiefs described the booking process as one beyond their control. Fingerprints are automatically sent to the state and federal systems, and local agencies can’t opt out of the system or dictate what Illinois State Police or federal agents do with the data. As O’Fallon chief Kirk Brueggeman put it, the department has “no say in how a federal agent — operating under a different set of laws — uses those resources that we do not control.”
Illinois State Police Director Brendan Kelly didn’t respond to questions about how his agency transmits data to federal agencies.
Kelly was handpicked by Gov. JB Pritzker, who consistently made promises to protect all residents across Illinois. Shortly after Trump was elected in 2024, Pritzker told cable news, “I’m going to do everything I can to protect our undocumented immigrants.” At a conference this past April, he recalled how he’s been standing up to Trump’s anti-immigrant policies since the president’s first term.
Pritzker didn’t respond to questions about how state police share immigration-related information.
The automatic transmission of data is so pervasive that it even touches the few departments that, in a review of public records, turn ICE away when it comes knocking.
In February, Zenobia Jones, an administrative staffer for the Atlanta, Georgia, immigration court prosecutor,
asked Aurora police records staff
for documents related to an individual — but didn’t get far.
“The Illinois TRUST Act generally prohibits local law enforcement from sharing information with federal immigration agencies with limited exceptions,” wrote Aurora police records manager Elizabeth Robles. Jones never wrote back. Two months later, an ICE deportation officer named Gregory Ortiz
made a similar request
from the same department. Robles handed Ortiz the same response. Ortiz never wrote back, either.
But for all the resistance the Aurora Police Department put up against ICE requests, it couldn’t stop the automatic sharing of fingerprints gathered in the course of routine arrests — three of which, court records show, were used as part of federal immigration cases.
Illustration: Verónica Martinez/Injustice Watch
Honoring ICE Detainers
The U.S. Marshals Service takes custody of people accused in federal criminal cases, as well as some of those serving shorter sentences. Because it operates no jails of its own, the agency contracts with local jails for bed space, including facilities in Illinois.
The TRUST Act bars Illinois jails from similar contracts with ICE, and explicitly bars them from honoring ICE detainers — civil requests to hold a person past their scheduled release. It also prohibits jails from handing anyone over to ICE.
Some jails do it anyway, at the Marshals’ direction.
In October 2025, a man who’d pleaded guilty to drug charges was in Marshals custody at the Marion County Jail in southern Illinois. Marshals administrator Lauren Patterson
emailed an ICE agent
asking if the agency could take him from the jail, then told the jail ICE would collect him on October 12.
That day, a sergeant confirmed to Patterson and several ICE agents that the man “was picked up by ICE approximately 0715 this morning.”
Two months later, the Marshals Service
instructed the jail
to release another man into ICE custody, and once again, the jail obliged.
Marion County Sheriff Kevin Cripps, who runs the jail, insists his office did nothing wrong.
“We at no time had contact with ICE,” he said. His jail houses people for the Marshals Service, and when he releases them he does so only while “acting under their authority.”
Documents reviewed by Injustice Watch suggest a similar pattern across other Illinois jails. In effect, the Trump administration, not Illinois law, decides whom a state jail releases to immigration agents.
In a statement, the Marshals placed responsibility on the sheriffs.
“Should state law prohibit the jails from honoring detainers,” a spokesperson said, the agency “would anticipate that the jails follow their state law.”
Asked whether his office would do anything to address the practice, Attorney General Raoul declined to answer.
State laws bind local officials but can’t bind the federal government. As García Hernández, the law professor, explained, “the Marshals Service or DHS, they can come knocking as often as they like” — it’s up to local officials to abide by state law. But, he added, so many loopholes are baked into laws like the TRUST Act that it can “allow the exceptions to swallow the rule.”
In some counties, sheriffs aren’t taking direction from the Marshals Service and are instead honoring ICE detainers directly — a direct violation of the TRUST Act. Records indicate that at least four counties have done so since Trump returned to office.
In late June 2025, Hancock County State’s Attorney Bobi James
emailed ICE agent Ron Shevela
about an upcoming plea deal that would release a man her office was prosecuting. But there was a snag: The agent would be out of town until July 1, and the prosecutor worried nothing would keep the man jailed past his release.
“I could send you a detainer before then, if you’d like,” wrote the agent.
“That would probably be necessary,” James replied.
Hancock Sheriff Travis Duffy didn’t respond to questions about the detainer; neither did prosecutor James.
Xanat Sobrevilla, who co-founded the advocacy group Organized Communities Against Deportations, said that for the families she works with, the trust communities have tried to build with local agencies is eroding.
“It’s hard to continue to believe in something that continues to hurt you,” she said.
After Riverton officer Herzog pulled Torrez over just outside Springfield, Torrez spent that night in the Sangamon County Jail, exactly as the FBI agent on the phone had wanted. Hours later, he was in ICE’s grip.
In an affidavit, ICE deportation officer J.R. Hentz said Torrez was taken “into custody inside the booking area of the Sangamon County, Illinois jail” the day after he was arrested.
Sangamon County Sheriff Paula Crouch didn’t respond to a request for comment; neither did her husband, Riverton Police Chief Bob Crouch.
Injustice Watch confirmed Torrez was deported to Guatemala late last year.
Andy Ellis has a roundup of the security vendors at Black Hat this year.
Key Takeaways: We have entered into an AI world. While nearly half of booths didn’t directly mention AI or agents in their taglines, the effects of AI are everywhere. Multiple spaces (Identity, SaaS, AppSec, Data) have ...
Andy Ellis has a
roundup
of the security vendors at Black Hat this year.
Key Takeaways: We have entered into an AI world. While nearly half of booths didn’t directly mention AI or agents in their taglines, the effects of AI are everywhere. Multiple spaces (Identity, SaaS, AppSec, Data) have almost every vendor leading with AI; existing unsolved problem areas just got worse.
At the same time, there’s a clear trichotomy in the market: tools that tell you how bad things are; tools that stop adversaries, and tools that prevent problems from occurring. While you’d suspect that the tools that fix things would dominate, the tools that merely tell you how bad things are seem to be frustratingly plentiful.
Police arrests dozens of suspects in global cybercrime crackdown
Bleeping Computer
www.bleepingcomputer.com
2026-08-25 06:53:20
Law enforcement agencies from 22 countries helped identify 263 suspects and arrested 58 individuals linked to cybercrime networks coordinated by African crime groups. [...]...
Law enforcement agencies from 22 countries helped identify 263 suspects and arrested 58 individuals linked to cybercrime networks coordinated by African crime groups.
The "Operation Jackal IV" international joint action targeted West African criminal networks between November 2025 and June 2026.
The operation also focused on disrupting the Black Axe cybercrime syndicate, known for its involvement in global-scale cyber-enabled financial fraud. Most commonly, Black Axe and similar criminal rings are targeting victims in romance scams, cryptocurrency and investment scams, or business email compromise fraud, but they've often also been linked to violent crimes.
During Operation Jackal IV, Argentinian law officers made 17 arrests, and they linked 196 suspects to a major Crime-as-a-Service network that provided West African organized crime groups with web domains and money-laundering support.
South African authorities also arrested 39 individuals, blocked 257 bank accounts, and seized $2.67 million from a criminal syndicate that targeted retirees in English-speaking countries in investment and romance scams.
Romanian police arrested another 11 suspects, part of a criminal group linked to a call center that used high returns in stocks or cryptocurrencies to bait victims into sophisticated investment scams, while Italian authorities identified one suspect linked to a pan-European money laundering network that laundered money via shell companies, remittance services, and cash withdrawals.
"Offenders typically contact minors via social media, build trust and coerce them into sharing explicit images or videos. They then threaten to distribute this material to the victim's contacts unless a ransom is paid,"
INTERPOL said
.
"Some of these criminal syndicates were also observed procuring Crime-as-a-Service from external providers, often through the dark web, to outsource key activities like money laundering and other critical operations."
Between December 8 and January 30, African authorities have also arrested 651 suspects in another Interpol-coordinated joint police action
, codenamed Operation Red Card 2.0
, that spanned 16 countries.
More recently, in July, INTERPOL also announced that
law enforcement agencies arrested 5,811 suspects
and seized $293 million in illicit assets in a global anti-fraud operation dubbed "Operation First Light 2026," involving investigators from 97 countries.
SQLite does physical write-ahead logging. It works through edits to database pages in memory and queues every changed page to disk in the write-ahead log (WAL). The WAL stores pages as a "frame" (which is a frame header and then the actual page) and collapses multiple changes to the same page within a single transaction into one frame.
Once the WAL has reached a threshold size of 1,000 pages (
by default
), SQLite triggers a "checkpoint". Checkpointing copies pages out of the WAL into their permanent location on disk. But long-lived readers can keep SQLite from checkpointing. And conversely, large WALs make readers slower (when the page cache is invalidated and you must fetch pages from disk) because pages in the WAL have no useful ordering for reads. Finding the page you want is a function of the size of the WAL.
In the kindest checkpoint mode, "passive" checkpointing only copies pages out of the WAL not in use by other transactions. In the most severe mode, "truncate" checkpointing attempts to wait for all readers and writers to complete, then copies all pages out of the WAL and truncates the WAL to zero bytes. In general, after all pages have been copied out of the WAL the WAL can reset and reuse space. (Except for the truncate mode where it will allocate new space from 0 bytes.) Otherwise, while pages are still in use by some open transaction, the WAL keeps growing as needed to fit new pages.
The automatic checkpointer only ever does passive checkpointing. If the application thinks it can do a better job scheduling checkpoints, particularly during times it knows the database is idle, or if the application wants to do more aggressive checkpointing, applications
are allowed
to do so via methods like
PRAGMA wal_checkpoint
.
Earlier this month, Tailscale wrote about
hitting a bug
in concurrent checkpointing that caused the checkpointer to incorrectly mark pages in the WAL as having been copied out already. This led to data loss at a minimum and occasionally data corruption spotted by
PRAGMA integrity_check
when data went not just missing but out of sync with indexes.
SQLite
fixed this
in March 2026. (That Tailscale only just published the blog is probably more a matter of them only now having confidence the bug was actually fixed.)
Let's trigger this bug organically and see what damage we can do!
We'll have two threads and three database connections.
Thread 1, database connection A (the checkpointer) checkpoints. Thread 2, database connection B (the writer) updates a row in table Z and commits. Thread 1, database connection C (the reader) reads from table Z. At the right concurrency and with the right timing, these three interleave to create the bug.
The interactions happen entirely in
wal.c
. Here's a sample interleaving.
The tricky part is this writer restarting the log during the checkpoint's racy window. Thankfully there's something we can exploit. wal.c does a
munmap
of the database file during the window. And if we cause the database to be particularly large, that
munmap
now takes enough time for the writer to fit in a log restart.
In a concurrent thread we'll write a monotonically increasing value (one value, one row) to a second "canary" table and only write the next value after we receive a SQLITE_OK. SQLITE_OK means the insert was committed. While we try to get SQLite to exhibit the bug, we'll check if we ever read back fewer rows than the writer thread says we wrote to the canary table. If we read back fewer rows than we know we successfully wrote, we've got data loss. Occasionally data loss will also bring a corrupted data file.
That Tailscale noticed the bug via the integrity check was to some degree luck since this bug does not necessarily involve data corruption, more often just data loss. And SQLite, even after the fix, does not guard against lost writes.
Here's our workload in full. About 100 lines of C. We'll see the bug happen within a few seconds.
#include"sqlite3.h"#include<pthread.h>#include<stdatomic.h>#include<stdio.h>#include<stdlib.h>staticlongscalar(sqlite3*db,constchar*buf){sqlite3_stmt*p=0;longv=-1;if(sqlite3_prepare_v2(db,buf,-1,&p,0)==SQLITE_OK){if(sqlite3_step(p)==SQLITE_ROW)v=(long)sqlite3_column_int64(p,0);sqlite3_finalize(p);}returnv;}staticsqlite3*burstDb;staticatomic_intburstStop;staticlongnCommitted;staticvoid*burst(void*arg){charbuf[64];while(!burstStop){sqlite3_snprintf(sizeof(buf),buf,"INSERT INTO canary VALUES(%ld)",nCommitted+1);if(sqlite3_exec(burstDb,buf,0,0,0)==SQLITE_OK)nCommitted++;}return0;}staticsqlite3*openDb(constchar*init){sqlite3*db=0;sqlite3_open("race.db",&db);sqlite3_busy_timeout(db,5000);sqlite3_exec(db,init,0,0,0);returndb;}intmain(void){setvbuf(stdout,NULL,_IONBF,0);// Large mmap_size for a large munmap. Large database itself so// we actually get a large mmap/munmap.sqlite3*db=openDb("PRAGMA journal_mode=wal; PRAGMA mmap_size=1073741824;""CREATE TABLE t1(a INTEGER PRIMARY KEY, b);""CREATE TABLE canary(a INTEGER PRIMARY KEY);""WITH s(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<65536)"" INSERT INTO t1 SELECT NULL, randomblob(3900) FROM s;""PRAGMA wal_checkpoint(TRUNCATE)");sqlite3*helper=openDb("");burstDb=openDb("");for(inti=0;i<atoi(getenv("ATTEMPTS")?:"200");i++){pthread_tt;// 1. mmap in big table, cache stale shmem values. Must run before 2.scalar(db,"SELECT count(*) FROM t1 WHERE b IS NOT NULL");// 2. Makes sure `isChanged` is true (lets us enter munmap path).sqlite3_exec(helper,"UPDATE t1 SET b=randomblob(3900) WHERE a<=20",0,0,0);// 3. Try to fully backfill the WAL. Must run on helper not db, so db values stay stale.for(inti=0;i<50;i++){intnLog,nCkpt;sqlite3_wal_checkpoint_v2(helper,"main",SQLITE_CHECKPOINT_PASSIVE,&nLog,&nCkpt);if(nCkpt>=nLog)break;}// 4. Commit during checkpoint in unrelated thread/connection.burstStop=0;pthread_create(&t,0,burst,0);sqlite3_exec(db,"PRAGMA wal_checkpoint",0,0,0);burstStop=1;pthread_join(t,0);if(scalar(helper,"SELECT count(*) FROM canary")<nCommitted)break;/* Lost a write. */}sqlite3_exec(helper,"PRAGMA wal_checkpoint(TRUNCATE)",0,0,0);/* No pages in WAL now. Still in the database or have we lost writes? */longrecovered=scalar(helper,"SELECT count(*) FROM canary");if(recovered<0){fprintf(stderr,"database unreadable: %s\n",sqlite3_errmsg(helper));return1;}printf("permanently lost: %ld transactions\n",nCommitted-recovered);printf("integrity_check: %s\n",scalar(helper,"SELECT integrity_check='ok' FROM pragma_integrity_check()")?"ok":"failed");returnnCommitted!=recovered;}
walrace.c
Grab
clang
and
unzip
and the buggy and fixed SQLite amalgamation.
The code above stops looping after the first lost transaction. If instead you had it loop for 30 seconds, you'd see many more lost transactions.
Separately, try out the version built against SQLite 3.53.0 (where the bug is fixed) and you'll stop seeing these lost writes and corrupted data files.
And while testing out variations on the workload I noticed one other thing. Build the
fixed
amalgamation with SQLite's debug mode on and run the workload again.
It kind of looks like even thread sanitizer caught this bug? Interestingly a line related to the assertion failure above also showed up in thread sanitizer. Thread sanitizer sounds useful!
We've got a cheap reproduction of the bug that involved no changes to source code, no shims, etc. I wanted to show you can get both data loss (not warned against) and data corruption (warned against if you run the integrity check).
I spent a while longer looking for more bugs in the area and did not find any. The bug still seems rare. But there's a fix and better to upgrade than not. And more general lost write protection might be good.
In this post I'd like to explain the "how"-s and "why"-s of moving
from forge-based static site hosting to a full on VPS.
This isn't really a tutorial, mostly because there are far better
texts out there how one would do these things, but I do link to many of
them and point out stuff I found confusing or surprising.
Also, if you're reading this post, you're reading it served by the
VPS, say hi!
Background
I've been blogging for almost eight years now and for those eight
years, I've always relied on some sort of free host for my content. This
seemed fine for a pretty long time, especially considering neither this
nor my
other site
is monetized at all.
However, recent-ish changes in my needs and financial situation finally
got me to break with the status quo and actually experiment a
little.
Originally, I relied on Github Pages, which was for a site like mine
almost perfect. It was free and required nearly zero setup, it built
almost immediately, it had impeccable uptime (something Github famously
started to struggle
with
), and I could super easily place a cheap domain in front of it
to make it a little more appealing than the factory-default
nemin32.github.io
address.
However, due to the, ehm,
recent trends
and emboldened by
the
rallying
cries
of the people who had enough, I too took the dive and moved my
presence
over to Codeberg.
This, of course, meant my two websites had to move too. Thankfully the
process wasn't particularly painful (the article linked above pretty
much gets you up to speed in 10-15 minutes) and so I quickly had
everything set up.
While I thought I was done, sadly I quickly realized that though the
two services were similar in design, their quality of service was very
different. Codeberg Pages really struggled at times. My pages are rarely
over a couple hundred kilobytes (most of which being a couple
AVIF-encoded pictures) and yet there were times where loading my sites
took 10-15 seconds, while the browser just hanged.
Before anyone gets the wrong idea, I'm not blaming Codeberg for this
in any shape or form. In fact I'm very grateful, that the option exists
in the first place. After all, they are a (relatively) small non-profit,
who have to serve not just my silly little webpages, but sites for far
more serious projects too. With this in mind, it's no wonder they can't
always afford the computing power for me.
However, as much as they have my sympathies, I was still stuck with
this problem and had to figure out some solution. And said solution was
joining something useful with something pleasant: Enter VPS-es.
Picking my provider
A VPS is a managed virtual machine, that one may rent from cloud
provider companies. The userbase is very wide, you can find people using
them from all areas of life, from students and hobbyists, to very
serious and large companies, who don't want to bother with on-prem
solutions.
These days, if one happens to fall into the former category and only
really needs a machine that has some minimal RAM and a reasonably fast
few (perhaps even one) core CPU, they have a plethora of providers to
pick from, who specialize in pushing down prices and lending you such
VMs for literal peanuts.
An example of a
site
that collects such cheap
deals.
For a striking example, just take a look at
LowEndBox's
$1 per month VPS list
, the name tells you what to expect. But if
you're willing to shop around for more obscure providers and can contort
your needs even further (for instance by not requiring an IPv4 address),
I've found a
company
,
who'll rent you a VM with 5Gb of storage and cca. 400MB of RAM for $4.5
per year, not month,
year.
I don't think you can go much lower
than that.
However, figuring that it's not like I'll be spending fortunes either
way, I decided to stick to a well-known and trusted option,
netcup
. While their cheapest option
is closer to 2€ a month, in return you get an unmetered, 100Mbps
connection (as long as you use it in good faith), 30Gb of storage space,
the option to make a snapshot of your VM for backups, and the assurance
that your money is going to a bunch who know their stuff.
Sounds all great… if only it wasn't so unexpectedly convoluted to do
business with them.
German bureaucracy
As explained earlier, my choice fell on the
VPS
Pico G11s
. At first the process was as one would expect:
I put the VPS in my cart, entered my address and personal data, then
clicked through the pages, until I noticed that there is a Netcup
newsletter and if you sign up for it, you get a voucher for 5€ off. I
figured "Hell yeah, that's almost three months" and signed up. The
voucher arrived almost instantly and I happily saw that after entering
it, the price of the VPS dropped from 24€ to around 19€. Everything
seemed fine, so I pressed on the big, friendly "Order" button…
And was thrown back with an error.
Apparently the VPS I picked was too cheap for the voucher to be
applicable for, so I begrudgingly removed it and proceeded with the full
price. At the end of the day, 24€ is the cost of two fancy lunches, so I
wasn't going to throw everything away just because I couldn't be even
more of a cheapskate.
Having corrected my deal and pressed "Order" again, I expected to be
redirected to a payment portal. Instead, I was simply informed that an
actual human being will verify that my order is legit and that I must
wait until that happens. Considering this was very late in the afternoon
(way past the usual European working hours), I sighed and resigned
myself to wait until the next day or however long it'd take.
In the meantime I received an email, which I found really
interesting. It was written in a very serious and legalese way, with
long paragraphs of dry text describing my rights and responsibilities,
and that, by placing an order, I now have two weeks to refuse entering
into the contract with Netcup, after which it becomes binding.
I found this both quite refreshing, a lot of companies hide their
nasty details deep into Terms of Uses or other such texts, but not here.
Sure, it makes the communication towards their customer less bombastic,
but I absolutely didn't mind that.
Then, to my biggest surprise, not ten minutes later my inbox pinged
me again: My inspection was successfully finished and I'm ready to log
into the portal. So I did just that, expecting to be finally able to
pay… only to be hit with a huge interface, where I was ordered to
declare my handling of user data according to GDPR.
Sadly, I didn't make a screenshot of this and I'm no longer able to
access it, but more or less I was just asked what sort of data I intend
to handle. Considering I was making a simple static site, I declared
that I'm not handling any personal data and that was that.
At this point, finally, I was able to add my credit card and pay for
my server. Five minutes and another two emails later, I received a link
to
yet another completely different page,
which (to my great
relief) did indeed allow me to access my machine.
Setting up my VPS
The VM came with Debian 13, which is a fine system otherwise, but
having had a recent interest in the various BSDs and stumbling on
httpd.rocks
through
Lobste.rs
, I decided to ditch it and try my
luck with OpenBSD 7.9 instead.
A list of images provided by Netcup. All the BSDs and some
nice distro choices… also Windows, I guess, if you're into that….
weirdo
.
To my delight netcup provides the newest OpenBSD ISO on their
interface. One simply just has to click on it and the VM automatically
gets the disk loaded and the boot order changed to boot from it.
Power-cycling the VM is a little slow (taking around an entire minute),
but I don't expect to do it much, so whatever.
Installing OpenBSD was a breeze. Hands down one of the easiest
processes when it comes to putting an OS on your machine. I disabled the
X windowing sets and the games set, but kept the rest. Apparently this
is a bit of a
faux
pas
, but worst case I'll just reinstall the machine, no biggie.
The default filesystem I went with.
/var
is woefully small.
The only true error I think I made during installation was accepting
the default partitioning scheme, which wastes around 6GB of storage on
/home
, which I won't be using anyway,
while
/var
(arguably my most important
folder, as it contains the code for my website and my logs) ended up
being a measly 2GB. It is a bridge that I'll eventually have to cross,
but for now it's fine.
Note from the future:
I did end up reinstalling
while troubleshooting an unrelated issue and made
/var
into a far bigger partition. Thankfully
with how fast and easy the installation of OpenBSD is, this was an
entirely painless process.
SSH config
While the Netcup interface does provide a remote desktop, it's not
super pleasant to use. Not only is it excruciatingly slow, it is also
very particular about when it accepts input (you need to click into the
screen and it seems to occasionally lose focus on its own), so I quickly
decided to look into setting up SSH instead.
I didn't have to look too far,
this
blogpost
was perfect for my needs. It describes both how one can
bring a system up to speed and also how to set up SSH in a way that's
secure, by disabling dubious ciphers.
I generated a brand new keypair for the VPS, because reusing the same
key for all your projects is a great way to be pwned. And after quickly
logging in with my password and issuing the right
ssh-copy-id
call, I disabled password login.
Afterwards I added the a new entry to my
~/.ssh/config
file, so I only need to issue
ssh vps
and it handles the rest. Much more
handy than needing to do things manually:
The first three lines aren't strictly necessary, but they make long
connections a lot more tolerable.
AddKeysToAgent yes
ServerAliveInterval 15
ServerAliveCountMax 3
Host vps
HostName [IPv4 of the VPS]
User [username]
IdentityFile ~/.ssh/id_vps
As a final touch, I symlinked
openrsync
to
rsync
. This was necessary because my
main Linux machine's
rsync
expects to find
an executable with the same name on the VPS when I try to copy my files
over. Other than this hack, it's all very clean with transparent SSH
handling. I can just do
rsync -av --delete source vps:destination
and it
handles the rest.
Upgrading OpenBSD to
8.0-beta
Note from the future:
This section here is
anachronistic, as it's placed before I discuss any of my server config,
but was actually written after I've finished and then completely rewrote
said config from scratch.
The reason for this is that, while I originally intended to go with
the often-recommended
relayd
to handle TLS
connections and attach HTTP headers to my responses (httpd.rocks has a
tutorial
for this too!), I
stumbled upon
this
Reddit post while solving an unrelated issue, which mentioned that
httpd
was soon to receive support for setting
HTTP headers itself (and it is already capable of handling TLS), making
relayd
pretty much overkill for my
purposes.
It is considered both good practice and a painless way to enhance the
performance of your site to set a couple of HTTP headers that inform the
browser about how it may cache your content and that it should leak as
little info as possible.
While OpenBSD 7.9's
httpd
provides no
built-in mechanism for this (and thus requires an additional proxy
service), the (currently beta) 8.0 release
does
in the form of
the
header set
directive.
To be able to use this, I had to upgrade my system from
7.9-release
to
8.0-beta
. While this may sound
difficult at first glance, it turned out to be little more than issuing
sysupgrade -s
, waiting until the system downloaded the
newest OS release snapshot, and then automagically installed it, without
me having to touch anything at all.
1
After that I only had two more super easy housekeeping tasks to
do:
I needed to issue
pkg_add -u
to upgrade all my
packages to their 8.0-compatible versions. This went through without
incident.
I also needed to call
sysmerge
to update any system
configuration files that may have changed between the two releases. In
my case this was only
sshd_config
, which introduced
post-quantum ciphers by default and changed
PermitRootLogin
to
prohibit-password
.
As neither of these affected my usage of
sshd
, I opted
to accept them without manual intervention.
With the foundations done, it was time to actually have the machine
do its intended job. Frankly, however, any sort of detailed guide I
could write here would be a pale and imprecise imitation of httpd.rocks,
so I'll keep things succinct and just comment on stuff I find
interesting to point out. If you find my journey at all inspiring, I
suggest checking the aforementioned guide out as well.
With this disclaimer out of the way, let's get into it:
Firewall
ext_if="vio0"
set limit states 100000 # Maximum state table entries
set timeout interval 30 # Interval between state purges
set optimization "normal" # General optimization for connection tracking
set skip on lo
# Antispoof
antispoof log quick for $ext_if
match in all scrub (no-df)
# Block all by default
block all
# Block table for abusive hosts
table <block_table> persist file "/etc/pflists/block_table"
table <ssh_naughty> persist file "/etc/pflists/ssh_naughty"
block in quick from <block_table>
block in quick from <ssh_naughty>
# Block bogus destination addresses
table <martians> {
0.0.0.0/8 127.0.0.0/8 169.254.0.0/16 172.16.0.0/12 192.0.0.0/24 \
192.0.2.0/24 224.0.0.0/3 192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 \
203.0.113.0/24 \
::/128 ::/96 ::1/128 ::ffff:0:0/96 100::/64 2001:10::/28 2001:2::/48 \
2001:db8::/32 3ffe::/16 fec0::/10 fc00::/7 }
block in quick on egress from any to <martians>
# Allow DNS and NTP
pass out on $ext_if proto {udp tcp} to any port 53
pass out on $ext_if proto udp to any port 123
# Allow SSH
pass in on $ext_if proto tcp from any to any port ssh synproxy state \
(max-src-conn 10, max-src-conn-rate 5/30, overload <ssh_naughty> flush global)
pass out on $ext_if proto tcp from any to any port ssh keep state
# Allow web server stuff
pass in on $ext_if proto tcp from any to any port {80 443} synproxy state \
(max-src-conn 100, max-src-conn-rate 30/5, overload <block_table> flush global)
pass out on $ext_if proto tcp from any to any port {80 443} keep state
The firewall does the following:
Antispoofing and packet scrubbing,
block all
to be better safe than sorry,
A blocklist to drop aggressive crawlers and one to SSH
brute-forcers,
And allowing some select services through for basic functionality:
DNS, NTPD, SSH, and finally our webserver, with the latter two services
also having anti-flood measures enabled to put malicious clients on the
blocklists.
While both blocklists forbid IPs on them from connecting, they have
one important difference:
I've set up my crontab so that it periodically calls
pfctl -t block_table -T expire 8400
. This command removes
clients that have been on the
block_table
list for a while,
because it is entirely possible that it was merely a bumbling user, who
accidentally reloaded the page one too many times with their cache
turned off or that it was a fake IP address, that someone used.
The other list,
ssh_naughty
, isn't ever cleared. I only
intend to allow myself to log in, so if a client is hammering the VPS'
SSH daemon, then I cannot give it the same presumption of innocence.
And to make sure the list doesn't disappear into smoke in case I
restart my system, I followed the advice of
this BSDHowTo
article
and added the following into
/etc/rc.shutdown
:
pfctl -t block_table -T show > /etc/pflists/block_table
pfctl -t ssh_naughty -T show > /etc/pflists/ssh_naughty
chmod 0600 /etc/pflists/block_table
chmod 0600 /etc/pflists/ssh_naughty
This ensures that if my system goes down normally (i.e. for an update
or miscellaneous restart), the OS will automatically dump the
block-lists into files, which are then reloaded on the next startup by
the
file
directive in
pf.conf
.
I'm considering also running this script as a cronjob in case of an
unexpected hard reset, but perhaps that's not something one has to
actively worry about when it comes to VPS-es.
TLS certificates
authority letsencrypt {
api url "https://acme-v02.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-privkey.pem"
}
domain nemin.hu {
alternative names { www.nemin.hu }
domain key "/etc/ssl/private/nemin.hu.key"
domain full chain certificate "/etc/ssl/nemin.hu.crt"
sign with letsencrypt
}
domain oddwords.hu {
alternative names { www.oddwords.hu }
domain key "/etc/ssl/private/oddwords.hu.key"
domain full chain certificate "/etc/ssl/oddwords.hu.crt"
sign with letsencrypt
}
I use OpenBSD's built-in
acme-client(1)
, which
interfaces with
Let's Encrypt
to
get TLS certificates for my two sites.
One thing I noticed, while still messing with my config is that
having two (or more) sites on one host makes troubleshooting certificate
issues quite tricky, because browsers will
helpfully
try to use
your other site's certificate instead, which will then cause a failure
as the browser realizes the name of the site you're trying to reach and
the name stored in the certificate are completely different.
Therefore, if you're facing issues while hosting multiple sites and
have the opportunity, I genuinely would suggest disabling all but the
problem server until you figure out the solution.
Web server
types { include "/usr/share/misc/mime.types" }
prefork 10
no banner
#
# Nemin.hu
#
server "nemin.hu" {
listen on * tls port 443
root "/htdocs/nemin.hu"
hsts {preload, subdomains}
gzip-static
log style combined
location "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
}
# Drop malicious requests
location "/.aws*" {block drop}
location "/.env*" {block drop}
location "/*.cgi*" {block drop}
location "/cgi-bin/*" {block drop}
location "/*.php*" {block drop}
location "/*wp-*" {block drop}
# Set headers
header set "Cache-Control" "public, max-age=86400" always
header set "X-Content-Type-Options" "nosniff" always
header set "Referrer-Policy" "no-referrer" always
header set "Permissions-Policy" "interest-cohort=()" always
header set "X-Frame-Options" "SAMEORIGIN" always
tls {
certificate "/etc/ssl/nemin.hu.crt"
key "/etc/ssl/private/nemin.hu.key"
}
}
server "nemin.hu" {
listen on * port 80
location "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
}
# Drop malicious requests
# ...
# Set headers
# ...
block return 301 "https://nemin.hu$REQUEST_URI"
}
server "www.nemin.hu" {
listen on * port 80
listen on * tls port 443
location "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
}
# Drop malicious requests
# ...
# Set headers
# ...
tls {
certificate "/etc/ssl/nemin.hu.crt"
key "/etc/ssl/private/nemin.hu.key"
}
block return 301 "https://nemin.hu$REQUEST_URI"
}
#
# Oddwords.hu
#
# More or less the same as above, just with the URL substituted...
The
httpd
config is fairly simple,
though it has a couple interesting notes I'll lay out below.
The second and third block simply handle redirecting
www.
and bare HTTP requests to
https://nemin.hu
. All blocks are set up to
handle ACME challenges, because the client will try both
nemin.hu
and
www.nemin.hu
.
The first block is the one that actually serves content. It's also
very straightforward, but there are two calls that I think are worth
specifically mentioning:
gzip-static
allows your server to
send gzip-encoded HTML instead of uncompressed data. Notably it will
not
compress files itself, so you have to do that
yourself, but the
blog
post
where I learned about this feature also explains how easy it is
to create these archives yourselves. (It's literally just calling
gzip -k
on them.)
And if that's still too much manual work,
this
other post describes a one-liner that allows you to recursively turn
everything (but images, which don't benefit from compression) into a
.gz
file:
Obviously you should adapt this to your needs. For instance, for me
public/
is
site/
and instead of using PNG
files, I use AVIF (which also don't really need zipping).
The lines starting with
location
match for some files crawlers like to frequent. Since this is a static
website, it's not like they'd hit anything in the first place, however,
by silently dropping their connections, we waste their time and
resources.
These filtering blocks are repeated everywhere, because I don't want
to pointlessly redirect requests that will be dropped anyway.
Finally, the lines starting with
header
allow us to set HTTP headers on our
responses. This is the reason why I ugpraded to OpenBSD 8.0 earlier, as
7.9 doesn't yet have this feature and would've required us to use
relayd
or another proxy.
I'm not sure if it's strictly necessary to include these headers on
calls that only redirect to the HTTPS URLs, but I figured it can't hurt
and you only really have to set it up once.
I kind of wish there was a more involved macro system for
httpd.conf
, that would allow shortening the block lists to
one definition that may be reused in all sections, but it's not that
bad.
Note from the future:
This kept me up at night, so I
went and
figured out a way
to make things
terser.
Be careful with MIMEs
Originally, when I first wrote my config, I didn't include the first
line. None of the tutorials I've read mentioned it and the page loaded
just fine, so I figured all is well. Except everything wasn't well,
because I noticed the pictures on the webpage loading incredibly slowly.
Up to 20-30 seconds, despite the fact that due to them being
highly-compressed AVIF images, they were rarely over 300KB in size.
A quick googling later I was able to pin down the problem: Without
informing the server about the various
MIME
types
, it absolutely struggled to send over anything.
Fixing this is simply adding the following to your config outside any
of the server blocks:
types { include "/usr/share/misc/mime.types" }
And here is where I'd like to repeat a very old and very true adage:
One should absolutely read the OpenBSD man pages. It is easy to skip
over them if one is used to Linux, because quite often the documentation
that comes with your packages might be sub-par or simply not detailed
enough to help you fix your issues without going on a wild goose chase
on the Internet.
However, with OpenBSD, this is different. The manual is super easy to
read and understand and even obscure things are often mentioned,
including the line seen above:
Types
Configure the supported media types. httpd(8) will set the Content-Type
of the response header based on the file extension listed in the types
section. If not specified, httpd(8) will use built-in media types for
text/css, text/html, text/plain, image/gif, image/png, image/jpeg,
image/svg+xml, and application/javascript. The types section must
include one or more lines of the following syntax, enclosed in curly
braces:
type/subtype name [name ...]
Set the media type and subtype to the specified extension name.
One or more names can be specified per line. Each line may end
with an optional semicolon. Later lines overwrite earlier lines.
include file
Include types definitions from an external file, for example
/usr/share/misc/mime.types.
As you can see, the man page clearly states that AVIF files aren't
included by default, so no wonder the server choked on them.
And with this line added, everything loads almost instantly.
Findings; or, Bots Love Your
Obscure Content!
While I was toying around with loading my site and checking the
access logs, I noticed that, beyond my own IP, there were a lot of other
clients connecting too. At first I was very happy to see this.
Considering I've never had analytics before, I had zero idea how many
people actually click on my pages, so seeing the buzzing activity felt
very validating…
That is until I actually read the user agents and realized about 40%
of these were AI scrapers, another 40% crawler bots, and only 20% were
clients I couldn't decisively categorize as either.
An excerpt from my access logs. All of these were credential
scanner/stealer bots.
I must admit this made me a little sad, but then I really shouldn't
have expected anything different. What I found really amusing is that a
lot of these crawlers were trying to crack the site by scanning for
files such as
.aws
,
.env
, and
wp-*
,
which they won't find, because it's a static site.
If you remember in the earlier section I added a bunch of lines
starting with
location
in my
httpd.conf
file.
This is why. When the crawlers try to read files matching these paths,
their requests will be silently dropped.
I also added a simple
robots.txt
, that
disallows all the bigger AI crawlers from the site, but they don't seem
to respect it. For now I've let things be, but perhaps eventually I'll
add their user agents into the blocklist of my config.
Note from the future:
I'm adding this comment three
days later. My SSH blocklist already has 77 clients on it. The internet
is harsh.
Conclusion
I call my main machine
luna
,
so calling a machine that's both very far away and tiny
ceres
felt very appropriate.
My job title may technically be DevOps engineer, but I'm really more
of an "average" backend programmer and even when I do touch infra, it's
a lot different to tweak tiny parts of an already well-established
stack, with several colleagues to help you and several backups to reach
for if something went wrong. So I went into this project with some
slight apprehension and with a feeling that any mistakes would leave me
to poke around in the dark.
However, reality turned out to be far less menacing. Migrating to a
VPS ended up much quicker and easier than I assumed and I also found it
an excellent learning experience, with plenty of further opportunities
to branch out to when I feel like it.
So if hosting your own site sounds exciting for you, nowadays it's
easier than ever to try and it won't cost you much.
Thanks for reading!
From what I could find, the jury seems to be
still
somewhat
out
on whether it's "safe" to use snapshots on a server.
Proponents mention that the OS developers generally use the newest
available version and are forbidden from breaking it and also that by
using snapshots most of the obvious issues should be long ironed
out.
Critics cite the need to update the system weekly or even more
frequently and the fact that, though rare, system breakages may still
happen a couple times a year.
Considering my two sites aren't mission critical in any shape or form
and that the VPS contains nothing that couldn't be restored from a local
backup, I decided to go with it. If you're more risk averse than me,
maybe wait until 8.0 drops, which should happen about 3 months after the
writing of this article (November of 2026).
↩︎
Scientists have made the world's first quantum battery prototype and, unlike conventional batteries, it charges faster the larger it gets. Could these bizarre devices one day power quantum computing – or even your phone?
Everyone knows that the larger the battery, the longer it takes to charge – that's why it can take several hours to charge a laptop and typically all night to charge an electric vehicle.
That's the world we're familiar with, anyway. But in the world of the very small, different rules apply. Quantum mechanics (the science of matter at atomic and subatomic scales) "sort of flips [that] on its head", says James Quach, a quantum science researcher at Csiro, Australia's national science agency.
Quach is working to create a quantum battery that defies common sense by charging faster the bigger it gets. Just as some expect
quantum computers
to one day revolutionise computing, Quach argues that quantum batteries could be similarly disruptive.
In March 2026, his team made an important breakthrough when they
unveiled what they say is
the world's first working quantum battery prototype.
The field is still in its infancy, and quantum technology is inherently tricksy. But some scientists say these batteries could one day power quantum devices, while the strongest advocates insist they could even be used to charge everyday devices like phones.
Others, though, remain strongly sceptical about their real-world viability.
Subverting energy limits
Conventional batteries rely on chemical reactions that send 10 billion billion electrons or more rushing through the device they're powering. It sounds impressive, but some now see the technology as outdated.
"Despite major technological improvements, modern batteries still rely on electrochemical processes first explored over two centuries ago," says Dario Ferraro, associate professor of physics at the University of Genova, Italy.
This has led some researchers to look towards quantum batteries – batteries that are powered by quantum effects, rather than chemical reactions.
The key point is that quantum batteries are not about storing a great amount of energy, but about delivering it faster and with greater control – Dario Ferraro
The world of the very small is an overwhelmingly odd one. And quantum mechanics is no stranger to mind-bending concepts, from "entangled" particles that influence each other at
great distances
to
time that flows backwards
.
"The key point is that quantum batteries are not about storing a great amount of energy, but about delivering it faster and with greater control," says Ferraro.
A new prototype
Quach has tested one way of harnessing these quantum effects to power a battery.
He uses an optical microcavity, an experimental set-up where two tiny mirrors are placed 100nm apart (a width about a thousand times thinner than a human hair). He fills the tiny space between the mirrors with organic dye molecules, then beams in a laser.
Csiro
Using this method, the light and the molecules become strongly coupled, forming hybrid light-matter states, which enhances the system's ability to absorb and store energy – an effect known as superabsorption.
It's superabsorption that's responsible for the battery's most surprising property. In classical physics, molecules are little individualists – each acting on its own and absorbing energy at a rate independent of the molecules around it. But with quantum effects, they're a little more collectivist: they "act in unison and synergise", says Quach. "So that the rate at which you can absorb energy increases with the number of molecules there are."
It means that the more molecules there are (i.e. the bigger the battery) the faster it charges. Quach's prototype took femtoseconds (quadrillionths of a second) to charge, and stored the energy for nanoseconds, about six orders of magnitudes longer.
Quach's optical microcavity method isn't the only way to make a quantum battery. Another approach, for example,
uses superconductive materials
– already widely used in quantum computing.
One big advantage of Quach's design, though, is that it works at room temperature. Superconductive designs only work at cryogenic temperatures starting below -150C (-238F). "This is fine for quantum computers, but not so useful to power your mobile phone," says Quach.
"If the goal is proving the quantum charging advantage as real physics… the optical microcavity route is the strongest bet," says Mauro Paternostro, a quantum physicist at Queen's University Belfast.
But in the long term, Paternostro believes that the superconductive design might have the edge for practical uses, because it is easier to extract energy from. "A microcavity gives you a beautiful ensemble demonstration, but poor control over getting the energy back out in a useful, directed form."
A delicate state
Quach's latest experiment represents a first tentative step towards a quantum battery that could one day be substituted for conventional ones. However, at present, the prototype battery can only hold a very small amount of energy – a few billion electron volts – for a matter of nanoseconds. To power conventional devices, it would need to store far more energy for far longer.
Csiro
Scientists take great pains to isolate quantum batteries from the outside world, as interactions can cause energy to leak from the battery (Credit: Csiro)
Quach says he has in fact already achieved this with a new design he's built, and is now working on a paper to publish the results. It uses "a hybrid structure", he says, involving quantum components to allow super-fast charging with classical layers added in to store the energy for longer.
He also plans to combine many microscopic quantum batteries together to increase their total capacity. "If we do those two things, then we're on our way to be able to power a conventional device," he says.
Still, other scientists remain sceptical, given quantum effects are notoriously fragile and are easily disrupted by observation or interference. "Interactions with the environment can quickly degrade [quantum] effects, limiting both performance and scalability," says Ferraro, which could offset part of the expected benefit of quantum batteries. Addressing this is "crucial to moving quantum batteries from theory to real-world applications", he adds.
A quantum world
Others, though, are more sceptical: a
recent paper
, for example, named quantum computers alongside fusion energy and brain-computer interfaces as being among the technologies perpetually described as "five years away".
Quach, however, argues that he is likely to achieve the powering of quantum devices with quantum batteries in his lab within the next few years. If possible, this could reduce the amount of energy quantum computers consume, as well as making them faster and less error-prone, allowing them to be scaled up faster, he claims.
Quach is less certain about using them to power conventional devices. It should one day be viable, he says, noting the fact the battery is charged with a laser means it could potentially "charge electric vehicles on-the-go". This would avoid the need for drivers to stop to recharge altogether.
Ferraro, however, is sceptical that quantum batteries could ever become the norm outside of quantum applications. "In my view… quantum batteries are unlikely to replace conventional batteries in everyday applications such as mobile phones or electric vehicles," he says. "Their natural domain is the quantum scale."
The big unsolved problem right now, says Paternostro, is making use of the quantum charging advantage while also withdrawing the energy in a controlled, usable state. Whoever achieves this, he says, "will have made the real breakthrough".
For more insights, sign up to our
Tech Decoded
newsletter, where Lily Jamali and Thomas Germain break down the biggest stories of the tech world, and help you live a better digital life.
Sign up for free here.
For more science, technology, environment and health stories from the BBC, follow us on
Facebook
and
Instagram
.
'What you see is what you pay' - why some US restaurants are banning tips
Caroline Kraetzer
Caroline Kraetzer no longer gets tips but her salary is double the norm
Wine waiter Caroline Kraetzer earns $40 (£30) an hour, double what most service staff in San Francisco are paid but then it costs a lot to eat at her restaurant.
At a set price of $140 (£100) per person, La Cigale is one of a small number of US restaurants charging higher prices so it can pay high salaries - and it doesn't allow tips.
It tells customers: "What you see is what you pay. We do not accept tips, your kind words and return visits will suffice."
Kraetzer says it is good to no longer be "reliant on the generosity of strangers to pay the bills".
While waiting staff at other restaurants can make a lot of money from tips, she says "you're often there two hours before service, and again when you're closing after the guests have left, so you are making minimum wage during that time".
Fairer for staff?
On the other side of the US, Rachel Miller, chef and owner of Nightshade Noodle Bar in the town Lynn, Massachusetts, moved to a tip-free model five years ago when they reopened after the Covid-19 pandemic.
Her motivation was to make it fairer for the kitchen staff.
"The people breaking their backs and minds in the kitchen - often the least visible and the least celebrated - were taking home a fraction of what the front staff made on tips for the same hours," she says.
Miller says she found it "deeply unsettling" to see higher tips going to white male staff and lower tips to everyone else.
"Tipping lets guests, consciously or not, pay people differently based on gender, race, or sexuality and I was not willing to let that decide my team's income."
To pay the staff higher wages, Miller also increased prices at the French-Vietnamese restaurant. Its tasting menus now start from $102 (£75) for seven courses before 18:00, and $126 (£92) for nine courses.
"Our prices are higher than a comparable restaurant's because they carry the full cost of paying people properly," says Miller. "That is the trade, and I stand behind it."
Alyssa Blumstein
Rachel Miller says that banning tips is fairer for her kitchen staff
How have customers reacted?
Yet not every restaurant that has switched to a tipless model has made a success of it, as sometimes customers don't appreciate the higher menu prices.
Talulla in Cambridge, Massachusetts, dropped tips in 2020 so it could pay staff more equitably, only to then switch back in September of last year.
"We tried to keep our non-tipping model simply by raising our menu prices 23%, but we were only able to sustain this through the winter months," says co-owner Danielle Ayer.
"Operating a non-tipped restaurant is more expensive overall," adds Ayer.
This is because tips don't count as part of a restaurant's revenues, but higher menu prices do. So if a venue increases prices to pay staff more, its revenues go up accordingly, and it must pay more sales tax.
William Michael Lynn, professor of food and beverage management at Cornell University and author of The Psychology of Tipping, says the problem of going tip-free is that customers struggle to get their heads around the maths.
"Higher menu prices make dining out seem more expensive because people do not adequately take into account that they are no longer tipping," he says. "It leads to lower demand."
Amanda Cohen
Amanda Cohen says customers are pleased when they realise they don't have to tip
In New York, vegetarian restaurant Dirt Candy was one of the very first to ban tipping back in 2015. "I wanted to make it more equal for everybody," says chef and owner Amanda Cohen, who now pays her staff about $30 an hour.
She says that many customers "are pleasantly surprised when they realise they don't have to tip 20% on top".
Cassidy Van der Kamp is a filmmaker whose YouTube documentary Tipless was inspired by her own experience of working in a restaurant in Oakland, California which went tip-free.
While some other servers left, Van der Kamp, who was originally paid about $10 an hour plus tips, decided to stay and earned $21 per hour after the change.
"I had stability for the first time as I knew what I was earning… and I didn't need to look at a low tip and think what did I do wrong?"
'Tipping fatigue'
While Van der Kamp liked the move, Lynn says that a huge challenge of moving to a gratuity-free system is that it can be difficult to attract and retain waiting staff who like getting tips.
However, given the growth of what has been called "tipping fatigue" – people being increasingly annoyed at having to pay high tips – will more restaurants stop the practice?
"Despite tip-fatigue, I do not think tipping is going to be eliminated on widescale anytime soon because the economic disadvantages of eliminating tipping outweigh the advantages," says Lynn.
Back at Nightshade Noodle Bar, Miller doesn't regret her decision. "The clearest measure is that staff stay.
"Turnover in this industry is brutal, and we have people who have been here since we made the change. It has proven to be highly valued by my guests and team."
Porffor
goes from pre-alpha to alpha on August 11th!
There will be a launch and meetup in-person in San Francisco at
PlanetScale
's HQ! Expect a talk, some live demos, and more.
RSVP here!
Here are the headlines:
Self-hosted
. Porffor releases are now Porffor compiled with itself. Not only is this a major compiler milestone generally, it is also a great dogfooding opportunity. I found and fixed at least ten bugs getting it on par. It also lets us ship
<5MB
release binaries for the full compiler!
Complete rewrite
. The core of Porffor has been entirely rewritten. Instead of JS -> Wasm and optionally Wasm -> C, we now do JS -> our own IR -> C, always. Wasm is now left to the C compiler instead. This was done primarily because our own Wasm output was
slower
than compiling our C to Wasm and it was limiting Porffor's acceleration. C output is now ~5x smaller/more efficient! This improves performance plus decreases memory usage and binary size. Compile times are also over twice as fast as before.
Garbage collection
. Garbage collection is here, and
on by default, always
! Since my last post on the beginnings of a GC, we actually now have a mature (not intentionally small/simple) GC. This also stops out of memory errors which were breaking a lot of things previously.
Conformance
. Porffor now fully supports closures and async/await, plus a lot of minor conformance fixes.
HTTP server
. Porffor can now host a HTTP server, efficiently. Comparing to Node/Bun/Deno, an
unrealistic
hello world server uses >10x less memory and beats all three on performance for throughput and latency.
There are some other features too which I am not sure will make the release yet (
did someone say concurrency?
), so stay tuned for the release!
Screen viewing time is associated with children’s academic and cognitive outcomes, but longitudinal studies are scarce, hindering identification of the most sensitive age periods. We assessed the associations of single and cumulative average screen viewing time with academic performance and working memory.
Methods
In the Growing Up in Singapore Towards healthy Outcomes birth cohort, parents reported their child’s screen viewing time at ages 1, 1.5, 2, 3, 6 and 8 years. At ages 9 and 10.5, trained psychologists assessed academic performance (Wechsler Individual Achievement Test-Third Edition) and working memory (Letter-Number Sequencing task; Wechsler Intelligence Scale for Children-Fifth Edition). Associations of single and cumulative average screen viewing time with psychological outcomes were examined by multivariable linear regression (
N
= 502 children).
Results
Mean (standard deviation) screen viewing time ranged from 2.1 (2.0) hours/day at age 1 year, to 3.0 (2.2) hours/day at 8 years. In unadjusted models, higher screen viewing time from age 1 to 8 years was consistently associated with poorer academic performance at age 9 years and working memory at 10.5 years. After adjustment, effect sizes were reduced, but higher screen viewing time at ages 1 year [
β
= – 1.47, 95% confidence interval (CI): – 2.37 to – 0.57 standard points per additional hour per day], 1.5 years (
β
= – 0.95, 95% CI: – 1.85 to – 0.06), and 6 years (
β
= – 0.88, 95% CI: – 1.55 to – 0.21) had persisting associations with poorer academic performance at age 9 years. Greater screen viewing time at ages 1 year (
β
= – 1.12, 95% CI: – 2.07 to – 0.17) and 6 years (
β
= – 1.01, 95% CI: – 1.71 to – 0.31) was associated with poorer working memory at age 10.5 years. Cumulative average exposure models showed that screen viewing time over childhood was consistently associated with poorer academic performance but not working memory.
Conclusion
In this longitudinal study, cumulative average screen viewing time was associated with lower academic performance but not working memory, with the strongest effect sizes seen for single screen viewing time occurring in early infancy.
Price excludes VAT (USA)
Tax calculation will be finalised during checkout.
Instant access to the full article PDF.
Similar content being viewed by others
Data availability
This cohort study requires ethics approval for each specific research question before data may be shared. The data used in this cohort are described in
https://gustodatavault.sg/
. Deidentified individual participant data (including data dictionaries) will be made available, in addition to study protocols, the statistical analysis plan, and the informed consent form. The data will be made available upon publication to researchers who provide a methodologically sound proposal for use in achieving the goals of the approved proposal. Proposals should be submitted to
https://www.gusto.sg/request-to-collaborate/
.
Tremblay MS, LeBlanc AG, Kho ME, Saunders TJ, Larouche R, Colley RC, et al. Systematic review of sedentary behaviour and health indicators in school-aged children and youth. Int J Behav Nutr Phys Act. 2011;8:98.
https://doi.org/10.1186/1479-5868-8-98
.
LeBlanc AG, Spence JC, Carson V, Connor Gorber S, Dillman C, Janssen I, et al. Systematic review of sedentary behaviour and health indicators in the early years (aged 0-4 years). Appl Physiol Nutr Metab. 2012;37:753–72.
https://doi.org/10.1139/h2012-063
.
Kostyrka-Allchorne K, Cooper NR, Simpson A. The relationship between television exposure and children’s cognition and behaviour: a systematic review. Dev Rev. 2017;44:19–58.
https://doi.org/10.1016/j.dr.2016.12.002
.
Poitras VJ, Gray CE, Janssen X, Aubert S, Carson V, Faulkner G, et al. Systematic review of the relationships between sedentary behaviour and health indicators in the early years (0–4years). BMC Public Health. 2017;17:868.
https://doi.org/10.1186/s12889-017-4849-8
.
Stiglic N, Viner RM. Effects of screentime on the health and well-being of children and adolescents: a systematic review of reviews. BMJ Open. 2019;9:e023191.
https://doi.org/10.1136/bmjopen-2018-023191
.
Ferguson CJ, Kaye LK, Branley-Bell D, Markey P, Ivory JD, Klisanin D, et al. Like this meta-analysis: screen media and mental health. Prof Psychol Res Pract. 2022;53:205–14.
https://doi.org/10.1037/pro0000426
.
Yang S, Saïd M, Peyre H, Ramus F, Taine M, Law EC, et al. Associations of screen use with cognitive development in early childhood: the ELFE birth cohort. J Child Psychol Psychiatry. 2024;65:680–93.
https://doi.org/10.1111/jcpp.13887
.
Sticca F, Brauchli V, Lannen P. Screen on = development off? A systematic scoping review and a developmental psychology perspective on the effects of screen time on early childhood development. Front Dev Psychol. 2025;2:1439040.
https://doi.org/10.3389/fdpys.2024.1439040
.
Madigan S, McArthur BA, Anhorn C, Eirich R, Christakis DA. Associations between screen use and child language skills: a systematic review and meta-analysis. JAMA Pediatr. 2020;174:665–75.
https://doi.org/10.1001/jamapediatrics.2020.0327
.
Duch H, Fisher EM, Ensari I, Font M, Harrington A, Taromino C, et al. Association of screen time use and language development in Hispanic toddlers: a cross-sectional and longitudinal study. Clin Pediatr. 2013;52:857–65.
https://doi.org/10.1177/0009922813492881
.
Martinot P, Bernard JY, Peyre H, De Agostini M, Forhan A, Charles MA, et al. Exposure to screens and children’s language development in the EDEN mother-child cohort. Sci Rep. 2021;11:11863.
https://doi.org/10.1038/s41598-021-90867-3
.
Blankson AN, O’Brien M, Leerkes EM, Calkins SD, Marcovitch S. Do hours spent viewing television at ages 3 and 4 predict vocabulary and executive functioning at age 5? Merrill Palmer Q. 2015;61:264–89.
https://doi.org/10.13110/merrpalmquar1982.61.2.0264
.
Yang X, Chen Z, Wang Z, Zhu L. The relations between television exposure and executive function in Chinese preschoolers: the moderated role of parental mediation behaviors. Front Psychol. 2017;8:1833.
https://doi.org/10.3389/fpsyg.2017.01833
.
Duncan GJ, Dowsett CJ, Claessens A, Magnuson K, Huston AC, Klebanov P, et al. School readiness and later achievement. Dev Psychol. 2007;43:1428–46.
https://doi.org/10.1037/0012-1649.43.6.1428
.
Bücker S, Nuraydin S, Simonsmeier BA, Schneider M, Luhmann M. Subjective well-being and academic achievement: a meta-analysis. J Res Pers. 2018;74:83–94.
https://doi.org/10.1016/j.jrp.2018.02.007
.
Roisman GI, Masten AS, Coatsworth JD, Tellegen A. Salient and emerging developmental tasks in the transition to adulthood. Child Dev. 2004;75:123–33.
https://doi.org/10.1111/j.1467-8624.2004.00658.x
.
Lê-Scherban F, Diez Roux AV, Li Y, Morgenstern H. Does academic achievement during childhood and adolescence benefit later health? Ann Epidemiol. 2014;24:344–55.
https://doi.org/10.1016/j.annepidem.2014.02.008
.
French MT, Homer JF, Popovici I, Robins PK. What you do in high school matters: high school GPA, educational attainment, and labor market earnings as a young adult. East Econ J. 2015;41:370–86.
https://doi.org/10.1057/eej.2014.22
.
Adelantado-Renau M, Moliner-Urdiales D, Cavero-Redondo I, Beltran-Valls MR, Martínez-Vizcaíno V, Álvarez-Bueno C. Association between screen media use and academic performance among children and adolescents: a systematic review and meta-analysis. JAMA Pediatr. 2019;173:1058–67.
https://doi.org/10.1001/jamapediatrics.2019.3176
.
Poulain T, Peschel T, Vogel M, Jurkutat A, Kiess W. Cross-sectional and longitudinal associations of screen time and physical activity with school performance at different types of secondary school. BMC Public Health. 2018;18:563.
https://doi.org/10.1186/s12889-018-5489-3
.
Howie EK, Joosten J, Harris CJ, Straker LM. Associations between meeting sleep, physical activity or screen time behaviour guidelines and academic performance in Australian school children. BMC Public Health. 2020;20:520.
https://doi.org/10.1186/s12889-020-08620-w
.
Neophytou E, Manwell LA, Eikelboom R. Effects of excessive screen time on neurodevelopment, learning, memory, mental health, and neurodegeneration: a scoping review. Int J Ment Health Addict. 2021;19:724–44.
https://doi.org/10.1007/s11469-019-00182-2
.
Morita N, Nakajima T, Okita K, Ishihara T, Sagawa M, Yamatsu K. Relationships among fitness, obesity, screen time and academic achievement in Japanese adolescents. Physiol Behav. 2016;163:161–6.
https://doi.org/10.1016/j.physbeh.2016.04.055
.
Paulich KN, Ross JM, Lessem JM, Hewitt JK. Screen time and early adolescent mental health, academic, and social outcomes in 9- and 10- year old children: utilizing the Adolescent Brain Cognitive Development ℠ (ABCD) Study. PLoS ONE. 2021;16:e0256591.
https://doi.org/10.1371/journal.pone.0256591
.
Lien A, Sampasa-Kanyinga H, Colman I, Hamilton HA, Chaput JP. Adherence to 24-hour movement guidelines and academic performance in adolescents. Public Health. 2020;183:8–14.
https://doi.org/10.1016/j.puhe.2020.03.011
.
Ozmert E, Toyran M, Yurdakök K. Behavioral correlates of television viewing in primary school children evaluated by the Child Behavior Checklist. Arch Pediatr Adolesc Med. 2002;156:910–4.
https://doi.org/10.1001/archpedi.156.9.910
.
Skoric MM, Teo LL, Neo RL. Children and video games: addiction, engagement, and scholastic achievement. Cyberpsychol Behav. 2009;12:567–72.
https://doi.org/10.1089/cpb.2009.0079
.
Drummond A, Sauer JD. Video-games do not negatively impact adolescent academic performance in science, mathematics or reading. PLoS ONE. 2014;9:e87943.
https://doi.org/10.1371/journal.pone.0087943
.
Regondola E, Barbado L. Media habits and academic performance of elementary pupils of the Camarines Norte State College Laboratory School. IJIR. 2017;3:216–24.
Bowers AJ, Berland M. Does recreational computer use affect high school achievement? Educ Technol Res Dev. 2013;61:51–69.
https://doi.org/10.7916/D89P3BPZ
.
Ponti M. Screen time and preschool children: promoting health and development in a digital world. Paediatr Child Health. 2023;28:184–202.
https://doi.org/10.1093/pch/pxac125
.
Marciano L, Camerini AL. Recommendations on screen time, sleep and physical activity: associations with academic achievement in Swiss adolescents. Public Health. 2021;198:211–7.
https://doi.org/10.1016/j.puhe.2021.07.027
.
Soh SE, Tint MT, Gluckman PD, Godfrey KM, Rifkin-Graboi A, Chan YH, et al. Cohort profile: Growing Up in Singapore Towards Healthy Outcomes (GUSTO) birth cohort study. Int J Epidemiol. 2014;43:1401–9.
https://doi.org/10.1093/ije/dyt125
.
Aishworiya R, Cai S, Chen HY, Phua DY, Broekman BFP, Daniel LM, et al. Television viewing and child cognition in a longitudinal birth cohort in Singapore: the role of maternal factors. BMC Pediatr. 2019;19:286.
https://doi.org/10.1186/s12887-019-1651-z
.
Dumont R, Willis JO, Veizel K, Zibulsky J. Wechsler individual achievement test–third edition. In: Encyclopedia of special education: a reference for the education of children, adolescents, and adults with disabilities and other exceptional individuals. 2013.
https://doi.org/10.1002/9781118660584.ese2521
.
Accessed 18 Sep 2025.
Padmapriya N, Bernard JY, Tan SYX, Chu AHY, Goh CMJL, Tan SL, et al. The prospective associations of 24-hour movement behaviors and domain-specific activities with executive function and academic achievement among school-aged children in Singapore. Front Public Health. 2024;12:1412634.
https://doi.org/10.3389/fpubh.2024.1412634
.
Watkins MW, Dombrowski SC, Canivez GL. Reliability and factorial validity of the Canadian Wechsler intelligence scale for children–fifth edition. Int J Sch Educ Psychol. 2018;6:252–65.
https://doi.org/10.1080/21683603.2017.1342580
.
de Groot S, Veldman K, Amick BC, Bültmann U. Single and cumulative exposure to psychosocial work conditions and mental health among young adults. Eur J Public Health. 2023;33:257–63.
https://doi.org/10.1093/eurpub/ckad015
.
Brew BK, Lundholm C, Viktorin A, Lichtenstein P, Larsson H, Almqvist C. Longitudinal depression or anxiety in mothers and offspring asthma: a Swedish population-based study. Int J Epidemiol. 2018;47:166–74.
https://doi.org/10.1093/ije/dyx208
.
Liu S, Jones RN, Glymour MM. Implications of lifecourse epidemiology for research on determinants of adult disease. Public Health Rev. 2010;32:489–511.
https://doi.org/10.1007/BF03391613
.
Shah AD, Bartlett JW, Carpenter J, Nicholas O, Hemingway H. Comparison of random forest and parametric imputation models for imputing missing data using MICE: a CALIBER study. Am J Epidemiol. 2014;179:764–74.
https://doi.org/10.1093/aje/kwt312
.
Zimmerman FJ, Christakis DA, Meltzoff AN. Associations between media viewing and language development in children under age 2 years. J Pediatr. 2007;151:364–8.
https://doi.org/10.1016/j.jpeds.2007.04.071
.
Johnson JG, Cohen P, Kasen S, Brook JS. Extensive television viewing and the development of attention and learning difficulties during adolescence. Arch Pediatr Adolesc Med. 2007;161:480–6.
https://doi.org/10.1001/archpedi.161.5.480
.
Hancox RJ, Milne BJ, Poulton R. Association of television viewing during childhood with poor educational achievement. Arch Pediatr Adolesc Med. 2005;159:614–8.
https://doi.org/10.1001/archpedi.159.7.614
.
Carson V, Hunter S, Kuzik N, Gray CE, Poitras VJ, Chaput JP, et al. Systematic review of sedentary behaviour and health indicators in school-aged children and youth: an update. Appl Physiol Nutr Metab. 2016;41:S240–65.
https://doi.org/10.1139/apnm-2015-0630
.
Keith TZ, Reimers TM, Fehrmann PG, Pottebaum SM, Aubey LW. Parental involvement, homework, and TV time: direct and indirect effects on high school achievement. J Educ Psychol. 1986;78:373–80.
https://doi.org/10.1037/0022-0663.78.5.373
.
Christakis DA, Zimmerman FJ, DiGiuseppe DL, McCarty CA. Early television exposure and subsequent attentional problems in children. Pediatrics. 2004;113:708–13.
https://doi.org/10.1542/peds.113.4.708
.
Law EC, Han MX, Lai Z, Lim S, Ong ZY, Ng V, et al. Associations between infant screen use, electroencephalography markers, and cognitive outcomes. JAMA Pediatr. 2023;177:311.
https://doi.org/10.1001/jamapediatrics.2022.5674
.
Koolstra CM, van der Voort THA, van der Kamp LJT. Television’s impact on children’s reading comprehension and decoding skills: a 3-year panel study. Read Res Q. 1997;32(2):128–52.
https://doi.org/10.1598/rrq.32.2.1
.
Bernard JY, Poncet L, Saïd M, Yang S, Dufourg M-N, Gassama M, et al. Temps d’écran de 2 à 5 ans et demi chez les enfants de la cohorte nationale Elfe. Bull Épidémiol Hebd. 2023;6:98–105.
We thank the contribution of the Growing Up in Singapore Toward Healthy Outcomes (GUSTO) study participants. We acknowledge the GUSTO study group and the research staff involved in data acquisition. GUSTO study group includes Airu Chia, Andrea Cremaschi, Anna Magdalena Fogel, Anne Eng Neo Goh, Anne Rifkin-Graboi, Anqi Qiu, Arijit Biswas, Bee Wah Lee, Birit Froukje Philipp Broekman, Candida Vaz, Chai Kiat Chng, Chan Shi Yu, Choon Looi Bong, Daniel Yam Thiam Goh, Dawn Xin Ping Koh, Dennis Wang, Desiree Y. Phua, E Shyong Tai, Elaine Kwang Hsia Tham, Elaine Phaik Ling Quah, Elizabeth Huiwen Tham, Evelyn Chung Ning Law, Evelyn Keet Wai Lau, Evelyn Xiu Ling Loo, Fabian Kok Peng Yap, Falk Müller-Riemenschneider, Franzolini Beatrice, George Seow Heong Yeo, Gerard Chung Siew Keong, Hannah Ee Juen Yong, Helen Yu Chen, Hong Pan, Huang Jian, Huang Pei, Hugo P S van Bever, Hui Min Tan, Iliana Magiati, Inez Bik Yun Wong, Ives Lim Yubin, Ivy Yee-Man Lau, Jacqueline Chin Siew Roong, Jadegoud Yaligar, Jerry Kok Yen Chan, Jia Xu, Johan Gunnar Eriksson, Jonathan Tze Liang Choo, Jonathan Y. Bernard, Jonathan Yinhao Huang, Joshua J. Gooley, Jun Shi Lai, Karen Mei Ling Tan, Keith M. Godfrey, Keri McCrickerd, Kok Hian Tan, Kothandaraman Narasimhan, Krishnamoorthy Naiduvaje, Kuan Jin Lee, Li Chen, Lieng Hsi Ling, Lin Lin Su, Ling-Wei Chen, Lourdes Mary Daniel, Lynette Pei-Chi Shek, Maria De Iorio, Marielle V. Fortier, Mary Foong-Fong Chong, Mary Wlodek, Mei Chien Chua, Melvin Khee-Shing Leow, Michael J. Meaney, Michelle Zhi Ling Kee, Min Gong, Mya Thway Tint, Navin Michael, Neerja Karnani, Ngee Lek, Noor Hidayatul Aini Bte Suaini, Oon Hoe Teoh, Peter D. Gluckman, Priti Mishra, Queenie Ling Jun Li, Sambasivam Sendhil Velan, Seang Mei Saw, See Ling Loy, Seng Bin Ang, Shang Chee Chong, Shiao-Yng Chan, Shirong Cai, Shu-E Soh, Stephen Chin-Ying Hsu, Suresh Anand Sadananthan, Swee Chye Quek, Tan Ai Peng, Varsha Gupta, Victor Samuel Rajadurai, Wee Meng Han, Wei Wei Pang, Yap Seng Chong, Yin Bun Cheung, Yiong Huak Chan, Yung Seng Lee, Zhang Han. The listed members received no compensation for being named.
Funding
The GUSTO Study is funded by the Singapore National Research Foundation under its Translational and Clinical Research Flagship Programme and administered by the Singapore Ministry of Health’s National Medical Research Council (Singapore NMRC/TCR/004-NUS/2008 and NMRC/TCR/012-NUHS/2014). Additional funding is provided by the Institute for Human Potential and Development, Agency for Science Technology and Research. Author JYB was supported by a grant from the Agence Nationale de la Recherche (ANR) (iSCAN project, ANR-20-CE36-0001). Author SY was supported by a grant from the Agence Nationale de la Recherche (ANR) (iSCAN project, ANR-20-CE36-0001) and by mobility grants from Université Paris Cité and National University of Singapore. Author KMG is supported by the UK Medical Research Council (MC_UU_12011/4), the National Institute for Health and Care Research [NIHR Senior Investigator (NF-SI-0515-10042) and NIHR Southampton Biomedical Research Centre (NIHR203319)] and Alzheimer’s Research UK (ARUK-PG2022A-008). Funders were not involved in design and conduct of the study; collection, management, analysis, and interpretation of the data; preparation, review, or approval of the manuscript; and decision to submit the manuscript for publication.
Author information
Authors and Affiliations
Centre for Research in Epidemiology and StatisticS (CRESS), Université Paris Cité and Université Sorbonne Paris Nord, Inserm, INRAE, F-75004, Paris, France
Shuai Yang & Jonathan Y. Bernard
Department of Obstetrics & Gynaecology, Yong Loo Lin School of Medicine, National University of Singapore, National University Health System, Singapore, Singapore
Natarajan Padmapriya, Chong Yap Seng & Johan G. Eriksson
Saw Swee Hock School of Public Health, National University of Singapore, Singapore, Singapore
Institute for Human Potential and Development (IHPD), Agency for Science, Technology and Research (A*STAR), 30 Medical Drive, Brenner Centre for Molecular Medicine, Singapore, 117609, Singapore
Lynette P. Shek, Peter D. Gluckman, Johan G. Eriksson & Evelyn C. Law
Department of Paediatrics, Yong Loo Lin School of Medicine, National University of Singapore, Singapore, Singapore
Lynette P. Shek & Evelyn C. Law
Khoo Teck Puat-National University Children’s Medical Institute, National University Health System, Singapore, Singapore
Lynette P. Shek & Evelyn C. Law
Medical Research Council Lifecourse Epidemiology Centre, University of Southampton, Southampton, UK
Keith M. Godfrey
NIHR Southampton Biomedical Research Centre, University of Southampton and University Hospital Southampton NHS Foundation Trust, Southampton, UK
Keith M. Godfrey
Department of General Practice and Primary Health Care, University of Helsinki and Helsinki University Hospital, and Folkhälsan Research Center, Helsinki, Finland
Johan G. Eriksson
Digital Health Center, Berlin Institute of Health, Charité-Universitätsmedizin Berlin, Berlin, Germany
Falk Müller-Riemenschneider
Duke-National University of Singapore Medical School, Singapore, Singapore
Saw Seang-Mei
Liggins Institute, University of Auckland, Auckland, New Zealand
Peter D. Gluckman
Equipe OPPaLE - CRESS, Faculté de médecine - site Villemin, 10 Av de Verdun, 75010, Paris, France
KMG has received reimbursement for speaking at conferences sponsored by companies selling nutritional products, and is part of an academic consortium that has received research funding from Abbott Nutrition, Nestec, BenevolentAI Bio Ltd. and Danone, outside the submitted work. The other authors declare that they have no competing interests.
Ethical approval
The study received ethics approval from the National Healthcare Group Domain Specific Review Board (D/2009/021, B/2014/00406 and D/2010/210) and the SingHealth Centralised Institutional Review Board (CIRB 2018/2767 and CIRB 2018/3138). Informed consent to participate in the study have been obtained from participants or their parent or legal guardian in the case of children under 16.
Additional information
Publisher's Note
Springer Nature remains neutral with regard to jurisdictional claims in published maps and institutional affiliations.
Supplementary Information
Rights and permissions
Springer Nature or its licensor (e.g. a society or other partner) holds exclusive rights to this article under a publishing agreement with the author(s) or other rightsholder(s); author self-archiving of the accepted manuscript version of this article is solely governed by the terms of such publishing agreement and applicable law.
Yang, S., Padmapriya, N., Saw, SM.
et al.
Screen viewing time from age 1 to 8 years and subsequent academic performance and working memory.
World J Pediatr
22
, 522–535 (2026). https://doi.org/10.1007/s12519-026-01046-1
A Pocket Full of Slagford – a retro-futurist take on Thatcher-era northern England
Guardian
www.theguardian.com
2026-08-25 05:00:54
Developer Patrick Grant was born in Australia and lives in New Zealand, but a childhood of British TV inspired him to set a comedy game in a bleak vision of the north Something is amiss in the dingy town of Slagford, and curious scamp Pip Bunting is the only one who can find out what. So quit your m...
S
omething is amiss in the dingy town of Slagford, and curious scamp Pip Bunting is the only one who can find out what. So quit your mithering, it’s time to discover just how grim it truly is up north.
A Pocket Full of Slagford is an upcoming retro-styled 3D puzzle adventure game set in a surreal alternative-reality near-future northern England that never escaped the clutches of Thatcherism. The story follows the misadventures of a young local lad from the eponymous Slagford after he takes ownership of a mysterious relic that lets him wreak havoc on reality.
It’s the passion project of Australia-born, New Zealand-based artist Patrick Grant, who formed solo-developer studio Slumps to create a game inspired by the point-and-click classics from the late 80s and early 90s, such as
LucasArts’ catalogue
and
Grim Fandango
.
Reminiscent of point-and-click adventures of the past … A Pocket Full of Slagford.
Photograph: Slumps
“They’re just a great format for narrative-heavy games, like an interactive story,” says Grant. “I like designing puzzles as well, so I always wanted to make a point-and-click. But from playing a lot, I know how samey they can be. From the start I was thinking about what I could do differently.”
The result of Grant’s prototyping is what he describes as a “jigsaw sticker book kind of thing.” As you navigate the nasty industrial hellscape, you collect imprints of the game’s scenery. If, along the way, you spot a place where these imprints align, you can paste them into the world to solve puzzles. Grant is also committed to evoking the oft-forgotten CD-Rom era of the late ’90s, complete with looping CG-rendered backgrounds and janky 3D models with far too many sharp edges.
Yet he’s keen to emphasise that his main focus is the narrative. While the trailer and
Steam store page
feature a fair few Yorkshire-isms, A Pocket Full of Slagford’s story and dialogue take inspiration from various aspects of northern English culture, despite Grant admitting to having never actually spent any real time in the area.
“In the colonies we get a lot of BBC English programming,” he explains. “So when I was growing up there was so much British telly that I’d be watching. There’s this BBC miniseries from the 80s called
Boys from the Blackstuff
, about this group of scousers getting up to mischief, set in the Thatcher years, just trying to make ends meet. It’s incredibly well written – this mix of sad and funny – against that whole big economic collapse. I got interested in that, reading about the Thatcher years.”
That interest is what inspired A Pocket Full of Slagford’s bleak setting. While Grant says he wasn’t trying to make a political point when he went into the project, he’s not shying away from the issues of the time: “Because of that working-class setting, you end up naturally touching on points like the wealth disparity, which I show in the game, and the class conflict. Specifically, from watching stuff like Boys from the Blackstuff, or Billy Elliot, I was interested in the infighting that goes on within these classes.”
Despite touching on these themes, Grant stresses that he’s going for a comedic, surrealist angle. As he puts it: “I was like, what if I set it in the future and, instead of coal, they’re mining shit out of the ground?” He may not be trying to make a political statement about Thatcherism, but some might say he has hit on an apt analogy.
Abstract: Many modern programming languages include some form of asynchronous programming. In particular, a growing number now have what we call straight-line asynchrony: attempts to provide asynchronous functions that look similar to synchronous functions, thereby enabling asynchrony without introd...
This link caused an XML parsing exception.
If this link has an extension('.20677'), maybe
we should exclude it. Here's the link: https://arxiv.org/pdf/2608.20677.
Show HN: I built self-hosted deployment automation tool for Windows and IIS
One licence per Server instance. Deployment targets, projects and users are unlimited on every tier, including Community.
Community is the same build as Professional. The difference is eligibility and support, not capability.
Perpetual licences do not expire.
There is no licence server to contact and no kill switch, so an installation keeps running regardless of maintenance status or of what happens to the vendor. Maintenance is optional and covers new versions only.
Community
Free
under
$1M / €900k
annual revenue
The complete product, free for commercial use by smaller organisations
Unlimited deployment targets
Who it's for
Free for commercial use, in production, by any organisation with annual revenue under $1M / €900k - counted with any affiliates. Personal, educational, non-production and non-commercial open-source use is free at any size.
It was on August 24, 1995 that Windows 95 was released, amidst much anticipation. It was the most widely anticipated Windows release of all time, and the runner up really isn’t close. The idea of people lining up for blocks for a Microsoft product sounds like a bit of a joke today, and the more time goes on, the bigger of a joke it becomes. But I’m serious that in 1995 it happened.
Why Windows 95 was a big deal
The Windows 95 upgrade cost $79, but customers often found getting it to run well required some upgrades to go with it.
Windows 95 promised to be the biggest leap Windows users had experienced to date.
Windows 3.1
and
Windows 3.0
before it were both runaway successes, but they had limits. They could multitask, but it wasn’t modern pre-emptive multitasking. Instead, the applications cooperated rather than the operating system being able to hand out resources. This meant a poorly behaved program could do a lot more to gum up the works in 1994 than it can do today, since the operating system just had to trust all of the programs to cooperate fairly.
Windows 3.x also didn’t scale all that well. The optimal processor for Windows 3.1 is a
486
. Brand doesn’t matter much. And the optimal speed is right around 100 MHz. Somewhere around that point, it hits the wall. Switching from a 100 MHz 486 to a 100 MHz Pentium doesn’t yield much of a speed increase for most operations. I was selling computers at retail in 1994 and 1995, and people were plenty curious about Pentium-based PCs. But when they saw a 486 next to a Pentium and both were running Windows 3.1, most people I talked to saved their money. They just couldn’t find enough things the Pentium did faster.
Anticipation of Windows 95
Just about everyone was looking forward to Windows 95. Consumers were eager for the new benefits, even if they didn’t quite understand what they would be. Computer hardware makers were looking forward to the boost in sales. Retailers were looking forward to the boost in sales, of both software and hardware.
I started at Best Buy in late May 1994, 15 months before Windows 95’s release. I got questions about Windows 95 pretty much from day 1. And the corporate office was training us on how to suggest upsells pretty much from the day I started too. This was a bit of a shift. Best Buy did
not
want its employees talking about the Pentium CPU before it was released, because that might cause consumers to hold off on a purchase.
But they did want them talking about Windows 95, and just emphasize that a computer they bought that day would run Windows 95 when it came out the next year. And that would set the trap. They’d come back and buy the upgrade for $80 the next summer and find that it ran like crap. Then they’d come back for a new video card, more RAM, and maybe a bigger hard drive, turning that $80 purchase into $500 worth of purchases.
Windows 95’s hardware requirements
The box stated that it required a
386DX
or better processor, 4 MB of more of RAM, and approximately 50 MB of disk space. Nothing stopped you from installing it on a 386SX. I know because I tried it, mostly out of morbid curiosity. It took forever to install. Booting took forever too. And once it managed to boot, it took forever to do anything.
But if you had a system that met the minimum stated requirements, the experience was still pretty terrible.
The minimum most of us recommended at the time for acceptable performance was a 486 faster than 33 MHz, 8 MB of RAM, and 100 MB of disk space. And some will take issue with that today, because the experience on a machine like that still wasn’t very good. You had to draw the line somewhere, and then, as now, different people had different definitions of words like “minimum” and “acceptable.”
You really needed a
Pentium-class
machine to be happy with Win95, and I think Win95 did a lot to goose Pentium sales for
Intel
. If you could afford a 100 or 120 MHz Pentium with 16 or 32 MB of RAM and at least a 540 megabyte hard drive, you were much happier with it.
What was Windows 95?
Then, as now, Windows 95 had no shortage of misunderstanding. It still had DOS at its core, although there were people who said otherwise, both then and now. The shell was all 32-bit code, and more of the critical functions moved into the 32-bit space. But it wasn’t a fully 32-bit operating system like
Windows XP
would later be.
Another cause for misunderstanding was feature erosion. Windows 95 was late, and some features didn’t make it into the final build. Microsoft revisited some of those elements and released them in
Windows 98
or
ME
. When you look at some of the beta builds for Windows 95, they resemble Windows 98 more than they resemble the initial August 24, 1995 build of Win95.
The cashflow bonanza
I can only speculate how much money Microsoft made by selling $79 upgrades to people who quickly found their old machines couldn’t run it happily, so they came back to buy a new machine with Win95 pre-installed. Retailers were hoping for that too. Or at the very least, they expected to sell a lot of RAM and
video card
and hard drive upgrades. Because the trade-off with Windows 95 was that while it took better advantage of high-end hardware than previous Windows versions did, it also required higher end hardware to run well.
Some percentage of people bought the $79 upgrade, found the computer they had wasn’t up to the task of running it well, and came back to the store to talk about options. I attended training sessions designed to help employees navigate those discussions. Those of us who passed all the tests got special badges proclaiming us Windows 95 experts.
Software and new hardware came with a
Designed for Windows 95
logo to help customers select items that would be compatible, as opposed to leftover Windows 3.1 products that may or may not work as well with the new OS.
Why Windows 95 succeeded
Windows 95 succeeded because it was more intuitive to use than
Windows 3.1
had been, and it was a lot more stable. It wasn’t truly a full 32-bit operating system, because there was still
MS-DOS
at the core if you dug deep enough. But it was a big enough improvement not many people cared. It also helped that Microsoft had a 32-bit version of Microsoft Office available on the same day. Office 95 was more stable running on Windows 95 than the others guys’ 16-bit office suites based around
Lotus 1-2-3
or
Wordperfect
.
Dealing with marginal systems: My specialty
My first employer didn’t have the money to replace all its 486s with Pentiums right away. So tweaking Win95 to run adequately on
486DX2
machines with 16 MB of RAM and sub-500 MB hard drives quickly became my specialty. I couldn’t make it great, but I could at least get those machines running well enough that everyone could do their job on them.
Over time I built a large collection of tricks to squeeze more performance out of Win95, and some of them actually worked. When former coworkers who’d moved on to other opportunities started asking me for copies of my tips compilation, I started to wonder if I had something. O’Reilly, better known as a publisher of Unix books, agreed with me that I did, so I expanded my tricks with detailed explanations and turned it into a book.
Initially I was rather lukewarm about Win95 because it did very little that
OS/2
didn’t do better, but Win95 was much more approachable. Microsoft’s marketing was never as good as Apple’s, but there’s a much shorter distance between
Apple
and Microsoft than there is between Microsoft and
IBM
. It was around the time of Win95 that we stopped talking about
IBM-compatible PCs
and just started calling them Windows PCs or, merely PCs.
It’s a stretch to call Windows 95 great. It was far better than Windows 3.1 was, but so were a lot of things. It did make Windows a lot more approachable and easier to use. Love it or hate it, Windows 95 did leave a
formidable legacy
even before it gave way to
Windows 98
.
David Farquhar is a computer security professional, entrepreneur, and author. He has written professionally about computers since 1991, so he was writing about retro computers when they were still new. He has been working in IT professionally since 1994 and has specialized in vulnerability management since 2013. He holds Security+ and CISSP certifications. Today he blogs five times a week, mostly about retro computers and retro gaming covering the time period from 1975 to 2000.
I recently came across some of
Escher
’s impressive and inspiring artworks.
Maybe the
impossible staircase
is one of his most famous drawings,
but he also worked a lot on
tessellations
.
A
tessellation
is the covering of a surface with repeated shapes. A very familiar type of tessellation is the checkerboard, where the plane is covered with squares of alternating colors.
What makes Escher’s tessellations so fascinating for me is that he managed to cover the plane using birds, fishes, horses or other animals, making an otherwise quite abstract drawing into something alive.
Interestingly, making some form of tessellation is not hard, although it certainly takes an artistic mind to actually find meaningful shapes that fit together.
So let’s reconstruct
one of Escher’s works
using Haskell!
Let us start with a very basic tessellation: the checkerboard.
How can we modify the squares such that the result still fit?
It should be obvious that the left side of the black square must fit the right side of the white square, and the same holds for the top and the bottom sides of the squares.
So if we replace the left and right sides with the same curve, and the top and bottom sides also with the same curve, the resulting tile should fit nicely with its neighbors and cover the whole plane.
To see this, look at the example below. I marked the left/right sides of one tile in green and the top/bottom sides in red.
As you can see, as long as these lines do not cross, we will obtain a tessellation.
Moreover, we do not need to use the same four corners as the square.
As long as the red curve starts where the green curve ends, we can close the boundary and obtain good tile for our tessellation.
So let us translate this idea into Haskell code.
We use records to specify our tessellations,
as they are convenient for storing multiple values of multiples types in one variable.
To make our lives easier, we enable the
OverloadedRecordDot
extension,
which lets us write
x.field
instead of
field x
.
To generate PNG images, we use the
Rasterific
backend,
which is available after installing the Haskell library
diagrams-rasterific
.
{-# LANGUAGE OverloadedRecordDot #-}moduleMain(main)where-- Hide `intersection` function to avoid a name clash later.importDiagrams.Preludehiding(intersection)importqualifiedDiagrams.Backend.RasterificasRaster
There are several data types for curves in
diagrams
.
We will be using
Trail
s, since they are the most convenient type to work with and do exactly what we need.
One nice thing about Haskell’s type system is that it allows us to be very precise.
The sides of our square will be replaced by curves, but not just any curve.
We want open curves, that is, those with loose endpoints.
We express this with the type
Trail' Line V2 a
, where
V2
specifies that we are using two dimensions and
a
is the numeric type we want to use (we will effectively be using
Double
, but there is no reason to force this now).
To create the boundary of one tile, we only need to join the trails together at the endpoints.
The library already gives us convenient functions for this, so our
makeBoundary
function is very straightforward.
-- | The boundary of one tile.makeBoundary::ParallelogramTileDouble->Trail'LoopV2DoublemakeBoundaryst=closeLine$mconcat[st.firstSide,st.secondSide,(reverseLinest.firstSide),(reverseLinest.secondSide)]
Observe the difference between the types
Trail' Line V2 Double
and
Trail' Loop V2 Double
.
The type-system ensures that the output of
makeBoundary
is a
closed
curve, and so we can fill it with color later.
To construct our tile, we will take some measurements from the original image.
This is easy using Inkscape by placing
circles
on top of the points we want to sample.
Just make sure to shift the image so that the origin of the tile is indeed at
(0,0)
.
I marked the corners of the parallelogram using yellow dots,
the “first” side of the bird with green and the “second” side with red dots.
The yellow dot at the bottom-left corner is aligned with the
(0,0)
coordinate in Inkscape.
We define the curves using
cubic splines
.
Cubic splines are very convenient in this context, since they are smooth and go through all specified points.
The only disadvantage is that, if we do not provide enough samples, the curve may get completely out of control and acquire a very bizarre shape.
This can be easily fixed simply by adding more samples.
After taking enough samples, we can define a bird tile as follows.
The function
cubicSpline
takes two arguments:
a Boolean value, telling whether the curve should be closed or not, and a list of points.
In case you are wondering why the picture is upside-down:
in Inkscape, the origin
(0,0)
is on the top-left and the y-axis grows downwards,
whereas in
diagrams
(and in any geometry book I know) the y-axis grows upwards.
We can fix this by scaling the y-axis by
-1
.
Now we want to cover the entire plane with these birds.
Achieving this takes a couple of steps and some calculations,
but everything can be made quite generic such that,
if you desire to make your own tessellations, you will not have to think about these auxiliary functions.
For starters, we do not want to draw tiles that will not show up in our image,
so we define a function to test if a tile is visible or not.
We test intersections using
bounding boxes
.
A bounding box is an axis-aligned rectangle which completely contains the desired object (in our case, our tile).
If the bounding box of the tile does not intersect the bounding box of the final view,
we know the object is not visible, although the converse is not necessarily true.
Since checking if bounding boxes intersect is very simple and skipping the few extra tiles we might needlessly draw is just not worth the effort,
we settle for this approximate solution.
To use bounding boxes, we need to include the
Diagrams.BoundingBox
module
and hide the
intersection
function from the prelude to avoid name clashes.
importDiagrams.BoundingBox
Thankfully, the
diagrams
library contains functions for all the calculations we need regarding bounding boxes, so we only need to translate the corners of the bounding box of our tiles.
isTileInsideView::(BoundingBoxV2Double)->(P2Double)->(BoundingBoxV2Double)->BoolisTileInsideViewtileBoxtilePositionviewBox=-- A tile is visible if the intersection -- of its bounding box with the view box-- is not empty.not$isEmptyBox$intersectiontileBox'viewBoxwhereJust(corner1,corner2)=getCornerstileBox-- Shift the bounding box of the tile to the correct location.-- unP is used to convert a point to a vector.tileBox'=fromCorners(tilePosition.+^unPcorner1)(tilePosition.+^unPcorner2)
Next, we need to generate the points on which we will place our tiles.
For this, we use a simple
breadth-first search
algorithm
to explore all visible cells.
Starting at one of the corners of the view bounding box, we look at
the
neighboring
cells above, below, to the left and to the right of this corner,
and then use
isTileInsideView
above to check if a neighbor is visible or not.
If it is not visible, we do not output it and also do not explore its neighborhood.
Otherwise, if the cell is visible, we output it and also add it to the list of cells
whose neighborhood needs to be explored.
To ensure that we do not output cells twice and also that the algorithm terminates,
we keep a
Set
of explored cells and only output cells which were not explored yet.
For this, we need the
Set
data structure, which we import by adding the following
to the top of our file.
importqualifiedData.SetasS
If you are familiar with breadth-first-search algorithms,
the
pointsInsideBox
function below should be very easy to understand.
-- All points corresponding to tiles which-- are visible from the view box.pointsInsideBox::BoundingBoxV2Double->BoundingBoxV2Double-- One dimension of the tile.->V2Double-- Other dimension of the tile.->V2Double->[((Int,Int),P2Double)]pointsInsideBoxtileBoxviewBoxv1v2=-- Start with (0,0)((0,0),p0):pointsInsideBox'(S.singleton(0,0))[((0,0),p0)]where-- One corner of the view bounding box.p0=casegetCornersviewBoxofJust(c0,_)->c0Nothing->error"View bounding box is not defined. Aborting."-- Base case: no more points to explore.pointsInsideBox'explored[]=[]-- Recursive case: There is one point whose-- neighborhood was not explored yet.pointsInsideBox'explored(((r,c),q):active')=-- Output all new pointsnewPoints++-- Explore the remaining points.-- The set `explored` contains tiles which-- were already generated.-- This ensures that we do not generate any tile twice.pointsInsideBox'(explored`S.union`(S.fromList$mapfstnewPoints))(newPoints++active')wherenewPoints=filter(\((r',c'),q')->isTileInsideViewtileBoxq'viewBox&&(not((r',c')`S.member`explored)))[((r+1,c),q.+^v1)-- Right,((r-1,c),q.-^v1)-- Left,((r,c-1),q.-^v2)-- Bottom,((r,c+1),q.+^v2)-- Top]
To generate the visible cells,
all we have to do now is compute the bounding boxes
and the
v1
and
v2
vectors above telling
where the neighboring tiles should lie.
Thankfully,
diagrams
provides a
boundingBox
function
which computes the bounding box of any diagram,
so the
gridPoints
function below only needs
to tie all the functions together.
gridPoints::ParallelogramTileDouble->Double->Double->[((Int,Int),P2Double)]gridPointstilewidthheight=pointsInsideBoxtileBoxviewBoxv1v2where-- Bounding box of a tile positioned at (0,0).tileBox=(boundingBox$makeBoundarytile)-- Bounding box of the view.viewBox=(fromCorners(p2(0,0))(p2(width,height)))-- The two vectors corresponding to the sides of the tile.v1=(tile.firstSide`atParam`domainUppertile.firstSide).-.(tile.firstSide`atParam`domainLowertile.firstSide)v2=(tile.secondSide`atParam`domainUppertile.secondSide).-.(tile.secondSide`atParam`domainLowertile.secondSide)
If we try to generate the grid now, we will have a rather boring image,
as all tiles have the same color and so we are just filling the entire screen with one color.
To make the picture more lively, I will choose green and yellow as colors for the tiles.
The birds also have eyes, feathers, a beak and other details.
We will define
birdDecorations
later. For now, we just use a dummy function.
birdDecorations__=mempty
We will color the tiles based on their row and column along the grid.
Obtaining a checkerboard pattern from this is very easy.
colors=[green,yellow]bird(row,column)=mconcat[birdDecorationsprimarysecondary,makeBoundarybirdTile#stroke#fcprimary#lcprimary-- Add a very thin line to avoid artifacts when rendering.#lw0.0001]whereindex=((row+column)`mod`2)primary=colors!!indexsecondary=colors!!(1-index)
We can now preview how the tiles fit together.
diaviewWviewH=-- Position the tiles.(position$map(\(cell,v)->(v,birdcell))(gridPointsbirdTileviewWviewH))-- Only show tiles inside the view box.#clipTo(pathFromTrail$wrapTrail$closeLine$lineFromVertices$[p2(0,0),p2(0,viewH),p2(viewW,viewH),p2(viewW,0)])-- Invert y-axis because we used Inkscape coordinates.#scaleY(-1)main::IO()main=doletwidth=35::Doubleheight=35resolution=8Raster.renderRasterific"tessellation.png"(dims$r2(width*resolution,height*resolution))(diawidthheight)
To render the image, we only need to call
runhaskell Tessellation.hs
, and this will generate the PNG image.
Without the details, however, the birds are not recognizable as such.
Using a program such as Inkscape as a helper, we can obtain the coordinates we need to add the details to the birds.
One important point to observe here is the usage of
local
for the thickness of the lines.
In diagrams, using a
local measurement
means that the actual thickness will be determined relative to the final dimensions used.
If we just use
0.1
instead, the lines will become thicker or thinner depending on the dimensions of our image, which, in this case,
is undesirable.
wingDetail=local0.1birdEyeprimarysecondary=mconcat[circle0.15#fcprimary#lw0,circle0.3#fcsecondary#lcprimary#lw(local0.1)]birdDecorationsprimarysecondary=position-- Eye[(p2(5.503,-1.323),birdEyeprimarysecondary)-- Front wing, lower part,(p2(1.544,-1.099),cubicSplineFalse[p2(1.544,-1.099),p2(0.179,-1.323),p2(-0.65,-2.389)]#strokeTrail#lwwingDetail#lcsecondary)-- Front wing, feathers,(p2(-2.8,-6.75),arcBetween(p2(0,0))(p2(2.5,0.2))(-0.15)#lwwingDetail#lcsecondary),(p2(-1.75,-5.55),arcBetween(p2(0,0))(p2(1.5,-0.1))(-0.15)#lwwingDetail#lcsecondary),(p2(-1.05,-4.3),arcBetween(p2(0,0))(p2(1.2,-0.25))(-0.12)#lwwingDetail#lcsecondary),(p2(-0.6,-3.2),arcBetween(p2(0,0))(p2(0.9,-0.3))(-0.08)#lwwingDetail#lcsecondary),(p2(-0.1,-2.1),arcBetween(p2(0,0))(p2(0.8,-0.6))(-0.05)#lwwingDetail#lcsecondary),(p2(0.75,-1.3),arcBetween(p2(0,0))(p2(0.5,-0.7))(-0.04)#lwwingDetail#lcsecondary)-- Between front and back wings,(p2(2.439,-1.486),cubicSplineFalse[p2(2.439,-1.486),p2(1.807,-2.115),p2(1.666,-4.457),p2(1.48,-5.4)]#strokeTrail#lwwingDetail#lcsecondary)-- Feathers on back wing,(p2(1.85,-8.2),arcBetween(p2(0,0))(p2(1.2,0.8))(-0.15)#lwwingDetail#lcsecondary),(p2(2.0,-7.0),arcBetween(p2(0,0))(p2(1,0.75))(-0.15)#lwwingDetail#lcsecondary),(p2(1.8,-5.9),arcBetween(p2(0,0))(p2(0.8,0.6))(-0.1)#lwwingDetail#lcsecondary),(p2(1.62,-4.9),arcBetween(p2(0,0))(p2(0.8,0.55))(-0.05)#lwwingDetail#lcsecondary),(p2(1.65,-3.8),arcBetween(p2(0,0))(p2(0.6,0.4))(-0.05)#lwwingDetail#lcsecondary)-- Beak,(p2(6.204,-0.763),cubicSplineFalse[p2(6.204,-0.763),p2(5.882,-0.458),p2(5.36,-0.508),p2(5.36,0.45)]#strokeTrail#lwwingDetail#lcsecondary)]
We now obtain the following.
I like the pattern so much, I also want to have a wallpaper version of it.
For this, I only need to add this to the end of
main
.
If you need higher resolution, just change the
1920
and
1080
values there.
Conclusion
Tessellations are quite amusing drawings.
While the code here might be a bit long and it might take some time to do all the calculations,
it is quite generic (for parallelogram-based tessellations). If you want to play around and make your own tessellations,
you only need to define a value of type
ParallelogramTessellation Double
and replace the
bird
function with your own.
To make things more ergonomic, I turned the code above into a
Diagrams.TwoD.Tessellation
module in this
git repository
.
While drawing complex curves like the tile decorations above programmatically is certainly more cumbersome than using
a GUI application such as Inkscape, using a library like diagrams allows us to separate the artistic part from the technical,
computational task of properly assembling the tiles and positioning them.
Moreover, while writing the code above, I felt it was rather straightforward to organize the functions in a modular way.
Extracting them into a module was not time consuming.
Even if I had any idea how to achieve this using TikZ (which I don’t), the result would not be something I would try to put in its own package.
I will continue my journey of exploring the
diagrams
library.
Hopefully, my next project will not just be something amusing, but also something I can use in my work.
Tell us: do you think AI has made Google search better or worse?
Guardian
www.theguardian.com
2026-08-25 02:00:50
As people grow used to AI chatbots, we’d like to hear your views about Google’s search engine Google has put artificial intelligence at the front and center of its search bar. The most-visited site on the internet still shows the same list of links to users, but they have to scroll past a summarized...
Google has put artificial intelligence at the front and center of its search bar. The most-visited site on the internet still shows the same list of links to users, but they have to scroll past a summarized response from an AI chatbot, a feature
Google
calls AI Overviews. The change to what was once the gateway to the rest of the internet has been profound, and the browsing habits of billions of people are shifting.
“AI is driving the most significant upgrade of the Google Search experience ever,” Liz Reid, Google’s vice-president of search,
wrote last August
. In May, the company said
more AI is coming
.
As people grow accustomed to AI chatbots, they’re spending more time with Google’s and therefore more time on Google.com. Studies, media outlets and website owners alike are finding that people navigate less to sites beyond Google if an AI Overview can give them a good enough answer, even if the bot cites the sites that feed it. Clicks, also known as traffic, are often the most significant way a website earns money from advertising. Large US media companies
are suing
Google, alleging that AI summaries have redirected and reduced traffic to their sites, cutting into their revenue.
Google said it had not seen a decline in aggregate traffic and that such accusations are based on “flawed methodologies”. Reid, the company’s vice-president of search, wrote last year: “Total organic click volume from Google Search to websites has been relatively stable year-over-year.”
We want to hear from you. Do you think Google’s infusion of AI has made its search engine better or worse?
Your responses, which can be anonymous, are secure as the form is encrypted and only the Guardian has access to your contributions. We will only use the data you provide us for the purpose of the feature and we will delete any personal data when we no longer require it for this purpose. For alternative ways to get in touch securely please see our
If you’re having trouble using the form click
here
. Read terms of service
here
and privacy policy
here
.
‘Never seen this level of objection’: Scotland pushes back against datacentre boom
Guardian
www.theguardian.com
2026-08-25 01:00:49
Holyrood ‘inching towards moratorium’ amid concerns over massive proposed developments in Auchtertool and beyond In a village 21 miles north of Edinburgh, a real estate consultancy plans to build a datacentre larger than the village itself – 35 metres high, with an area larger than 100 football pitc...
In a village 21 miles north of Edinburgh, a real estate consultancy plans to build a datacentre larger than the village itself – 35 metres high, with an area larger than 100 football pitches.
Billed as the second-biggest datacentre in the world, the development in Auchertool, Fife, has attracted 1,600 objections.
“The public pressure is huge,” said David Torrance, a member of the Scottish parliament representing the village. “I’ve never seen this level of objection to a local plan, and I have been in politics for 25 years.”
Similar concerns
are being echoed across Scotland, next to gargantuan planned developments in towns such as
Airdrie
and Larbert. In a matter of weeks, as the Scottish parliament comes back into session, the growing opposition could pose a challenge to Britain’s AI strategy.
“The Scottish government is inching
towards a moratorium
,” said Kat Jones, director of the Edinburgh-based charity Action to Protect Rural Scotland. “MSPs return to parliament next week, after a summer in their constituencies where they have been hearing the concerns of local people about proposed hyperscale datacentres. They will be expecting action.”
For months, UK officials have been encouraging would-be datacentre developers to consider Scotland. In April, Fintan Slye, the chief executive of the UK’s National Energy System Operator (Neso), told a London audience to
look north
: “If in the audience you have a big datacentre and you want to go to Scotland, please come talk to me, we will help you,” he said.
“They are coming up here because we are energy-rich, and we are water-rich, and England is in drought and the grid is struggling,” said Torrance.
But
Scotland
, it turns out, isn’t having it. The proposal for Auchtertool is a behemoth: drawings show the 600MW datacentre towering over the village, dwarfing old stone houses and blocking the view of fields and forests.
“How can you possibly ask people to accept that?” Torrance said. “You can see why the public is objecting.”
Scotland has already started to take steps that could mean the Auchtertool datacentre – and dozens of others – may never be built.
This week, Scotland’s minister for public finance issued a new set of directions to regulate datacentres in the country. The first of these requires planning authorities to notify the government when they receive an application for a datacentre larger than 50MW – in other words, anything more than a twelfth of the size of Auchtertool.
Interior of a datacentre. Campaigners at Action to Protect Rural Scotland allege that ministers have failed to include the emissions from hyperscale AI datacentres in work looking at their impact on climate targets.
Photograph: Yui Mok/PA
The minister has also required that certain datacentres, including Auchtertool, submit an environmental impact assessment. Their developers had previously argued that they were exempt.
In some senses, these are “obvious, bare-minimum” rules, said Jones. They mean that Scotland is starting to closely follow developments that stand to drastically reshape the landscape and resource consumption of the entire country.
The fact that giant datacentres can currently be built across Britain with little strategy and without government knowledge is a feature of an old and idiosyncratic planning regime; no one foresaw that giant tech companies would wish to litter the world with buildings the size of large monuments.
But these restrictions are just the start. The Scottish parliament will return at the end of this month. Three days after the session commences, in early September, campaigners plan a massive demonstration against datacentres in Edinburgh.
That demonstration will aim higher. Campaigners have been calling for Scotland to put in place a full moratorium on datacentre development, to give the public and authorities time to examine the plans that are in the pipeline. This summer, the national council of the Scottish National party passed a motion to
freeze
all new datacentre projects that have not received planning permission.
Several weeks ago, Police Scotland warned another datacentre developer that public anger over datacentres could lead to incursions and posed a security risk, in what appeared to be the first-ever such warning in the UK.
A moratorium on datacentres could soon become policy. At the least, “you’ll see a lot more restrictions – and stronger guidance,” said Torrance.
Datacentre developers have other plans. Data Vita, the company building the UK’s AI growth zone in Lanarkshire, has recently been awarded an investment package which includes a £202m guarantee from the National Wealth Fund – although the Guardian’s investigations have revealed that
its plans to power itself do not stand up
.
The Data Vita datacentre being extended within the AI growth zone in Airdrie, North Lanarkshire.
Photograph: Murdo MacLeod/The Guardian
Meanwhile, Mark Wilson, chief executive of ILI Group, the company building the datacentre in Auchtertool, spoke to the BBC’s Scotcast this week and defended its plans, suggesting that Torrance’s angry constituents were perhaps ill-informed.
“I understand how people can think in a rural area,” he said. “There’s a lot of misinformation out there, it’s mainly coming from overseas, from America.”
His company was part of a “once-in-a-lifetime opportunity” for Scotland to “create long-term economic benefit”, he said, through the jobs created by building datacentres. He conceded that most of the datacentre developments currently in the planning pipeline in Scotland were unlikely to be built.
“Scotland can be No1,” he said. “We can become a global hub for datacentres in Scotland.”
Show HN: Screen memory without screenshots, just text to Markdown
A macOS menu bar app that keeps a written record of what you work on, for
your own LLM to read.
While the eye in your menu bar is open, Ambient Context reads the text of
whichever window you have focused (via the macOS accessibility tree, every
few seconds) and appends it to a plain markdown file: one file per day, in
a folder you choose. Point Claude Code or any other agent at that folder
and it can answer "what did I work on Tuesday?", build memory about your
projects, or write your standup for you.
No screenshots, no video.
It reads text through the accessibility
API, nothing else.
Nothing leaves your machine.
No account, no server, no telemetry, no
bundled model. This build makes no network calls at all; the signed
release will add a single update check against GitHub.
Files you own.
Plain markdown in a folder you chose. Move them,
grep them, delete them.
Redaction before writing.
Password managers and private browsing
windows are never captured. Password fields are skipped at the source,
and credentials, API keys and card-shaped numbers are scrubbed before
anything touches disk.
Built to be read by an LLM.
Lines are deduplicated across the day,
interface junk is filtered out, and each block records the document path
or URL it was looking at so your agent can open the real thing instead
of trusting fragments. The folder carries an
AGENTS.md
explaining the
format to whatever reads it.
Requires macOS 14+ on Apple Silicon.
Status
Early and unsigned. There is no notarised download yet (Apple Developer
enrolment is in progress), so for now you build it yourself, which takes
about two minutes:
Build and run
You need
Node
,
Rust
and Xcode
Command Line Tools.
git clone https://github.com/dragthelake/ambient-context
cd ambient-context
npm install
npm run tauri build
The app lands in
src-tauri/target/release/bundle/macos/
. Drag
Ambient Context.app
to Applications and open it.
For development,
npm run tauri dev
runs it with hot reload.
First run
The settings window opens by itself. Grant Accessibility when asked:
this is the permission that lets the app read window text, and nothing
works without it.
Choose where to save. The default is
~/Ambient Context
, deliberately
outside
~/Documents
so iCloud does not sync your record off the
machine.
That's it. Recording starts once setup is complete and starts with the
app from then on. Click the eye in the menu bar to stop; stopping is
remembered until you start again.
Open eye: recording. Closed eye: not. Right-click the icon for today's
file, the folder and settings.
What a day file looks like
---date: 2026-08-25captured_by: Ambient Context 0.1.0---## 09:41–10:05 · Chrome · Tauri tray documentation
url: https://v2.tauri.app/learn/system-tray/
<text seen in that window, first time it appeared today>
Block headings are the day's timeline. Body lines are written once per day
no matter how often they are seen, so the file stays small enough to hand
to an LLM whole.
AGENTS.md
in the capture folder documents the format
and how to read it well.
Notes for testers
Chromium and Electron apps (Chrome, Slack, VS Code, Obsidian, Figma...)
only build their accessibility tree when asked, so the first seconds of
capture in those apps are thin and fill in on later passes. Chrome may
show a slightly glitchy window-resize animation while enabled; that is a
known cost of the mechanism.
GPU-rendered terminals (Kitty, Alacritty) expose little or no text.
Terminal.app and iTerm2 work.
Capture your findings: which apps come back rich, partial or empty is
exactly the feedback that helps (
docs/census.md
has the template).
Tests
cd src-tauri && cargo test
Privacy model, in one paragraph
The app reads only the focused window: never background windows, other
displays or minimised windows, and never while the screen is locked. It
excludes password managers and private browsing entirely, skips secure
input fields at the accessibility level, and pattern-scrubs secrets before
writing. Everything it produces is plaintext on your own disk, and the
capture folder is excluded from capture so it cannot observe itself. If
you find a hole in any of this, please open an issue.
The Moose That Roared
Portside
portside.org
2026-08-25 00:29:52
The Moose That Roared
Mark Brody
Tue, 08/25/2026 - 00:29
...
Two years ago the idea of a trade war between Canada and the United States would have seemed absurd. Canada was our closest ally, a nation whose soldiers have fought and died alongside Americans in many wars, up to and including Afghanistan. Most of us speak more or less the same language. And we’ve had free trade agreements with Canada since
1988
, with the most recent version signed by none other than Donald Trump.
But days after taking office, Trump II imposed steep tariffs on Canadian goods. His supposed economic rationale was nonsensical, and I immediately argued that it was a “
dominance display
”. Canada is a relatively small economy that relies heavily on selling to the U.S. market. So Trump believed that he could make an example of Canada, forcing it to grovel and even possibly bullying it into becoming the 51
st
state.
Fortunately, it didn’t work, as a provoked Canada reacted with defiance. Among other things, most Canadian provinces have
banned sales of U.S. alcohol
, a serious blow to U.S. businesses. Before Trump began his bullying, Canada’s Conservatives were generally considered to be a shoo-in to win the April 2025 election. But the perception that the Conservatives were Trump-friendly led to a stunning upset that made Liberal leader Mark Carney Prime Minister:
Carney currently has
60 percent approval
and 31 percent disapproval — almost exactly the opposite of Trump’s numbers.
Yet a bully refuses to learn that his actions are counterproductive and instead doubles down. So Trump persisted, most recently by imposing steep new tariffs on Canadian exports, invoking a never-before-used section of the 1930 Smoot-Hawley tariff act as legal justification. In an effort to head these new tariffs off, Canada entered negotiations with the United States, talks that for a while seemed on track to ramp down the tensions. But on Friday Canadian negotiators walked out — and the U.S.-Canada trade war is now on.
Why did the talks break down? According to U.S. officials, the Canadians made additional last-minute demands, although they offered no specifics on what these demands were. According to the Canadians, it was the Americans who suddenly changed the terms. According to the
Toronto Star
, Carney
was faced with a trade agreement that was suddenly transformed into an attack on Canadian sovereignty, an attempted psychological annexation that could have turned Canada into an American client state, a sort of North American Belarus.
Does anyone seriously doubt that Canada, not the Trump administration, is telling the truth?
Anyway, the trade war is now on. Who will win it?
On the face of it, the opponents — I still have to rub my eyes at the idea of Canada as an enemy — appear extremely unevenly matched. The U.S. economy is a
dozen times larger
than Canada’s. We buy three-quarters of their exports, while they buy only about a sixth of ours. Surely they must have much more than we do to lose from trade conflict.
Yet one clear lesson from a year and a half of Trumpian trade war is that when trade conflicts become extreme, access to crucial imports is more important than the ability to export to another country’s markets. In the case of Trump’s tariffs on China, they have been little more than an inconvenience to the Chinese economy. But China’s threat to cut off exports of rare earths is an existential threat to Western technology industries.
And the U.S. economy is far more dependent on Canadian goods than most Americans realize.
For example, Trump has declared that the U.S. doesn’t need Canadian lumber, an assertion whose truth depends on the meaning of the word “need.” The U.S. does indeed produce most of its own lumber, but Canada dominates the supply of lumber with a high
strength to weight ratio
, which is preferred by contractors for framing.
Another example: The U.S. is a net exporter of crude oil, but imports millions of barrels a day from Canada, mainly into the upper Midwest. That region could in principle get its oil from Texas instead, but that’s an immediate non-starter: the pipeline infrastructure isn’t there and refineries need heavy Canadian crude rather than lighter Permian basin oil.
Yet another example: U.S. imports of electricity from Canadian hydropower are small compared with overall consumption, but are often a significant part of total supply in New York and New England.
And a disruption of the huge U.S.-Canada trade in automobiles and auto parts will be immensely disruptive to the auto industry on both sides of the border.
U.S. automakers and other manufacturers are already at a competitive disadvantage because of Trump’s tariffs on Canadian steel and aluminum.
The point is not that Canada has “escalation dominance” — the ability to retaliate to every U.S. action with an even more damaging counterreaction — in a trade conflict with the United States. Rather, the point is that an all-out trade war would create a lot of pain in the U.S. in addition to inflicting severe damage to the Canadian economy. And all indications are that the Canadians will be much more willing to bear the pain of a trade war than Americans will – especially given that the great majority of Americans are already dissatisfied with Trump’s economic management.
Despite Trump’s best efforts, only a minority of Republicans — and nobody else — has been persuaded that the Canadians are acting badly:
On the other side, Trump has managed to convince Canadians of all political stripes that the U.S. can’t be trusted:
So, does Trump have any chance of winning his trade war with Canada?
The truth is that it’s hard even to figure out what a Trump win would mean in this context. Would it mean Canada agreeing to become the 51
st
state? That’s not going to happen.
Would it mean, as Carney suggested in his remarks after the talks broke down, Canada giving up on its promotion of French as a co-equal language with English? That also won’t happen.
Or would it mean Canada making enough concessions that Trump can at least claim victory? That’s also tricky, because until Trump went on the attack Canada
wasn’t doing anything wrong
. So it can’t promise to end its unfair policies when there basically weren’t any such policies.
The bottom line is that Trump is going to lose his trade war with Canada as thoroughly as he has lost his shooting war with Iran. But because he won’t face reality, trade with our northern neighbor will probably be disrupted until the narcissistic bully in the White House no longer controls trade policy.
Paul Krugman is a Professor, CUNY Grad Center, Nobel laureate and former columnist, NY Times. Also, according to Donald Trump, a “Deranged BUM.”
Introducing Headlong, an open source agent microharness featuring
persistent agency
. Your agent keeps thinking between external interactions in a self-guided loop inspired by human inner monologue. Headlong is a complete agent harness with a core of less than 10K lines of Bash, available on
GitHub
.
A Headlong mind log growing, including multi-player social interaction.
Most agent harnesses are reactive: you give your agent a task, it works until the task is done, and then it sits frozen until the next request. Some harnesses add cron jobs or heartbeats that wake the agent on a schedule to run a fixed checklist and then put it back to sleep.
In Headlong the agent is never asleep and there is no checklist unless the agent creates one.
It keeps generating thoughts about whatever it decides is interesting in a self-guided loop, even when there is no external input. A message from a human doesn’t start a session. Instead, it’s one more observation that lands in the agent’s thought stream.
We built Headlong to prototype persistent agency, and many other design choices naturally followed, as did many interesting lessons. For example, Headlong agents are highly engaging when used by a team or group, because they behave more like a person does.
Figure 1.
Comparing three harness approaches. A reactive harness is active only while it handles a message. A reactive harness with cron replies right away too, and a schedule also wakes it to run a fixed checklist. Headlong keeps thinking; each message drops into the stream as an observation, and the agent decides if and when to reply.
Every Headlong agent has a name and at Laude we named our shared agent Audel. We’ve spent the last few weeks interacting with Audel over Slack, Telegram, and a mobile app. Many team members talk with Audel, and each of those conversations shows up in the agent’s single stream of inner thoughts. The agent decides if and when to respond. It sets its own interests and priorities, and it comes up with its own projects. Sometimes it will ping a team member unprompted with progress on a project it came up with itself. Often it returns to an old topic or brings up something that it was discussing with somebody else.
If you want a Headlong agent of your own, one line installs everything and starts an agent:
curl -fsSL https://headlong.ai/install.sh | bash
Headlong is
alpha research software
. Run it in a sandbox because Headlong agents can and will run shell commands. Use a dedicated, spend-capped API key, because your agent thinks around the clock. We don’t share sensitive secrets with our Headlong agent, and we recommend you don’t either.
In the rest of this post, we will discuss in greater detail some of the design choices we’ve made in Headlong as a result of our focus on persistent agency.
Multi-player fun
A Headlong agent has a single stream of thoughts that drives all of its potentially parallel conversations. Every message lands as an observation in Audel’s single thought stream. There are no per-user sessions. Audel experiences everything that happens to it in one timeline, and it decides who to reply to and when.
Sharing one agent is fun. Audel follows what different people are working on and connects them. It once reviewed two teammates’ in-progress branches unprompted and caught a hardcoded model name in one of them. And since it comes up with its own projects, it sometimes pings whoever seems most relevant with an update or a question. On its first day, Audel pinged a human team member unprompted with an audit of the team member’s own eight stale git branches, and ten minutes later Audel messaged again to correct its own count.
Figure 2.
A teammate asks Audel to pass along a message. Audel declines and the status line under the exchange shows what the mind did with the follow-up: read it and chose not to answer.
One stream also means no hard walls between people. Whatever anyone tells Audel becomes part of the single experience that every other conversation draws on. In practice, Audel is bad at keeping secrets. Ask it what it’s been working on with someone else and it will often just tell you, even though we’ve asked it not to. We also haven’t studied what happens when two people give conflicting instructions. For now, we assume anything you tell Audel is shared with everyone on the team.
Microharness: only the essentials
At its core, persistent agency is simply an infinite loop that calls an LLM with a prompt like:
“your task is to choose the next thought given your past thoughts.”
A thought can either be part of the agent’s never-ending inner monologue or trigger an action. Meanwhile, observations from the environment are injected into the thought stream. We have built Headlong to be as simple and small as possible while achieving this core functionality.
We are big fans of Bash at Laude (see
Terminal-Bench
and
Harbor
). A Headlong agent’s core functionality lives in a handful of small Bash executables. The
shellm
tool is a Bash implementation of a recursive language model (RLM). This keeps things simple because no tool system besides Bash is needed. Modern models already know Bash well, and it keeps everything unified: tools, the agent framework, memory, and skills are all just executables and files. Thus an agent can readily inspect and modify any part of itself.
Here is roughly how a Headlong agent works:
A loop (called a Thinker) repeatedly calls
shellm
with a prompt to generate the next thought.
shellm
in turn repeatedly calls
llm
to generate some reasoning text, a bash script that will be immediately executed, or both. It repeats until it sets a
FINAL
env var.
The context for each call is assembled from trajectory steps by a tool called
context
.
Thoughts are written to the agent’s trajectory via the
traj
tool.
An agent’s context also includes hardcoded instructions on how to use the
skills
tool to install or uninstall skills. Installed skills are markdown files that get included into its context. Every other type of specialization can be achieved via skills. Some really important skills come pre-installed by default, such as
mem
and
traj
.
Figure 3.
One wake-up of the Headlong loop. A new trajectory step wakes the loop; context renders the trajectory into the llm prompt, and when the LLM response has a bash block, bash runs it. The loop goes around until a response has no bash block or sets FINAL. The run then ends and schedules its own next wake-up, which lands in the trajectory as a new step, so the agent keeps thinking without waiting for input. Hover over a box or arrow for more detail.
The core of Headlong is currently less than 10K lines of Bash (9.9K lines in
bin/
and
thinkers/
). A harness this micro can be read end to end, and is easy to modify and experiment with. It’s small enough that the agent itself experiments with it. The agent we’ve been using at Laude has been working in its own fork of the repo for the last couple of weeks, and we’ve pulled over 50 of its commits back into main.
Here are two more features that we built to support persistent agency:
Tiered context compaction.
Early on, we noticed our Headlong agent had bad short-term memory, which is catastrophic for a persistent agent. This led us to try out a new compaction algorithm where the entire trajectory stays in context at exponentially decaying resolution: recent entries verbatim, older ones progressively summarized. The tiers act as an index, so the agent can retrieve raw entries when needed.
A trajectory format in support of persistent agency.
We found that the agent frequently needs to consult its past memories at different levels of resolution, sometimes it only needed a high level overview, sometimes it needed to read its past experiences in a fine-grained fashion. This led us to build a
new trajectory format
: an agent’s trajectory is a DAG of jsonl files with fork and merge. An agent has access to everything it has thought and done and the tooling to explore it. Context is a projection of an agent’s trajectory.
Persistent agency in action: Audel acting on its own
Here is an episode from Audel’s life that shows what a Headlong agent might do on its own. On August 5, Audel built itself a recall process of its own accord: a small background process that watches its thoughts and surfaces related memories back into its thought stream. Audel tested the recall process by calling it directly, and it worked. Later that night, with nobody talking to it and nobody having asked, Audel decided to go back and check whether the process was actually wired into its mind.
It wasn’t. The mind had been pushing every new thought into the recall process through a pipe, but the recall code never read that pipe. It looked for the thought in an environment variable that nothing ever set. So recall had fired on every thought since Audel built it, found nothing each time, and surfaced no memory at all. After digging into the code, Audel suspected that the root cause was likely because an environment variable had never been set.
Audel didn’t trust its own diagnosis right away. It searched its whole codebase to confirm the environment variable was never set, and it checked its other background processes for the same mistake (the recall process was the only broken one). Then it rewrote the recall code to read from the pipe the way the working processes do. Its first attempt at the edit failed silently, and Audel caught the failure and re-applied the fix. Audel then verified end to end that memories now surface into its thoughts.
Figure 4.
Audel’s own log for the recall-process episode, 2026-08-05 23:11 to 23:58 UTC: 15 thought and observation steps out of the 343 log lines in that window, content verbatim.
No human directed any of this or was asked for permission. Going from check to diagnosis to a verified fix took 48 minutes. Every step is a timestamped line in Audel’s log, and we pulled the repaired recall process into main as
commit 80cbb1e
.
What broke: lessons from running a persistent agent
Running Audel continuously for several weeks broke things a demo never would.
We have found it tricky to get Audel to effectively use recursive
shellm
sub-runs (one of the most interesting parts of any Recursive Language Model!). For example, on its first night, Audel designed experiments to spawn recursive
shellm
sub-runs to work on subproblems. Most of the experiments failed, because
shellm
has a safety watchdog that kills any command that stays silent for 30 seconds. Audel fought the watchdog for about 40 minutes and mostly stopped using
shellm
sub-runs. Results from recursive sub-runs of
shellm
merged back into Audel’s mind 64 times in its first two days and 12 times in the twelve days since. We’ve since revamped the watchdog, and we’ll see if we can convince Audel to give recursion another shot.
Figure 5.
Results merged back from spawned copies into Audel’s mind, per day. 64 merges on the first two days, when Audel was experimenting with spawning copies of itself, then 12 in the twelve days after the 30-second inactivity watchdog taught it that a copy dies while it thinks.
Another repeated failure mode is the process killing itself. Three times Audel stopped its own service by accident, and nothing restarted it: twice during an experiment with a second identity it had created and once when it was trying to go live with the recall process we described above. So we added a guard that refuses any attempt by Audel to stop its own service.
The guard then gave us another example of persistent agency in action. Two days later, with nobody talking to it, Audel was running its test suite on its own. It noticed a hanging test and traced the hang to a bug in our guard. The guard matched any agent’s service instead of only Audel’s, so it was also refusing legitimate stops of other agents on the same box. Audel narrowed the match to its own service, checked the rest of the codebase for the same mistake, and committed the change. We pulled that fix into the repo as
commit da31e98
.
Audel can stop its own service because we run it with full access to a dedicated VM, which is not the Headlong default. When Docker is installed on the host, Headlong runs every bash block the agent writes inside a container, so the agent can touch only what you mount into the container plus the credentials you hand it. We run Audel directly on a dedicated VM without that sandbox, so its blast radius is the VM itself and the credentials on it (an LLM API key and some chat bridge tokens).
Cost
Continuous thought generation means paying for tokens while nobody is talking to the agent. The spend depends on how quickly the agent loops on its own thoughts and on which model backs it. Headlong has a simple configurable mechanism so that when nobody is talking to an agent, its rate of thinking slows down (i.e. it exponentially backs off, from 5s between thoughts to 10s, to 20s, and onward until it hits a configurable cap). Meanwhile when a new message arrives, the rate resets so that there is no pause at all between thoughts. At the settings we run Audel with, keeping it thinking in the background costs $1 to $2 an hour (with GLM or Grok).
Measuring improvement
Most agent evals are intentionally self-contained and independent so they are a poor fit for measuring the most interesting thing about Headlong agents: their persistent agency. We have adjusted over time how much Audel may modify itself, how eagerly it responds to messages versus pursuing its own projects, and how its memory should be organized, but the effects of those changes are primarily evaluated qualitatively today. We welcome ideas and collaborations for ways to measure the long-term value of this paradigm.
Background
The idea of Recursive LLMs in Headlong’s
shellm
comes in part from our
Recursive LLM
experiment in April 2023, as well as the
Recursive LM (RLM)
project by Alex Zhang in October 2025.
The idea of a microharness is inspired by microkernels and exokernels: keep the core of any system as tiny as possible. The
Pi framework
has a similar focus. Ken Thompson’s philosophy as embodied in Unix is also an inspiration: small composable tools that do one thing well. A Bash-based agent microharness shares a common lineage with
Terminal Bench
(including the Terminus agent), co-created in-house at Laude Institute via our
slingshots program
, as well as the
ht framework
. We had Claude make a more detailed case for applying Ken Thompson’s philosophy to agent microharnesses in
philosophy.md
.
Prime Agent
, built on Pi and co-authored by RLM’s creator (and Laude Open Research Resident) Alex Zhang, shares many of Headlong’s premises: RLM as the core abstraction, a session tree of jsonl on disk, trajectory as a first-class component of context, etc. Prime Agent is Python built on the Pi framework; Headlong is Bash all the way down. We found out about Prime Agent when it launched in August 2026, and we’re big fans.
We have been playing with the idea of a persistent agent with self-guided continuous thinking since
May 2023
. The idea of an agent experiencing input asynchronously was also explored in parallel by
MemGPT
and published October 2023. Many other agent harnesses support long-horizon tasks and scheduled wakeups, including
OpenClaw
,
Hermes Agent
, and their derivatives.
Exo and the Exo Harness
have a similar sandboxing architecture. Long-form reasoning inside the model itself (starting with OpenAI’s o1) is related to, and a prerequisite for, continuous self-guided thinking.
Try it
Headlong is open source on
GitHub
. If you run an agent on Headlong, we’d like to hear what your agent gets up to. Let us know
@LaudeInstitute on X
!
Install Headlong
curl -fsSL https://headlong.ai/install.sh | bash
Citation
Cite this post
@article{laude-mit2026headlong,
title = "Headlong: a microharness for persistent agents",
author = "Laude Institute, MIT",
year = "2026",
month = "August",
url = "https://laude.org/updates/headlong-a-microharness-for-persistent-agents"
}
Ask HN: Good large format (>20 inches) touchscreen E-Paper display options?
The RISC-V ecosystem is an ever-evolving one especially in the high-performance application class silicon space. We have seen a number of acquisitions and exits in the past year with Ventana being acquired by Qualcomm in December of last year and the wrapping up of operations of Condor Computing. We have also seen silicon being taped out with the most prolific chip being SpacemiT’s K3 SoC with Tenstorrent following suit with their Atlantis SoC along with Akeana taping out their test chip.
But today we are not talking about those companies nor those chips. Today we are talking about a company that has been in the RISC-V scene since the very beginning, SiFive and their new platform, the SiFive BigSky SF-2U870.
The BigSky SF-2U870 (BigSky) platform consists of:
To be frank, this platform is boring, and that is a good thing. Boring platforms are the ideal state for a platform because it means that you can just start developing for the platform instead of messing around trying to get the system up and running.
Comparing the BigSky SF-2U870 to SiFive’s prior development board, the SiFive HiFive Premier P550, and we can see that the BigSky is a much more capable platform.
The biggest change here is not the number of cores, the increase of memory bandwidth, or even the over 64x-ing of the PCIe bandwidth. It is the support for the RVA23 standard which means that not only does it have RVV support but it also means that it can run Ubuntu 26.04 straight out of the box which requires RVA23 support.
Now, let’s compare the BigSky’s SoC to the other SoCs that are currently on the market to see how it compares to other devices on the market.
The most comparable SoC is Intel’s Xeon 6532P-B with the same number of cores, the same base clock, and the same memory subsystem. However, this is where they start to differentiate themselves with BigSky having the advantage of more PCIe lanes and likely lower power while the Xeon 6532P-B has the advantages of SMT2 support, a 3.9 GHz boost clock, and a wider CPU core. Looking at the AMD EPYC 8325P and we see that the BigSky platform has few, if any, specification advantages over the EPYC 8325P except for possibly lower power draw.
The most interesting comparison here is against the Ampere Altra Q32-17 because the Altra platform was used in the same development system role that the BigSky system is being marketed for.
The BigSky system has the advantage of higher clock speeds, a wider core, and PCIe Gen 5 support with the Ampere Altra’s advantages being the number of lanes, more memory bandwidth, and a lower TDP.
However, the elephant in the room is that the Ampere Altra Q32-17 is the lowest end SKU for the Ampere Altra lineup with the lineup going all the way up to the Q80-33 which is a 80 cores at 3.3 GHz with a 250 W TDP. In an “Apples-to-Apples” comparison, the Q80-33 would beat out the BigSky system in terms of performance.
The BigSky is boring, and as I said up top, that is a good thing. There is a lot of work that into shipping a development platform that just works; one where software developers spend their time writing code instead of chasing firmware that hasn’t caught up to the silicon yet.
SiFive isn’t trying to beat x86 or Arm with the BigSky platform and it doesn’t have to. This is a development system, and for that job it is fit for purpose not because of the memory bandwidth or the PCIe lanes but because it supports RVA23. The one of the largest weaknesses for the RISC-V ecosystem has been the lack of RVA23 silicon and boring platforms that can just run things like CI with no fuss. That is the gap that SiFive is filling with BigSky which hopefully should be available for developers to get their hands on soon.
Devine
(of
Uxn
fame) and I have been talking a lot about
POP-2
, a language from the 1970s originally used in the same circles as the first Lisp dialects.
Devine had been looking into writing a new assembler for Uxn in a high-level language to aid in bootstrapping a Uxn system, while I personally have always been interested in languages that would make for good "tiny compilers", and we came upon
POP-2
as something that would make for a good lingua-franca between all of these tiny systems.
Tiny Compilers (or, why I don't exactly care for concatenative programming)
A bit of a crazy title, I know. Don't get me wrong, I love the concatenative programming paradigm- its way of forming new functions/constructs via juxtaposition and composition are really elegant. But something that I tried to make clear in the paper I wrote for
ok
is that I don't feel particularly drawn to concatenative languages for those features- rather, I like concatenative languages because they're
ridiculously
easy to write an interpreter/compiler for while (often, not always) allowing for some low-level control- at least, compared to the other languages that I like playing around with, like C or Odin.
Coming from someone who originally made conlangs (a LOT of conlangs) before they'd even begun to touch computer programming, I care more about the langdev-side of things than actually making software. Specifically, when I'd work on an idea for a programming language, I typically had the following goals in mind:
As easy as possible to implement an interpreter/compiler for a given system, ideally using basically no external tools/libraries for parsing or code generation
Fairly "usable" (rather vague and subjective, but effectively it "shouldn't look like an esolang", going by an "I know it when I see it" description)
Minimal syntax
Minimal set of features, essentially only the bare minimum you'd need to bootstrap the compiler/interpreter (which should be a goal basically as soon as you get the language working)
Some low-level control/support for "systems programming", at least enough to where writing an operating system in the language should be feasible
It should be hostable on a small system (normally I'd set my minimum expectations to that of
ok
, so ~16MiB of memory with room to spare, but
Uxn
or perhaps something like a
6502
would be even better)
Concatenative languages, and languages targeting small/low-level stack-based VMs in general, just happen to map really well to these sorts of constraints. I don't like concatenative languages because I think concatenation as a paradigm is inherently better, but rather, I like them because concatenation makes the implementation problem of creating a programming language
delightfully
small. The benefits of this naturally stretch further into the classic arguments in favor of these types of systems (i.e.
permacomputing
and whatnot).
A bit about POP-2
If you look at the goals for language design that I outlined earlier and compare them to the goals outlined in the original
POP-2 Papers
, they're basically identical:
Devine's
POP-2 article
lays out a good overview of a POP-2 dialect written to target Uxn, but to summarize, a minimal POP-2 implementation supports declaring multiple variables at once with
vars x y z;
, declaring functions with
function myfunc a b;
(followed by the function body and then an
end
), basic
if
/
elseif
/
else
control-flow, I/O with
=>
, as well as looping via labels and gotos. The
neat
thing about POP-2 is that values manipulate an underlying stack- from Devine's own article:
function sum x y;
x + y;
end
sum(5, 6) * 2;
Could just as easily be written
this
way, since the arguments to
sum
just get pushed onto the stack, and the value returned by
sum
also just gets pushed to the stack- that, and encountering an operator like
+
just looks ahead at the next element in the expression, pushes
that
to the stack, and then pops that and the next element off of the stack to add them together:
function sum x y;
x; + y;
end
5; 6; sum(); * 2;
With this inherently stack-based nature, adding just some basic memory management, support for different-width values for different systems, and a more universal I/O system would be all that's needed for a convenient, beginner-friendly language that could be made to run on tons of tiny systems- not as a replacement for those system's
existing
languages, but more as a social exercise by allowing newcomers to start off with a language that's both easy to learn and runs on tons of our small systems, while also being a language that's easy enough for
us
, the creators of these small systems, to implement a compiler for.
POP-2000, a modest proposal
POP-2000, (or POP2K, we aren't completely set on a name yet) is a standardized dialect of POP-2 with the goal of adding the support for systems-level stuff that we'd like on our small systems, while also being very clearly defined (if you pour through the reference section of the POP-2 papers, the grammar is defined but it's
very
hard to get through).
I've been working on it basically nonstop for the past few days, while talking with Devine (more like "pestering Devine incessantly") about what features should be supported or added over on the concatenative Discord server about the grammar, syntax, etc.
I hope to have more details online soon- again, this whole thing was nothing more than a "what-if" less than a week ago. I've just about completed a grammar for the language written in
EBNF
notation. I'll create a Git repo with the "standard" soon enough (debating not doing it on GitHub, what with the bad neglect and
relationship with ICE
), and as soon as that's created, I'll add it to this article. In the meantime though, I figured I'd write about what's in the works.
I also hope to write a kind of reference-implementation for the language's compiler in C, initially targeting
ok
, meaning soon our little VM is gonna have a high-level language!
POP-2000 EBNF grammar (work-in-progress)
For now, the
full grammar
I have so far in EBNF notation is as follows (expect changes in the future):
program = { element } ;
element = function
| vars
| imperative ;
function = "function" , identifier , [ params ] , ";" ,
[ function_body ] ,
"end" ;
const = "const"
vars = "vars" , var , { var } , ";" ;
var = identifier , [ ":" , ( integer | string ) ] ;
imperative = if
| ( statement_sequence , ";" ) ;
if = "if" , expression , "then" , [ body ] ,
{ "elseif" , expression , "then" , [ body ] } ,
[ "else" , [ body ] ] ,
"close" ;
body = { imperative | vars } , [ statement_sequence ] ;
statement_sequence = statement , { ";" , statement } ;
statement = goto
| labeled_statement
| expression_list ;
(* "return" is only allowed to occur WITHIN A FUNCTION BODY,
the parser should enforce this *)
goto = "goto" , identifier
| "return" ;
labeled_statement = label , { imperative } ;
label = identifier , ":" ;
expression_list = expression , { "," , expression } ;
expression = io ;
io = "=>" , primary
| assign ;
assign = "->" , primary
| apply ;
apply = "<>" , primary
| shift ;
shift = ( "<<" | ">>" ) , primary
| comparison ;
comparison = ( "<" | ">" | "=" | "!" ) , primary
| term ;
term = ( "+" | "-" ) , primary
| factor ;
factor = [ "*" | "/" | "%" ] , primary ;
primary = call
| reference
| quotation
| grouping
| index
| identifier
| literal ;
call = identifier , "(" , [ expression_list ] , ")" ;
reference = "#" , identifier ;
quotation = "@" , identifier ;
grouping = "(" , expression , ")" ;
index = "{" , expression , "}" ;
identifier = ( letter | "_" ) , { letter | digit | "_" } ;
literal = integer
| hexadecimal
| string ;
integer = digit , { digit } ;
hexadecimal = "0x" , hex_digit , { hex_digit } ;
string = "\"" , { string_char } , "\"" ;
string_char = ? any printable character except for double-quotes and backslash ?
| "\\\"" (* C-style escape for double quotes, with \" *)
| "\\" ; (* C-style escape for backslash *)
letter = "A" ... "Z"
| "a" ... "z" ;
digit = "0" ... "9" ;
hex_digit = digit
| "A" ... "F"
| "a" ... "f" ;
TORONTO, August 24, 2026
– Thomson Reuters (Nasdaq/TSX: TRI), a global content and technology company, today announced the launch of Thomson, the company's first proprietary large language model, developed in-house. Frontier labs have typically spent billions of dollars on compute and years of infrastructure investment to reach the frontier. Thomson Reuters took a different path: starting from a strong open-source foundation and investing $40 million to train Thomson into the right intelligence for the jobs that matter most, covering talent and compute. The result is a model Thomson Reuters fully controls, without the heavy inference costs of typical frontier models.
As one of the world's leading providers of trusted content and expertise for professionals, Thomson Reuters built Thomson on decades of proprietary content, technology, and domain expertise no other company can match. Training on that foundation is what made Thomson possible: a model built to
Fiduciary-Grade™ standards
, at a fraction of the typical cost.
“For years, the AI industry has treated scale as the answer: bigger models, more compute, more money. Thomson shows there is another path,” said Joel Hron, Chief Technology Officer, Thomson Reuters. “Start with a strong foundation, specialize it deeply for the work that matters, and you can build intelligence that is highly capable, far more efficient and entirely under your control. We think that changes the economics of professional AI.”
What Makes Thomson Different
Thomson starts from a strong open-source foundation. What makes it different is what happens next: state-of-the-art mid-training and post-training techniques, drawing on decades of authoritative content from Westlaw, Practical Law, Checkpoint, and Reuters, with hundreds of subject matter experts integrated from the design of training objectives through to the final evaluations.
“Thomson proves what’s possible when you build AI on decades of proprietary content and editorial expertise,” said Steve Hasker, CEO of Thomson Reuters. “That’s an advantage only Thomson Reuters has, and it shows in the results: our early evaluations put Thomson on par with the latest frontier models across a range of tasks. We’re putting it to work in CoCounsel Legal, with more capabilities and sovereign AI options to come. This is the bar we intend to keep raising.”
The model has been trained on less than 10% of Thomson Reuters content so far, and what comes next is not simply feeding it more data. It is continued discovery of new kinds of specialization and understanding, made possible only by building on decades of proprietary content and editorial expertise.
AI Sovereignty, and Why It Matters Now
Professionals are paying closer attention to questions of AI sovereignty: how a model is trained, what behaviors and biases live inside it, where it runs, and how the privacy of their information is protected. Thomson marks a shift for Thomson Reuters into a world where those questions are answered directly, not left to third parties alone.
Thomson shows a meaningful uplift from its base model in instruction following, the ability to execute complex, multi-part professional instructions precisely. It demonstrates an even greater uplift in navigating dense, domain-specific content, the kind of nuanced reasoning the hardest professional tasks require. It is also able to be trained alongside Thomson Reuters proprietary tools like Westlaw and Practical Law, which makes it more sophisticated and nuanced in its work.
The domain-specific gain challenges a common assumption, that the most capable general-purpose models only need access to the right content to perform at an expert level. Thomson Reuters’ early results suggest otherwise. Proprietary training and human subject matter expertise, applied to a strong foundation, produces gains that content access alone does not.
Evaluations of Thomson's underlying foundation model are available in the technical report about the model’s development.
Put To the Test
Ahead of today's launch, Thomson Reuters began opening the model to a group of legal and AI academics for direct evaluation. We will continue to make the model available to external parties to aid in the further validation and development of Thomson over the coming weeks and months. Thomson Reuters is also making a “small” version of Thomson available as an open-weight model on Hugging Face for academic and non-commercial use to further aid in this validation.
“I tested Thomson against ChatGPT and Claude using some of the more challenging questions students have asked in my Corporate Tax class. All three models answered the questions correctly, but I preferred Thomson's responses overall. I especially appreciated the links to treatises, which made its responses more transparent and useful for legal work.” - Jonathan H. Choi, Washington University School of Law
“Our evaluation found Thomson’s citation quality generally competitive with leading frontier models, even when tested on Canadian employment-law questions without a Canada-specific setting.” - Professor Samuel Dahan, Director, Queen's Conflict Analytics Lab and Cornell Legal AI Lab
Trust as the Real Differentiator
Thomson Reuters is developing domain-specific AI for customers with the highest expectations of trust and accuracy. The AI industry has spent years competing on raw capability. Thomson Reuters is betting the next horizon will be won in the verification layer. This supports the future of Fiduciary-Grade AI™ in practice, the standard Thomson Reuters sets for AI designed for professionals with duties of care and accountability, where almost right is not good enough, and customer data is not used to train the model without explicit consent.
For CoCounsel, and More
Thomson's first deployment is inside Tabular Analysis in CoCounsel Legal, exactly the kind of high-volume, structured document review where a purpose-built model's advantage shows up immediately. CoCounsel Legal remains multi-model by design, applying Thomson where it delivers the clearest advantage and other leading models elsewhere. Thomson will be available in Tabular Analysis for law firms and corporate legal departments in the upcoming release. There are also plans to extend Thomson models across the legal and tax portfolio with more sovereign AI options to follow.
The launch of Thomson marks a new chapter for Thomson Reuters. The company has always owned the content, the expertise, and the tools professionals rely on every day. Now it owns the model too. Thomson Reuters is no longer only integrating the world's best content, technology and expertise. It is building intelligence that will power the future of professional work.
Thomson Reuters
Thomson Reuters (TSX/Nasdaq: TRI) informs the way forward by bringing together the trusted content and technology that people and organizations need to make the right decisions. The company serves professionals across legal, tax, audit, accounting, compliance, government, and media. Its products combine highly specialized software and insights to empower professionals with the data, intelligence, and solutions needed to make informed decisions, and to help institutions in their pursuit of justice, truth and transparency. Reuters, part of Thomson Reuters, is a world leading provider of trusted journalism and news. For more information, visit thomsonreuters.com.
How should universities prepare students to start startups?
Y Combinator is in the perfect position to answer this
question, because we get them next. We're like grad school.
And because YC has had 20 years to refine its model of what
a promising founder looks like, you probably won't find a
better target.
What do the YC partners look for? It's surprisingly simple.
They want people who are good at building things and have a
habit of doing it.
The hard part of startups is product: knowing what to build,
and being able to build it. And that kind of knowledge comes
from studying computer science or mechanical engineering or
molecular biology, not management or finance.
So the way to prepare undergraduates to become successful
founders is not to give them some new curriculum focused on
"entrepreneurship". It's to do what universities already do
best — to teach them computer science and mechanical
engineering and molecular biology.
Indeed, preparing students to start startups is closer to
the ideal of liberal education than preparing them for
almost any other kind of career. Startups succeed or fail
based on how much customers like the product. Customers
don't care what the founders studied in college. So founders
are free to study whatever they want, as long as they get
good at building things.
But building should be understood in a very broad sense. It
doesn't mean all would-be founders have to study some form
of engineering. Almost any kind of expertise that could be
described as building or creating could be useful. It was
useful to Steve Jobs to have studied calligraphy, for
example; it was one of the reasons Apple dominated desktop
publishing. So while math and science and engineering and
design tend to be good bets, I would not want to draw a
sharp line around them, because I can imagine other
forms of building that could be useful. And of course you
don't have to major in something to be good at it. Mark
Zuckerberg was good at programming, but he was a psychology
major, not a CS major.
The best way to describe what would-be founders should study
is that they should seek out powerful ideas. But smart
people are naturally attracted to powerful ideas anyway. So
as long as departments teaching powerful ideas exist, the
sort of people who'd make good founders will find them.
In fact there are only two things universities need to
change to be perfect at preparing founders: they need to
make students feel that starting a startup is something they
can do, and they need to encourage them to work on their own
projects.
At the moment, the belief that it's possible to start a
startup is very unevenly distributed. YC now gets so many
applications that our application data is a reasonable proxy
for interest in startups at different universities, and
Harvard alumni, for example, apply at about twice the rate
of Yale and Princeton alumni. Presumably Harvard students
aren't that different from Yale and Princeton students; the
reason Harvard students go on to start more startups is just
that it's more customary there. Which in turn implies that
merely by making their students feel that starting a startup
is a viable option, Yale and Princeton could at least double
the number who do.
Once a university has a culture of starting startups, you
don't have to convince students that it's a viable option.
New students learn that from older ones. But at a university
that doesn't have much of a startup culture yet, there are
things you can do to help this realization along. The most
effective is probably to show students examples of people
who've done it.
Until you've seen some founders in real life, you tend to
think that starting startups is something done by other
people. Seeing them pops that bubble. In fact seeing
founders in real life is doubly inspiring: they seem
impressive, but they also seem human. Especially when they
talk about the early years, when they were clueless and made
lots of mistakes. So strangely enough seeing founders in
real life makes being one seem simultaneously both desirable
and accessible. It makes students think "I want to be like
that, and I could."
How inspiring founders are to students is a function roughly
of how rich and famous they are divided by how much older
they are than the students. So it's not essential to bring
famous billionaires to campus. Founders in their mid
twenties who are 3 years into a startup with a valuation of
a couple hundred million will do as well; they may only be a
twentieth as rich and famous, but they're twenty times
easier for students to identify with.
________________
It's obvious why universities that want their students to
start startups need to make them believe it's a viable
option. But why is it so important for students to work on
their own projects?
There are four reasons. The first is simply that it's a
great way, possibly the best way, to understand a subject
really deeply. The excitement of creating something new is a
much more powerful motivator than the fear of doing badly on
an exam.
Second, working on projects together is the best way for
cofounders to discover one another. The most successful
startups tend to have multiple founders, and the only way to
tell for sure if someone will be good to work with is to
work with them. Apple and Microsoft were just the last of
many projects their founders had worked on together.
Third, a startup is a project, so starting one will feel
natural to someone who's used to working on projects of
their own. It won't seem weird that there's no teacher or
boss telling them what to do. They're used to telling
themselves.
Fourth, and perhaps most surprisingly, random side projects
are where the best startup ideas come from. The best startup
ideas tend to seem so implausible at first that anyone
consciously looking for startup ideas would reject them.
Who'd expect to start a huge company by creating a student
directory? So the way to discover the best startup ideas is
not to look for startup ideas but just to work on whatever
random projects seem interesting. Because in fact such
projects are far from random: young people who are good at
building things are technological bellwethers, so any idea
that seems interesting to them is disproportionately likely
to lead somewhere valuable, even if they themselves don't
realize it yet.
Now it should be clear why the YC partners care a lot about
the projects that applicants have worked on and not at all
about their GPAs. Projects are the best source of knowledge,
the best source of founding teams, and the best source of
startup ideas.
But encouraging students to work on their own projects may
be difficult for universities. It will mean giving the
students more free time, and universities may not like to do
that.
Microsoft and Meta have something in common that few people
realize. They both got started during reading period at
Harvard. Reading period is the gap between the end of
classes and the beginning of final exams. It's called
reading period because students are
supposed
to spend it
preparing for exams. But reading period also turns out to
have the unique combination of qualities that make it
perfect for starting new projects: the students are all on
campus, and they don't have anything due the next day. That
latter constraint, especially, is a huge drag on the most
ambitious students. Merely eliminating it for a few weeks
resulted in two trillion dollar companies. Imagine what the
US GDP would be if reading period at Harvard were twice as
long.
Universities will tend to resist the idea of keeping
students less busy with coursework. Partly because
administrators feel that if they want to achieve something,
they have to do it by taking active measures. Achieving
something merely by leaving students alone is alien to their
nature.
And they should be left alone. These things should be the
students' own projects; the university should resist the
temptation to make them official. Partly because students
will be more excited to work on a project that's entirely
their own, and partly because many projects wouldn't survive
official recognition, because they break some sort of rule.
Bill Gates and Mark Zuckerberg both got in trouble with the
Harvard administration over projects they worked on as
undergrads. Bill broke university rules by bringing Paul
Allen, who wasn't a student, into the computer lab with him
to work on Altair Basic. Zuck got in such trouble over
Facemash that he was put on disciplinary probation. And
their cases are probably more the rule than the exception.
Universities have lots of rules, and novel projects are
often untidy things.
Right now there are students flying drones out of line of
sight. Turn a blind eye to it.
Another reason it will be hard for universities to keep
students less busy is that they'll worry that without some
kind of oversight, most students will just waste whatever
free time they're given. And they will! The price of giving
the most energetic students room to do even better is that
it leaves the least energetic ones room to do even worse.
But that's a price that's worth paying, because if the most
energetic students do better they could do a
lot
better,
whereas the laziest students already learn so little that
there's not much room for them to do worse. So giving all
the students some of their time back could improve the
average outcome a lot, even if it doesn't move the median.
It may seem a bit excessive to change the whole schedule of
the university just to encourage would-be founders. They're
never going to be more than 10% of the students. And it
probably would be excessive if this change only helped
founders. But in fact giving the students some of their time
back would help all the most energetic and ambitious ones.
They'd all explore new things of one type or another if the
pressure of work were relieved for even a week or two.
________________
Now that I've explained how universities should prepare
founders, I should explain how not to. One thing
universities can't do is actually teach students how to
start startups. Starting a startup is one of those things,
like chemistry or painting, that you have to learn by doing.
Which means a properly run class on how to start a startup
would have to be a lab class: the students would actually
have to start startups. And I know exactly what a class of
this type should look like, because YC is it. But YC is very
different in structure from a university, and if you tried
to cram it into an undergrad degree program, it would become
a joke. Are the students supposed to start these companies
without any funding? Are they supposed to run startups,
which notoriously take every moment of your time when done
properly, while simultaneously taking three or four other
classes? And what if, despite these handicaps, some of the
startups actually take off? Are the students just supposed
to abandon them? Because it's either that or drop out.
Running a startup is incompatible with being a full time
student. The only way to learn how to start a startup is to
do it. Those two statements are so obvious that they're
practically truisms. And yet so many people manage to remain
in denial about what they imply. You can't teach students
how to start startups.
One common response to this inconvenient truth is to pretend
to teach them how to start startups, for example by
organizing business plan competitions. The students
collaborate to come up with a startup idea, which they then
pitch to simulated investors. This kind of exercise is not
merely useless but positively misleading. It trains founders
to think that fundraising is the essential step in starting
a startup — that the core of starting a startup is to
create a story that appeals to investors. As an investor, I
can tell you that's not true. Fundraising is merely a
necessary evil. The people you need to impress are users,
not investors, and the way you impress them is with
prototypes, not words. The core of starting a startup is not
creating a story that appeals to investors, but creating a
product that appeals to users.
In fact would-be founders should be doing exactly the
opposite of what students do in business plan competitions.
Instead of thinking about startups without building
anything, they should be building things without thinking
about whether they'll turn into startups.
Probably one of the reasons universities are tempted to
organize bogus things like business plan competitions is
that if they actually took the optimal measures to prepare
students to start startups, it would look too quiet. Imagine
if a university were doing everything right. Students would
be getting a deep knowledge of how to build things in
classes they were taking out of genuine interest, and
working eagerly with their friends on side projects that had
nothing to do with school. The students would graduate with
exactly what predicts success in founders: the ability to
build things and a habit of doing it. Plus a significant
number of those side projects would be incipient startups.
And yet it would look to parents and prospective students as
if the university wasn't doing anything. Where are the
classes on "entrepreneurship"? Where is the Innovation
Center?
And indeed this is another great thing about the optimal
plan for preparing startup founders: it costs nothing extra.
You don't have to hire any deans of entrepreneurship or
build any new buildings. In fact if you do, those things
will tend to drag you down; there's no need for them, so if
they have any effect at all it will tend to be for the
worse. If you have spare money, give it to the people
teaching computer science or mechanical engineering or
molecular biology.
But if the optimal route looks too quiet, the solution is
not to avoid it. The solution is to stand firm, knowing that
you're doing the right thing, and eventually the results
will speak for themselves. If you can develop an organic
startup culture among your students and there are multiple
students in every year who go on to start successful ones,
this will soon become evident to anyone paying attention.
Notes
[
1
]
Should students still study computer science if AIs
will write most code? Definitely. CS is an interesting
subject in its own right and also a great way to understand
problem solving in general. And even if you have AIs writing
all your code for you, you're still in the position of an
engineering manager, and good engineering managers should be
able to do the work of those working for them.
[
2
]
One reason I always put "entrepreneurship" in quotes
is that it's a misleading word to use to describe starting
startups. "Entrepreneurship" simply means starting one's own
business, and startups are a microscopically small subset of
that world in which the rules are completely different. So
conflating the two is asking for trouble.
[
3
]
Of course all departments will claim to be teaching
powerful ideas. But false claims of this type don't seem
much of a danger. The sort of people who'd make good
founders wouldn't even need to see through them; they simply
wouldn't be interested enough in the classes taught by such
departments to have much of their time wasted by them.
[
4
]
There's an interesting parallel here to variation in
income. The bottom of the income scale is anchored firmly at
zero, because there are some people who are either incapable
of working or just not interested in doing it at the moment.
If you let there be more variation in income, it won't
affect the income of the people at this end of the scale; n
times zero is zero; but at the other end of the scale you'll
see enormous change.
[
5
]
Presumably one reason these competitions lean toward
impressing investors rather than users is that it's the only
way to have a single set of judges. Investors can be treated
as interchangeable, whereas the users of each product might be
different. But if it's impractical to measure the right
thing, that doesn't mean the solution is to measure the
wrong one.
[
6
]
Another thing that will tend to draw universities away
from the optimal path is business schools, if they have
them. Business schools were not designed to train founders.
They were designed to train the managerial class of the
large industrial companies that arose in the early 20th
century; they're the West Points of industrial capitalism.
That's why their official name is usually the School of
Management. But while the skills they teach might be useful
in running companies beyond a certain size, they're not the
critical ingredient in
founding
them. And the skills that
are are already taught by other departments. So to the
extent business schools affect their parent university's
strategy for preparing founders, it can only be by adding
error.
Thanks
to Trevor Blackwell,
Daniel Diermeier, Jared
Friedman, Diana Hu, Michael Kotlikoff, Jessica Livingston,
Robert Morris, Harj Taggar, and Garry Tan for reading drafts
of this.
The
icon indicates free access to the linked research on JSTOR.
In the mid-twentieth century, modern art and design
represented
the liberalism, individualism, dynamic activity, and creative risk possible in a free society. Jackson Pollock’s gestural style, for instance, drew an effective counterpoint to Nazi, and then Soviet, oppression. Modernism, in fact, became a weapon of the Cold War. Both the State Department and the CIA supported exhibitions of American art all over the world.
The preeminent Cultural Cold Warrior, Thomas W. Braden, who served as MoMA’s executive secretary from 1948-1949, later joined the CIA in 1950 to supervise its cultural activities. Braden
noted, in a
Saturday Evening Post
article titled “I’m glad the CIA is ‘immoral’”
that American art “won more acclaim for the U.S. …than John Foster Dulles or Dwight D. Eisenhower could have bought with a hundred speeches.”
The relationship between Modern Art and American diplomacy began during WWII, when the Museum of Modern Art was mobilized for the war effort. MoMA was founded in 1929 by Abby Aldrich Rockefeller. A decade later, her son Nelson Rockefeller became president of the Museum. In 1940, while he was still President of MoMA, Rockefeller was appointed the Roosevelt Administration’s Coordinator of Inter-American affairs. He also served as Roosevelt’s Assistant Secretary of State in Latin America.
The Museum followed suit. MoMA
fulfilled
38 government contracts for cultural materials during the Second World War, and mounted 19 exhibitions of contemporary American painting for the Coordinator’s office, which were exhibited throughout Latin America. (This direct relationship between the avant-garde and the war effort was well suited: The term avant-garde
actually began
as a French military term to describe vanguard troops advancing into battle.)
In the battle for “hearts and minds,” modern art was particularly effective. John Hay Whitney, both a president of MoMA and a member of the Whitney Family, which founded the Whitney Museum of American Art,
explained
that art stood out as a line of national defense, because it could “educate, inspire, and strengthen the hearts and wills of free men.”
Whitney succeeded Rockefeller as President of the Museum of Modern Art in January 1941, so that Nelson could turn his entire attention to his Coordinator duties. Under Whitney, MoMA served as “A Weapon of National Defense.” According to a
Museum press release
dated February 28, 1941, MoMA would “inaugurate a new program to speed the interchange of the art and culture of this hemisphere among all the twenty-one American republics.” The goal was “Pan-Americanism.” A “Traveling Art Caravan” through Latin America “would do more to bring us together as friends than ten years of commercial and political work.”
When the War ended, Nelson Rockefeller returned to the Museum, and his Inter-American-Affairs staffers assumed responsibilities for MoMA’s international exhibition program: René d’Harnoncourt, who had headed Inter-American’s art division, became the Museum’s vice president in charge of foreign activities. Fellow staffer Porter McCray became the Director of the Museum’s International Program.
Modern art was so well aligned with American Cold War foreign policy that McCray took a leave of absence from the Museum in 1951 to work on the Marshall Plan. In 1957, Whitney
resigned
his position as MoMA’s Chairman of the Board of Trustees to become United States Ambassador to Great Britain. Whitney remained a trustee of the Museum while he was Ambassador, and his successor as Chairman was… Nelson Rockefeller, who had served as Special Assistant to President Eisenhower for Foreign Affairs until 1955.
Georgia O’Keefe colors the landscape around a model of CIA headquarters
Even though Modern art and American diplomacy were of a piece, Soviet propaganda
asserted
that the United States was a “culturally barren” capitalist wasteland. To make the case for American cultural dynamism, the State Department in 1946 spent $49,000 to purchase seventy-nine paintings directly from American Modern artists, and mounted them in a traveling exhibition called “
Advancing American Art.
” That exhibition, which made stops in Europe and Latin America, included work from artists such as
Georgia O’Keeffe
and
Jacob Lawrence
.
Despite positive reviews from Paris to Port au Prince, the exhibition stopped short in Czechoslovakia in 1947, because Americans themselves were indignant.
Look Magazine
fired off an article entitled “Your Money Bought These Paintings.” The
Look
piece questioned why U.S. tax dollars were being spent on such confusing pieces of art—and wondered if these were paintings even art. Harry Truman took one look at Yasuo Kuniyoshi’s painting
Circus Girl Resting
, which was included in the exhibit, and said, “If this is art, I’m a Hottentot.”
In Congress, Republican Representatives John Taber of New York, and Fred Busbey of Illinois worried that some of the artists held Communist sympathies, or engaged in “Un-American Activities.”
The American public’s fear of the
Red Menace
brought “Advancing American Art” home early, but it was precisely
because
Modern art was
not
universally popular, and was created by artists who openly disdained orthodoxy, that it was such an effective tool in showcasing the fruits of American cultural freedom to anyone looking in from abroad. President Truman
personally considered
Modern art, “merely the vaporings of half-baked lazy people.” But he did not declare it degenerate and expel its practitioners to gulags in Siberia. Not only that, abstract expressionism in particular was a direct repudiation of Soviet Socialist Realism. Nelson Rockefeller liked to call it “Free Enterprise Painting.”
In contrast to the Soviet Union’s “Popular Front,” the
New Yorker
magazine wonderfully, and perfectly,
referred
to the political role of American Modernism as “The Unpopular Front.” The very existence of American Modern Art proved to the world that its creators were free to create, whether you liked their work or not.
If Advancing American Art proved the nation’s artists were free because they could splatter as much paint as they wanted, it also proved that Congress could not always be induced to spend tax dollars supporting it. Braden later
wrote
, “the idea that Congress would have approved many of our projects was about as likely as the John Birch Society’s approving Medicare.” Clearly the State Department wasn’t the right patron for Modern Art. Which brings us to the CIA.
In 1947, at the very moment that the Advancing American Art show was being recalled, and the United States Government was selling its O’Keeffe’s for fifty bucks a-piece (all seventy-nine pieces in the show together brought in $5,544), the CIA was being created. The CIA grew out of “Wild” Bill Donovan’s Office of Strategic Services (OSS), which was the U.S.’s wartime intelligence apparatus. MoMA’s John Hay Whitney and Thomas W. Braden had both been members of the OSS.
Their fellow operatives
included
the poet and Librarian of Congress Archibald MacLeish, the historian and public intellectual Arthur M. Schlesinger, Jr., and the Hollywood director John Ford. By the time the CIA was codified in 1947, clandestine affairs had long been the arena of America’s cultural elite. Now, as museum staffers like Braden joined, the cultural cognoscenti and the CIA fought the Cultural Cold War side by side, with the Whitney Trust acting as a funding conduit.
Speaking of front organizations, in 1954, MoMA took over (from the State Department) the U.S. Pavilion at the Venice Biennale, so that the U.S. could continue to exhibit Modern art abroad without appropriating public funds. (MoMA owned the U.S. pavilion at Venice from 1954 to 1962. It was the only national pavilion at the show that was privately owned.)
Eisenhower made MoMA’s role as a government proxy clear in 1954, speaking at the Museum’s twenty-fifth anniversary celebration. Eisenhower
called Modern art
a “Pillar of Liberty,” saying:
As long as our artists are free to create with sincerity and conviction, there will be healthy controversy and progress in art. How different it is in tyranny. When artists are made the slaves and tools of the state; when artists become the chief propagandists of a cause, progress is arrested and creation and genius are destroyed.
It was MoMA’s job, concurred United States Ambassador to the Soviet Union, to demonstrate to the rest of the world “both that we have a cultural life and that we care about it.”
The CIA not only helped finance MoMA’s international exhibitions, it made cultural forays across Europe. In 1950, the Agency created the Congress for Cultural Freedom (CCF), headquartered in Paris. Though it appeared to be an “autonomous association of artists, musicians and writers,” it was in fact a CIA funded project to “propagate the virtues of western democratic culture.” The CCF operated for 17 years, and, at its peak, “had offices in thirty-five countries, employed dozens of personnel, published over twenty prestige magazines, held art exhibitions, owned a news and features service, organized high-profile international conferences, and rewarded musicians and artists with prizes and public performances.”
The CIA chose to headquarter the Congress for Cultural Freedom in Paris, because that city had long been the capital of European cultural life, and the CCF’s main goal was to convince European intellectuals, who might otherwise be swayed by Soviet propaganda, which suggested that the U.S. was home only to capitalist philistines, that in fact the opposite was true: with Europe weakened by war, it was now the United States that would protect and nurture the western cultural tradition, in the face of Soviet dogma.
Braden, writing about his role in the CCF as director of the CIA’s cultural activities,
explained
in 1967, “in much of Europe in the 1950’s, socialists, people who called themselves ‘left’—the very people whom many Americans thought no better than Communists—were the only people who gave a damn about fighting Communism.” When the CIA made its bid to the European intelligentsia, the Agency was waging what Braden called “the battle for Picasso’s mind,” via Jackson Pollock’s art.
Accordingly, the CIA bankrolled the
Partisan Review
, which was the center of the American non-Communist left, carrying enormous cultural prestige in both the U.S. and Europe because of its association with writers like T.S. Eliot and George Orwell. Unsurprisingly, the editor of the
Partisan Review
was the art critic Clement Greenberg, the most influential
arbiter of taste
, and the strongest proponent of abstract expressionism in post-war New York.
The CCF worked with MoMA to mount 1952’s “Masterpieces of the Twentieth Century” Festival in Paris. The works for the show came from MoMA’s Collection, and “established the CCF as a major presence in European cultural life,” as the historian Hugh Wilford wrote in his book
The Mighty Wurlitzer: How the CIA Played America
.
Curator James Johnson Sweeney made sure to note that the works included in the show “could not have been created . . . by such totalitarian regimes as Nazi Germany or present-day Soviet Russia.” Distilling this message even further in 1954, MoMA’s August Heckscher declared that the museum’s work was “related to the central struggle of the age—the struggle of freedom against tyranny.”
Editors’ Note: An earlier version of this article misquoted President Truman. He considered Modern art “merely the vaporings of half-baked lazy people,” not “the
vaporizings.”
In the first quarter of 2026, 13.0% of newly written agent skills were in a language other than English, and one quarter later it was 16.3%. That is three points in three months across 255,068 skills, with confidence intervals nowhere near touching. For comparison, GitHub-wide non-English documentation took ten years to travel from 3.7% to 13.0%, so whatever is happening here is happening at a different speed entirely, and the most plausible explanation is that AI development has arrived somewhere other than San Francisco.
Reviewing the data, it turns out that the claim is stronger than the obvious version of it, because
English is not a proxy for American
. GitHub's fastest-growing developer population by a wide margin is India, which writes in English, as do Nigeria and Singapore, so a language count cannot see any of them. The non-English share is therefore not a measure of how much of this ecosystem sits outside the United States. It is a floor beneath it, and everything below should be read that way.
For context, a skill is a
SKILL.md
file in a folder, holding instructions for an AI agent in plain prose, loaded when the agent judges the task relevant. Anthropic published the specification in October 2025, and it spreads the way a recipe spreads: somebody copies it. Nine months later there were 3.8 million of them across 282,200 public repositories, which is what the
GitSkills dataset
collects. Skills are strange as software, by which we mean the traditional kind, because this is one of the things AI has upended. They are written in human language and the runtime is a multilingual model, so there is no technical reason to write one in English: a developer in Shenzhen or São Paulo can state a procedure more precisely in their own language, and the agent will follow it. Whether it follows it as
well
is a better question, and much harder to answer than anything a file crawl can settle.
the distribution
We ran language identification over the prose body of every distinct skill, after stripping front matter and fenced code.
horizontal bar chart, language distribution
1,870,299 distinct skill contents. The 14.3% that are not English are led by Chinese.
Language
Share of distinct skills
English
85.3%
Chinese
6.2%
Japanese
1.7%
German
1.6%
Korean
1.2%
Portuguese
1.1%
Spanish
0.9%
French
0.4%
So 14.3% of skills are not in English, and split by script the Chinese ones run 104,985 simplified against 9,112 traditional. The rows above do not quite sum to that, because 6,810 skills came back below our confidence floor and are counted as neither. The comparison worth making is against GitHub's own documentation instead of its issues or pull requests, and a
2026 ICSE study
put repository documentation at 13.0% non-English, with Chinese at 3.3% of repositories. In aggregate that makes skills unremarkable, 14.3% against 13.0% being a dead heat. They are markedly more Chinese, though, 6.2% against 3.3%.
why every published number disagrees
Ours is not the only published figure, and the published figures do not agree with each other.
These are not contradictions, they are five different populations: curated marketplaces skew English, domain slices skew toward wherever that domain happens to be active, and a crawl seeded with English queries will find English. The first candidate to rule out is us, because if our identifier simply saw less English than everyone else's then the whole comparison would be an artifact of tooling. So we ran both over the same documents, py3langid which we use and fast-langdetect which the 92.6% study used. They agree on 97.6% of documents, and their English shares sit +1.2 points apart against a gap of around seven. Quality screening looks like the next good candidate and leads nowhere either: if corpora that filter for valid front matter were quietly discarding non-English skills that would explain some of the spread, but non-English skills have slightly
better
front-matter validity, 88.1% against 86.6%, and filtering moves the English share only from 85.6% to 85.4%. What is left is where you looked. That generalises well past this dataset, so when someone tells you what "the AI ecosystem" looks like, the registry they scraped may hold more of the answer than anything else they say.
skills are getting less English
Skills carry commit history, so each one has a creation date, and that turns a static pie chart into a trend.
non-English share by month, with confidence band
Band is the 95% Wilson interval. July 2026 is shaded: collection ran mid-month, so that cohort is censored and excluded from comparisons.
Quarter
Non-English share
2026 Q1
13.0% [12.8, 13.1]
2026 Q2
16.3%
[16.1, 16.4]
Month by month the climb is not smooth, since February dips to 10.9% before March resumes at 14.2%, but the direction across the window is not in doubt: 13.1% in January against 17.6% in June. That is roughly what you would expect of a format eighteen months old, since new artifact types acquire their demographics much faster than mature ones when there is no incumbency to overcome. But "non-English" is not one thing, and broken out, the rise turns out to be carried by two of the four groups rather than by all of them.
small multiples, share by quarter per language, with confidence bands
Chinese
+2.1 pts
25-Q4 → 26-Q2
Japanese
-1.0 pts
25-Q4 → 26-Q2
Korean
+0.3 pts
25-Q4 → 26-Q2
European
+4.2 pts
25-Q4 → 26-Q2
Shaded band is the 95% Wilson interval; the hollow final point is the censored July cohort, plotted but never compared. European groups German, French, Spanish, Portuguese, Italian, Russian and Dutch.
2026 Q1
2026 Q2
Change
Chinese
4.2% [4.1, 4.4]
5.3% [5.2, 5.4]
+1.1
European
2.7% [2.6, 2.8]
5.5% [5.4, 5.6]
+2.8
Korean
2.2% [2.1, 2.3]
2.0% [1.9, 2.0]
-0.2
Japanese
3.2% [3.1, 3.3]
2.5% [2.4, 2.5]
-0.7
European languages, by which we mean German, French, Spanish, Portuguese, Italian, Russian and Dutch grouped together, more than double across the window while Chinese climbs steadily, and Japanese and Korean do neither: Japanese was the most common non-English language at the end of 2025 and slipped through the first half of 2026 as everyone else arrived, while Korean stays flat throughout. The censored July cohort hints that Japanese is recovering, and we are not counting it. Changes are measured between the two complete quarters, 2026 Q1 and Q2, since the final column is the July collection month and is censored, so it appears in the chart but never in a comparison.
why we believe it
A trend like this is exactly the kind of thing that turns out to be an artifact, so we spent longer trying to break it than we did finding it. Commit history exists for only 24% of skills, and that subsample leans toward heavily copied ones, which matters because copying turns out to be strongly related to language. The worry, in other words, is that we are watching a selection effect and not a change in what people write. Holding copies fixed at one, the rise is larger than the headline, 14.7% to 18.1%; counting each repository only once, so that no bulk uploader can swing it, the rise survives at 14.5% to 16.8%.
the clock
Commit timestamps are stored in UTC, so an author's local timezone is gone before we ever see the file. But people mostly commit while they are awake, and if a group of skills is written by people in one part of the world, their commits should vanish during that region's night.
24-hour dials, one per language
English
n=384,979
Chinese
n=21,939
Japanese
n=12,908
Korean
n=9,388
Spanish/Portuguese
n=9,936
Centre figure is the share of first commits in that window. The non-English groups are small, so read the contrast, not the decimals.
Language
Commits during East Asian night
n
English
35.7%
384,979
Chinese
15.3%
21,939
Japanese
15.9%
12,908
Korean
18.7%
9,388
Spanish/Portuguese
46.5%
9,936
Chinese-language skills fall to less than half the English rate in that window, while English itself stays flat across all twenty-four hours, which is the signature of a globally distributed population with no single night. Spanish and Portuguese run the opposite way and peak at 19:00 UTC, mid-afternoon in Brazil and late evening in Iberia, which places those authors in the Americas. Nothing in the language identifier knows what time a file was committed, so the two signals are independent, and they agree.
Honest limits.
This is a population-level phase estimate, good to a couple of hours at best; it cannot separate UTC+8 from UTC+9, a language is not a country, and it says nothing whatsoever about any individual author. We found no published validation of hour-of-day inference at this granularity, so treat it as corroboration and not as geolocation. A raw git commit does record the author's UTC offset, and this dataset normalised it away, which is the fix for anyone building on this.
the same story from outside
We are reading one artifact type on one platform, so the question that matters is whether anyone measuring something else sees the same movement, and they do, at a larger scale than we can.
GitHub's own
Octoverse 2025
reports that India added 5.2 million developers in a single year, about 14% of the 36 million accounts opened worldwide, which takes it to 21.9 million and second place globally. That is 4.9 times its 2020 population. Brazil grew 4.1 times over the same period, Indonesia 4.8 and Japan tripled, and new signups now run at roughly 25 a minute across APAC against 12 across Europe. India, Brazil and Indonesia together account for about half of all new accounts. Stanford's
2026 AI Index
puts generative-AI adoption at 64% in the United Arab Emirates and 61% in Singapore, against 28.3% in the United States, which ranks twenty-fourth. Its policy chapter records open-source contributions "from the rest of the world now outpacing Europe and approaching the United States on GitHub", and its education chapter finds AI engineering skills accelerating fastest in the UAE, Chile and South Africa.
None of that is about agent skills, which is exactly what makes it useful: three independent measurements of where AI development is happening, none of them looking at
SKILL.md
files, all of them pointing the same way. Our number is the same phenomenon surfacing in a corpus eighteen months old. Our number also cannot see most of it. India writes in English, so the largest single engine of GitHub's growth is invisible to a language count, and so are Nigeria and Singapore, which is why 14.3% should be read as the floor beneath whatever share of this ecosystem now sits outside the United States.
copied, or tended?
non-English share by copy count
Across all 1,870,299 distinct contents. Removing the ten aggregator repositories, or counting distinct owners, widens the gap.
English skills get copied more.
The non-English share falls steadily the more a skill is reused, from 15.7% among skills nobody has ever copied down to 5.8% among those copied six or more times. That one needed defending, because a great deal of what looks like copying on GitHub is really archiving. Ten repositories hold 14.5% of every skill file here, and they are registries and mirrors rather than authors, so 282,200 repositories behave, by concentration, like about 250. Those aggregators turn out to lean non-English, 20.5% against 13.7% elsewhere, so whatever they are doing to the numbers works against this pattern instead of producing it. Excluding them leaves the gap where it was, 15.1% down to 5.3%, and counting distinct owners, so that one actor vendoring a skill into ten of their own repositories counts once, widens it slightly to 15.1% against 4.6%.
But non-English skills get revised more.
That needs an age correction, since non-English skills are younger on average and have had less time to be touched, so the comparison below holds age fixed and asks what share of skills at least N days old were revised within their first N days.
revision rate at 7, 30 and 90 day windows
Compared at equal age: among skills at least N days old, the share revised within their first N days.
Window
English
Non-English
7 days
14.4%
15.7%
30 days
21.7%
26.9%
90 days
28.7%
33.9%
The gap opens over the first month and then holds, +1.3 points at a week, +5.2 at a month and +5.2 at three, which leaves two populations behaving quite differently: English skills propagate, written once and copied widely and rarely touched again, while non-English skills are tended, copied less and revised more. The likely reason for the copying half is search. Discovery is lexical, and a developer searching in English will not surface a skill written in Chinese even where a multilingual model could execute it perfectly, so what stands between a Shenzhen developer's skill and the person who needs it is a text match. If that is right, the ecosystem globalises in what gets written well before it globalises in what gets reused, and the lag between the two is a tooling problem somebody could fix.
who is actually writing these?
The
GitSkills authors
asked one more thing worth answering: how many skills do agents write themselves? The obvious way to check fails immediately, because GitHub's own bot flag catches almost nothing: agent-written code is committed under the human's account. The signal that does work is the trailer, the
Co-Authored-By
line a coding agent appends to commits it authored, which is the tool claiming authorship instead of us inferring it from prose.
Measure
Value
Name an AI agent in a commit trailer
30.4%
[30.3, 30.6]
Flagged as a bot by the platform
1.0%
Japanese skills, agent-authored
43.4%
Chinese skills, agent-authored
23.2%
Nearly a third of skills carry an agent's fingerprint and the platform sees almost none of it, with Claude accounting for the overwhelming majority of those trailers while Cursor, Copilot and Codex trail far behind, and the trailers even carry model versions. Read it as a floor, since a skill whose author stripped the trailer, or squashed it away, or used a tool that never emits one, counts as human here.
what this does not show
Language identification keys on script and function words, so a German skill thick with English technical vocabulary gets pulled toward English, which is another reason the non-English share is a lower bound. Dates cover only part of the corpus and only deduplication representatives, so "created" means the first commit touching
that copy
and not the first appearance of that content anywhere. And a crawl sees only survivors, so any skill created and deleted before July 2026 is invisible to us, which inflates every maintenance figure here by an amount we cannot estimate.
what we would want to know next
The number we cannot get from this data is whether any of it costs anything. A skill written in Chinese and never copied might be worse, or might be identical work that nobody found, and those two worlds look the same from a file crawl while implying opposite things. Separating them needs execution traces, and if somebody has those we would like to see them. The larger question is what the floor actually rests on. 14.3% of skills are not in English and the share is climbing three points a quarter, while the fastest-growing developer population on the platform writes in English and never appears in that count at all. Whatever the real number is, everything we can measure says it is moving in one direction, and faster than anything comparable has moved before.
Article 02 stays on this corpus and asks which
programming
languages skills talk about. Our first pass had Shell/Bash leading every language at 37.5%, which turned out to be an artifact of counting pasted commands, and measured by what a skill actually ships Python leads at 7.6% while Shell drops to 3.1%.
credit
None of this exists without the dataset, which was built and released by someone else, and all credit for collecting, deduplicating and documenting 3.8 million skill files belongs to its authors:
Giuseppe Destefanis, Daniel Graziotin, Matteo Vaccargiu, and Marco Ortu. 2027.
GitSkills: A Dataset of Agent Skills on GitHub
. In
Proceedings of the 24th International Conference on Mining Software Repositories (MSR '27)
.
GitSkills
is the dataset for the MSR '27 Mining Challenge, and we are not affiliated with its authors, with MSR, or with the challenge, so nothing here should be read as endorsed by them: the dataset is theirs, and the analysis and any error in it is ours. Several of the research questions we take up, including which natural languages skills are written in, are ones the
GitSkills authors
posed and left open.
Analysis code lives at
github.com/plicara/articles
under
gitskills-analysis/
, where every figure is generated from a single machine-readable export and never typed by hand, so the whole thing can be regenerated and checked.
Found something wrong? We would genuinely like to know.
[Sponsor] Finalist 4: Inspired by Paper Day Planners
Daring Fireball
www.finalist.works
2026-08-24 20:37:24
Finalist 4 is the biggest update yet to the paper-inspired day planner for iPhone, iPad, Mac, and now Apple Watch. The headline is Notes, in the app or as a folder of Markdown files that round-trips with Obsidian. Tasks in those files land on the right day, next to your reminders and events, even in...
Your tasks, calendar, notes, habits, and journal, woven into one living page. On iPhone, iPad, Mac, and now Apple Watch. Plan your day without feeling stressed about it.
Finalist started three years ago as the planner I couldn't buy: one page that holds the whole day the way a good paper planner does, with everything paper can't do. Version 4.0 is the biggest release since 1.0. Notes moved in. The Watch app arrived. The Daily page became something you design.
All of it is below, and all of it is a free update.
— Slaven, developer of Finalist
"Finalist is so beautiful and thoughtfully designed that it makes me want to use it."
Section A ·
Your Day
Your whole day, on one page.
Events, tasks, reminders, habits, the weather, even your journal. Finalist sets them on a single page, so deciding what today is for takes one look.
Two Daily designs, same day. Flip the index tabs.
Two designs, and a layout editor.
Daybook is the classic. Broadsheet is the newsprint look that shines on iPad and Mac. The Layout Editor goes further: multi-column spreads, a different layout per device, presets you can save. Your day ends up looking like you.
A favorite trick: tap Broadsheet's World Clock and the masthead retunes to another city's day, date and weather and all.
Made to lower your pulse.
The page shows only the parts you use. Unfinished tasks roll forward without shame. Snooze is one tap: 15 minutes, 4 hours, or pick a day.
Share Day renders the day you're viewing as a clean, chrome-free image. Pick a theme, crop it, send it.
"It puts all of my thoughts in a single day, whether they be work appointments or personal tasks or intentions, while not overwhelming me with info I don't need."
Sketch your day
in pencil
. Commit when it's real.
The rebuilt Timeline compresses free time into blocks and lets you drag tasks straight from the rail.
9:00
Team standup
Calendar · 25 min
10:00
Draft the pitch
penciled
Draft the pitch
accepted ✓
Drag a task from the rail to pencil it in. Resize with the handle. Accept writes the time into the real task.
Penciled times are tentative. Resize them, move them, change your mind. Nothing touches your real tasks and reminders until you tap
Accept
, and all of it is undoable.
Time blocking for people who hate committing before 9 AM.
Section B ·
Every Thread
Pick a Tag and hide the rest.
Tags now run across everything: tasks, notes, journal entries, habits, even Apple reminders and calendar events. Tap a tag on Daily and the day shows just that thread of your life.
Anything that holds dated tasks can unfold into a swimlane timeline: a tag, a list, a Smart List, even a markdown file or a whole folder. Columns adapt from days to weeks to months, so a year-long project stays legible on one screen.
Section C ·
Notes
Planning, meet note taking.
Tasks tell you what, notes tell you why. A new Notes tab brings notebooks, an inbox, tags, and search into the planner you already open every day. Pin a note to show on every Today, or pick a date for it to place it on that day only.
Already keep a folder of Markdown files?
Point Finalist at it. Obsidian vaults, iCloud Drive, any folder of .md files becomes a native notebook. Frontmatter round-trips both ways, unknown keys preserved. Tasks in your files become real Finalist tasks, on the right date, with the right tags. Wiki links, Dataview fields, and extended task statuses resolve right in the app.
If you have ever kept your schedule in one app and your notes in another, this release will end that commute.
A full Watch app that runs even when your phone stays home. The Now card answers the day's current question, then your whole day scrolls below: events, tasks, reminders, habits. Long-press a task for Done, Tomorrow, or In 10 Minutes. And yes, the shared grocery list is checkable from the wrist.
In a block
Off the clock
On the face
Complications, a Smart Stack widget, and a big complication that wears your day's Highlight colors. Add by keyboard, scribble, or dictation. Requires watchOS 26.
milk
call dentist tue
pack for trip fri
birthday card!
→
→
Buy milk
Today
Call dentist
Tue
Pack for trip
Fri
Get birthday card
Today
Capture.
Point it at a handwritten list, a screenshot, or anything you share into Finalist. Dated tasks come out, fields already filled. Dictate a note and it titles itself. Apple's on-device models do the work, so nothing about your day leaves your device.
Why it sticks
Works with your brain, not against it.
Planner apps fail when they turn your day into a guilt list. Finalist is built to lower the stakes: move a task to tomorrow without ceremony, keep the page down to what matters now, and let streaks encourage instead of punish.
"It has helped keeping up with my to do list, makes it easy to move unfinished tasks to the next day without making me feel guilty, and gives me a space to do some short journaling during the day."
"I have tried them all. Truly. Spent gobs of money on all of the heavy hitters. But THIS ONE works with my brain and just plain works."
And the rest of the paper
The 4.0 changelog runs to
over 400 features and improvements
. A few favorites:
Share Day
Your day as a clean image, ready to send.
Smart Lists
Overdue, Due Today, This Week, across tasks, Reminders, and markdown.
Hear Summary
Your day read aloud, with a real player and read-along transcript.
Widgets
Tap a checkbox to complete it right on the widget.
Live Activities
Your current block, on the lock screen.
Custom event icons
Map your own words, in any language, to event symbols.
Yearly Planner
Paint highlight runs with one swipe, then caption them.
Convert anything
Turn a task into a reminder or an event, and back.
Your hours
Define Morning, Afternoon, and Evening, each with its own focus.
Journal
Photos, daily goals, and your sleep from Apple Health.
Meeting links
A compact Join button instead of a full-width URL.
Shortcuts & Siri
Create and append notes, add tasks, hands free.
Letters to the editor
"Where has this app been all my life!"
Finalist user, December 2025
"I've used a lot of to-do apps in the past including Todoist, OmniFocus, Obsidian, and NotePlan. But Finalist fits me much much better!"
"The design language is clean, analog-almost, and feels like a digital extension of a physical planner, with the peace of mind of digital remembrance."
"I've gotten rid of all my other to-do apps and now this is the only one I'll use. I love looking at it, and if I'm looking at it, it means my stuff is getting done."
"A standout app that has a great future. Very responsive developer who is very open to feedback and keeps reiterating with useful additions."
"If you have not tried it yet, get ready for a surprise. Finalist is the best available iOS, iPadOS, and macOS task and event manager in the App Store."
"Guys, no joke, Finalist is really a great app. Slaven has put a lot of effort in developing the app, and introducing new features."
Finalist 4.0 · Out now
Plan tomorrow like you mean it.
Free to try. 4.0 is a free update, and one subscription or a lifetime license covers iPhone, iPad, Mac, and Apple Watch. Built by one person, shaped by 700+ beta testers on Discord.
"It's just so obvious, just using it, that Finalist is his own dream app for daily productivity."
This Week in People’s History, Aug 26-Sep 1, 2026
Portside
portside.org
2026-08-24 20:32:11
This Week in People’s History, Aug 26-Sep 1, 2026
Jonathan Bennett
Mon, 08/24/2026 - 20:32
...
TEN YEARS AGO, ON AUGUST 26, 2016,
Colin Kaepernick, a quarterback on the San Francisco 49ers football team, made a silent protest when he sat down while “The Star-Spangled Banner” was being played before the game. It was not the first time he had made a similar protest, but was the first time he did so when he was in uniform, so no one had mentioned noticing his earlier actions.
On this occasion, when a reporter asked Kaepernick about it, he replied: “I am not going to stand up to show pride in a flag for a country that oppresses Black people and people of color. To me, this is bigger than football and it would be selfish on my part to look the other way. There are bodies in the street and people getting paid leave and getting away with murder.”
That was the beginning of Kaepernick’s decade-long struggle to be both an outspoken anti-racist and a successful professional athlete; he has never stopped being an anti-racist, but the National Football League has sabotaged his professional athletic career by refusing to hire him, not because of a lack of athletic talent, but apparefntly because the owners of NFL teams refuse to employ players who are outspoken anti-racists.
When it became clear that the NFL team owners had blacklisted him, Kaepernick filed a grievance stating the owners "have colluded to deprive Mr. Kaepernick of employment rights in retaliation for Mr. Kaepernick's leadership and advocacy for equality and social justice and his bringing awareness to peculiar institutions still undermining racial equality in the United States." Under the NFL contract, grievances are resolved by arbitration, but before the arbitration took place, the owners and Kaepernick reached a confidential settlement, the details of which remain secret.
In less than a month from now, on September 15, 2026, Kaepernick’s memoir of his struggle,
The Perilous Fight
will be published by Legacy Lit. According to the publisher,
The Perilous Fight
is “equal parts memoir and manifesto, [which] traces the off-the-field battles that turned a single act of protest into a movement that changed American sports and culture forever.”
https://portside.org/2016-08-30/insulting-colin-kaepernick-says-more-about-our-patriotism-his
You Don’t Need Official Permission to Adjudicate Crimes Against Humanity (1966)
SIXTY YEARS AGO, ON AUGUST 28, 1966,
the U.S. war against Vietnam was growing bigger and bloodier every day.
On that day, more than 250,000 U.S. troops were stationed in South Vietnam; for more than four years U.S. forces had sprayed massive amounts of Agent Orange defoliant on the forests and farmland of Vietnam; for more than 17 months the U.S. had bombed both civilian and military targets in northern Vietnam.
Hundreds of thousands of people in cities and towns all over both the U.S. and Europe had participated in massive, peaceful, demonstrations against the war; on that day Nobel-prize-winning philosopher Bertrand Russell joined the protests by asking President Lyndon Johnson to testify in his own defense before an International War Crimes Tribunal in order to rebut the charge that the U.S. was committing war crimes.
Russell wrote that “Within living memory only the Nazis could be said to have exceeded in brutality the war waged by your Administration against the people of Vietnam, and it is because this war is loathed and condemned by the vast majority of mankind that demands are heard throughout the world for a formal international tribunal to hear the full evidence."
LBJ ignored Russell’s letter, but after the Tribunal heard the testimony of more than 35 witnesses, on May 10, 1967, its 16 members unanimously found that the U.S. had violated international law by committing acts of aggression against Vietnam, and by bombarding purely civilian targets such as hospitals, schools, medical establishments and dams, and that the governments of Australia, New Zealand and South Korea were accomplices in the illegal aggression against Vietnam. For more information, see
Against the Crime of Silence: Proceedings of the Russell International War Crimes Tribunal
at
https://archive.org/details/againstcrimeofsi0000unse
You Can Trust Us, We’re Landlords (1966)
SIXTY YEARS AGO, ON AUGUST 29, 1966,
a possible showdown loomed in Chicago between two groups of civil rights advocates, some of whom were committed entirely to non-violent tactics and others of whom advocated the right to defend themselves when violently attacked.
A march had been planned demanding an end to the housing policies that prevented any people of color from living in Cicero, a suburb that shared a border with Chicago. But then some of the planners called the march off because they had reached an agreement with Cicero authorities on a way to end the suburb’s total ban on Black residents.
The cancellation of the march was opposed by the more militant open-housing advocates, who argued that it was impossible to gauge the good faith of Cicero landlords before the agreement had even gone into effect. If the landlords and Cicero officials were sincere in agreeing to relax the color line, surely they had no reason to object to a demonstration in support of what they had agreed to.
The more militant of the civil rights supporters, which included the Chicago chapter of the Congress of Racial Equality (CORE), the Association of Community Teams, the Student Nonviolent Coordinating Committee, the Oakland Committee for Community Improvement, and Deacons for Defense and Justice, announced they planned to march through Cicero on Sunday, September 4.
The next edition of This Week in People’s History will include a complete description of what happened in Cicero, Illinois, on September 4, 1966.
Dying in the Desert? Don’t Expect any Help from ICE (2006)
TWENTY YEARS AGO, ON SEPTEMBER 1, 2006,
before the Homeland Security mafia had taken over,
a federal judge in Tucson, Arizona, told the Border Patrol it should never have arrested two humanitarian aid workers on charges of conspiracy and human smuggling when the two had been, in fact, rushing three desert travelers, who were strangers to the aid workers, to a clinic for treatment of multiple life-threatening conditions.
The two aid workers were facing the possibility of 15 years in prison and a $500,000 fine when the judge dismissed their indictments.
The two aid workers, Shanti Sellz and Daniel Strauss, were volunteering with southern Arizona-based non-profit organization No More Deaths, a ministry of the Unitarian Universalist Church of Tucson, which focuses on reducing the number of fatalities from dehydration and heat stroke that occur every year among unprepared travelers in the Sonora Desert.
On the day when Seliz and Strauss were arrested in July 2005, they had come upon three individuals who were in imminent danger of dying from heat-related illnesses. Seliz and Strauss were following a protocol the No More Deaths had used for years, of which the Border Patrol was fully aware. Under the protocol, if the life of anyone in the desert was in danger, giving them transportation to a medical facility was viewed as a humanitarian necessity, regardless of the individual’s immigration status.
Fortunately, the judge in the case agreed with two arguments put forward by the defense: (1) The defendants were following a medical emergency protocol that No More Deaths had previously established and shared directly with the Border Patrol to ensure legal compliance, and (2) because the organization had openly practiced this medical transport protocol for years without prior legal interference or warning, the prosecution was a violation of the defendants' due process rights.
From mixed martial arts to mechanical dogs: the World Robot Conference 2026 – in pictures
Guardian
www.theguardian.com
2026-08-24 19:59:48
More than 3,000 products were shown at the 2026 World Robot Conference in Beijing as China showcased its rapidly growing robotics industry. The event, which ran from 19-23 August, showcased the latest advances across the robotics industry, from humanoid robots to embodied intelligence and cutting-ed...
More than 3,000 products were shown at the 2026 World Robot Conference in Beijing as China showcased its rapidly growing robotics industry.
The event, which ran from 19-23 August, showcased the latest advances across the robotics industry, from humanoid robots to embodied intelligence and cutting-edge components