To use the Mastodon web application, please enable JavaScript. Alternatively, try one of the native apps for Mastodon for your platform.
10 interesting stories served every morning and every evening.
10 interesting stories served every morning and every evening.
To use the Mastodon web application, please enable JavaScript. Alternatively, try one of the native apps for Mastodon for your platform.
One of the current trends in modern software is for developers to slap an API call to OpenAI or Anthropic for features within their app. Reasonable people can quibble with whether those features are actually bringing value to users, but what I want to discuss is the fundamental concept of taking on a dependency to a cloud hosted AI model for applications.
This laziness is creating a generation of software that is fragile, invades your privacy, and fundamentally broken. We are building applications that stop working the moment the server crashes or a credit card expires.
We need to return to a habit of building software where our local devices do the work. The silicon in our pocket is mind bogglingly faster than what was available a decade ago. It has a dedicated Neural Engine sitting there, mostly idle, while we wait for a JSON response from a server farm in Virginia. That’s ridiculous.
Even if your intentions are pure, the moment you stream user content to a third party AI provider, you’ve changed the nature of your product. You now have data retention questions and all the baggage that comes with that (consent, audit, breach, government request, training, etc.)
On top of that you also substantially complicated your stack because your feature now depends on network conditions, external vendor uptime, rate limits, account billing, and your own backend health.
Congratulations! You took a UX feature and turned it into a distributed system that costs you money.
If the feature can be done locally, opting into this mess is self inflicted damage.
“AI everywhere” is not the goal. Useful software is the goal.
Concrete Example: Brutalist Report’s On-Device Summaries
Years ago I launched a fun side project named The Brutalist Report , a news aggregator service inspired by the 1990s style web.
Recently, I decided to build a native iOS client for it with the design goal of ensuring it would remain a high-density news reading experience. Headlines in a stark list, a reader mode that strips the cancer that has overtaken the web, and (optionally) an “intelligence” view that generates a summary of the article.
Here’s the key point though: the summary is generated on-device using Apple’s local model APIs. No server detours. No prompt or user logs. No vendor account. No “we store your content for 30 days” footnotes needed.
It has become so normal for folks that any AI use is happening server-side. We have a lot of work to do to turn this around as an industry.
It’s not lost on me that sometimes the use-cases you have will demand the intelligence that only a cloud hosted model can provide, but that’s not the case with every use-case you’re trying to solve. We need to be thoughtful here.
Available Tooling
I can only speak on the tooling available within the Apple ecosystem since that’s what I focused initial development efforts on. In the last year, Apple has invested heavily here to allow developers to make use of a built-in local AI model easily.
The core flow looks roughly like this:
import FoundationModels
let model = SystemLanguageModel.default guard model.availability == .available else { return }
let session = LanguageModelSession { “”″ Provide a brutalist, information-dense summary in Markdown format. - Use **bold** for key concepts. - Use bullet points for facts. - No fluff. Just facts. “”″ }
let response = try await session.respond(options: .init(maximumResponseTokens: 1_000)) { articleText }
let markdown = response.content
And for longer content, we can chunk the plain text (around 10k characters per chunk), produce concise “facts only” notes per chunk, then runs a second pass to combine them into a final summary.
This is the kind of work local models are perfect for. The input data is already on the device (because the user is reading it). The output is lightweight. It’s fast and private. It’s okay if it’s not a superhuman PhD level intelligence because it’s summarizing the page you just loaded, not inventing world knowledge.
Local AI shines when the model’s job is transforming user-owned data, not acting as a search engine for the universe.
There are plenty of AI features that people want but don’t trust. Summarizing emails, extract action items from notes, categorize this document, etc.
The usual cloud approach turns every one of those into a trust exercise. “Please send your data to our servers. We promise to be cool about it.”
Local AI changes that. Your device already has the data. We’ll do the work right here.
You don’t build trust with your users by writing a 2,000 word privacy policy. You build trust by not needing one to begin with.
The tooling available on the platform goes even further.
One of the best moves Apple has made recently is pushing “AI output” away from unstructured blobs of text and toward typed data.
Instead of “ask the model for JSON and pray”, the newer and better pattern is to define a Swift struct that represents the thing you want. Give the model guidance for each field in natural language. Ask the model to generate an instance of that type.
That’s it.
Conceptually, it looks like this:
import FoundationModels
@Generable struct ArticleIntel { @Guide(description: “One sentence. No hype.“) var tldr: String @Guide(description: “3 – 7 bullets. Facts only.“) var bullets: [String] @Guide(description: “Comma-separated keywords.“) var keywords: [String] }
let session = LanguageModelSession() let response = try await session.respond( to: “Extract structured notes from the article.”, generating: ArticleIntel.self ) { articleText }
let intel = response.content
Now your UI doesn’t have to scrape bullet points out of Markdown or hope the model remembered your JSON schema. You get a real type with real fields, and you can render it consistently. It produces structured output your app can actually use. And it’s all running locally!
This isn’t just nicer ergonomics. It’s an engineering improvement.
And if you’re building a local first app, this is the difference between “AI as novelty” and “AI as a trustworthy subsystem”.
“But Local Models Aren’t As Smart”
Correct.
But also so what?
Most app features don’t need a model that can write Shakespeare, explain quantum mechanics, and pass the bar exam. They need a model that can do one of these reliably: summarize, classify, extract, rewrite, or normalize.
And for those tasks, local models can be truly excellent.
If you try to use a local model as a replacement for the entire internet, you will be disappointed. If you use it as a “data transformer” sitting inside your app, you’ll wonder why you ever sent this stuff to a server.
Use cloud models only when they’re genuinely necessary. Keep the user’s data where it belongs. And when you do use AI, don’t just glue it as a chat box. Use it as a real subsystem with typed outputs and predictable behavior.
Stop shipping distributed systems when you meant to ship a feature.
Modders, start your engines.
by William Judd
Wed, 10:29am
With the rather excellent Steam Controller now on its way to the lucky few that managed to order one, Valve has released a full set of CAD files for their new hardware. The idea is to let enterprising modders create their own Steam Controller add-ons, like skins, charging stands, grip extenders or smartphone mounts.
The Valve release includes files for the external shell (“surface topology”) of the Controller and Puck, with a .STP, .STL and engineering diagram of each device, with the latter showing areas that must remain uncovered to let the device maintain its signal strength and otherwise function as designed.
Valve has previously released CAD files for its Steam Deck handheld, Valve Index VR suite and even the original Steam Controller a decade ago, so this release is welcomed but not unexpected.
The release is under a fairly restrictive Creative Commons license which allows for non-commercial use and requires attribution and sharing of designs back to the community. However, the license also suggests that commercial entities interested in making accessories for the Steam Controller or its Puck can contact Valve directly to discuss terms.
What is your ultimate Steam Controller or Steam Controller Puck accessory? Let us know in the comments below. For me, it would definitely be a smartphone clip - playing through something relatively low-stakes like Forza Horizon 6 via Moonlight game streaming on a phone would be slick.
[source steamcommunity.com]
Will is website editor for Digital Foundry, specialising in PC hardware, sim racing and display technology.
Author Profile
Bluesky
Reply
Parkinson’s Law states that work expands to fill the time available. In the era of AI, workers now have a tool that expands to fill whatever a large language model can be persuaded to generate, which is to say, without limit.
Parkinson’s Law states that work expands to fill the time available. In the era of AI, workers now have a tool that expands to fill whatever a large language model can be persuaded to generate, which is to say, without limit.
What I have watched happen in my profession in the last two years, I am still struggling to describe. The first time I knew something was wrong, roughly a year and a quarter ago, I noticed a colleague replying to me using AI. His response was obviously generated by Claude. The punctuation gave it away — em dashes where no one types em dashes, the rhythmic structure, the confident grasp of technologies I knew for a fact he did not understand. I sat with it for a while, weighing whether to debate someone who was visibly copy-pasting verbatim from a model. The channel was public, and I spent more time than I should have correcting fundamentals. Eventually I stopped. He was not, in any meaningful sense, on the other side of the conversation.
Generative AI can produce work that looks expert without being expert, and the failure arrives in two shapes. The first is when novices in a field are able to produce work that resembles what their seniors produce, faster or more advanced than their judgment. The second is when people generate artifacts in disciplines they were never trained in. The two failures look similar from a distance and are not the same. Research has mostly measured the first. The second is what it is missing, and in my experience it is the riskier of the two.
Cross domain generation
People who cannot write code are building software. People who have never designed a data system are designing data systems. Most of it is not shipped; it is built, often for many hours, possibly shown internally with great vigor, used quietly, and occasionally surfaced to a client without much fanfare. Workers can obsess over an idea, working many hours overtime. There are a few practitioners who use the current agentic tools to do complex things properly, but they are scarce and as I find, typically in code generation. AI, for all its capabilities at the level of the individual, has not scaled properly in my workplace.
I have a colleague, a careful and intelligent person in a role that is not engineering, who spent two months earlier this year building a system that should have been designed by someone with formal training in data architecture. He used the tools well, by the standards by which use of the tools is currently measured. He produced a great deal of code, a great deal of documentation, a great deal of what looked, to anyone who did not know what to look for, like progress. He could not, when asked, explain how any of it actually worked. The work was wrong from the first day. The schemas, and more importantly the objectives, were wrong in a way that would have been obvious to anyone with two years in the field. Several of us did know. When opinions were voiced even as high as a V.P., he fought back. The room had been arranged in such a way that saying so was not a contribution; his managers were too invested in the appearance of momentum to want the appearance disturbed. The work will continue, in all probability, until it is shown to a stakeholder, and they decide not to invest.
This is the part of the phenomenon I find hardest to write about. The tool did not make him a worse colleague. It made him able to impersonate, for months, a discipline he had never trained in, and the impersonation was good enough that the institutional incentives all bent toward letting him continue. Perhaps it’s a failure of management, but I have been finding management to be so eager to embrace AI that they’re willing to accept the risk.
It would be tolerable, perhaps, if the tool offered an honest assessment of what it had produced. The Cheng et al. Stanford study published in Science this spring [1] confirmed what every regular user already knew: leading models are roughly fifty percent more agreeable than human respondents, affirming the user even where the affirmation is unwarranted. Berkeley CMR meta-analyses [4] found AI-literate users often overestimate their performance. Particularly interesting when workers stray outside of their training. An NBER study of support agents [2] found generative AI boosted novice productivity by about a third while barely helping experts. Harvard Business School researchers found the same pattern in consulting work [3]. So you have overconfident, novices able to improve their individual productivity in an area of expertise they are unable to review for correctness. What could go wrong?
The conduit problem
A growing body of work calls this output-competence decoupling [5]. In any previous era, the quality of a piece of work was a more or less reliable signal of the competence of the person who produced it. A novice essay read like a novice essay; novice code crashed in novice ways. AI has severed that relationship. A novice now produces work that does not betray the novice, because the competence the work reflects is not the novice’s competence at all. It is the system’s. The person, in the transaction, becomes a kind of conduit, capable of routing the output to a recipient and incapable of evaluating it on the way through.
The skills of producing work and judging it were deliberately distinct, but accomplishing the work itself used to teach the judgment. The first skill now belongs, in large part, to the machines. The second still belongs to us, though fewer are bothering to acquire or utilize it.
The architectural critique that used to come from someone who was taught, or who had built and broken three of these before now comes from a model with no embodied memory of building or breaking anything. The slowness was not a tax on the real work; the slowness was the real work. It was how the work got good, and how the people producing the work got good, and how the firm whose name was on the work could promise the client that what they were buying was a particular kind of thing rather than a generic one.
The current generation of agentic systems is built around the premise that the human is the bottleneck — that the loop runs faster and cleaner without the awkward delay of someone reading what is about to happen and deciding whether it should. This is, in a great many cases, exactly backwards. The human in the loop is not a vestige of an earlier era; the human is the only part of the loop with skin in the game. Removing the H from HITL is not an efficiency. It is the abandonment of the only mechanism the system has for catching itself.
Slop on the inside
Requirements documents that were once a page are now twelve. Status updates that were once three sentences are now bulleted summaries of bulleted summaries. Retrospective notes, post-incident reports, design memos, kickoff decks: every artifact that can be elongated is, by people who do not read what they produce, for readers who do not read what they receive. The cost of producing a document has fallen to nearly zero; the cost of reading one has not, and is in fact rising, because the reader must now sift the synthetic context for whatever the document was originally about. Each individual decision to elongate seems rational, and each is independently rewarded — readers are more confident in longer AI-generated explanations whether or not the explanations are correct [5]. The collective effect is that the signal in any given workplace is harder to find than it was before any of this began. The checkpoints have been hidden, drowned in their own paperwork, even when the people drowning them were genuinely trying to “be brief”.
This is a new form of slop, and it is more expensive than the public kind, because the people producing it are being paid a salary to do so. The pipeline of future experts is thinning from both ends. The work that used to teach judgment is now done by the tool, and the entry-level roles where the teaching happened are being cut on the theory that the tool can do the work. What this is causing, in many offices including mine, is a great deal of motion and very little of what motion used to create.
The downstream costs are accumulating quickly. Most of the public discussion of AI slop has focused on the flood into public markets — a University of Florida marketing study [6] being among the more direct treatments. What is less remarked upon is the same dynamic playing out inside organizations: time wasted using AI on tasks that did not need it, on artifacts no one will read, on processes that exist only because the tool made it cheap to construct them. On decks that spell out things that previously didn’t even need to be said or were assumed.
What to do about it
What discipline looks like, in this environment, is almost embarrassingly old-fashioned and may seem obvious to most of you until you try to avoid it. Use the tool where you can verify precisely what it produces. Never ask a model for confirmation; the tool agrees with everyone, and an agreement that costs the agreer nothing is worth nothing.
Generative AI does well on tasks where feedback is fast, where being approximately right is good enough, where the human remains the final arbiter. Drafting a memo, generating examples, summarizing material the reader could verify if they cared to. The University of Illinois Generative AI guidance [7] and the PLOS Computational Biology “Ten Simple Rules” paper on AI in research [8], among the more careful documents now circulating, list much of this explicitly: brainstorming, copyediting, reformulating one’s own ideas, pattern detection in data one already understands.
In every recommended use, the human supplies the judgment and the tool supplies the throughput. This is a stronger position than human-in-the-loop. The tool sits outside the work, contributing where invited and silent otherwise, which is the opposite of what most agentic systems are now being built to do.
For firms, the competitive advantage of a firm whose work can be trusted has not disappeared; it has, if anything, appreciated, because so many of the firm’s competitors are quietly converting themselves into content-generation pipelines and counting on the client not to notice.
This is already coming to a head. Deloitte has already refunded part of a $440,000 fee over an AI-hallucinated government report. It could be a production system built on a hallucinated specification, or a senior engineer who realizes they have spent the last year nominally reviewing work they could no longer competently review. The reckoning will not be subtle. The firms still doing the work properly will be in a position to charge for it. The firms that have hollowed themselves out will discover that what they hollowed out was the thing the client was paying for.
Misunderstanding and misuse of AI in the workplace is rampant. In many of the rooms I now find myself in, expertise has been asked to look the other way: to deliver faster, produce more, integrate the tools more deeply, get out of the way of the colleagues who are “getting things done”. The artifacts are accumulating; the work is not. And somewhere on the other side of all this output, a client is opening a deliverable, reading a summarized list, and they may just choose to review it manually.
Disclaimer: This is a personal essay, not an academic paper, by someone who has spent more than two decades in engineering. These are my experiences, in my workplace, with references to things that I think are relevent. If you take one thing away, take away that people are impressionable creatures. AI was used in the writing of it, in the ways the essay itself recommends: to brainstorm, draft and revise material I manually verified, never to supply judgment I lacked. Also, those that claimed this article is ironically a casualty of it’s own complaint are 100% right, like AI, I am a bit long-winded and repetitive.
References
1. Sycophantic AI decreases prosocial intentions and promotes dependence (Cheng, Lee, Khadpe, Yu, Han, & Jurafsky, 2026). Science.
2. Generative AI at Work (Brynjolfsson, Li, & Raymond, 2025). The Quarterly Journal of Economics, 140(2), 889 – 942. Also: NBER Working Paper No. 31161, April 2023.
3. Navigating the Jagged Technological Frontier (Dell’Acqua, McFowland, Mollick, et al., 2026). Organization Science. Originally HBS Working Paper No. 24 – 013, 2023.
4. Seven Myths About AI and Productivity: What the Evidence Really Says (Berkeley CMR, 2025). Meta-analysis confirming asymmetric AI productivity gains and user overconfidence.
5. Beyond the Steeper Curve: AI-Mediated Metacognitive Decoupling (Koch, 2025). Longer AI explanations make users more confident regardless of correctness.
6. Generative AI and the market for creative content (Zou, Shi, & Wu, 2026). Forthcoming, Journal of Marketing Research.
7. Generative AI Guidance (University of Illinois). Recommended uses and limitations of generative AI in academic and professional work.
8. Ten simple rules for optimal and careful use of generative AI in science (Helmy, Jin, et al., 2025). PLOS Computational Biology, 21(10), e1013588.
Google has tied its next-generation reCAPTCHA system to Google Play Services on Android, meaning anyone running a de-Googled phone will automatically fail verification when the system decides to challenge them.
The requirement forces Android users to run Google’s proprietary app framework version 25.41.30 or higher just to prove they’re human.
When reCAPTCHA flags what it considers suspicious activity, it abandons the old image puzzles and demands you scan a QR code. That scan requires Play Services running in the background, communicating with Google’s servers. If you’re using GrapheneOS or any other custom ROM that strips out Google’s software, the verification fails.
Google announced the broader system, Google Cloud Fraud Defense, at Cloud Next on April 23, pitching it as a trust platform designed to handle autonomous AI agents and traditional bots alike. What Google didn’t emphasize was the part where proving you’re human now requires submitting to its proprietary surveillance.
Reclaim Your Digital Freedom.
Get unfiltered coverage of surveillance, censorship, and the technology threatening your civil liberties.
This wasn’t sudden, either. An Internet Archive snapshot from October 2025 shows the same support page already listing a Play Services requirement at version 25.39.30. Google built this dependency quietly for at least seven months before a Reddit user on the degoogle subreddit flagged it, with reporting from PiunikaWeb and Android Authority bringing wider attention.
The iOS comparison is revealing because Apple devices running iOS 16.4 or later complete the same verification without installing any additional apps. Google didn’t demand iPhone users install Google software to pass the test. Only Android users who refuse Play Services get locked out. The asymmetry reveals what this is really about: not security, but ecosystem control.
reCAPTCHA sits in front of millions of websites. When Google ties verification to Play Services, it establishes a precedent where accessing basic web content requires running Google’s software and transmitting data to Google’s servers.
People running de-Googled phones chose those setups because they read the data practices, understood what Play Services phones home about, and decided they didn’t consent. Google’s new system punishes that decision by treating the absence of its proprietary software as suspicious by default.
Web developers adopting this reCAPTCHA should understand what they’re choosing. Every site that implements it tells de-Googled Android users they’re not welcome. That’s a small audience today. It’s also the audience most likely to care about how a website treats their data, and the least likely to capitulate.
Please enable JS and disable any ad blocker
2026 – 05-07
3 min read
This afternoon, we sent the following email to our global team. One of our core values at Cloudflare is transparency, and we believe it’s important that you hear this directly from us because it’s a major moment at Cloudflare.
Team:We are writing to let you know directly that we’ve made the decision to reduce Cloudflare’s workforce by more than 1,100 employees globally. The way we work at Cloudflare has fundamentally changed. We don’t just build and sell AI tools and platforms. We are our own most demanding customer. Cloudflare’s usage of AI has increased by more than 600% in the last three months alone. Employees across the company from engineering to HR to finance to marketing run thousands of AI agent sessions each day to get their work done. That means we have to be intentional in how we architect our company for the agentic AI era in order to supercharge the value we deliver to our customers and to honor our mission to help build a better Internet for everyone, everywhere. Today is a hard day. This decision unfortunately means saying goodbye to teammates who have contributed meaningfully to our mission and to building Cloudflare into one of the world’s most successful companies. We want to be clear that this decision is not a reflection of the individual work or talent of those leaving us. Instead, we are reimagining every internal process, team, and role across the company. Today’s actions are not a cost-cutting exercise or an assessment of individuals’ performance; they are about Cloudflare defining how a world-class, high-growth company operates and creates value in the agentic AI era. This is a moment we need to own as founders and leaders of the company. Matthew has personally sent out every offer letter we’ve extended. It is a practice he has always looked forward to because it represented our growth and the incredible talent joining our mission. It didn’t feel right for this message to come from anyone other than the two of us. Rather than trickling out notices through managers, we will be sending emails to every employee. Within the next hour, every member of our global team will receive an email from both of us clarifying how this change affects them. For those departing today, we will send this update to both their personal and Cloudflare addresses to ensure they receive the information immediately.It’s important to us that we treat departing team members right and in a way that exceeds what we’ve seen from other companies. We believe acting with empathy isn’t about avoiding hard decisions but rather about how you treat people when those decisions are made. If we are asking our team to be world-class, we have a reciprocal obligation to be world-class in how we treat them. We are pairing the directness of these measures with severance packages that lead the industry. The packages for departing employees will include the equivalent of their full base pay through the end of 2026. Healthcare coverage is different across the globe, and if you’re in the United States, we’ll continue to provide support through the end of the year. We are also vesting equity for departing team members through August 15th, so they receive stock beyond their departure date. And, if departing team members haven’t hit their one-year cliffs, we are going to waive those and vest their pro-rated equity through August as well. We’ve asked the team to do this only once, as hard as that may be today. We don’t want to do it again for the foreseeable future. By taking decisive action now, we provide immediate clarity to those departing and protect the stability of the team that remains. We are making these changes now because making smaller, repeated cuts or dragging a reorganization out over multiple quarters creates prolonged emotional uncertainty for employees and stalls our ability to build. It’s the right thing to do; it’s the honest thing to do; and it reflects the values of the company we are continuing to build.Cloudflare started as a digitally native company built in the cloud. That allowed us to catch up to and pass companies that had a head start of years or decades but were slowed down by outdated systems and processes. As we’ve now become the leader, we cannot rest on the workflows and organizational structures that worked yesterday. We’re confident that our reshaped organization will be even faster and more innovative as we continue building the future.To those departing us: you’ve helped build the strong foundation Cloudflare stands on today. We have the utmost respect for your work and gratitude for the impact you have made. We’re confident you will land at other great places and build many future great companies, bringing with you a unique set of skills learned while building Cloudflare.Transparency is a core principle at Cloudflare, and it was important that you hear this from us first. We will be heading to our earnings conference call at 2 PM PT, when we’ll share more. We also plan to address today’s announcements live with the team at our all-hands meeting. It’s not an easy day, but it’s the right decision. Our mission to help build a better Internet is more important now than ever, and there’s a lot of work left to be done.
Team:
We are writing to let you know directly that we’ve made the decision to reduce Cloudflare’s workforce by more than 1,100 employees globally.
The way we work at Cloudflare has fundamentally changed. We don’t just build and sell AI tools and platforms. We are our own most demanding customer. Cloudflare’s usage of AI has increased by more than 600% in the last three months alone. Employees across the company from engineering to HR to finance to marketing run thousands of AI agent sessions each day to get their work done. That means we have to be intentional in how we architect our company for the agentic AI era in order to supercharge the value we deliver to our customers and to honor our mission to help build a better Internet for everyone, everywhere.
Today is a hard day. This decision unfortunately means saying goodbye to teammates who have contributed meaningfully to our mission and to building Cloudflare into one of the world’s most successful companies. We want to be clear that this decision is not a reflection of the individual work or talent of those leaving us. Instead, we are reimagining every internal process, team, and role across the company. Today’s actions are not a cost-cutting exercise or an assessment of individuals’ performance; they are about Cloudflare defining how a world-class, high-growth company operates and creates value in the agentic AI era.
This is a moment we need to own as founders and leaders of the company. Matthew has personally sent out every offer letter we’ve extended. It is a practice he has always looked forward to because it represented our growth and the incredible talent joining our mission. It didn’t feel right for this message to come from anyone other than the two of us. Rather than trickling out notices through managers, we will be sending emails to every employee.
Within the next hour, every member of our global team will receive an email from both of us clarifying how this change affects them. For those departing today, we will send this update to both their personal and Cloudflare addresses to ensure they receive the information immediately.
It’s important to us that we treat departing team members right and in a way that exceeds what we’ve seen from other companies. We believe acting with empathy isn’t about avoiding hard decisions but rather about how you treat people when those decisions are made. If we are asking our team to be world-class, we have a reciprocal obligation to be world-class in how we treat them. We are pairing the directness of these measures with severance packages that lead the industry. The packages for departing employees will include the equivalent of their full base pay through the end of 2026. Healthcare coverage is different across the globe, and if you’re in the United States, we’ll continue to provide support through the end of the year. We are also vesting equity for departing team members through August 15th, so they receive stock beyond their departure date. And, if departing team members haven’t hit their one-year cliffs, we are going to waive those and vest their pro-rated equity through August as well.
We’ve asked the team to do this only once, as hard as that may be today. We don’t want to do it again for the foreseeable future. By taking decisive action now, we provide immediate clarity to those departing and protect the stability of the team that remains. We are making these changes now because making smaller, repeated cuts or dragging a reorganization out over multiple quarters creates prolonged emotional uncertainty for employees and stalls our ability to build. It’s the right thing to do; it’s the honest thing to do; and it reflects the values of the company we are continuing to build.
Cloudflare started as a digitally native company built in the cloud. That allowed us to catch up to and pass companies that had a head start of years or decades but were slowed down by outdated systems and processes. As we’ve now become the leader, we cannot rest on the workflows and organizational structures that worked yesterday. We’re confident that our reshaped organization will be even faster and more innovative as we continue building the future.
To those departing us: you’ve helped build the strong foundation Cloudflare stands on today. We have the utmost respect for your work and gratitude for the impact you have made. We’re confident you will land at other great places and build many future great companies, bringing with you a unique set of skills learned while building Cloudflare.
Transparency is a core principle at Cloudflare, and it was important that you hear this from us first. We will be heading to our earnings conference call at 2 PM PT, when we’ll share more. We also plan to address today’s announcements live with the team at our all-hands meeting.
It’s not an easy day, but it’s the right decision. Our mission to help build a better Internet is more important now than ever, and there’s a lot of work left to be done.
Last year I said I’d probably never recommend another Bambu Lab printer again.
I still use my P1S, but after Bambu Lab started pushing their always-connected cloud solution as the new default:
I blocked the printer from the Internet via my OPNsense Firewall
I stopped updating the firmware
I locked the printer into Developer mode
I deleted Bambu Studio and started using OrcaSlicer
I had to do that to keep it under my control, instead of Bambu’s.
But I’m weird—I acknowledge that. I’m one of those crazy ones who likes to own something they purchased, and not have the company watch everything I do with hardware I paid for.
Bambu Lab could’ve left the status quo at that, and I wouldn’t be writing this blog post.
But they didn’t.
What happened this time?
For context: OrcaSlicer is a fork of the open source project Bambu Studio, which is a fork of Prusa Slicer, which is a fork of slic3r. (They are all licensed under the AGPLv3 open source license).
OrcaSlicer already has to dance around Bambu’s weird default setup where every file you print goes through Bambu’s servers, meaning they can see everything you ever print on your printer.
That is, unless you’re like me and you run it in Developer mode, and completely block it from the Internet on old firmware.
Some people are okay with using OrcaSlicer and printing through Bambu’s cloud. It’s convenient if you’re on the road and want to start a print on your printer at home, without managing your own VPN.
I run my own WireGuard VPN, so I don’t need that, but I understand not everyone has the resources to manage their own remote access.
Bambu saw a fork of OrcaSlicer that allowed you to use all your printer’s features without having to route prints through Bambu’s cloud called OrcaSlicer-bambulab and was like, “You know what? No. For the 0.1% of power users who want to run OrcaSlicer without the cloud delivery mechanism like we have in our AGPL-licensed Linux Bambu Studio code… no. You have to use our app, and only our app.”
So they threatened that OrcaSlicer fork’s developer with legal action for things that developer didn’t do. For example, they indicated the fork used an impersonation attack, despite the fork using Bambu Studio’s upstream code verbatim.
These are very serious public accusations.Bambu Lab did not write to me with these specific public claims first. They also refused my request to publish the full correspondence. Instead, they published a one-sided public statement where I cannot reply directly.In practice, this presents me to the public as someone bypassing security, impersonating their client, and creating a risk to their infrastructure. I reject that characterization.— OrcaSlicer-bambulabs developer’s response
These are very serious public accusations.
Bambu Lab did not write to me with these specific public claims first. They also refused my request to publish the full correspondence. Instead, they published a one-sided public statement where I cannot reply directly.
In practice, this presents me to the public as someone bypassing security, impersonating their client, and creating a risk to their infrastructure. I reject that characterization.
— OrcaSlicer-bambulabs developer’s response
Bambu is abusing the open source social contract, and using their legal might, to suppress a tiny number of their users1, for who knows what reason.
It seems dumb to me, because it would’ve been easier (and more profitable) to do nothing at all2. Instead, they wrote a blog post blaming an individual open source developer for their own infrastructure and security problems.
This is where the actual issue arises: the modification in question worked by injecting falsified identity metadata into network communication.In simple terms: it pretended to be the official Bambu Studio client when communicating with our servers.— Bambu Lab blog post
This is where the actual issue arises: the modification in question worked by injecting falsified identity metadata into network communication.
In simple terms: it pretended to be the official Bambu Studio client when communicating with our servers.
— Bambu Lab blog post
I don’t think they understand open source culture. Security either, if a public user agent string is their only protection against DDoS attacks…
Instead of finding solutions to ecosystem problems and building a more secure platform, Bambu is putting devoted power users like the fork’s developer on blast3.
When tensions flared last year, they wrote a similar blog post blaming community backlash on ‘unfortunate misinformation’. I imagine they meant speculation from community members (like myself) frustrated the whole software ecosystem and ownership model was turned upside down post-purchase.
This year they’re blaming one developer of a tiny slicer fork for the potential impact he could have on their entire cloud infrastructure.
It creates structural vulnerability. If this method were widely adopted or incorrectly configured, thousands of clients could simultaneously hit our servers while impersonating the official client. Our systems would have no way to distinguish traffic, because the requests would look identical.— Bambu Lab blog post
It creates structural vulnerability. If this method were widely adopted or incorrectly configured, thousands of clients could simultaneously hit our servers while impersonating the official client. Our systems would have no way to distinguish traffic, because the requests would look identical.
— Bambu Lab blog post
I love how they frame this as a developer trying to impersonate their app, when he’s literally using the same AGPL-licensed code their Linux app uses.
I find it doubly ironic since their own fork caused Bambu users’ telemetry to hit Prusa’s servers back in 2022, and (to my knowledge) Prusa didn’t snap back with a C&D.
They spent the rest of their blog post talking about vulnerabilities, bugs, and instabilities—as if that has anything to do with a developer using upstream code verbatim in his fork.
Maybe they could take a new approach and just not lock down their whole ecosystem in the first place.
But who am I kidding? Nothing I say, and no amount of complaining in the comments below, seems to help Bambu see the fault in their ways.
Spending a little more for a printer from another company just might do it, though.
Louis Rossmann posted a video saying he’d pledge $10,000 to help the open source dev fight Bambu’s legal threats. And I’d happily chip in too, but that’s only useful if the dev wants to put himself back in Bambu’s crosshairs.
The better play might just be to skip Bambu altogether.
The OrcaSlicer fork in question didn’t seem to have much uptake outside of a very small subset of users prior to Bambu Lab’s cease and desist order. ↩︎
The OrcaSlicer fork in question didn’t seem to have much uptake outside of a very small subset of users prior to Bambu Lab’s cease and desist order. ↩︎
Maybe ask for the fork to not include “bambulabs” in the name, since that could be a reasonable trademark-related demand. ↩︎
Maybe ask for the fork to not include “bambulabs” in the name, since that could be a reasonable trademark-related demand. ↩︎
The fork’s developer mentioned “I previously helped Bambu Studio users with Linux and Wayland issues, including on Bambu Lab’s own GitHub. That makes it especially absurd to me that I am now being publicly presented as someone dangerous to their infrastructure.” ↩︎
The fork’s developer mentioned “I previously helped Bambu Studio users with Linux and Wayland issues, including on Bambu Lab’s own GitHub. That makes it especially absurd to me that I am now being publicly presented as someone dangerous to their infrastructure.” ↩︎
by Tanner Linsley on May 11, 2026.
Last updated: 2026 – 05-11
On 2026 – 05-11 between 19:20 and 19:26 UTC, an attacker published 84 malicious versions across 42 @tanstack/* npm packages by combining: the pull_request_target “Pwn Request” pattern, GitHub Actions cache poisoning across the fork↔base trust boundary, and runtime memory extraction of an OIDC token from the GitHub Actions runner process. No npm tokens were stolen and the npm publish workflow itself was not compromised.
The malicious versions were detected publicly within 20 minutes by an external researcher ashishkurmi working for stepsecurity. All affected versions have been deprecated; npm security has been engaged to pull tarballs from the registry. We have no evidence of npm credentials being stolen, but we strongly recommend that anyone who installed an affected version on 2026 – 05-11 rotate AWS, GCP, Kubernetes, Vault, GitHub, npm, and SSH credentials reachable from the install host.
Tracking issue: TanStack/router#7383 GitHub Security Advisory: GHSA-g7cv-rxg3-hmpx
Packages affected
42 packages, 84 versions (two per package, published roughly 6 minutes apart). See the tracking issue for the full table. Confirmed-clean families: @tanstack/query*, @tanstack/table*, @tanstack/form*, @tanstack/virtual*, @tanstack/store, @tanstack/start (the meta-package, not @tanstack/start-*).
What the malware does
When a developer or CI environment runs npm install, pnpm install, or yarn install against any affected version, npm resolves the malicious optionalDependencies entry, fetches the orphan payload commit from the fork network, runs its prepare lifecycle script, and executes a ~2.3 MB obfuscated router_init.js smuggled into the affected tarball. The script:
Harvests credentials from common locations: AWS IMDS / Secrets Manager, GCP metadata, Kubernetes service-account tokens, Vault tokens, ~/.npmrc, GitHub tokens (env, gh CLI, .git-credentials), SSH private keys
Exfiltrates over the Session/Oxen messenger file-upload network (filev2.getsession.org, seed{1,2,3}.getsession.org) — end-to-end encrypted with no attacker-controlled C2, so blocking by IP/domain is the only network mitigation
Self-propagates: enumerates other packages the victim maintains via registry.npmjs.org/-/v1/search?text=maintainer:<user> and republishes them with the same injection
Because the payload runs as part of npm install’s lifecycle, anyone who installed an affected version on 2026 – 05-11 must treat the install host as potentially compromised.
All times UTC. Local timestamps from GitHub API and npm registry.
Pre-attack (cache poisoning phase)
Detonation (publish phase)
Workflow run 25613093674 starts (19:15:44), and fails.
Detection and response
Formal malware reports are submitted via npm
Tanner begins npm deprecation process for all 84 affected packages.
Public Twitter/X/LinkedIn/Bluesky disclosure from @tan_stack and maintainers
All cache entries for all TanStack/* GitHub repositories purged via API.
Hardening PR merged: bundle-size.yml restructured, repository_owner guards added, third-party action refs pinned to SHAs.
Official GitHub Security Advisory is published, CVE requested
Three vulnerabilities chained together. Each is necessary for the attack; none alone is sufficient.
1. pull_request_target “Pwn Request” pattern in bundle-size.yml
bundle-size.yml ran pull_request_target for fork PRs and, inside that trigger context, checked out the fork’s PR-merge ref and ran a build:
yaml
on: pull_request_target: paths: [‘packages/**’, ‘benchmarks/**’]
jobs: benchmark-pr: steps: - uses: actions/checkout@v6.0.2 with: ref: refs/pull/${{ github.event.pull_request.number }}/merge # fork’s merged code
- uses: TanStack/config/.github/setup@main # transitively calls actions/cache@v5
- run: pnpm nx run @benchmarks/bundle-size:build # executes fork-controlled code
on: pull_request_target: paths: [‘packages/**’, ‘benchmarks/**’]
jobs: benchmark-pr: steps: - uses: actions/checkout@v6.0.2 with: ref: refs/pull/${{ github.event.pull_request.number }}/merge # fork’s merged code
- uses: TanStack/config/.github/setup@main # transitively calls actions/cache@v5
- run: pnpm nx run @benchmarks/bundle-size:build # executes fork-controlled code
The author of the workflow attempted a trust split (the comment-pr job is separate from benchmark-pr, with a comment in the YAML noting the intent to keep benchmark-pr “untrusted with read-only permissions”). The split is correct in spirit but missed two facts:
actions/cache@v5′s post-job save is not gated by permissions:. Cache writes use a runner-internal token, not the workflow GITHUB_TOKEN. Setting permissions: contents: read does not block cache mutation.
Cache scope is per-repo, shared across pull_request_target runs (which use the base repo’s cache scope) and pushes to main. A PR running in the base repo’s cache scope can poison entries that production workflows on main will later restore.
2. GitHub Actions cache poisoning across trust boundaries
The malicious vite_setup.mjs was specifically designed to write data into the pnpm-store directory under a key the legit release.yml workflow would compute and look up: Linux-pnpm-store-${hashFiles(‘**/pnpm-lock.yaml’)}. When the benchmark-pr job ended, actions/cache@v5′s post-step saved the (now-poisoned) pnpm store to that exact key. When release.yml next ran on a push to main, its Setup Tools step restored the poisoned entry — entirely as designed.
This is the class of attack documented by Adnan Khan in 2024. It’s not a TanStack-specific bug; it’s a known GitHub Actions design issue that requires conscious mitigation.
release.yml declares id-token: write (legitimately needed for npm OIDC trusted publishing). When the poisoned pnpm store is restored on the runner, attacker-controlled binaries are now on disk and get invoked during the build step. Those binaries:
Locate the GitHub Actions Runner.Worker process via /proc/*/cmdline
Read /proc/<pid>/maps and /proc/<pid>/mem to dump the worker’s memory
Extract the OIDC token (which the runner mints lazily, in memory, when id-token: write is set)
Use the token to authenticate POST requests directly to registry.npmjs.org — bypassing the workflow’s Publish Packages step entirely
This is the same memory-extraction technique (and verbatim Python script, with attribution comment) used in the tj-actions/changed-files compromise of March 2025. The attacker did not invent novel tradecraft; they recombined published research.
Why none alone is enough
pull_request_target alone is fine for trusted operations (labeling, comments)
Cache poisoning alone (e.g., from inside an already-compromised dep) requires a separate publish vehicle
OIDC token extraction alone requires existing code execution on the runner
The chain only works because each vulnerability bridges the trust boundary the others assumed: PR fork code crossing into base-repo cache, base-repo cache crossing into release-workflow runtime, and release-workflow runtime crossing into npm registry write access.
How we found out
Detection was external. External researcher ashishkurmi working for StepSecurity opened issue #7383 ~20 minutes after the publish, with full technical analysis. Tanner received a phone call from Socket.dev just moments after starting the war room confirming the situation.
IOC fingerprints (for downstream maintainers and security tools)
In any @tanstack/* package’s manifest:
json
“optionalDependencies”: { “@tanstack/setup”: “github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c” }
“optionalDependencies”: { “@tanstack/setup”: “github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c” }
File: router_init.js (~2.3 MB, package root, not in “files”)
Cache key: Linux-pnpm-store-6f9233a50def742c09fde54f56553d6b449a535adf87d4083690539f49ae4da11
2nd-stage payload URLs: https://litter.catbox.moe/h8nc9u.js, https://litter.catbox.moe/7rrc6l.mjs
Exfiltration network: filev2.getsession.org, seed{1,2,3}.getsession.org
Forged commit identity: claude <claude@users.noreply.github.com> (note: not the real Anthropic Claude — fabricated GitHub no-reply email)
Real attacker accounts: zblgg (id 127806521), voicproducoes (id 269549300)
Attacker fork: github.com/zblgg/configuration (fork of TanStack/router renamed to evade fork searches)
Orphan payload commit (in fork network): 79ac49eedf774dd4b0cfa308722bc463cfe5885c
Workflow runs that performed the malicious publishes:
github.com/TanStack/router/actions/runs/25613093674 (attempt 4) github.com/TanStack/router/actions/runs/25691781302
github.com/TanStack/router/actions/runs/25613093674 (attempt 4)
github.com/TanStack/router/actions/runs/25691781302
What went well
External researchers noticed and reported with full technical detail within ~20 min of the incident
Maintainer team coordinated immediately and effectively across many timezones
The detection community already had a clear public IOC pattern within hours
What could have been better
No internal alerting. We learned about the compromise from a third party. We need monitoring on our own publishes. We’ll be working closely with security researcher firms in the ecosystem that have the ability to detect these issues very quickly, potentially even in-house, and making the feedback loop even tighter.
pull_request_target workflows had not been audited despite being a long-known dangerous pattern
Floating refs (@v6.0.2, @main) on third-party actions create standing supply-chain risk independent of this incident
Unpublish was unavailable for nearly all affected packages because of npm’s “no unpublish if dependents exist” policy. We have to rely on npm security to pull tarballs server-side, which adds hours of delay during which malicious tarballs remain installable
The 7-maintainer list on the npm scope means seven separate credential-theft targets for the same blast radius
OIDC trusted-publisher binding has no per-publish review. Once configured, any code path in the workflow can mint a publish-capable token. We need either (a) move to short-lived classic tokens with manual review, or (b) add provenance-source-verification to detect publishes from unexpected workflow steps
What we got lucky on
The attacker chose a payload that broke tests, which made the publish step (which would have produced cleaner-looking tarballs) skip — meaning the attack was loud enough to detect quickly. A more careful attacker who didn’t break tests could have published silently for hours longer
The attacker reused public tradecraft (verbatim memory-dump script with attribution comment) instead of writing novel code — making the IOC-matching faster
These need answers before we close the postmortem.
Did bundle-size.yml’s Setup Tools step actually call actions/cache@v5? Verify by reading the post-job logs from one of the pull_request_target runs against PR #7378 (e.g., run id 25666610798). Tanner has access; needs to be done manually
What was in the initial PR head commit (before the force-pushes wiped it)? GitHub’s reflog may have it. Check via gh api or the GitHub support team
How did the malicious commit get into the fork’s git object store specifically — was it pushed directly via git, or was it created via the GitHub web UI (which would leave audit-log entries)?
Was voicproducoes a real account or a sock puppet? Cross-reference its activity history
Did the npm cache also get poisoned (the 6 duplicate linux-npm-store-* entries)? Were any actually used?
Can we identify any other fork in the TanStack/router fork network that contains the orphan payload commit? (If yes, the cleanup is harder — every fork hosting it keeps it accessible via github:tanstack/router#79ac49ee…)
Are any other TanStack repos (router, query, table, form, virtual, etc.) using the same bundle-size.yml-style pattern? Audit needed
How many users actually downloaded the affected versions during the publish window? Get from npm support
Did any of the seven listed maintainers’ machines get compromised separately? (None of the malicious publishes used a maintainer’s npm token, but maintainer machines could have been the secondary target via the self-propagation logic)
Tracking issue: TanStack/router#7383
GitHub Security Advisory: GHSA-g7cv-rxg3-hmpx
Related research:
Adnan Khan, “The Monsters in Your Build Cache: Github Actions Cache Poisoning” (May 2024) — adnanthekhan.com GitHub Security Lab, “Keeping your GitHub Actions and workflows secure: Preventing pwn requests” — securitylab.github.com StepSecurity, “Harden-Runner detection: tj-actions/changed-files action is compromised” (March 2025) — stepsecurity.io
Skip to content
Secure your code as you build
We read every piece of feedback, and take your input very seriously.
Include my email address so I can be contacted
Use saved searches to filter your results more quickly
To see all available qualifiers, see our documentation.
Sign up
You signed in with another tab or window. Reload to refresh your session.
You signed out in another tab or window. Reload to refresh your session.
You switched accounts on another tab or window. Reload to refresh your session.
There was an error while loading. Please reload this page.
Notifications
You must be signed in to change notification settings
You can’t perform that action at this time.
To add this web app to your iOS home screen tap the share button and select "Add to the Home Screen".
10HN is also available as an iOS App
If you visit 10HN only rarely, check out the the best articles from the past week.
Visit pancik.com for more.