Devoured - July 13, 2026
Apple is suing OpenAI for trade secret theft involving hardware design, while developers are increasingly moving toward intent engineering and proactive memory agent frameworks to manage complex, long-horizon tasks.
Apple Sued OpenAI
Apple is suing OpenAI for trade secret theft, alleging that former employees stole confidential hardware specifications and product designs.
Deep dive
- Apple alleges senior OpenAI leadership directed staff to steal confidential technical specifications.
- Former Apple VP of product design Tang Tan and senior electrical engineer Chang Liu are specifically named as defendants.
- Allegations include using Apple code names during recruitment and coaching employees to evade internal security checks.
- Apple claims OpenAI used proprietary metal finishing techniques without permission.
- The lawsuit seeks to enjoin OpenAI from using Apple trade secrets and demands the return of all stolen intellectual property.
- OpenAI stated it has no interest in competitors' trade secrets.
Decoder
- Discovery: A legal process where parties exchange information and evidence related to a lawsuit prior to trial.
Original article
Apple filed a lawsuit Friday against OpenAI over allegations of trade secret theft and breach of contract.
The iPhone maker alleges that this misconduct, which it says reveals a pattern of theft from OpenAI employees who previously worked at Apple, was directed by OpenAI’s senior leadership, including Chief Hardware Officer Tang Tan.
The lawsuit, which was filed in the U.S. District Court for the Northern District of California, accuses Tan of using Apple’s confidential project code names during OpenAI’s recruiting process, asking job candidates to bring in Apple hardware components to their interviews, coaching departing Apple employees on how to evade the company’s security procedures, and asking for details about the company’s unannounced products.
Before joining OpenAI, Tan had spent 24 years at Apple, most recently as VP of product design for the iPhone and Apple Watch.
The accusations come at a time when OpenAI is rumored to be developing its first hardware product, which would likely compete with the iPhone. In April, industry analyst Ming-Chi Kuo suggested this device could be a smartphone that would rely on AI agents instead of apps. If true, it would be one of the largest threats to Apple’s core hardware business to date.
Apple’s former lead designer Jony Ive’s device startup io was acquired by OpenAI last year in a $6.5 billion deal to aid the AI company with its hardware ambitions. While io was named in the filing, Ive was not.
Tan is not the only OpenAI employee referenced in the new complaint. Apple also alleges that Chang Liu, who spent eight years at Apple as a senior systems electrical engineer, failed to return an Apple-issued laptop after leaving the company for OpenAI in 2026 and had used the computer to download confidential Apple technical documents.
Apple says in the complaint that the stolen documents included information about unannounced technologies, features, and products, including technical specifications, engineering presentations, and proprietary project data.
Liu is also accused in the lawsuit of sharing Apple’s confidential information with other Apple employees applying for jobs at OpenAI, advising at least one of them on what to study before their interview.
Apple sent a letter to OpenAI in February to raise its concerns and received no response, the company said in the complaint.
It alleges that the behavior of these former employees is part of OpenAI’s strategy to extract Apple’s confidential information, which included asking Apple employees to bring designs and prototypes to their interviews, and answer questions about things like component and vendor selection processes.
Apple says its ongoing investigation revealed that OpenAI and its partners have even used Apple’s confidential information while the AI model maker develops its own hardware product. For instance, the filing references a proprietary metal finishing technique that OpenAI used after it allegedly misled a partner into believing it had Apple’s permission to do so.
Like many tech companies, Apple typically investigates potential trade secret theft or other improper activity by analyzing communications that took place on company-owned devices and reading through its server logs. By taking the case to court, Apple will have an opportunity to learn more about the extent of the alleged operation through the legal discovery process.
Apple is asking the court to bar OpenAI from using or disclosing its trade secrets, require the company to return any confidential Apple materials, and preserve evidence related to the case.
“This is the tip of the iceberg. Apple lacks visibility into what’s been happening behind closed doors at OpenAI, where such misconduct is normalized and exemplified by leadership,” the filing states. “As a natural result, OpenAI’s nascent hardware business now rests on the shakiest of foundations, rotten to its core by its illegal reliance on misappropriated trade secrets.”
In a prepared statement, Apple also said the following:
At Apple, our teams are constantly developing breakthrough technologies to create the best products and services in the world, and protecting their work and intellectual property is something we take very seriously. Recently, significant evidence has emerged suggesting individuals employed by OpenAI wrongfully took Apple’s secret and confidential information regarding our unreleased technologies, processes, and products. We will always defend our teams’ hard work and innovations, and we are taking all appropriate steps to do so.
OpenAI was asked for comment. The company responded after publication, pointing to its public statement shared on X, which reads: “We have no interest in other companies’ trade secrets. We remain focused on building innovative technology that empowers people everywhere.”
The filing is available here, or you can read it below.
China recovered its first reusable rocket and showed a new way to do it
China successfully executed its first mid-air rocket recovery using a sea-based net, signaling a rapid push to close the reusability gap with SpaceX.
Decoder
- Orbital-class booster: A rocket first stage capable of reaching the necessary velocity to put a payload into orbit before returning to Earth.
- Propulsive landing: A landing method where the rocket uses its own engine thrust to slow its descent, popularized by SpaceX’s Falcon 9.
Original article
China’s sprawling state-owned rocket developer, maker of the country’s Long March rocket family, announced it recovered a reusable orbital-class booster for the first time Friday in the South China Sea.
The milestone mission began with the liftoff of a Long March 10B rocket from the Wenchang Commercial Space Launch Site on Hainan Island, China’s southernmost province. Powered by seven kerosene-fueled engines, the approximately 209-foot-tall (63.6-meter) rocket took off at 12:15 am EDT (04:15 UTC), or 12:15 pm local time at the seaside spaceport at Wenchang.
About 10 minutes later, the Long March 10B booster descended from space and guided itself into a four-legged frame affixed to an offshore vessel. Tensioned cables stretched over the ship in a grid pattern captured the rocket as it shut down its landing engines, leaving the smoldering booster hanging in midair. The rocket’s upper stage continued into orbit and deployed a payload known only as CX-26. Chinese officials hailed the flight as a “complete success.”
A growing number
“A historic day in China’s space program!” wrote Mao Ning, a spokesperson for the Chinese Foreign Ministry, on X. “China’s Long March 10B has successfully completed its maiden flight—and recovered its first stage via a sea-based net. This marks the country’s first-ever controlled rocket recovery. A major leap toward reusable launch capabilities.”
The landing on Friday makes the China Aerospace Science and Technology Corporation (CASC) and its subsidiary, the China Academy of Launch Vehicle Technology (CALT), the third enterprise to accomplish this feat. SpaceX did it with its Falcon 9 rocket in 2015 and with its Starship/Super Heavy booster in 2024. Blue Origin landed its New Glenn booster on an offshore platform for the first time last November.
SpaceX and Blue Origin use propulsive landings to return their Falcon 9 and New Glenn boosters to offshore platforms or onshore landing pads. With Starship, SpaceX pioneered a new method of catching the rocket’s reusable booster back at its launch pad using mechanical arms mounted to the launch tower.
The Long March 10B employs a different approach for recovery, combining an offshore vessel floating downrange with the catch technique, somewhat like what SpaceX uses for Starship. Catching the rocket in this way reduces the effect of reuse on payload capacity. The Long March 10B doesn’t have to carry the extra mass of landing legs, and recovering it downrange reduces how much fuel the rocket must consume during its descent.
In a statement, CASC said the Long March 10B test flight “validated key core technologies” for a reusable launch architecture, such as multiple engine restarts with high-altitude ignition, high-precision navigation and control, and the first capture and recovery using a net system on a sea-based platform.
Friday’s launch was the first flight of the Long March 10B, a medium-lift rocket with a payload capacity of approximately 16 metric tons (35,000 pounds) to low-Earth orbit. This is slightly less than the lift capacity of SpaceX’s Falcon 9. The Long March 10B has two stages, with seven YF-100K engines on the booster consuming kerosene and liquid oxygen, and a single methane-fueled YF-219 engine on the second stage.
“Moving forward, the Long March 10B development team will continue to optimize the vehicle’s performance and accelerate the iterative upgrading of reusable rocket technologies,” CASC said. “The first stage reuse flight test is expected to be completed by the end of this year.”
The Long March 10B is similar to China’s Long March 10A rocket, which is still awaiting its first full-scale test flight. The Long March 10A has the same first stage booster as the Long March 10B, but a different upper stage and a payload fairing to accommodate cargo and satellites. The Long March 10A, on the other hand, is designed for future crew launches to China’s Tiangong space station using the country’s new human-rated spaceship, the Mengzhou, replacing China’s Shenzhou crew capsule and the Long March 2F rocket used to power it into orbit.
Chasing the Moon
A heavier configuration, known simply as the Long March 10, is a key part of China’s Moon program. This more powerful rocket will combine three Long March 10 first stage boosters—each reusable—together to generate more thrust at liftoff. A second stage and third stage will propel Chinese astronauts and their lunar landers toward the Moon. The Chinese government says it aims to land its citizens on the Moon by 2030. Friday’s launch was a small step toward that goal.
China launched a scaled-down version of the Long March 10A rocket in February with a prototype of the Mengzhou capsule to test the spacecraft’s launch abort system, which would trigger to whisk crew members away from a failing rocket. The Mengzhou test went well, and remarkably, the Long March 10A continued flying after the capsule fired away from the booster, eventually coming back to Earth for a controlled splashdown at sea. The Long March 10B took this achievement a step further with a midair catch.
Multiple commercial and government-backed Chinese rocket companies are trying to level the playing field with the United States. China is the world’s second-largest spacefaring nation, but US companies, dominated by SpaceX, are launching payloads into orbit about twice as often as Chinese rockets. SpaceX’s blistering launch cadence is made possible by the partially reusable Falcon 9, something Blue Origin and Chinese companies are seeking to emulate.
US military officials have identified China’s advancements in reusable rocketry as a key to unlocking the country’s ability to potentially threaten US assets in space. “I’m concerned about when the Chinese figure out how to do reusable lift that allows them to put more capability on orbit at a quicker cadence than currently exists,” said Maj. Gen. Brian Sidari, the Space Force’s deputy chief of space operations for intelligence, at a conference last year.
SpaceX has used the Falcon 9’s rapid-fire launch cadence to deploy more than 12,000 satellites for its commercial Starlink Internet network. Starlink has spawned several spinoffs for the US military, including a secure communications network called Starshield, a constellation of spy satellites based on the Starlink design. More recently, SpaceX has won contracts to provide the Space Force with a new Space Data Network and support an emerging capability using satellites to identify moving targets on the ground and in the air.
All of this would give US forces an advantage in any future conflict with China, which is still in the early stages of launching its own versions of Starlink. China’s mastery of rocket reuse would significantly expand the country’s launch capacity, accelerating its ability to close the gap.
“Clearly, they admire the work that’s being done by SpaceX and are trying to replicate it, and at the same time take it away from the United States if it ever came to it,” said Charles Galbreath, a retired US Space Force colonel and director and senior resident fellow for space studies at the Mitchell Institute think tank’s Spacepower Advantage Center of Excellence.
“We’ll see what happens next,” Galbreath told Ars. “Are they able to rapidly turn and increase their launch rate as a result of this potential reuse? What impact will that have on their ability to field an operational architecture of satellites?”
More to come
Two Chinese rocket companies have already tried to recover their rockets after launching from one of China’s inland spaceports. The first was LandSpace, a privately funded firm that debuted its medium-class Zhuque-3 rocket in December. The rocket reached orbit, but the booster crashed near the landing zone in the Gobi Desert at high speed. A few weeks later, another one of China’s state-owned rocket builders successfully launched the first Long March 12A rocket, but the booster again lost control on descent and could not be recovered.
The next flight of the Zhuque-3 rocket could happen later this month or in August, with LandSpace again expected to attempt to land the booster downrange. Other Chinese rockets that could soon achieve reusability include Space Pioneer’s Tianlong-3, China Commercial Rocket Co.’s Long March 12B, CAS Space’s Kinetica-2, i-Space’s Hyperbola-3, and Galactic Energy’s Pallas-1. Further into the future, China aims to debut a huge new reusable rocket on the scale of Starship, named the Long March 9.
In the United States, there are SpaceX’s Falcon 9, Falcon Heavy, and Starship, along with Blue Origin’s New Glenn rocket. Rocket Lab is aiming to launch its first medium-lift Neutron rocket with a reusable booster by the end of the year. Relativity Space is developing a partially reusable heavy-lifter named Terran R, and Firefly Aerospace is partnering with Northrop Grumman on the Eclipse rocket, which officials say will eventually have a recoverable and reusable first stage. Stoke Space has the bolder ambition of a fully reusable rocket, called Nova.
Several European companies also plan to test reusable rocket technology, but their vehicles are not as mature as many of the US and Chinese rockets. Rocket builders in India, Japan, and Russia have reuse in their roadmaps, with varying degrees of realism.
The proliferation of Chinese rocket companies, scattered across four land-based spaceports and multiple ocean-going launch platforms, should set up China to quickly ramp up its launch cadence.
“It probably won’t be but a few years before they’re able to achieve a much higher launch cadence,” Galbreath said. “They also have more launch sites than the United States currently, so if you couple their number of sites with reusability, they could surpass us in terms of launch rate, which in and of itself is more of a pride thing. But it’s the capability that’s being launched as a result of that that could actually have a significant impact on our competition, and if we got to it, a conflict.
“There’s nothing wrong with competition as long as it’s peaceful,” Galbreath said. “That can drive innovation, but I’m concerned that the historic example of Chinese behavior has not always remained peaceful. So, we have to look at everything they do carefully. On the one hand, they’re competing with SpaceX, but we know that because of the way China has organized its military, its space capabilities, all under military control, that there is significant utility that their armed forces will receive from this race.”
The Wave Has Arrived”: Zhipu Co-Founder Tang Jie's Letter to Staff
Zhipu founder Tang Jie has announced a two-year 'Touch High' plan that prioritizes foundation model research over short-term commercialization.
Deep dive
- Zhipu is deprioritizing short-term vertical product revenue to focus on four key areas: long-horizon task execution, autonomous agent systems, AI-driven self-training, and extreme safety governance.
- Tang Jie defines AGI as the accumulation of human wisdom, rejecting post-hoc safety patches in favor of embedding ethics and national law into the model's value function.
- The company is investing tens of billions into 'mechanical interpretability' to map the neural logic of black-box decisions.
- Zhipu's open-source strategy (GLM-5.2) is presented as a structural commitment to inclusive intelligence rather than a marketing tactic.
- The 'Touch High' plan signals an internal mandate to reach AGI performance levels regardless of short-term quarterly market pressures post-IPO.
- The leadership believes current chat-based LLM architectures are nearing their capability limit, shifting focus to self-evaluation and long-context reasoning.
Decoder
- Mechanical Interpretability: The field of research dedicated to reverse-engineering neural networks to understand how specific internal activations lead to output decisions.
- Long-horizon task: AI capabilities that allow models to plan, execute, and maintain memory over sequences lasting weeks or months, rather than immediate Q&A.
- Self-Play: A training technique where models learn by competing against other instances of themselves to generate data and find optimal strategies without human input.
- Token Volume: The primary unit of commercial measurement for large-model usage and training capacity, effectively acting as the 'fuel' for AGI development.
Original article
“The Wave Has Arrived”: Zhipu Co-Founder Tang Jie’s Letter to Staff
After a lockup expiry sent the stock down more than 19%, Zhipu’s Tang Jie published a full-staff letter announcing a full return to foundation-model research and a two-year “Touch High” plan. The message is very clear: strategic investment, no chasing of short-term application revenue, resources concentrated on the underlying capabilities needed for AGI.
The framing is deliberately philosophical. Tang defines AGI not as one genius’s intelligence but as the sum of all humanity’s wisdom, and insists on continuing what the company calls its “counter-intuitive” path — the same instinct that put GLM-130B into the open before ChatGPT existed. The GLM-5.2 release is the product expression of that stance: a top-3 model on the Artificial Analysis leaderboard, shipped with a million-token context and MIT weights anyone can download, deploy, and commercialize.
Tang Jie identifies four technical peaks that must be crossed on the road to AGI.
On AI safety, Tang Jie believes capability and containment must scale together. He rejects the industry norm of treating safety as a post-hoc compliance layer, insisting instead that human ethics, social norms, and national law be embedded as foundational axioms in the model’s value function from the outset. Zhipu has committed resources in the tens of billions to “mechanical interpretability” — research aimed at converting opaque model decisions into transparent, auditable logic — and Tang cites the fact that leading overseas frontier labs have withheld full public release of their most capable models due to risk concerns as a signal, not a curiosity. His conclusion is that when a technology reaches the level of force capable of altering the course of civilization, safety is no longer an ancillary feature; it becomes the prerequisite for the technology’s permitted existence.
On Open Source, Tang frames it not as a commercial strategy but as a structural commitment to inclusive intelligence. His position is that genuine AI safety cannot be built on technological closure and barriers — it requires broad co-construction, co-sharing, and oversight conducted in the open. That conviction produced the GLM-5.2 release under the most permissive MIT license, with no restrictions based on entity type, supporting a one-million-token context and available to any developer for download, deployment, and commercialisation. For Tang, “Touch High” — pushing the frontier upward — and open access are not in tension: one hand reaches for the summit, the other paves the road down so that the heights reached belong to all of humanity, not to a handful of gatekeepers.
The Wave Has Arrived — To every Zhipu employee and every partner who cares about the future of artificial intelligence
Allow me to use this article to address three things: who we are, how we see this era, and the strategic directions in which we have decided to invest all our strength.
(I) Who We Are: “Essence, Counter-Intuition, Focus”
Zhipu has never been a company that chases trends. It grew from a laboratory, carrying twenty years of methodology from that laboratory. This methodology can be summarized in three words: essence, counter-intuition, focus — think deeply enough, and you dare to bet against the grain; choose contrarily enough, and you must hold your ground long enough.
Looking back, almost every key decision we made once appeared “counter-intuitive.” In 2006, we sat in obscurity with an academic search system running on a single desktop computer, because we had reasoned through that behind it lay the question of “excavating the mechanisms of disciplinary evolution” — a matter worth answering over ten years. Between 2021 and 2022, when “making machines think like humans” was regarded by most as a moonshot-level fantasy, we reallocated resources, bet on hundred-billion-parameter scale, and produced GLM-130B — a full year and a half before ChatGPT set the world alight. And on the day Zhipu listed on the Hong Kong Stock Exchange on 8 January 2026, we treated it as a brand-new starting point, resolutely returning wholesale to foundational model research and driving full force toward the next generation of models.
Others rang the bell; we reset to zero. This is not a posture — it is a conviction. If the destination is AGI, then short-term interests or industry trends are merely scenery along the road to the endgame.
(II) How We See This Era: The Upper Bound of Intelligence Is Being Rewritten
If there is one thing the past twenty years have taught us, it is this: genuine commercial opportunity never resides in minor tweaks to products or business models; it resides in the leap of intelligence’s upper bound. This is our most fundamental judgment about the current AI transformation, and the insight we most wish to convey.
The evolution of the intelligence upper bound follows a clear trajectory. Artificial intelligence is completing the transition from perceptual intelligence to cognitive intelligence — machines no longer merely “see” and “hear”; they are beginning to “understand” and “reason.” The next step points directly toward AGI.
We hold a plain yet exacting definition of AGI: AGI is not the wisdom of any single genius, but the sum of all human wisdom. It should be capable of creating original knowledge on the order of the Theory of Relativity — that is the only standard by which we measure whether the summit has truly been reached. On the road to that destination stand several peaks that must be crossed; they are also where today’s technological waves are most turbulent: Peak One: Long Horizon Task; Peak Two: Autonomous Agent System; Peak Three: Self-Evolving.
(III) The Direction in Which We Invest All Our Strength: “Touch High”
Once the trend is clear, what remains is choice. And Zhipu’s choice is, as always, “counter-intuitive” — at a moment when the industry is broadly accelerating commercial monetization, we have decided to break upward. We have named this strategy the “Touch High Plan.” Over the next two years, we plan to invest strategically — not pursuing short-term application monetization, but aiming directly at AGI’s next high ground. This investment will be concentrated on four core engines: Long Horizon Task, Autonomous Agent System, Fully Self Training, and Extreme Safety Governance.
(IV) Open Ecosystem: The Underlying Logic of Inclusive Intelligence and Safety Governance
We have always believed that artificial intelligence, as a strategic technology leading the future, cannot develop over the long term without an open and collaborative industrial ecosystem. We are convinced that genuine safety is not built on technological closure and barriers, but on broad co-construction, co-sharing, and oversight conducted in the open.
(V) Conclusion: Why Now, Why Us
Some will ask: why, after listing, does Zhipu continue to pour its core resources into the most uncertain direction of “touching high”? Because we believe a simple truth: those who truly reach the summit turn the mountain into a road. The wave has come; the trend is irreversible. Zhipu will be the one who meets the crest of the wave and reaches upward.
Among China’s large-model founders, Zhipu’s leaders have been unusually explicit — and unusually consistent — in tying the company to AGI since 2019. The vocabulary, the roadmap, and the refusal to pivot all predate the July 2026 letter by years. Read together, the public statements explain why “Touch High” was less a reversal than a return.
“We don’t build China’s ChatGPT”
Zhang Peng set the position early and has not moved off it. In a 2023 interview he explained why Zhipu refused to sell vertical, industry-specific models: “an industry model is essentially rebuilding the wheel of traditional algorithms inside the shell of a large model,” and “only a general model of a certain scale can produce human-like cognitive emergence”.
The five-level map to AGI
Zhipu is the Chinese firm that has most openly published an AGI roadmap. Tang Jie’s five-level scheme, which Zhang Peng also uses publicly, defines the climb. Zhipu places today’s frontier around L1 to L3, which is why agents, reasoning, and self-improving training keep recurring in its releases.
Reframing AGI as a business
The one place Zhang Peng translates the creed into unit economics is the capital-markets story. After Zhipu’s first post-IPO results in March 2026, he offered what he called the “first principle” of AGI commercialization: AGI commercial value equals the intelligence ceiling multiplied by token consumption.
Tang Jie’s radicalism
Tang Jie supplies the harder edge. He halted the team’s internationally recognized graph-neural-network and knowledge-graph research and moved the whole group to large language models before the bet was safe. After DeepSeek’s emergence in early 2025, he judged the “chat paradigm” to be near its ceiling and reframed the goal as “making AI actually do things.”
Strip away the stock drama and Zhipu is running a live experiment on three questions that matter well beyond one company.
- Can open weights be a durable strategy at the frontier? Zhipu is betting that giving away SOTA models builds a moat through developers and ecosystem rather than eroding one.
- Does an Entity List placement bind a software company? So far the designation has reshaped Zhipu’s supply chain toward domestic chips without visibly slowing its model releases.
- Can a research-first culture survive public markets? The Touch High plan is a direct refusal of the quarterly logic that public listing usually imposes. Whether shareholders tolerate a two-year monetization pause after a 2,200% run is the open question the next eight quarters will answer.
The company’s own history is the reason to take the gamble seriously. The last time Zhipu made a large, unpopular, long-horizon bet — trillion-scale open pre-training in 2021–2022 — it was early rather than wrong. Touch High asks the market to extend the same benefit of the doubt one more time.
Your Browser Does Math Differently on Every OS, and Anti-Bot Systems Read the Bits
Small discrepancies in how operating systems calculate floating-point math reveal a browser's true OS, providing anti-bot systems a reliable fingerprinting signal.
Deep dive
- Mathematical Leakage: Chrome 148 replaced portable fdlibm routines with native platform libm calls, causing non-deterministic outputs across OS environments.
- Surface Areas: Leakage occurs in JavaScript's Math.tanh, CSS calc() trigonometric functions, and Web Audio DSP operations.
- Vendor Discrepancies: Each OS (Linux, macOS, Windows) uses unique polynomial approximations for transcendental functions, creating distinct OS signatures.
- Implementation Pitfalls: Using incorrect libraries (e.g., Apple's Accelerate vs. scalar libsystem_m) or failing to account for hardware FMA instructions leads to detectable inconsistencies.
- Remediation: Correct spoofing requires either transcribing exact vendor coefficients with FMA contraction disabled or directly mapping and calling target DLLs (like UCRT) using platform-specific ABI conventions.
Decoder
- ULP (Unit in the Last Place): The smallest possible increment between two representable floating-point numbers; used here to describe the tiny precision differences between math libraries.
- libm: The C standard library module providing mathematical functions like sine, cosine, and tangent.
- Minimax polynomial: An approximating polynomial designed to minimize the maximum error between a function and its approximation.
- FMA (Fused Multiply-Add): A CPU instruction that performs (a
- b) + c as one operation with a single rounding step, critical for maintaining bit-parity across different architectures.
Original article
Fingerprinting is usually about canvas, WebGL, fonts, audio. There is a quieter signal, and it lives in the last bits of a number.
Run this in any console:
Math.tanh(0.8)
// 0.6640367702678491 genuine Linux Chrome (glibc)
// 0.664036770267849 genuine macOS Chrome (libsystem_m)
// 0.6640367702678489 genuine Windows Chrome (UCRT)
That output is an approximation, and its exact bits depend on the OS that computed it. A genuine Mac runs Math.tanh through Apple’s math library. Linux runs it through glibc. The two disagree on about a quarter of all inputs, usually by one unit in the last place (1 ULP). Windows, through the Universal C Runtime, disagrees with both on a few percent, and on the input above all three land on a different bit.
The same call, run on genuine Chrome 150 across three real machines:
| Call | Linux (glibc) | macOS (libsystem_m) |
Windows (UCRT) | Split |
|---|---|---|---|---|
Math.tanh(0.5) |
0.46211715726000974 |
0.46211715726000974 |
0.46211715726000974 |
all three agree |
Math.tanh(0.7) |
0.6043677771171636 |
0.6043677771171635 |
0.6043677771171635 |
Linux alone, 1 ULP |
Math.tanh(0.8) |
0.6640367702678491 |
0.664036770267849 |
0.6640367702678489 |
all three differ, 2 ULP spread |
Math.tanh(0.9) |
0.7162978701990245 |
0.7162978701990245 |
0.7162978701990244 |
Windows alone, 1 ULP |
One tanh call on the right input is a per-OS signature. Claim macOS, return Linux math bits, and you have contradicted your own User-Agent.
This tell is recent. Until Chrome 148, V8 computed tanh itself with a bundled fdlibm port, so it returned the same bits on every OS and leaked nothing. V8 commit c1486295ae5 replaced it with std::tanh, which reads the host libm. It first shipped in V8 14.8.57, which is Chrome 148. Chrome 147 and earlier do not leak here. Chrome 148, 149, and 150 do.
Why one function returns different bits
IEEE 754 defines how a double is stored. It does not require sin, cos, tanh, or exp to be correctly rounded. Correct rounding is expensive, so every vendor ships a libm that trades a fraction of a ULP for speed, with its own minimax coefficients, lookup tables, and reduction constants.
The three implementations produce three sets of bits:
- Linux: glibc
- macOS: Apple
libsystem_m - Windows: UCRT (
ucrtbase.dll)
They agree almost everywhere and split just often enough to classify the OS. A detector needs no math, only a table: genuine macOS Chrome returns one pattern for cos(1), genuine Linux Chrome returns another, and a single comparison tells them apart.
Four traps
“Just reimplement the Mac functions” breaks on contact, for four reasons.
1. Only some math leaks. V8 ships its own math and links it statically: Math.exp, Math.pow, Math.atan, and most of the rest come from bundled llvm-libc, and Math.sin / Math.cos from a bundled glibc-derived dbl-64 routine. All of them are identical on every OS, so spoofing them creates an inconsistency. The exception is Math.tanh: since Chrome 148 V8 computes it with the platform std::tanh instead of the bundled routine it used before, so it now reads the host libm. It is the only Math.* that leaks the OS, and that asymmetry is itself checkable.
2. JavaScript math and CSS math are different code paths. CSS sin(), cos(), and atan2() do not share code with Math.sin. The layout engine reduces the angle in degrees, then calls platform std::sin on the reduced value. That gives a different result than a direct radian sin(), and it hits the host libm, so all seven CSS trig functions leak. We reproduced the degree reduction and the radians-to-degrees step bit-for-bit, not just the leaf function.
3. macOS has two math libraries that disagree. Apple Silicon carries scalar libsystem_m and the Accelerate framework’s vector routines (vvsin, vvtanh). They are different code. Across a million inputs they diverge on 10 to 89 percent, depending on the function. Take cos(0): scalar returns exactly 1.0, Accelerate returns 0.9999999999999999. So “reproduce Apple’s math” is undefined until you know which library the browser calls, at which site. We resolved it by driving real Chrome on a real Mac over the debugging protocol and reading the exact double. Answer: scalar libsystem_m backs Math.tanh, CSS trig, and the audio compressor’s per-sample transcendentals. Accelerate backs Chrome’s Web Audio DSP on Mac, the FFT, the vector math, and the biquad filters.
4. Architecture leaks. ARM and x86 differ on fused-multiply-add and on NaN sign propagation. A reproduction that is correct on paper drifts if the compiler fuses a multiply-add on one target and not the other.
The map: what leaks where
| Operation | V8 Math.* (JS) |
CSS calc() |
Web Audio |
|---|---|---|---|
sin cos tan |
V8 bundled | host libm | Accelerate (osc FFT), sin scalar in the compressor |
asin acos atan atan2 |
V8 bundled | host libm | not used |
tanh |
host libm | none | not used |
exp |
V8 bundled | host libm | scalar in the compressor |
log log2 log10 pow |
V8 bundled | host libm | scalar log10f / powf in the compressor |
| vector add/mul/scale, FFT | n/a | n/a | Accelerate (vDSP) on Mac |
sqrt abs + - * / |
hardware | hardware | hardware |
How to close it
No noise. Perturbing the output fails twice. A reference comparison sees a value that matches no real OS, and per-call randomness breaks determinism, which is its own tell. The target is a value identical to the OS you claim, which noise cannot produce.
Reproduce the algorithm exactly. Recover the target’s minimax coefficients, exponent tables, and reduction constants from its libm, and transcribe them to portable C. Match every bit, including the inputs where the target rounds the wrong way.
Make it deterministic. That explicit fma() matters. Compile with FMA contraction off (-ffp-contract=off) so the compiler never invents or drops a fusion of its own. Now the fused ops are exactly the ones Apple fuses, and the result is identical on FMA and non-FMA CPUs.
When reproduction is not worth it, lift the original. Windows UCRT is x86-64, the same ISA as a Linux server, and position-independent. Map the genuine ucrtbase.dll into memory at runtime and call its exports directly. The bits are genuine because the code is genuine, no reverse-engineering required.
Patch the chokepoint, gate it. Hook the single function that owns the value, where the engine calls libm. Gate on the claimed OS: Linux keeps glibc, Mac gets the reproduction.
Watch the clock. A perfect reproduction that runs slow is still a tell. Our first build lowered every fma() to a software call, because the default x86 baseline predates hardware FMA. That ran 2.5 to 6 times slower than native. A loop timing Math.tanh against Math.sin would show a ratio no real browser has. Turning on hardware FMA cut each fused op to one instruction: about 6 times faster, faster than glibc, and bit-identical.
Validation
None of this ships without proof. Our harness runs 871,000 inputs per release across every branch and domain: dense grids, interval boundaries, subnormals, signed zeros, infinities, NaNs. Two ground truths back it:
- A genuine-device oracle: a real Mac computing both scalar and Accelerate results for every input, so we know exactly where the two disagree.
- A genuine-browser anchor: real Chrome on a real Mac over the debugging protocol, computing
Math.tanhand every CSS trig function at full precision. This is the surface a fingerprinter reads.
Why it matters
Math is deterministic, cheap to probe, hard to fake, and almost never on a spoofing stack’s radar. That makes it a strong signal for a defender and a liability for a scraper. Getting it right takes reverse-engineering vendor libm internals, mapping how three engines route math per call site, matching algorithms to the last bit, holding determinism across architectures, and proving it against real hardware.
Scrapfly’s browser carries all of it. Send a request through our API and ask to present as macOS, and the identity holds down to the rounding of a cosine.
Nginx vs Caddy vs Traefik in 2026 — I Ran All Three Under Real Production Load
Traefik outperformed Nginx and Caddy in operator efficiency for a logistics firm, saving 6 hours of manual configuration time per month despite slightly higher resource usage.
Deep dive
- Performance Comparison: Nginx showed highest throughput (46k req/s), followed by Caddy (41k req/s) and Traefik (36k req/s).
- Operational Efficiency: Traefik minimized manual effort by using label-based discovery, saving 6 hours/month over Nginx.
- Migration Risks: In-production cutover revealed that Traefik’s strict adherence to timeout annotations broke large CSV exports that Nginx previously allowed via different default behavior.
- Conclusion: Performance is secondary to operational maintainability in high-churn Kubernetes environments.
Decoder
- Ingress Controller: A Kubernetes component that manages external access to services, typically providing load balancing and TLS termination.
- nf_conntrack: A Linux kernel subsystem used by netfilter to track network connections, which can become a bottleneck or failure point under high load if not sized correctly.
- 502 Bad Gateway: An HTTP status code indicating the proxy server received an invalid response from the upstream application server.
Original article
Nginx vs Caddy vs Traefik in 2026 — I Ran All Three Under Real Production Load
Same Kubernetes cluster, same microservices, same TLS requirements. One proxy broke during ingress-nginx migration week. Guess which.
I’ve terminated more TLS than I care to admit. Reverse proxies are the part of the stack everyone forgets until certificates expire, upstreams go silent, or — in March 2026 — your ingress controller hits end-of-life and compliance asks what your migration plan is.
A logistics client ran ingress-nginx on EKS for four years. Fine until it wasn’t supported. They asked me to compare Nginx (F5 NIC), Caddy, and Traefik on the same cluster before picking a path forward. Same twelve microservices. Same cert issuer. Same load tests. I ran each as the edge for six weeks.
RKE2 v1.36 making Traefik the default ingress is not abstract news if you operate Rancher clusters. It is a migration ticket with a deadline.
The Test Bed: Production Shape, Controlled Variables
Cluster: EKS, 12 services, ~35,000 requests/minute average, ~61,000 peak during dispatch windows. Mix of REST JSON, WebSocket tracking, and one large CSV export (15–40 MB responses).
Each proxy setup:
- Automatic TLS (Let’s Encrypt / ACME)
- HTTP/2 and HTTP/3 where supported
- Rate limiting on public endpoints
- Prometheus metrics scraped the same way
- Same pod resource requests: 2 CPU / 2Gi per ingress controller replica
I tracked: p50/p99 proxy latency, memory at idle and at 10k connections, config reload behavior, and operator time per new service route.
Throughput vs Operator Time — Pick Your Poison
Nginx (F5 NIC ingress on Kubernetes):
- Proxy throughput: ~46,000 req/s in our wrk suite (2 KB JSON upstream) — highest of the three
- p99 proxy overhead: ~0.9ms at median load
- Idle memory: ~35 MB per controller pod; ~120 MB at 10k connections
- New service route: manual Ingress YAML + annotation review — ~25 minutes including PR
- Strength: raw performance, massive community knowledge, every senior SRE has scars here
Caddy 2.11 (standalone ingress on VMs + DaemonSet edge):
- Proxy throughput: ~41,000 req/s — ~11% behind Nginx on pure JSON proxying
- p99 overhead: ~1.2ms — TLS termination gap narrowed; automatic HTTPS is not a gimmick
- Idle memory: ~28 MB; ~95 MB at 10k connections
- New route: 12-line Caddyfile block or JSON API push — ~8 minutes for a standard service
- HTTP/3 on by default. ECH support mattered for a client with aggressive TLS inspection policies.
Traefik 3.7 (Kubernetes CRD + IngressRoute):
- Proxy throughput: ~36,000 req/s — lowest raw number, still 3x headroom over peak traffic
- p99 overhead: ~1.6ms under burst; token-bucket rate limiting smoother than Nginx leaky bucket for our spike pattern
- Idle memory: ~48 MB; ~135 MB at 10k connections
- New route: label on Deployment — often zero manual steps after conventions exist
- ingress-nginx annotation compatibility layer saved two weeks on migration —
rewrite-target,proxy-body-size, most of what they already had
TLS, Reloads, and the Config Formats You’ll Maintain at 2 AM
Nginx: Cert rotation via cert-manager worked. Config reload via nginx -s reload is battle-tested. When we fat-fingered a proxy_pass typo, Nginx refused reload and kept the old config — annoying in CI, lifesaving in prod.
Caddy: Automatic HTTPS is the real product. Two lines, cert appears, HTTP/3 works. JSON API reload with zero downtime felt like cheating on a homelab. In Kubernetes we still needed to wire cert storage — not hard, but not literally zero config at scale.
Traefik: Watching Docker/K8s events and building routes dynamically is magic until it isn’t — a mislabeled pod got public traffic for eleven minutes before we caught it in access logs. Convention documentation became mandatory: label schema, entrypoint names, middleware chains.
The Migration Week Incident
Cutover Tuesday, 09:40 local — dispatch managers start their morning export ritual. Traefik at 60% traffic, ingress-nginx still handling legacy annotations on two services. A deployment rolled out with a malformed Ingress annotation — nginx.ingress.kubernetes.io/proxy-read-timeout set to "30" (seconds) on an export service that needed 300.
Nginx ingress honored the low timeout. Traefik’s translated middleware did too — correctly, per config. Large CSV exports died at 30 seconds flat. Users saw 502 Bad Gateway. Error rate: 0% → 8% in three minutes.
We extended the timeout annotation, confirmed upstream p99 was 42 seconds for huge exports, set 300s with a async export fallback on the roadmap.
For the node-level debugging — journalctl, connection tracking, file descriptor limits — turned out nf_conntrack table was 92% full on two nodes from the export spike. Not a Traefik bug. A connection tracking budget we had never sized for long-lived downloads.
When I Would Choose Nginx
- You terminate massive traffic on dedicated edge nodes and need every req/s
- Large-file streaming (GB-scale) where Nginx’s buffer tuning still wins
- Team has a decade of Nginx config and F5 support contract
- You are standardizing on F5 NIC post ingress-nginx EOL and want vendor continuity
When I Would Choose Caddy
- Small cluster or VM fleet — TLS just works with minimal config
- Developer velocity over raw throughput; HTTP/3 and ECH matter
- You hate maintaining Certbot sidecars and annotation archaeology
- <10 services, mostly stable routes, homelab-to-production pipeline
When I Would Choose Traefik
- Kubernetes-native stack with frequent service churn — labels beat YAML surgery
- Migrating off ingress-nginx in 2026 — annotation compatibility is real
- RKE2 / Rancher shops where Traefik is already the default path
- You want dynamic upstreams without reloading the world
Verdict
There is no “best” proxy — only the one that matches your operational model.
For this client’s EKS fleet with weekly deploys and a migration deadline, Traefik won — not because it was fastest, but because operator time and ingress-nginx compatibility beat 11% throughput we weren’t using. We kept Nginx on a dedicated edge VM for the CSV export CDN path where buffer tuning and raw streaming matter. Caddy runs my personal staging cluster because I refuse to maintain Certbot on a Saturday.
What You Should Do This Week
- If you still run ingress-nginx, inventory annotations and test Traefik’s compatibility layer on a non-prod namespace. March 2026 EOL is not a surprise anymore — it’s a calendar event.
- Log
X-Forwarded-Forand upstream status on every 502. Half of "proxy broke" is timeout misconfig. - Check
nf_conntrackusage before blaming the ingress controller for connection drops on large downloads. - Write a rate-limit test that hits the same endpoint from two IP paths — corporate LB misconfig shows up before customers complain.
- Document your label/schema conventions before Traefik auto-discovery becomes auto-misrouting.
Proxies do not create outages. They reveal the config you did not test. Make sure you know what’s on the other side.
Your Azure DevOps pipelines have a 2027 deadline, and the clock has just started
Azure DevOps is retiring its legacy workload identity issuer in July 2027, forcing a mandatory transition to the Microsoft Entra issuer.
Deep dive
- Deprecation: The legacy Azure DevOps issuer will be retired on July 1, 2027.
- Migration: Requires updating the Federated Credential subject format on App Registrations.
- Scope: Only affects single-tenant Entra applications; multitenant apps remain on the legacy issuer.
- API: Uses the undocumented
MigrateToEntraIssuerREST operation found via browser inspection.
Decoder
- Workload Identity Federation: A mechanism for services like Azure Pipelines to authenticate to cloud resources without long-lived secrets by using short-lived tokens.
Original article
Your Azure DevOps pipelines have a 2027 deadline, and the clock has just started
As of 1st July 2026, the Azure DevOps issuer for workload identity federation is officially deprecated, with full retirement set for 1st July 2027. If that sentence meant nothing to you, here’s the short version: any Azure Pipelines Service Connection you created before late 2025 probably needs attention, and if you ignore it, those pipelines will stop authenticating to Azure a year from now.
The portal will happily convert them for you, one Service Connection at a time, a couple of minutes each. That’s perfectly civilised if you have five. If you have several hundred (or more than about 10 if you’re anything like me) then this isn’t going to work.
But luckily for you I’ve gone through the hassle of figuring out how to programmatically call the migration.
What’s actually changing
Workload identity federation is the secretless way Azure Pipelines authenticates to Azure. Instead of storing a service principal secret that expires and takes a pipeline down with it, the Service Connection trades a short-lived token for access. That trust is anchored by a Federated Credential on an App Registration, and every federated credential names an issuer, the authority that mints the token.
Older connections use the Azure DevOps issuer, the one with the https://vstoken.dev.azure.com prefix. Microsoft is standardising on the Microsoft Entra issuer (https://login.microsoftonline.com) across its services, so the old issuer is on the way out. New connections have used the Entra issuer since November 2025, which is why this only bites the older ones.
One important boundary to keep in mind though as DevOps won’t indicate this for you, the deprecation only covers single-tenant Entra apps and Managed Identities in the Azure public cloud. Multitenant applications and the sovereign clouds are explicitly out of scope, and the Azure DevOps issuer keeps working for them.
Programmatically calling the migration
The portal’s Update button isn’t doing anything magical. Under the bonnet it fires a single REST call against the Service Connection, with an operation of MigrateToEntraIssuer. There’s no documented API for it that I could find, but you can watch the portal make the call in your browser’s dev tools and replay it yourself.
The script below runs in two phases. First it pre-creates the Entra federated credential on each App Registration, waits a moment for it to propagate, then calls the migrate operation.
#Requires -Version 7.0
#Requires -Modules Az.Accounts, Az.Resources
<#
.SYNOPSIS
Bulk-migrates Azure DevOps WIF service connections from the deprecated Azure DevOps
issuer to the Microsoft Entra issuer.
Phase 0 pre-creates the Entra-issuer federated identity credential on each in-scope single-tenant app registration.
Phase 1 (parallel, REST): calls operation=MigrateToEntraIssuer and reads the outcome from operationStatus.state.
.DESCRIPTION
The Entra-issuer FIC uses:
Issuer : https://login.microsoftonline.com/<tenantId>/v2.0
Subject : /eid1/c/pub/t/<b64url(tenantId)>/a/<b64url(AzureDevOpsAppId)>/sc/<orgId>/<endpointId>
Audience : api://AzureADTokenExchange
The subject is the flexible-FIC format - NOT the old sc://<org>/<project>/<name>.
b64url segments are base64url of the GUID byte array (Guid.ToByteArray), padding stripped.
The a/ segment is the Azure DevOps first-party app id (499b84ac-..)..
.NOTES
- Single-tenant apps only. Multitenant (AzureADMultipleOrgs) are out of scope and skipped.
- Run with $WhatIfMode = $true first; it prints the per-connection plan without changing anything.
- 'c/pub' assumes Azure public cloud.
#>
# ---------------------------------------------------------------------------
# Parameters
# ---------------------------------------------------------------------------
$OrganizationUrl = 'https://dev.azure.com/redstorltd'
$EndpointIds = @() # If empty the script will enumerate all WIF connections in the org. Enter individual service connection IDs to limit the scope
$ApiVersion = '7.1'
$ThrottleLimit = 5 # parallel migrate calls
$PropagationSeconds = 90 # wait between FIC creation and migration
$WhatIfMode = $true # Set to $false to execute the migration. $true prints the plan only.
$TenantId = '' # Required, should be set to your Entra ID Tenant
$AdoAppId = '499b84ac-1321-427f-aa17-267ca6975798' # Azure DevOps first-party app id (constant for all connections)
# ---------------------------------------------------------------------------
# Connect + context
# ---------------------------------------------------------------------------
if (-not (Get-AzContext)) { Connect-AzAccount | Out-Null }
# Azure DevOps REST auth.
# Az.Accounts 5.x returns .Token as a SecureString, so decode it to plain text.
$adoToken = (Get-AzAccessToken -ResourceUrl '499b84ac-1321-427f-aa17-267ca6975798' -AsSecureString).Token
$headers = @{ Authorization = "Bearer $(ConvertFrom-SecureString $adoToken -AsPlainText)" }
# Organisation (instance) ID - the <orgId> segment of the subject.
$OrgId = (Invoke-RestMethod -Headers $headers -Method Get -Uri "$OrganizationUrl/_apis/connectionData").instanceId
if($null -eq $OrgId) { throw "Failed to retrieve orgId from $OrganizationUrl/_apis/connectionData" }
Write-Host "Org '$(($OrganizationUrl -split '/')[-1])' (id $OrgId), tenant $TenantId." -ForegroundColor Green
# Base64url of a GUID's byte array (matches the ADO flexible-FIC subject encoding).
function ConvertTo-Base64Url([guid]$Guid) {
[Convert]::ToBase64String($Guid.ToByteArray()).TrimEnd('=').Replace('+','-').Replace('/','_')
}
# ---------------------------------------------------------------------------
# Enumerate candidate connections (azurerm + WIF)
# ---------------------------------------------------------------------------
Write-Host "Enumerating projects and service connections..." -ForegroundColor Cyan
$projects = (Invoke-RestMethod -Headers $headers -Method Get -Uri "$OrganizationUrl/_apis/projects?api-version=$ApiVersion").value
$candidates = foreach ($project in $projects) {
$eps = (Invoke-RestMethod -Headers $headers -Method Get `
-Uri "$OrganizationUrl/$($project.id)/_apis/serviceendpoint/endpoints?type=azurerm&api-version=$ApiVersion").value
foreach ($ep in $eps) {
if ($ep.authorization.scheme -eq 'WorkloadIdentityFederation' -and $ep.authorization.parameters.workloadIdentityFederationSubject.StartsWith("sc://")) {
[pscustomobject]@{ EndpointId = $ep.id; Name = $ep.name; ProjectName = $project.name }
}
}
}
$candidates = $candidates | Sort-Object EndpointId -Unique
if ($EndpointIds.Count -gt 0) { $candidates = $candidates | Where-Object EndpointId -in $EndpointIds }
Write-Host "Found $($candidates.Count) WIF connection(s) to consider." -ForegroundColor Green
# ---------------------------------------------------------------------------
# Phase 0: resolve app, skip multitenant, compute issuer/subject, create FIC
# ---------------------------------------------------------------------------
$ready = [System.Collections.Generic.List[object]]::new()
$skipped = [System.Collections.Generic.List[object]]::new()
foreach ($c in $candidates) {
$base = "$OrganizationUrl/$($c.ProjectName)/_apis/serviceendpoint/endpoints/$($c.EndpointId)"
$ep = Invoke-RestMethod -Headers $headers -Method Get -Uri "$base`?api-version=$ApiVersion"
$appObjectId = $ep.data.appObjectId
if (-not $appObjectId) {
$skipped.Add([pscustomobject]@{ Name = $c.Name; Reason = 'No app object id (managed identity or non-automatic connection)' }); continue
}
$app = Get-AzADApplication -ObjectId $appObjectId -ErrorAction SilentlyContinue
if (-not $app) {
$skipped.Add([pscustomobject]@{ Name = $c.Name; Reason = "App $appObjectId not found / no access" }); continue
}
if ($app.SignInAudience -ne 'AzureADMyOrg') {
$skipped.Add([pscustomobject]@{ Name = $c.Name; Reason = "Out of scope - SignInAudience=$($app.SignInAudience)" }); continue
}
$issuer = "https://login.microsoftonline.com/$TenantId/v2.0"
# The a/ segment is the Azure DevOps first-party app id - constant for all connections.
$AdoAppSegment = ConvertTo-Base64Url ([guid]$AdoAppId)
$subject = "/eid1/c/pub/t/$(ConvertTo-Base64Url $TenantId)/a/$AdoAppSegment/sc/$OrgId/$($c.EndpointId)"
$ficName = "ado-entra-$($c.EndpointId)"
$exists = Get-AzADAppFederatedCredential -ApplicationObjectId $appObjectId -ErrorAction SilentlyContinue | Where-Object { $_.Subject -eq $subject -and $_.Issuer -eq $issuer }
if ($WhatIfMode) {
Write-Host "[WhatIf] $($c.Name): would $(if($exists){'reuse'}else{'create'}) FIC then migrate." -ForegroundColor Yellow
} elseif (-not $exists) {
New-AzADAppFederatedCredential -ApplicationObjectId $appObjectId -Name $ficName -Issuer $issuer -Subject $subject -Audience 'api://AzureADTokenExchange' -ErrorAction Stop | Out-Null
Write-Host " Created FIC for '$($c.Name)'." -ForegroundColor DarkGray
}
$ready.Add([pscustomobject]@{ EndpointId = $c.EndpointId; Name = $c.Name; ProjectName = $c.ProjectName })
}
if ($skipped.Count) { Write-Host "`nSkipped $($skipped.Count):" -ForegroundColor Yellow; $skipped | Format-Table -AutoSize }
if ($WhatIfMode) {
Write-Host "`n[WhatIf] $($ready.Count) connection(s) would be migrated. Set `$WhatIfMode = `$false to execute." -ForegroundColor Yellow
return
}
# ---------------------------------------------------------------------------
# Propagation wait, then Phase 1: migrate (parallel REST)
# ---------------------------------------------------------------------------
Write-Host "`nWaiting ${PropagationSeconds}s for FIC propagation..." -ForegroundColor Cyan
Start-Sleep -Seconds $PropagationSeconds
$results = $ready | ForEach-Object -ThrottleLimit $ThrottleLimit -Parallel {
$c = $_; $headers = $using:headers; $org = $using:OrganizationUrl; $apiVer = $using:ApiVersion
$base = "$org/$($c.ProjectName)/_apis/serviceendpoint/endpoints/$($c.EndpointId)"
try {
$current = Invoke-RestMethod -Headers $headers -Method Get -Uri "$base`?api-version=$apiVer" -ErrorAction Stop
$refs = @(foreach ($r in $current.serviceEndpointProjectReferences) {
@{ description = $r.description; name = $r.name; projectReference = @{ id = $r.projectReference.id; name = $r.projectReference.name } }
})
$body = [ordered]@{
id = $current.id; type = $current.type
authorization = @{ scheme = 'WorkloadIdentityFederation' }
serviceEndpointProjectReferences = $refs
} | ConvertTo-Json -Depth 10
$resp = Invoke-RestMethod -Headers $headers -Method Put -Uri "$base`?operation=MigrateToEntraIssuer&api-version=$apiVer" -ContentType 'application/json' -Body $body -ErrorAction Stop
$state = $resp.operationStatus.state
if ($state -match 'Failed') {
[pscustomobject]@{ Name = $c.Name; Status = "Failed ($state)"; Detail = $resp.operationStatus.statusMessage }
} else {
[pscustomobject]@{ Name = $c.Name; Status = "OK ($state)"; Detail = '' }
}
}
catch {
[pscustomobject]@{ Name = $c.Name; Status = "HTTP error ($($_.Exception.Response.StatusCode.value__))"; Detail = $_.Exception.Message }
}
}
# ---------------------------------------------------------------------------
# Summary
# ---------------------------------------------------------------------------
$ok = @($results | Where-Object Status -like 'OK*').Count
Write-Host "`nDone. $ok of $($results.Count) migrated, $($skipped.Count) skipped." -ForegroundColor Green
$results | Format-Table -AutoSize -Wrap
A couple of things worth knowing if you adapt it. The migrate call returns HTTP 200 even when the server-side migration fails, so the real result lives in operationStatus.state rather than the status code. And the new subject isn’t the old sc://org/project/connection format, it’s the flexible-credential format, where the app segment is Azure DevOps’s own application ID and stays constant for every connection. Get either wrong and validation fails, which is at least a safe way to fail.
Don’t “fix” your multitenant apps
The script intentionally skips multitenant App Registrations, the tempting shortcut is to switch its signInAudience to single-tenant so it qualifies, then convert it like the rest. Please don’t do this blindly.
signInAudience is a property of the App Registration, not the Service Connection, so flipping it changes every use of that identity, not just the pipeline you’re looking at. Plenty of apps are multitenant on purpose, most often because they deploy across tenants, an identity homed in one tenant with rights in another. Make it single-tenant and that cross-tenant access will stop working, which is also precisely why Microsoft left these out of scope.
The Entra issuer’s subject is tenant-scoped, and it can’t do the cross-tenant trick the old issuer did.
Getting started
Find your affected connections, test the two-phase run against a single one, confirm a pipeline still authenticates, then let it loose. The canonical walkthrough, including the manual conversion path, is on Microsoft Learn: Convert service connections from the Azure DevOps issuer to the Microsoft Entra issuer. The official announcement with the full timeline is on the Azure DevOps blog.
The benchmark grading every text-to-SQL model has wrong answers in its key
Popular text-to-SQL benchmarks like BIRD and Spider contain erroneous 'gold' answers, misleading model developers and skewing evaluation rankings.
Deep dive
- BIRD and Spider benchmarks contain significant annotation errors in their reference 'gold' queries.
- SQLsure audit discovered joins that violate declared primary/foreign key relationships in 8.2% of BIRD training queries.
- Current 'execution accuracy' metrics inherently reward models for matching incorrect benchmark reference results.
- Enterprise analytics requires stricter validation than benchmark-style accuracy, focusing on semantic correctness (grain, join cardinality, non-additive metrics).
- Constraint-aware evaluation enables reference-free, deterministic auditing of SQL queries.
- Automated semantic checks can serve as both a CI gate and a tool for LLM agents to verify SQL before execution.
Decoder
- Execution Accuracy: A metric that evaluates text-to-SQL models by comparing the result of a generated query against the result of a 'gold' reference query.
- Fan-out: A data modeling scenario where joining tables causes rows to be duplicated, potentially inflating aggregate results like counts or sums.
- Grain: The level of detail represented in a table row (e.g., individual transactions versus daily summaries).
Original article
The benchmark grading every text-to-SQL model has wrong answers in its key
BIRD and Spider are the exams of the text-to-SQL world. Every model you've seen ranked — GPT, Claude, Gemini, every fine-tuned SQLCoder variant — gets its accuracy number by comparing its output against these benchmarks' gold queries: SQL written by experts, reviewed, and published as ground truth.
We pointed a deterministic semantic checker at the ground truth itself. It took about two seconds, and one of the answers in the key is provably wrong by a factor of eight.
That finding is the hook. The reason to keep reading is what it implies: the way this entire field measures itself has a blind spot — and it's the same blind spot that ships wrong numbers to enterprise dashboards every day.
Layer 1 — Gold isn't always gold
The method (no AI, no labeling)
sqlsure validates SQL against declared facts — what one row means, which joins multiply rows, what's safe to sum. Benchmarks conveniently publish those facts: every BIRD and Spider database ships its primary and foreign keys. So the audit is mechanical: build the rulebook from each database's own declarations, parse all 2,568 gold queries (1,034 Spider dev + 1,534 BIRD dev), flag joins that contradict the declared facts, review every flag by hand — and, for BIRD, by executing the shipped databases.
| Spider dev | BIRD dev | |
|---|---|---|
| gold queries parsed | 1,034 / 1,034 | 1,534 / 1,534 |
| joins observed | 518 | 1,419 |
| anomaly flags | 30 | 15 |
| flags confirmed real | 30/30 | 14/15 (1 benign-but-fragile) |
| spurious flags | 0 | 0 |
The 8× answer
BIRD dev question #571 asks: "For the user No.24, how many times is the number of his/her posts compared to his/her votes?" We executed the benchmark's own database: user 24 has 3 posts and 8 votes. The correct answer is 3 ÷ 8 = 0.375. The gold query returns 3.0 — its join creates a 3 × 8 cartesian product per user, and the inflated count divided by the distinct count algebraically collapses to… the post count. Off by exactly the fan-out factor.
-- BIRD gold (returns 3.0):
SELECT CAST(COUNT(T2.Id) AS REAL) / COUNT(DISTINCT T1.Id)
FROM votes T1 JOIN posts T2 ON T1.UserId = T2.OwnerUserId
WHERE T1.UserId = 24
-- correct (returns 0.375):
WITH v AS (SELECT COUNT(*) c FROM votes WHERE UserId = 24),
p AS (SELECT COUNT(*) c FROM posts WHERE OwnerUserId = 24)
SELECT CAST(p.c AS REAL) / v.c FROM p, v
We also found a schema-level defect — european_football_2 declares 29 foreign keys on its Match table but omits the league link its own gold answers use 13 times. And the training set is worse: our follow-up audit of all 9,428 BIRD train queries found 8.2% of joins unbacked by any declared relationship, including eight databases that declare zero foreign keys at all.
After our audit, we found the expert-corrected BIRD dataset from the VLDB'26 annotation-errors project: 10 of our 15 dev flags were independently identified by their human review, and their expert fix for #571 computes exactly our 0.375.
Layer 2 — Execution accuracy is not ground truth
Here's the part that matters more than any single wrong answer. The field's standard metric — execution accuracy — asks: does the generated query's result match the gold query's result?
To be fair to it: that design elegantly solves a real problem. SELECT SUM(sales) and an equivalent subquery formulation are different SQL with the same answer — comparing results instead of text correctly accepts both. Equivalent SQL is the failure mode execution accuracy was built for, and it handles it well.
But it has an unexaminable assumption: that the gold result is right. Follow the chain when it isn't:
question → gold SQL (wrong) → gold result (wrong) → execution accuracy
rewards matching the wrong result
penalizes the correct answer
A model that answers #571 correctly — 0.375 — is marked wrong. A model that makes the same fan-out mistake as the annotator is marked right. At scale, this doesn't just add noise: correcting annotation errors has been shown to materially change reported performance and even reorder model rankings. Companies choose AI systems off these leaderboards. Procurement decisions are partly downstream of annotation bugs.
| Failure mode | Example | Does execution accuracy handle it? |
|---|---|---|
| Equivalent SQL, same result | different formulations of the same sum | yes — by design |
| Wrong SQL, wrong gold result | #571's fan-out ratio | no — it rewards the bug |
Layer 3 — Enterprise SQL is harder than any benchmark
Suppose every benchmark answer were perfect. The gap between "passes the benchmark" and "trustworthy in production" would still be wide, because enterprise analytics adds semantics no execution check can see: joins that fan out and silently double-count, non-additive measures (you can't sum averages), semi-additive measures (Monday's bed count plus Tuesday's isn't two days of beds), canonical metric definitions, row-level security, fiscal calendars, hidden business filters. A query can be syntactically valid, execute cleanly, and match another query's result while violating every one of these. Correct SQL syntax ≠ correct analytics — and the experts who wrote BIRD's answer key just demonstrated that even careful humans fall into exactly these traps.
Layer 4 — Constraint-aware evaluation
There's a complementary way to judge SQL: not "does the result match gold?" but "does the query respect the declared semantics of the data?" — grain, join cardinality, additivity, metric definitions, column policy. Facts that teams already declare in dbt tests, PK/FK constraints, and semantic layers.
The two axes are complements, not rivals: execution accuracy checks outcome against a reference; constraint validation checks reasoning against declared truth — needs no reference answer at all, which is exactly why it can audit the reference answers themselves. It's deterministic (same query, same verdict), and every rejection carries a fix a model can apply mechanically. We've published it as an open eval metric — a semantic pass rate to report alongside execution accuracy.
Why this matters if you're deploying AI on your data
- If you pick models off leaderboards: some of the ranking signal is annotation error. Ask vendors for semantic-validity numbers, not just execution accuracy.
- If you fine-tune on BIRD/Spider train: your model is learning from schemas where up to 8% of gold joins aren't backed by any declared relationship — including databases with no declared links at all.
- If your agents write SQL in production: there is no gold answer to compare against out there. Constraint validation is the only reference-free check that exists — which is why it belongs in the loop, not just in the eval.
The future of text-to-SQL isn't just better models
SQL generation has become good enough that evaluation is now the bottleneck. The next generation of benchmarks shouldn't only check whether results match a reference — they should verify whether queries respect grain, join cardinality, additivity, metric definitions, and policy.
pip install sqlsure
How Airflow is using AI to make data engineering more resilient, not more complex
Apache Airflow 3.3 integrates AI-driven features to autonomously validate schemas, resume failed jobs, and classify errors based on custom team runbooks.
Deep dive
- Schema drift is validated semantically, avoiding false negatives from traditional rule-based checks.
- The Task State Store survives across retries, allowing long-running Spark or Databricks jobs to resume instead of restarting.
- LLMRetryPolicy enables intelligent decision-making that avoids unnecessary retries for permanent errors like expired credentials.
- Fallback rules ensure the pipeline continues to function deterministically if the LLM is unavailable.
Decoder
- DAG (Directed Acyclic Graph): A collection of tasks organized in a way that reflects their relationships and dependencies in Airflow.
Original article
How Airflow is using AI to make data engineering more resilient, not more complex
Your pipeline failed at 2am. What if it could fix itself?
A data engineer at a global asset management firm told me something recently that stuck with me. When pipelines fail before the market opens, it can take many people and many hours to diagnose the root cause across multiple systems. Portfolio managers need performance numbers at the start of the trading day. Every minute of delay has consequences.
The current failure response is manual. The on-call engineer gets paged. They open the logs. They walk through a mental checklist: is this a transient network issue? A rate limit? An expired credential? A schema change upstream? Each failure category requires a different response. Retry with backoff, fail immediately and escalate, or fix the data and rerun. The checklist is tribal knowledge. The response time typically depends on who is on call.
This is not an AI application problem. Nobody is building an agent here. This is a data engineering operations problem, and AI can make it dramatically better without changing how you build pipelines.
I have been thinking about this through the lens of three capabilities we are building into Apache Airflow’s Common AI provider and Airflow 3.3. Together, they form an autonomous pipeline health loop:
- Detect: Catch data drift before it breaks anything
- Resume: Pick up where you left off instead of having to restart
- Fix: Turn your 2am playbook into an automated retry policy
Each one uses AI to solve a specific operational pain point that every data engineer recognizes.
Detect: Catch Data Drift Before It Breaks Anything
I wrote my first data pipeline almost three decades ago, and I faced my first data drift issue almost immediately. An upstream system changed a field format without telling anyone. My pipeline did not fail. It just started producing wrong numbers. I spent an embarrassing amount of time debugging my own code before realizing the input had changed underneath me.
It is 2026, and data drift is still a bane for data engineers everywhere. The tools have gotten better. The data volumes have gotten larger. The fundamental problem has not changed.
Industry estimates suggest that over 35% of unplanned data downtime originates from unexpected incoming schema or data drift.
The insidious part is that schema drift often does not crash the pipeline. An upstream system renames user_id to userId. A column type changes from INT to STRING. A new nullable column appears. The pipeline runs, completes successfully, and loads NULL values, misaligned fields, or incomplete records into your analytics tables. Nobody gets paged. The executive dashboard just starts showing wrong numbers. By the time someone notices, bad data has propagated downstream for hours or days.
The scenarios that do crash the pipeline are almost better, because at least you know something is wrong.
Traditional schema validation uses rule-based checks: column counts, type matching, constraint verification. These catch the obvious cases. They miss the subtle ones. A varchar(255) in Postgres and a STRING in Snowflake are semantically identical but syntactically different. A rule-based check flags these as mismatches. A human looks at them and says “these are fine.” A column renamed from user_id to customer_id might be the same field after a refactor, or it might be a completely different concept. A rule-based check cannot tell the difference. A human can, but a human is not checking schemas at 4am before the nightly ETL runs.
The LLMSchemaCompareOperator in Airflow’s Common AI provider uses an LLM to compare schemas across databases, file formats, and cloud storage with semantic understanding. It catches what rule-based checks miss, and it runs automatically before the pipeline touches any data. It is available today in apache-airflow-providers-common-ai 0.4.0.
@dag(tags=["schema-validation"])
def nightly_etl_with_schema_gate():
@task.llm_schema_compare(
llm_conn_id="pydanticai_default",
db_conn_ids=["postgres_source", "snowflake_target"],
table_names=["customers"],
context_strategy="full",
)
def check_before_etl():
return (
"Compare schemas and flag any mismatches that would "
"break data loading. No migrations allowed - report only."
)
@task.branch
def decide(comparison_result):
if comparison_result["compatible"]:
return "run_etl"
return "notify_team"
comparison = check_before_etl()
decision = decide(comparison)
@task(task_id="run_etl")
def run_etl():
return "ETL completed"
@task(task_id="notify_team")
def notify_team():
return "Schema drift detected - team notified"
decision >> [run_etl(), notify_team()]
The schema check runs as the first task in the DAG. If the source and target schemas are compatible, the pipeline proceeds. If the LLM detects drift that would break loading, the team gets notified before any data moves. No partial writes. No silent corruption. No downstream contamination.
The LLM handles the semantic matching that rule-based checks cannot: type equivalences across databases (varchar(n) vs STRING, timestamp vs timestamptz), column renames that preserve meaning, and subtle structural differences like a field moving from required to nullable. The operator returns structured SchemaMismatch results with severity rankings, so you can gate your pipeline on critical mismatches while letting cosmetic differences pass through.
This also works across storage formats. You can compare an S3 Parquet file against a Postgres table, or a CSV landing zone against a Snowflake staging schema:
s3_source = DataSourceConfig(
conn_id="aws_default",
table_name="customers",
uri="s3://data-lake/customers/",
format="parquet",
)
LLMSchemaCompareOperator(
task_id="compare_s3_vs_db",
prompt="Compare S3 Parquet schema against Postgres and flag breaking changes",
llm_conn_id="pydanticai_default",
db_conn_ids=["postgres_default"],
table_names=["customers"],
data_sources=[s3_source],
)
For teams running cross-database ETL or ingesting data from external partners, this replaces a manual pre-flight check that most teams skip because it is too tedious to maintain. The operator runs automatically on every pipeline execution. Upstream application teams can deploy schema changes without notifying you, and your pipeline catches the drift before it matters.
The connection to the rest of this post is direct: schema drift that gets caught here never becomes a 2am failure that the retry policy has to classify. Detection is cheaper than recovery.
Resume: Pick Up Where You Left Off
A gaming company I spoke with recently described a pain point that I hear constantly: long-running Databricks jobs that fail and restart from scratch. A Spark job processes millions of events, runs for 45 minutes, fails at minute 40, and then reruns the entire thing. The compute cost doubles. The SLA slips.
This is not a new problem. It is one of the oldest problems in data engineering. What is new is a clean, general-purpose solution.
Airflow 3.3 introduces the Task State Store, a persistent key-value store scoped to each task instance that survives across retries. The pattern is simple: before you submit a long-running external job, store the job handle. On retry, check if a handle exists. If it does, reattach to the running job instead of submitting a new one.
@task(retries=2, retry_delay=timedelta(seconds=5))
def run_spark_job(task_state_store=None, ti=None):
job_id = task_state_store.get("job_id")
if job_id:
print(f"Try {ti.try_number}: reattaching to existing job: {job_id}")
else:
job_id = submit_spark_job()
task_state_store.set("job_id", job_id, retention=NEVER_EXPIRE)
print(f"Try {ti.try_number}: submitted job: {job_id}")
result = poll_until_complete(job_id)
task_state_store.set("status", "complete")
return result["rows_written"]
The task_state_store is injected into the task function automatically, just like ti. You read from it with .get(), write to it with .set(), and the state persists across retries without any external database or custom code. The NEVER_EXPIRE retention ensures the job handle survives for as long as retries are happening.
This is not specific to Spark. The same pattern applies to any long-running external job: Databricks, EMR, Dataproc, Flink, or any system where you submit work and poll for completion. The first operator to adopt this pattern is the SparkSubmitOperator, which now automatically stores the external application ID (e.g. YARN application ID) and reattaches on retry instead of submitting a duplicate.
For the asset management firm I mentioned earlier, this directly addresses their start-of-day SLA problem. A failed Spark job that reattaches in seconds instead of restarting for 45 minutes is the difference between hitting the market-open deadline and missing it.
Fix: Turn Your 2am Playbook Into a Retry Policy
This is the capability I am most excited about.
Every data engineering team has a version of the same document. It might be a Confluence page, a Notion doc, a Slack bookmark, or just the tribal knowledge in a senior engineer’s head. It is the on-call runbook: the decision tree that the person who gets paged at 2am walks through to figure out what went wrong and what to do about it.
The playbook typically looks something like this:
Every data engineer recognizes this table. The categories are well understood. The actions are deterministic. And yet, every Airflow DAG handles all of these the same way: retries=3, retry_delay=timedelta(minutes=5). Wait five minutes, try again, hope it works. Three times.
An expired API key does not fix itself after five minutes. A schema mismatch does not resolve on the third attempt. Meanwhile, a rate limit that would have cleared in 60 seconds waits 5 minutes for the first retry, because the DAG has no way to know that a shorter delay would have been sufficient.
Airflow 3.3 introduces pluggable retry policies based on the Common AI provider. An LLMRetryPolicy that classifies errors using an LLM at failure time. The key insight: the instructions parameter is where your team’s runbook goes.
from airflow.providers.common.ai.policies.retry import LLMRetryPolicy
from airflow.sdk.definitions.retry_policy import RetryAction, RetryRule
# Your team's 2am playbook, encoded as instructions.
ONCALL_PLAYBOOK = (
"You are the on-call error classifier for our nightly ETL pipelines. "
"Classify each error using our team's runbook:\n\n"
"- rate_limit: API throttling or quota exceeded. "
" RETRY after 60s. These almost always resolve.\n"
"- auth: Credentials expired, revoked, or missing permissions. "
" FAIL immediately. Retrying wastes 3 attempts and delays the real fix. "
" Page the platform team.\n"
"- network: Connection refused, timeout, DNS failure. "
" RETRY after 10s. Transient.\n"
"- data: Schema mismatch, type error, corrupt file, bad input. "
" FAIL immediately. This is an upstream data problem, not infrastructure. "
" Notify the data quality channel.\n"
"- resource: Table, bucket, or service not found. "
" FAIL. The resource will not appear on its own.\n"
"- transient: Temporary issue not covered above. "
" RETRY after 30s.\n"
"- permanent: Code bug, config error, or anything requiring a deploy to fix. "
" FAIL. No amount of retrying helps.\n\n"
"When in doubt between transient and permanent, check if the error message "
"references a specific resource, credential, or schema. "
"If it does, it is probably not transient."
)
etl_retry_policy = LLMRetryPolicy(
llm_conn_id="pydanticai_default",
instructions=ONCALL_PLAYBOOK,
timeout=30.0,
fallback_rules=[
RetryRule(
exception=ConnectionError,
action=RetryAction.RETRY,
retry_delay=timedelta(seconds=10),
),
RetryRule(
exception=PermissionError,
action=RetryAction.FAIL,
),
],
)
That ONCALL_PLAYBOOK string is your team’s runbook. The same decision tree that a senior engineer carries in their head, now encoded as the system prompt for the retry policy. Different teams can have different playbooks. A team that runs financial reconciliation pipelines with strict SLAs might have different thresholds and escalation rules than a team running experimental ML training jobs.
When a task fails, the LLMRetryPolicy sends the exception text to the LLM along with these instructions. The LLM returns a structured classification: error category, whether to retry, a suggested delay, and its reasoning. The policy acts on that classification automatically.
The fallback_rules are the safety net. If the LLM itself is unavailable (its own network issue, rate limited, timeout), the policy falls back to deterministic exception matching. An LLMRetryPolicy with good fallback rules is strictly better than the default retry behavior, never worse.
Here is what this looks like for three tasks using the same playbook:
@task(retries=3, retry_delay=timedelta(minutes=1), retry_policy=etl_retry_policy)
def task_auth_error():
"""LLM reads the playbook, classifies as auth -> FAIL immediately."""
raise PermissionError(
"403 Forbidden: API key expired for service account analytics@proj.iam"
)
@task(retries=3, retry_delay=timedelta(minutes=1), retry_policy=etl_retry_policy)
def task_rate_limit():
"""LLM reads the playbook, classifies as rate_limit -> RETRY after 60s."""
raise RuntimeError(
"429 Too Many Requests: Rate limit exceeded. Retry after 60 seconds."
)
@task(retries=3, retry_delay=timedelta(minutes=1), retry_policy=etl_retry_policy)
def task_data_error():
"""LLM reads the playbook, classifies as data -> FAIL immediately."""
raise ValueError(
"Column 'user_id' expected type INT but got STRING in row 42."
)
The auth error fails immediately. No one gets woken up for three futile retries before the real escalation. The rate limit retries with the right delay on the first attempt instead of waiting through the default retry interval. The data error fails and surfaces as a data quality issue, not a generic pipeline failure.
This is what changes the 2am experience. Instead of a data engineer getting paged and spending 20 minutes reading logs to figure out what kind of error it is, the retry policy classifies it in seconds and takes the right action. The engineer still gets notified for failures that require human intervention, but they get notified with context: “auth failure, API key expired for analytics@proj.iam, no retries attempted” is a fundamentally different alert than “task failed after 3 retries.”
The playbook that used to live in a Confluence page that no one updated now lives in the code, versioned alongside the DAG, and executes automatically on every failure.
A Note on AI Pipeline FailuresThis is not just about traditional ETL. Teams running AI and agentic workloads on Airflow are hitting the same retry problem, with one additional wrinkle: LLM provider rate limits.
An enterprise AI company I spoke with recently runs agentic workflows where a DAG fires for each incoming customer request. Their pipelines make dozens of LLM calls per run across multiple providers. Rate limiting from providers like Anthropic and OpenAI is a constant operational issue. Their team built custom LLM load balancing to swap between providers and round-robin across deployments of the same model.
The LLMRetryPolicy handles the first part of this natively. A 429 Too Many Requests from an LLM provider gets classified as rate_limit, and the policy retries with the appropriate delay instead of failing the entire DAG run. The playbook can encode provider-specific knowledge:
AI_PIPELINE_PLAYBOOK = (
"You are the error classifier for AI-powered document processing pipelines. "
"These pipelines make many LLM calls per run and interact with "
"external document stores.\n\n"
"- rate_limit: LLM provider throttling (429, quota exceeded, "
" 'rate limit' in message). RETRY after 60s. Very common, "
" almost always resolves. Do NOT fail on first occurrence.\n"
"- auth: API key expired or revoked. FAIL immediately.\n"
"- data: Document parsing failure, corrupt PDF, missing required fields. "
" FAIL. Notify the data team.\n"
"- resource: Model endpoint not found, deployment deleted. FAIL.\n"
"- transient: Timeout, connection reset. RETRY after 15s.\n"
"- permanent: Invalid prompt, context length exceeded, "
" unsupported file type. FAIL.\n"
)
The Loop: Detect, Resume, Fix
These three capabilities work independently, but together they form a pipeline health loop that addresses the most common operational pain points in data engineering:
Detect upstream problems before they propagate. Resume efficiently when failures happen mid-pipeline. Fix failures intelligently based on what actually went wrong.
None of these require you to build an AI application. You are not writing agents. You are not building RAG pipelines. You are adding a decorator, a parameter, or a policy to the pipelines you already run. The AI is embedded in the infrastructure, not in your application logic.
That is the distinction I keep coming back to. There is a lot of conversation right now about data engineers building AI applications, orchestrating agents, and constructing LLM pipelines. All of that is real and important. But there is a quieter, more immediate opportunity: using AI to make the pipelines you already run more resilient, more self-healing, and less dependent on someone being awake at 2am to walk through a mental checklist.
Try It
Schema validation is available today:
pip install "apache-airflow-providers-common-ai>=0.4.0"
Task State Store and LLM Retry Policy ship with Airflow 3.3, currently in beta:
pip install -U "apache-airflow==3.3.0b1"
Example DAGs for all three capabilities are in the Airflow repository. The LLM Retry Policy documentation is at airflow.apache.org.
If you are running Airflow today and want to try the schema validation operator, all you need is a pydanticai_default connection configured with your LLM provider of choice (OpenAI, Anthropic, Google, AWS Bedrock, Groq, Mistral, Ollama, or any of the 20+ supported providers).
Questions, feedback, or ideas for other capabilities like these: the Airflow community Slack channel #airflow-ai is where these conversations happen.
Vikram Koka is the Chief Strategy Officer at Astronomer and an Apache Airflow PMC member.
Apple is suing OpenAI over theft of trade secrets in blockbuster lawsuit
Apple is suing OpenAI for trade secret theft, alleging that former employees took proprietary hardware designs to the AI developer.
Original article
Apple has sued OpenAI, alleging it stole confidential trade secrets and unreleased hardware information through former Apple employees who joined the company. Apple is seeking damages, the destruction of any misappropriated materials, and changes to future OpenAI hardware if it uses Apple's proprietary technology. The lawsuit marks a dramatic shift in the companies' relationship, as they remain AI partners through Apple Intelligence while increasingly competing in the race to build AI-powered devices.
AI-Powered UI Design with Real React Components (Website)
UXPin's new Forge tool generates UI by utilizing your actual React component library rather than creating generic vector-based designs.
Decoder
- JSX: A syntax extension for JavaScript often used with React to describe what the UI should look like.
Original article
Your components. Your rules. AI that actually follows both.
Forge designs with your real React components – not generic pixels. Refine it and export production-ready code. Start with a built-in library or connect your own.
Figma's AI generates more vectors. UXPin's AI generates with our real code. That's a fundamental architectural difference and it's why we switched.
Kenji Sano
This is like the best of Figma and Lovable, but for companies.
James Crennan
I've worked with UXPin Classic and Merge for over a year now. Always amazed by the prototyping results I get with UXPin. Highly recommended!
Matt Hallowes
The image-to-UI feature is great for early-stage work. I upload a rough wireframe or screenshot and Forge interprets it using our real components. Saves me from starting every project from a blank canvas.
Kari Brooks
UXPin has become my go-to design tool because it bridges the gap between static design and real interaction. The ability to build prototypes with code components, logic, and states makes everything feel like the final product, eliminating the need for explanations with notes or workarounds. The design system support keeps projects consistent and scalable. Shipping changes faster.
Abe Dearmer
One canvas. Three superpowers.
Generate UI with your production components
Forge generates UI using the same components your team ships in production. Every element comes from your React library – with real props, variants, and states.
Refine the generated UI
Start with AI. Refine with manual edits. Adjust layout, edit props, and add interactions. All on the same code-backed components. No need to switch tools.
Export code you can ship
Production-ready JSX from your component library. What you see is what developers get. No specs or rebuilds. Copy it, open in CodeSandbox, or export it.
When I used UXPin Merge, our engineering time was reduced by around 50%. Imagine how much money that saves across an enterprise-level organization with dozens of designers and hundreds of engineers.
Erica Rider, UX Architect @ BackBlaze
We synced our Microsoft Fluent design system with UXPin’s design editor via Merge technology. It was so efficient that our 3 designers were able to support 60 internal products and over 1,000 developers.
From prompt to production in one tool
- Pick your components — Choose a built-in library or connect your own via Git.
- Prompt or design manually — Describe the UI you need, upload a screenshot for context, or design manually with real components. Switch between AI and manual editing at any point.
- Refine visually — Adjust layout, tweak props, and add interactions. Your prototype behaves like the real product.
- Iterate with AI — Use follow-up prompts to modify the design in place. Forge updates the components using the correct props and variants.
- Export and ship — Export production-ready JSX from your selected component library. Open in CodeSandbox, copy to clipboard, or export to your project.
Choose your building blocks
Use open-source React libraries, your own design system via Git, or templates built with real components. AI follows your design rules to create production-ready layouts and saves the time you'd normally spend coding components into a system.
AI that follows your design system
- Real components, not shapes: Forge uses your real React components with the same props, variants, and states as in production.
- Your design system sets rules: Generate UI with React components from your library, following your design system rules.
- Conversational iteration: Forge remembers context, so each prompt builds on the previous one as you refine the same design.
- Multiple AI models: Choose between OpenAI and Claude, switch anytime, or use your own API key for billing and compliance.
- Image-to-UI: Upload a screenshot, wireframe, or sketch, and recreate the UI with your components.
- AI or manual edits: Generate a starting point and refine it with AI or manual edits at any stage.
How Forge compares
Forge vs. Figma’s AI: Figma generates vectors that represent UI, not real components. They can match your design system visually but aren’t connected to code. Developers still need to rebuild the UI. Forge generates UI with real React components, so the result is production-ready.
Forge vs. Lovable / Bolt: Lovable and Bolt are useful for MVPs without a design system. They generate UI using their own components and patterns. As projects grow, consistency becomes harder to maintain. Forge works with your component library and design rules, so UI stays consistent as you scale.
Forge vs. v0: v0 generates code based on shadcn. It works well within that setup. It is optimized for a specific component stack. Forge works with any React component library, built-in or custom. You can also refine UI with design tools, not just edit code. This gives teams more control over how UI is built.
Built for teams with design systems to protect
- Design system guidelines: Define rules in plain text that constrain all Forge output across the projects.
- Git integration: Sync your custom component library. Updates in code reflect in design automatically.
- Version control: Work with the right version of your coded library in projects. Choose a branch or tag to control updates.
- Per-project chat history: Chat history saved per user and project so you can continue where you left off.
- Bring your own API key: Use your own OpenAI or Anthropic account for billing and compliance. Stay in control of usage and costs.
- Component documentation: Generated directly from your synced library. Always up to date with your components and their props.
Frequently Asked Questions
What is Forge? Forge is the AI system in UXPin. It generates, edits, and reviews UI using real React components from your library. The output is production-ready JSX that developers can ship directly.
What component libraries does Forge support? Built-in: MUI, shadcn/ui, Ant Design, and Bootstrap — ready to use immediately. Custom: any React component library synced via Git.
What AI models does Forge use? Forge supports multiple AI models, including Claude Sonnet, Claude Opus, Claude Haiku, and GPT models. You can also bring your own OpenAI or Anthropic API key.
How is Forge different from Figma’s AI? Figma's AI generates vectors; UXPin Forge generates UI using your real React components with real props. There is no translation step.
Can I control how strictly the AI follows my design system? Yes. Teams can control how closely AI output follows their design system. Forge prioritizes the components connected to your project.
Can I switch between AI and manual design? Yes. Same canvas, same components. Use Forge to generate the UI, then switch to manual design tools for refinement, interactions, and states.
Claude Code on desktop now has an in-app browser
Claude Code now includes a sandboxed in-app browser, enabling agents to navigate, read, and interact with external documentation and live websites.
Deep dive
- The in-app browser is fully sandboxed for security.
- It allows agents to click through and interact with sites automatically.
- Users can configure whether browser sessions should persist between tasks.
- The tool is optimized for retrieving docs, design specs, and real-time project context.
- Other recent improvements include a security plugin for vulnerability detection and dynamic agentic workflows.
Decoder
- Sandboxed: An isolated execution environment that prevents the browser from accessing host system files or unauthorized network paths.
Original article
Claude Code on desktop now has an in-app browser.
Claude can pull up docs, designs, or any other site. It can read, click through, and interact the same way it does with your local dev servers.
It's sandboxed and configurable: you choose whether sessions persist.
Make sure to update to the latest version of the desktop app.
Read more in the docs: code.claude.com/docs/en/desktop#browse-external-sites
Proactive Memory for Long-Horizon Agents
Researchers achieved higher task pass rates by introducing a proactive memory agent that selectively reminds action-oriented models of critical, buried trajectory data.
Deep dive
- The memory agent creates a structured memory bank from trajectories.
- It decides autonomously whether to intervene with a reminder or remain silent.
- This 'plug-and-play' module works with existing frontier models.
- It outperforms always-on context injection and passive retrieval strategies.
- The authors trained Qwen3.5-27B on the SETA framework to advance open-weight memory policies.
Decoder
- Behavioral state decay: The phenomenon where an AI loses track of environment facts or past decisions as a task trajectory grows too large for the context window.
- Pass@1: A metric representing the probability that a model solves a coding task correctly on its first attempt.
Original article
Remember When It Matters: Proactive Memory Agent for Long-Horizon Agents
In long-horizon tasks, decision-relevant state is often scattered across an expanding trajectory, while the action agent must surface it and act. As trajectories grow, task requirements, environment facts, prior attempts, diagnoses, and open subgoals can be buried in the context window or pushed beyond it, failing to influence decisions when needed. We call this failure mode "behavioral state decay". We study memory as an active intervention mechanism rather than passive retrieval. A separate memory agent runs alongside an unmodified action agent, updating a structured memory bank from the recent trajectory and deciding whether to inject a memory-grounded reminder or remain silent. The module is plug-and-play with frontier action agents and existing agent harnesses. Across Terminal-Bench 2.0 and $\tau^2$-Bench, it improves pass@1 for both weaker and stronger action agents, with gains of +8.3 pp on Terminal-Bench and +6.8 pp on $\tau^2$-Bench. Ablations show that selective intervention outperforms passive bank exposure, always-on injection, advisor-only guidance, and general retrieval. As an early step toward open-weight memory policies, we train Qwen3.5-27B on SETA using SFT and GRPO, improving validation reward and achieving partial transfer to Terminal-Bench.
OpenWiki Brains: Proactive Memory for AI Agents
LangChain's OpenWiki Brains gives AI agents proactive memory by autonomously building and updating a local markdown-based wiki from your personal tools.
Deep dive
- Supports connectors for Gmail, Notion, Git, Twitter, and Hacker News.
- Runs scheduled local jobs to keep memory updated without requiring a persistent server.
- Uses markdown files, making the agent's 'knowledge' human-readable and auditable.
- Distinguishes between 'Code Brain' (for codebase context) and 'Personal Brain' (for broad project/interest context).
- Plans for future updates include full-text semantic search and additional connectors for Slack and LangSmith.
Decoder
- Proactive Memory: A system where the agent autonomously refreshes its knowledge base from connected sources, rather than waiting for user input.
Original article
Introducing OpenWiki Brains, general-purpose wiki memory for agents
We’re launching OpenWiki Brains as a framework for giving agents proactive memory.
Existing memory solutions allow agents to improve over time by updating memory files based on patterns discovered through use or explicit changes to agent instructions. With OpenWiki Brains, agents can build memories proactively by fetching relevant context through the tools, channels, and files you give it access to, without the need to explicitly tell it to remember something.
We recently launched OpenWiki as an OSS CLI for codebase documentation. You ran it in a repo, it generated a wiki for that codebase, and it kept the wiki updated as the code changed.
With OpenWiki 0.1.0, we’re expanding the concept to support more agent workflows beyond code agents.
OpenWiki can now create a general-purpose brain for your agents. It connects to sources like Gmail, Notion, git repos, Twitter/X, Hacker News, and web search, then turns that information into a local wiki your agents can use as memory. It can also keep that wiki updated automatically, so your agents have access to fresh context without you manually writing or maintaining it.
The goal is your agents should know the important context about your work, projects, interests, and research without forcing you to track and copy all of that context into every session.
Why agents need wiki memory
Agents work better when they have the right context.
For coding agents, that context is usually the repo. They need to know where key logic lives, how files connect, and which patterns the codebase expects. That was the original reason we built OpenWiki.
But agents increasingly work across more than code. They help with research, planning, writing, customer work, personal workflows, and internal tools. For those tasks, useful context is scattered across many places.
It might live in Gmail, Notion, bookmarked posts, Hacker News threads, git repos, or repeated web searches.
You can ask an agent to search those sources each time, but that is slow and inconsistent. You can write the context down yourself, but then you have to keep it updated.
OpenWiki Brains gives agents a durable place to look. It turns your connected sources into a structured wiki that can be refreshed over time.
How this is different from built-in memory
Many agents already have memory. Claude, ChatGPT, LangSmith Fleet, and other assistants can remember facts you tell them and use those facts in future conversations.
That memory is useful, and OpenWiki Brain doesn't need to replace it.
The limitation is that built-in memory is mostly reactive. It remembers information you explicitly give the agent, or information the agent can infer from your conversations with it.
That works for preferences and facts you've already shared. It works less well for context that changes across your tools every day.
If an important project update happens in Slack, your agent should be able to know about it. If relevant meeting notes land in Notion, it should be able to incorporate them. If a useful thread shows up in email, or you bookmark something on Twitter/X, that context may matter later even if you never paste it into a chat.
OpenWiki Brain is proactive memory. It connects to your sources, looks for information that matches what you asked it to care about, and writes that information into a wiki your agents can use later.
Built-in memory helps agents remember what you told them. OpenWiki Brain helps agents from the places you already work.
With this announcement, we're introducing two new concepts for OpenWiki Brain.
Personal Brain
Personal Brain is the main new mode in OpenWiki 0.1.0.
It creates a local wiki based on the sources you connect. The wiki can include context about active projects, topics you are researching, people or companies you are working with, saved links, relevant emails, notes, and other information your agents may need later.
During setup, OpenWiki asks what the brain should focus on. We provide a default prompt for a general personal assistant, but you can customize it.
For example, you could tell OpenWiki to focus on active projects, AI research topics, customer context, saved links, or recent notes from a Notion workspace.
That prompt helps OpenWiki decide what to preserve when it ingests new information.
Connectors
Personal Brain works through connectors. Connectors let OpenWiki pull context from the places where your information already lives.
The first set of connectors includes:
- Gmail
- Notion
- Git repositories
- Twitter/X
- Hacker News
- Web search
Slack support is coming soon.
Some connectors are deterministic. Gmail can fetch recent emails. Twitter/X can fetch recent timeline data or bookmarks. Hacker News can fetch recent posts. Git repos can inspect recent commits.
Other connectors need a more agentic approach. Notion and web search are good examples. There is no simple feed of "everything relevant." For those sources, OpenWiki gives the agent tools at ingestion time. You describe what you want it to look for, and the agent searches with that goal in mind.
Keeping the brain up to date
Running locally is what makes “staying current” practical. Because the brain lives on your machine, OpenWiki can update it the same way any local tool does, by running a scheduled job that pulls new information from your connectors and refreshes the wiki on disk. There’s no server you need to provision or long‑running process to keep alive; it just runs on a cadence you choose.
When the scheduled run starts, OpenWiki goes through your configured connectors and updates the wiki with new information.
The intended workflow is that you configure your sources once, then let OpenWiki maintain the brain in the background.
OpenWiki Code Brain
OpenWiki still supports the original codebase workflow, now called Code Brain.
Code Brain runs inside a git repo, generates documentation, writes it into an openwiki directory, and updates agent instruction files with a reference to the wiki.
Code Brain and Personal Brain are separate because they solve different problems. Code Brain cares about repo structure, git history, file relationships, and coding conventions. Personal Brain cares about broader work context across your connected sources.
The prompts, connectors, and workflows to update memory are all different, but the underlying idea is the same. OpenWiki gives agents generated, maintained context they can use when they need it.
Markdown first
OpenWiki Brains currently use plain Markdown files.
Markdown is easy to read, easy to inspect, and easy for agents to navigate. It also keeps the brain visible on the filesystem instead of hiding it behind an interface.
We expect the format to evolve. Inter-page linking, richer knowledge formats, and formats like Google's Open Knowledge Format are all interesting directions. For now, Markdown gives us a simple starting point that works with existing agent workflows.
What comes next
There are a few areas we want to improve.
First, more connectors. Slack is coming soon, and we expect to add more sources over time like LangSmith traces, Claude/Codex local sessions, and more.
Second, better retrieval. Right now, the brain is a wiki on the filesystem. We are exploring full-text search, MCP, semantic search, and agentic search over the brain.
Third, better formats. Markdown works well as a starting point, but we want to keep exploring better ways to represent agent memory and link related context.
We'd love feedback from the community on all of this.
Try it
OpenWiki is open source and available now.
You can use Code Brain to generate and maintain documentation for a repo. You can use Personal Brain to generate a general-purpose wiki from your connected sources and keep it updated automatically.
Check out the repo here: https://github.com/langchain-ai/openwiki
And try it via NPM: https://www.npmjs.com/package/openwiki
npm install -g openwiki@latest
openwiki personal --init
OpenAI's head of safety is reportedly leaving as part of company reorganization
OpenAI is reorganizing its safety department, with head of safety systems Johannes Heidecke departing amid a broader merger of safety and research teams.
Decoder
- Frontier-model: Refers to the most powerful, large-scale AI models that push the state-of-the-art in performance.
Original article
OpenAI's head of safety is reportedly leaving as part of company reorganization
The role will be replaced by an executive in charge of both research and safety teams.
Along with a significant restructuring of OpenAI's safety and research teams, the company's head of safety systems is expected to leave his post, according to a new report. As first reported by Wired, Johannes Heidecke told OpenAI staff in a memo seen by Wired that he would be leaving the company. Heidecke first started at OpenAI in 2021, according to his LinkedIn.
According to the report, OpenAI's Saachi Jain, who has led OpenAI's safety teams before, will slot in as the interim head of safety systems following Heidecke's departure. Wired also reported that OpenAI's safety teams will report to Mia Glaese, who will become the company's new vice president of research and safety as part of the reorganization. OpenAI's chief research officer, Mark Chen, told Wired in a statement that it was "important that our safety work is integrated with frontier-model development, with an earlier and more direct role in shaping key model, product and launch decisions."
The staff shifts come on the heels of OpenAI's latest model release, GPT-5.6, after it was recently approved by the US government. The company still has a Head of Preparedness on its roster, who was hired earlier this year to "prepare for and mitigate ... severe risks," as indicated by OpenAI's CEO, Sam Altman, on X.
Frontier and Center: Who evaluates the evaluations?
Google researchers propose using information theory to replace static benchmarks with 'difficulty-calibrated' maps of AI agent performance.
Deep dive
- Current benchmarks rely on static, binary pass/fail grades, which fail to reveal the 'terrain' of an agent's capabilities.
- 'Discovery Bench' uses information theory to modulate query difficulty via surprisal (predictive likelihood of a dataset given a query).
- The researchers found that agents often hit performance 'cliffs' where small increases in query vagueness cause total failure.
- The team identified issues in existing benchmarks like KramaBench, noting that 'evaluating the evaluators' is a necessary step for robust AI systems.
- Testing via ambiguity sweeps (high, medium, low) provides a more nuanced gradient for improvement than a single scalar score.
- The team warns against over-optimizing for the evaluation metric itself, which can lead to models that pass tests but fail in real-world, messy environments.
Decoder
- Surprisal: In information theory, a measure of how informative a specific term is; rare or pointed terms have higher surprisal than common ones.
- F1 score: A metric that balances precision and recall to evaluate the accuracy of a system's retrieval performance.
- Ground truth: The validated, 'correct' expected output used to verify the accuracy of AI model results.
- Sharding: The practice of splitting a large dataset into smaller, more manageable pieces; in this context, it refers to tables being distributed across many files.
Original article
Frontier and Center: Who evaluates the evaluations?
Editor’s note: Some of the most interesting questions in AI are being asked by information theoreticians, around how to provide context to an emerging class of AI agents. A few weeks ago, we waded into those waters with a blog about the Open Knowledge Format, a specification that formalizes the LLM-wiki pattern into a portable, interoperable format to represent the metadata, context, and curated knowledge that modern AI systems need to operate. That blog generated a ton of interest, so we’ve decided to bring you more of the same, as part of our new “Frontier and Center” series. Today, we hear from two members of Google Data Cloud’s frontier AI team on the recurring challenge of how to systematically evaluate whether or not an agent is able to answer questions effectively based on its context.
A passing grade is the least interesting thing an exam can tell you. It says the student cleared the bar; leaving you entirely in the dark about how narrow their failures were, how effortless their passes were, or what to teach next. Yet this is exactly how we evaluate AI agents. We run a fixed benchmark, calculate a score, and declare progress. In doing so, we are handing our agents a pass/fail exam when what we actually need is a map of the agent’s capabilities: a picture of the terrain that shows exactly where capability falls off, and by how much.
For data agents, this map matters a lot for data discovery in search and retrieval — the unglamorous first step where an agent, handed a vague human question and a warehouse or data lake of thousands of tables and files, has to find the right datasets before it can reason over anything. Discovery is a "needle in a haystack" problem. Real users phrase their questions imperfectly, and inferring what datasets to retrieve presents a real challenge to agents. So the interesting question in evaluations is never "can the agent pass?" It is "how vague can the question get before the agent breaks?" An exam cannot easily answer that, but a map can.
Today, we share an approach rooted in information theory that we’ve been leveraging to add detail and nuance, i.e., fidelity, to benchmarks, so we can better understand agents’ performance as a part of their evaluations. Along the way, the added fidelity exposed some deeper issues with the quality of emergent evaluation cases themselves.
Difficulty, measured
When it comes to retrieval, evaluation cases are often stratified into tiers of difficulty. This can happen organically, e.g., pervasive and enduring failure scenarios are deemed difficult. Or it can be from labels applied by humans or machines categorizing some questions as "easy" or "hard" for an agent to answer correctly, e.g., based on the context provided in the query. While this kind of sentiment-based labeling is not the only way to label test cases, it’s frequently used despite its imperfections, such as being challenging to reproduce.
Despite being an industry staple, the approach of assessing every evaluation case by hand is unrealistic at scale. What we need is a rigorous approach that can modulate the difficulty of evaluation cases. We’re iterating on a meta-benchmark we call Discovery Bench: a framework that modulates an evaluation case by generating “easy” and “hard” variations of every case. This allows us to audit how close or how far an agent is from succeeding in those cases.
The lever for modulating the difficulty of an input query comes via a tried-and-trusted concept that’s present across information theory and machine learning: surprisal, or the likelihood of an output given a set of inputs. In our case, a query’s surprisal represents the uncertainty that remains about the correct dataset given the query.
The thinking behind our approach is simple: A term or a phrase in an evaluation query has high informative power when it sharply distinguishes the target from everything else in the corpus. Therefore, we can adjust the difficulty of evaluation cases by adding or removing terms with varying levels of informative power.
Let’s work through a real example from KramaBench, a publicly available benchmark. One of KramaBench’s datasets has information about orbiting satellites, and the example query from the suite includes the following text: "…the total count of satellite major altitude changes for satellite 48445 during 2024 using TLE history."
The token "TLE" is sharply distinguishing; it points almost uniquely at the TLE_____48445 table from the dataset. Strip it, and the query degrades to "the count of satellite altitudes for satellite 48445," whose vague phrasing now matches density tables, precise-orbit files, and decay logs alike. Surprisal makes this quantitative: rare, pointed terms carry more bits than common ones.
The remaining surprisal of a query is how much uncertainty is left about its answer. As surprisal approaches zero, the query has become specific enough to pinpoint exactly one dataset.
The heart of the idea behind Discovery Bench is this refinement loop, which we call iterative surprisal-based query refinement, or iSQR, which generates cases with higher or lower informative power to test where an agent can start successfully answering the query.
The crux is being able to control the challenge embedded into the evaluation case by making adjustments: Instead of one fixed phrasing per question, we generate the same question at three levels of calibrated ambiguity [high, medium, low], with each grounded in bits (not subjective opinion). We can even justify, term by term, why a word was added or removed. Difficulty stops being a property that is attributed by sentiment or classification, and becomes one we engineer.
The cliff you couldn't see
Here is what Discovery Bench’s difficulty dial reveals — and what a single-phrasing benchmark structurally cannot.
We have an F1 agent that's built for recall (on Gemini 3.1 Pro). Running it against KramaBench and across the full sweep of ambiguity levels traces a curve: 0.34 at high ambiguity, 0.76 at neutral, 0.81 at medium, 0.78 at low.
Two findings fall out immediately (and neither were visible to a conventional eval).
First, the cliffs. This query scores a perfect F1 = 1.00 at neutral phrasing — and 0.00 at high ambiguity. It is the satellite-48445 case from above: drop the distinguishing token "TLE" and the agent loses the table entirely. Same query, same agent, same ground truth; one notch vaguer and it falls off a cliff. A static benchmark tests the neutral phrasing, stamps "solved," and reports flat ground where there is a precipice. Pass/fail was particularly misleading in that it did not just miss the cliff, but it told us the terrain was level.
Second, the sweet spot. For Discovery Agent, medium ambiguity beat neutral, and low ambiguity sometimes underperformed it. More specificity is not monotonically better for the system being evaluated; there is an optimal amount of steering. That is a graded, actionable signal. This is the "how close, how hard" texture we were missing from a scalar. It tells you where to hill-climb, or improve, the agent: in our case, straight at concrete failure modes like time-sharded tables (precision collapsing to ~8% as the agent over-retrieves 21 near-identical shards for a two-table answer) and context blow-up (F1 dropping from 0.75 to 0.32 once a query triggers long search chains). The map did not just say that the agent failed, but it said where, and why.
We're not alone
The field is converging on meta-benchmarking and exerting greater control of how we challenge and evaluate our agents. A growing body of work uses item response theory, the latent-ability model behind standardized testing, to treat difficulty as a measured quantity rather than a label. What we have not seen elsewhere is the combination: information-theoretic ambiguity sweeping applied as a meta-benchmark over live enterprise data.
A benchmark we trusted turned out to be broken
We built our first evaluation on kramabench-astronomy, a benchmark established in the field, and one which other teams had already leaned on for their own evals. Teams derived benchmarks from this dataset, and we hypothesized subtle issues may have been introduced over time. When we actually read the benchmarks used by teams, with Gemini's help, we found it was wrong in meaningful ways: ground-truth tables that did not answer their query, a question whose 124 sharded tables exceeded what some teams’ retrieval APIs could even return, months specified where exact dates were required. Quietly broken ground truth means quietly wrong conclusions not just for us, but for every prior analysis built on it.
This is the generalized crux of the matter: an evaluation is itself an artifact that can be defective, and almost nobody evaluates it. We instrument the agent and trust the ruler, but where do we validate that the measuring stick makes sense?
When two maps disagree
Now the recursive turn: If difficulty is something we generate, then we need to evaluate the generator itself; we should not trust it blindly either.
So we built the same ambiguity sweep two ways: steering terms from a pure-LLM guess, versus terms grounded in TF-IDF surprisal. The two disagreed violently. At high ambiguity, the LLM-built sweep scored the agent at F1 ≈ 0.34; the grounded sweep, ≈ 0.85. One of these maps is badly distorted. The grounded one, predictably, is the more robust: surprisal gives it a footing the free-running LLM lacks.
This is "evaluate your evals," made concrete. The information-theoretic lens does not only grade the agent along a continuous axis; it grades the benchmark's own construction, and adjudicates between the two.
Evaluate your evals
We have spent years optimizing agents against rulers we never measured. The bitter irony is that better models make this worse: as agents clear coarse benchmarks, the score saturates near the top and the exam loses its ability to highlight where the agent can be improved.
So the call to action is uncomfortable and overdue: evaluate your evals. Read your ground truth. Treat difficulty as a measured quantity, not a label: sweep it, plot it, find the bit-width where your system breaks. Ask not just "did it pass?" but "how close was the miss, how hard was the pass, and would a slightly vaguer question have sent it off a cliff?" Build evaluations that produce signals; not just verdicts.
There is a genuine tension to sit with here. Difficulty-as-entropy is only as reliable as the model that estimates the entropy. There's a risk that if we push too hard on a measurable proxy, we optimize the ruler instead of the agent. That is not a reason to retreat to pass/fail; it is a reason to keep the evaluator under the same scrutiny as what it is evaluating. The moment we stop asking who evaluates the evaluators is the moment our maps stop being useful again.
Apple Sues OpenAI, Accusing It of Stealing Company Secrets
Apple is suing OpenAI, alleging the firm used coercive interview tactics to steal proprietary manufacturing secrets for its own new hardware business.
Original article
Apple has accused OpenAI of stealing secrets about products still in development. OpenAI's new hardware business allegedly asked job candidates from Apple to share details about secret projects and to bring device components and prototypes to their interviews. It used the information to approach at least one of Apple's manufacturing partners, asking them to demonstrate Apple's technique for finishing metal on its devices. Apple is seeking an injunction that would prevent OpenAI from possessing, using, or sharing its trade secrets, as well as an order requiring OpenAI to return Apple's intellectual property.
Home robots already walk. 1X's new hands try to solve the part that actually matters
1X is focusing on tactile sensor-equipped hands with 25 joints to overcome the precision and durability hurdles currently stalling humanoid home robots.
Decoder
- Backdrivable: A mechanical system that allows external force to move the joints, preventing the robot from becoming rigid or dangerous when it encounters resistance.
- Degrees of freedom: The number of independent joints or directions in which a robot hand can move, defining its range of motion.
Original article
Humanoid robots learned to walk years ago. The thing still tripping them up is the hand.
1X has given its NEO home robot new hands, and they are the most interesting thing about it. A robot can stride across a stage and still be useless in a kitchen. Lifting a wet glass takes precision, fast corrections and the restraint not to squeeze too hard.
Wired, which got an early look, called the fingers “freaky fast.” The speed makes for a good clip. What actually matters is quieter: whether the hand can feel what it is holding.
25 joints and a sense of touch
Each hand has 25 degrees of freedom, 1X says: 22 across the fingers and palm, and three more in the wrist. The joints are backdrivable, so they give way when pushed rather than staying rigid. A knock does not have to become a fight.
The more important trick is the skin. According to Digital Trends, NEO’s tactile sensors read both pressure and sideways movement across the fingers. That lets the hand notice a glass starting to slip and tighten its grip before it hits the floor.
Why hands are the hard part
Factory robots have had grippers for years, but they usually work with parts placed in exactly the same spot every time. A home is the opposite. Objects turn up in odd shapes and unpredictable weights, wet or half-hidden, and the machine has to cope with all of it.
1X rates the hands IP68 and says they use food-safe materials, sensible choices for something meant to work near sinks and dinner plates. The fingers also bend past a human range and wrap around awkward shapes. On paper, the hardware looks ready for chores.
The catch nobody demos
Capable hands do not add up to capable housework. NEO still has to spot an object, choose the right grip and repeat the task in a messy room. It has to do that again and again, with no one setting it up first. One polished clip does not prove that.
There is a bigger asterisk. For a chore NEO does not know, 1X offers “Expert Mode,” with a human operator guiding it remotely. It is a clever way to remotely operate a fleet. It also means a stranger may be steering a camera-equipped machine around your home. The autonomy is still a work in progress.
A crowded, and quietly European, race
1X sits in Palo Alto now, but it started in Norway as Halodi Robotics. That makes it one of several European bets on humanoids, alongside Europe’s own contenders. The field is loud. Some rivals argue home robots should skip legs and fingers altogether, and others think the whole humanoid craze is overblown. The race for a working robot hand runs underneath all of it.
NEO is real enough to pre-order, at a $200 deposit. The hands are the most convincing part of the pitch. The next demo worth watching should drop the finger drumming and show NEO finishing an ordinary chore, start to finish, on its own.
Pepsi challenge for LLMs
As models reach 'good enough' status for general tasks, the industry competitive advantage is shifting from pure model intelligence to privacy, bundling, and user experience.
Decoder
- Open-weight models: AI models whose trained parameters are publicly available for download and execution locally, unlike proprietary 'black-box' APIs.
- Normie prompts: Simple, general-purpose user queries like 'what is the best' or basic fact-checking, as opposed to complex coding or scientific reasoning.
Original article
Pepsi challenge for LLMs
Contrarian view during a week of huge new model launches:
All of us do a lot of “normie prompts” - these are use cases which are really like Google searches (“what’s the name of..” “is it true that…” “what’s the best…”). These are a very high % of total prompts- maybe not in terms of value creation (like code gen or the frontiers of math/science we’re going to) but it’s ubiquitous.
If you plugged these LLM prompts into the various frontier models could they tell the difference on the quality of output? I think not. We’d all fail in a blind taste test I think, as the models are now “good enough”.
We’re already at the point of diminishing returns in terms of what LLMs return back for a large % of use cases. And there’s implications:
- Open source models will constitute the majority of LLM queries. Open weight models lag by 18-24 months but adding to the question above, could you tell the difference on non-frontier local AI models that can run on modern Mac hardware? I’ve been doing exactly this with models like Qwen 27b dense and honestly they’re great for the normie prompts. There’s a huge incentive for NVIDIA, apple, and maybe even handset manufacturers like Samsung/etc to host open weight AI as an add on to just get you to buy their software.
- AI pricing heads to zero. And we’ll see free and ad-supported AI will be a thing in the consumer market, and open weight models are part of the story here too. Seems like we are <12-18 months to being able to just have ad supported AI particularly for developing markets and segments where the monthly fee doesn’t make sense. Monthly/metered might just be a thing in B2B use cases.
- Once quality differences even out the competitive dimension shifts to other factors. Privacy, interconnectivity, free, bundling. The other idea here is that the moat becomes the wrapper (err we call them harnesses now? lol) and the product built around the LLM.
- Of course premium/frontier models will continue to exist. As long as there are big differences outside of the normie prompts, then you’ll hire one LLM over another for world generation, coding, science, labor replacement/augmentation etc. Just saying I’m not sure we’ll need frontier models for 90%+ of consumer use cases.
I think the prevalence of benchmarking in the launch of new AI models is in agreement with this. This week I tried Grok 4.5 and Fable for some coding experiments and you need to really spend time to pick up the differences. So we use benchmarks to point out what’s not so obvious.
Some of us will remember when computers were all measured in megahertz and megabytes, and the PC industry compared itself that way. Over time, that gave way to design, power efficiency, etc. Today we’re benchmarking and calculating cost per token and so on. It’s about to evolve, I think.
Improving Smart Tiered Cache for public cloud regions
Cloudflare's new region hints for Smart Tiered Cache prevent inefficient, cross-continental traffic hairpinning for public cloud origins behind anycast IPs.
Decoder
- Anycast: A network addressing and routing method where a single IP address is assigned to multiple physical locations, and routers send traffic to the topologically closest node.
- Hairpinning: A routing inefficiency where traffic travels from an origin to a remote proxy and back to the same geographic region, adding unnecessary latency.
- PoP (Point of Presence): A physical location where a CDN hosts servers to connect to the internet and cache content closer to end users.
Original article
Improving Smart Tiered Cache for Public Cloud Regions
In 2021, we shipped Smart Tiered Cache. The idea: for each origin behind your site, Cloudflare picks the single best upper-tier data center to route through, based on real-time latency. Flip one switch, and we find the fastest path from our network to your origin.
That works as long as an origin IP lives in one fixed place. Public cloud origins usually don't. They sit behind anycast or regional unicast front ends, so one origin IP can look equally close to a dozen Cloudflare data centers at once — and the latency probes have nothing to lock onto. Smart Tiered Cache handles this the safe way: when there's no clear winner, it falls back to several upper tiers. Nothing breaks. You just lose the thing that made a single closest tier worth it, which is cache efficiency.
Smart Tiered Cache for Public Cloud Regions fixes this by letting you provide a cloud region hint. With that hint, Cloudflare can map public cloud origins to the right region and select better primary and fallback upper tiers, even when the origin IP itself looks anycast or ambiguous.
We made our most popular tiered cache topology smarter
Since it was launched, Smart Tiered Cache has become the most popular tiered cache topology among Cloudflare customers. It’s available to all plans, for free.
Much of our work aims to continually improve it. Over time, we’ve extended Smart Tiered Cache to handle more origin architectures, including:
- November 2024: Smart Tiered Cache for R2: We taught Smart Tiered Cache to automatically select the closest upper tier to where the R2 bucket actually lives, reducing latency with zero configuration.
- January 2025: Smart Tiered Cache for Load Balancing: We extended Smart Tiered Cache to select a single optimal upper tier for an entire Load Balancing pool, so all origins in the pool share the same cache, improving hit ratios.
Each of these improvements has shared a common goal: understand the customer’s origin infrastructure and automatically do the best thing for that infrastructure.
While we’ve been improving this system for a while, customers still had a common frustration: Smart Tiered Cache did not work when an origin is behind an anycast or regional unicast network, because this architecture prevented us from knowing where the origin is located. And this wasn’t an edge case, either. Origins hosted on public cloud providers behind anycast IPs are a growing slice of the Internet.
Today, we’re closing that gap for origins hosted on AWS, GCP, Azure, and Oracle Cloud.
Why anycast cloud origins are different
Smart Tiered Cache works by measuring the latency from each Cloudflare data center to the origin’s IP address. The data center with the lowest latency becomes the upper tier: the single point through which all cache misses funnel on their way to your origin. By concentrating cache misses at one data center, you get higher cache hit ratios, fewer connections to your origin, and lower latency on origin pulls. This works well when the origin has a fixed, unicast IP address that can be reliably probed.
Many cloud providers use anycast or regional unicast networking for their load balancers, front-end services, and regional ingress points. When we probe these IPs, the origin appears to be “close” to many data centers simultaneously. That is because the IP address represents the cloud provider’s front end, not a single physical origin location. Different Cloudflare data centers may reach different nearby cloud edges for the exact same IP, and the provider then carries the request across its own network to the actual backend. So Smart Tiered Cache cannot confidently pick one best upper tier.
In practice, this could result in hairpin traffic across continents, adding a whole extra round trip. Say your origin sits in Singapore, behind an anycast IP from a cloud provider. Because of how anycast works, our Chicago data center might show the lowest probe latency to that IP. Smart Tiered Cache would then select Chicago as the upper tier. The result: a request from an end user in Asia hits a nearby Cloudflare data center, gets routed cross-continent to the upper tier in Chicago, and Chicago fetches from the origin back in Singapore, crossing the ocean twice. That hairpinning adds hundreds of milliseconds of latency, and it's one of the most consistently reported issues from customers with cloud-hosted origins.
To address this unnecessary back-and-forth, Smart Tiered Cache learned to detect anycast origins with a constraint from physics: the speed of light. We measure probe latencies from multiple checkpoint data centers around the world to the origin. If the combined latencies from two checkpoint data centers are faster than what light in fiber could physically travel between the two, the origin must be answering from multiple locations, not one. That means it's anycast.
When Smart Tiered Cache detects an anycast origin, it plays it safe: it won't pin that IP to a single upper tier. Instead, it falls back to a tiered cache topology with multiple upper tiers. Tiered caching still works, but spreading traffic across multiple tiers instead of one means more requests reach the origin. For some setups that’s a fine trade. But if you want one upper tier close to an origin that lives on a public cloud behind anycast IPs, there hasn't been a good option — until now.
Tell us the region
From the Cloudflare dashboard, go to Caching > Tiered Cache > Origin Configuration. Find your origin IP, click "Set Region Hint," and tell us the cloud region (for example, aws:us-east-1 or gcp:europe-west1). Smart Tiered Cache takes over from there. Note that, on the dashboard, region hints can only be set for origins whose IPs we've detected as anycast.
You can set hints one IP at a time, or bulk-edit cloud regions for all your origin IPs at once. Beyond the dashboard, the same configuration is available via the API and through Terraform, so you can integrate it into your existing infrastructure-as-code workflows.
We're launching with AWS, GCP, Azure, and Oracle Cloud, with more providers coming.
How Smart Tiered Cache for Public Cloud Regions works
Every few hours, we fetch the latest IP range files from each supported cloud provider. These files map every cloud region to its current set of IP prefixes, so when a provider adds, removes, or reassigns a subnet, we pick it up.
We match those subnets against our upper tier database, which is built from continuous latency probing refreshed every 15 minutes. For each cloud region, each matching subnet contributes a weighted vote based on its current upper-tier assignment. The upper tier with the strongest signal becomes the region’s primary upper tier. Primary and fallback always come from different points of presence (PoPs), so losing one PoP can't take out both.
Some regions don't have enough probe data, for example, perhaps the new region’s cloud provider is still rolling out, or the region has no origin onboarded to Cloudflare yet — so there’s nothing to vote on. We fall back to geography: the closest of our Tier 1 PoPs. As origins come online and probe data builds up, the region quietly switches from that geographic guess to the option backed by real data.
Try it now, and what's next
All this means that the work of selecting the optimal region for your cache — the constant probing, the algorithmic choice of each region's best upper tier, the geographic fallbacks, the failover across PoPs — runs on our side. Your job is selecting the region hint.
If your anycast origin sits on a public cloud, you can turn this on now. In the dashboard, go to Caching > Tiered Cache > Origin Configuration. Find your origin IP, click Set Region Hint, and pick your region.
Next up, we’re expanding to more providers, and continuing to teach Smart Tiered Cache to recognize more origin setups and pick the right path on its own. To learn more about how Tiered Cache can benefit your service, check out our Tiered Cache documentation.
Introducing Feature Views
Databricks introduced Feature Views to unify machine learning feature logic across training and real-time inference using a single, governed definition.
Decoder
- Feature Store: A centralized repository that standardizes the definition, storage, and access of machine learning features for both training and serving.
- Training/Serving Skew: A performance degradation caused by differences in how data is processed or calculated during the model training phase versus the live production prediction phase.
- Unity Catalog: Databricks’ governance and discovery layer for data, analytics, and AI assets across the lakehouse.
Original article
- What it is: Feature Views are a managed framework for defining an ML feature once and using it everywhere — the same definition powers historical data for experimentation and training, and production pipelines for batch or real-time inference.
- The challenge it solves: Productionizing real-time ML. Experiment with features in a notebook, and rapidly productionize them with a few API calls. Eliminate training/serving skew, duplicated feature code, and fragile self-managed streaming and online store infrastructure that make ML hard to scale.
- The outcome: Features become governed Unity Catalog objects, materialized by managed pipelines, with streaming features served at a 200ms end-to-end p99.
In a perfect world, ML Features are built only once. But for many teams, a feature that works in a notebook still turns into duplicated logic, fragile pipelines, one-off backfills, online store plumbing, and governance overhead. For real-time use cases like fraud detection, personalization, and recommendations, that complexity gets even harder to absorb because models depend on fresh signals to make accurate predictions. Common challenges include:
- Re-implementing feature logic across real-time and historic training
- Training/serving skew degrading model performance
- Discovering and re-using features across use cases
- Backfilling features with large historic lookback into the online store
- Maintaining complex production infrastructure at scale
- Governing and tracking lineage across components and pipelines
Databricks is excited to announce the Public Preview of Feature Views, a framework for creating managed feature pipelines directly within Databricks. With Feature Views, you author a feature once and let the platform handle everything from experimentation to real-time serving.
What are Feature Views?
A Feature View is a simple, powerful abstraction that spans the full ML lifecycle. A data scientist or ML engineer defines their feature logic — the source, the entity, the time-series column, and the computation. From that one definition, Databrick’s Feature Store generates historical, point-in-time-accurate data for experimentation and training. When they're ready, users materialize the Feature View, and Databricks runs the pipelines that compute feature data for efficient inference.
The same Feature definition supports both batch and streaming sources. Experimentation and productionization are the same for both sources. Switching from a batch source to a streaming source is as simple as a few lines of code.
Here's the same feature view definition, running as a streaming and a batch feature.
Why Feature Views?
1. One definition, no skew
The single biggest source of failure in real-time ML is the gap between how a feature is computed for training and how it's computed at serving time. Feature Views close that gap by construction: there is a single definition, and the platform computes the training values and the online inference values against that single definition so they match. For ML teams, this means much less code to maintain and a much smoother path to production.
Better recommendations for hundreds of millions of travelers start with better features. Feature Views cut our feature code dramatically - our data scientists go faster and focus on what drives traveler value, not how to compute it.—Jules Marshall, Sr. Director of Data, Skyscanner
2. Genie Code for Experimentation
Get building quickly and easily with the Feature Engineering Client SDK and Genie Code. The SDK makes it simple to declare features locally in a notebook, instantly compute them correctly over historical data, and assemble a point-in-time-accurate training set.
Because Databricks co-locates feature definitions, feature data, model training, and MLflow in one environment, data scientists can move from feature idea to model experiment in a single notebook.
With Genie Code, teams can use Feature Views to run one-shot model-experimentation workflows: identifying the right data sources, generating feature ideas, and experimenting with models and data in a single notebook.
3. Production-ready pipelines you don't have to operate
When a feature is ready for production, register it in Unity Catalog and call materialize_features. Databricks creates and manages the pipelines on your behalf, writing to the appropriate online and offline stores.
Production-ready means high-quality data, scalable infrastructure, and mission-critical reliability. Feature Views orchestrates battle-tested GA products like Lakebase and RTM under the hood, optimizing how components work together to support Feature Serving workloads. Corner cases work out of the box, such as backfilling long windows, stream features, or expiring stale rows from the online store.
4. Real-time freshness when you need it
For use cases where every new event should immediately change the value served to the model, Feature Views support streaming features sourced from Kafka, delivering end-to-end p99 latency of 200ms from event to online availability. A RollingWindow looks backward from each event's timestamp with millisecond resolution, so an aggregate like "sum of transactions in the last 10 minutes" is always current.
Under the hood, Databricks orchestrates the components that make this fast: Spark Realtime Mode processes events continuously and updates rolling aggregates per event rather than waiting for microbatches; Lakebase serves as a streaming-optimized online store that minimizes write amplification for frequent, small upserts; and Model Serving retrieves features at inference time. You author the rolling-window feature — the platform builds the pipeline.
5. Governed in Unity Catalog, integrated across the platform
Materialized Features are data, and they should be governed like data. In Databricks, Feature Views are first-class Unity Catalog objects — discoverable, access-controlled, and tracked with full lineage. Features are packaged with the model: when you log a model with MLflow, its feature dependencies are recorded, and at inference time, Model Serving automatically looks up the required features — no custom lookup code, no manual plumbing. Combined with MLflow, Model Serving, and Genie Code, Feature Views make Databricks a single place to develop, deploy, and govern your entire ML stack.
Genie Code is natively integrated with Feature Views, so data scientists can build and iterate on features from simple prompts. Ask it to add new features to a notebook, and Genie Code can generate the right code in context, using the data and governance already in Databricks.
How teams are using Feature Views
- Financial services teams use RollingWindow streaming features for sub-second transaction signals for fraud detection.
- Personalization and recommendation teams capture a user's freshest in-session intent to drive engagement, while reusing the same definitions offline for model training.
- Platform teams consolidate previously fragmented feature pipelines into governed Unity Catalog objects, removing the operational burden of self-managed online stores and stream processors.
Getting started
To get started, just ask Genie to use Feature Views to build a new experiment.
It can help you define a feature, analyze importance for your dataset, build a training set, and — when you're ready for production — register and materialize it. Streaming materialization additionally requires an Enterprise-tier workspace in a region that supports Lakebase.
To learn more, check out the documentation:
- Read the Feature Views documentation to define your first feature
- Try the Feature Views quickstart notebook to get your hands on code
- See documentation on model training with Feature Views and materializing Feature Views for the full training and serving workflows
Feature Views let you author a feature once and use it across experimentation, batch, and real-time serving — without operating the underlying infrastructure yourself. Take an existing batch feature and see how much stronger a signal it provides with millisecond-level freshness, and let Databricks run the pipelines that get it there.
If these are the kinds of problems you want to work on, we're hiring.
Code review is theater now
Code review has become ineffective as a quality gate because AI-generated pull request volume now outpaces the human capacity to provide meaningful feedback.
Decoder
- DORA: DevOps Research and Assessment, a set of metrics (Deployment Frequency, Lead Time for Changes, etc.) used to measure software delivery performance.
- Policy-as-code: The practice of codifying operational and security requirements into automated scripts that enforce rules across infrastructure and deployment pipelines.
Original article
Back in March, Gene Kim shared a conversation he had with Jez Humble on LinkedIn. Jez made a beautifully sarcastic remark:
Don’t worry about code reviews, Gene. Code reviews and approvals have always involved a lot of theater. We just need to perpetuate that illusion a little longer and keep pretending that humans are actually reviewing all that agent-generated code.
Jez is absolutely right; code reviews do involve a lot of theater. Especially now in the era of AI-generated code. In the short amount of time since this post, this trend has become more pronounced. Code review used to be considered a solid approach to ensuring quality and compliance. It just isn’t anymore, and we need to be honest about its effectiveness for development teams today.
The chocolate belt wrappers
Consider the all-too-familiar process of reviewing a pull request (PR). The notification bell icon lights up, indicating that you have something to review. You open it, review the code, slap “LGTM” on it, and click “approve.” It compiles. Ship it.
Now consider the scenario in which agents write the majority of the PRs. You probably know how this ends up if you’ve ever seen the “Job Switching” episode of I Love Lucy.
In the episode, Lucy and Ethel take jobs on an assembly line wrapping chocolates. Everything starts fine until then the belt speeds up. Lucy and Ethel can’t keep pace, so they start hiding chocolates wherever they can. The chocolates keep coming. The wrapping of chocolates, what we call code review, becomes theater.
In our world, these chocolates are PRs, AI coding agents are the belt, and code review is Lucy, frantically trying to keep up while the quality of what’s getting through drops with every passing minute. A lot of what’s coming off that belt can be slop. It compiles. (Or, sometimes not.) If you’re lucky, it passes your test matrix. Looking closely at the code, it looks fine until you realize the model copied a pattern from its training data that doesn’t actually fit your problem. The person reviewing would likely not realize this. The reviewer would likely check whether the syntax and structure are correct, not whether the code should exist in the first place.
Agents can produce huge chunks of code in the time it takes to read this sentence. The PRs reflect this. Now consider the burden this places on a reviewer. Is it reasonable to evaluate a 40,000-line change? Does it get better if we atomize it into 4,000 tiny 10-line diffs? You can read each diff and still miss whether it’s the right change. That’s because you weren’t part of the reasoning that produced it. You have no context whatsoever. It’s like flipping to the middle of a book and claiming you know where you are in the story.
Yes, AI makes producing code much, much faster. However, reviewing that code has become much, much harder. As an industry, we tout and celebrate the speed. But we don’t talk about the PRs piling up, putting everyone downstream under pressure.
The chocolate belt speeds up
If you take a look at the 2026 DORA report, 90% of developers now use AI tools at work. Developers are spending 2+ hours a day with these tools, completing 21% more tasks and merging 98% more pull requests.
With great power comes great responsibility. The average number of bugs per developer is up 54%. Faros AI’s analysis of 10,000+ developers found incidents per pull request are up 242.7%. We’ve essentially doubled our merge rates while breaking things three times as often. We see the impact of AI-generated code in our own data, too. Our 2026 AI Pulse report found that AI reduces task hours across every part of the delivery pipeline except for code review. 72% of developers use AI to write code, but only 56% bother using it for their reviews. The chocolate belt is accelerating, and Lucy and Ethel are starting to look nervous.
To be fair, Daniel Stenberg, the creator of curl, recently noted that AI-generated contributions have gone from slop to genuinely good. Problem solved, right? Not quite. PRs are arriving faster than his team can review them. We have better chocolates, but the same belt speed problem. Our review queue is starting to resemble a backlog.
So what do we do about it? The prevailing sentiment right now is to chuck AI at the review problem, too. Make Ethel check Lucy’s work. But think about that. They’re standing at the same belt and they’ve trained on the same data. They have the same blind spots. “AI reviewed it so we’re good” is the new “the dog ate my homework.” Except now the dog wrote the homework, ate it, barfed it up, and gave it an A+.
That’s the real takeaway from the DORA data. AI is an amplifier. It can amplify our intelligence or our stupidity. We need to be careful. Right now, a lot of us have the chocolate belt of PRs cranked up to full speed.
Enter the wrapping machine
The chocolate belt does exactly what it’s supposed to do. The wrapping process (code review) is what failed. And the fix has been staring us in the face since the Continuous Delivery (CD) movement began. Our deployment pipeline is the assurance mechanism, not the human with the approve button. If quality and security requirements are missing from the pipeline as automated checks, code review will never ensure they are met. We are simply hoping that a human – somewhere in the chain – might catch the problem.
Yes, we still need people who can look at a system and say, “This is the wrong approach.” That’s not going away. But we’re expecting that same person also to be the last line of defense against every bug and every security gap in every deployment. That was never going to work. We just didn’t have a reason to admit it until now.
What’s actually in the chocolate
Let’s stop pretending code review is something it isn’t.
Code review is great for knowledge sharing and catching design-level issues. But it’s horrible at catching every bug in a 40,000-line diff. Bugs matter when code is shipping to production.
So the question we should be asking ourselves isn’t “how do we make code review scale?” It’s “how do we build a pipeline that can verify what it’s shipping, regardless of who or what wrote the code?”
Policy-as-code is one way to get there. We write rules that define our deployment standards, and the pipeline checks every deployment against them. The developer sees what went wrong and how to fix it. There’s no waiting around for someone to review a diff.
Learning to wrap chocolate
It would be foolish of me not to mention the fact that there’s something a chocolate wrapping machine can’t teach you. And that’s the process of wrapping chocolate. In our world, that’s the act of conducting a code review. It’s how junior engineers develop judgment.
Mentorship comes from reading other people’s code, getting feedback on your own, and absorbing the unwritten reasons behind certain decisions. That pipeline is already breaking. 73% of organizations have reduced junior developer hiring in the past two years. Junior devs dropped from 32.8% to 24.8% of Stack Overflow respondents between 2024 and 2025. If we let that continue without figuring out another way for juniors to learn, we’re in trouble. We end up with a generation of engineers who can prompt effectively but can’t reason about a system’s design.
I’m not saying we need to remove code review. But we need to stop kidding ourselves that it’s the all-seeing, all-knowing quality gate we’ve built it up to be.
Wrapping up
To reiterate, Jez was right. Code review has worked well enough when humans are involved in the volume of code being reviewed. It was good enough when a team merged a handful of PRs a day. However, it’s not good enough when AI is generating them.
The answer isn’t a better performance. It’s a better pipeline. One that can prove our software works before it hits production. The CD community has been saying this for years. Most of us just didn’t have a reason urgent enough to listen. But with the advent of AI and code generation, we’re now compelled to.
If our quality gates live in our pipeline, it doesn’t matter whether the code was written by a human, an AI, or a very determined cat walking across a keyboard.
If the quality of our code reviews is determined by a human’s abilities, we’re in trouble, because AI sped up the belt, and the chocolates aren’t going to wrap themselves.
Happy deployments!
pgrust (GitHub Repo)
The pgrust project has achieved full regression test compatibility with PostgreSQL 18.3, promising significant performance gains through a Rust-based architectural rewrite.
Decoder
- Regression Tests: A suite of tests used to ensure that new code changes do not break existing functionality in a software system.
- Thread-per-connection: A concurrency model where each client connection is handled by a lightweight thread rather than a full process, typically reducing memory overhead and improving context-switching speed.
- Disk-compatible: A system that can read and write data files created by another system, allowing for interoperability between different database implementations.
Original article
pgrust
A Postgres rewrite in Rust.
pgrust targets compatibility with Postgres 18.3 and matches Postgres's expected output across more than 46,000 regression queries.
pgrust is disk compatible with Postgres and can boot from an existing Postgres 18.3 data directory.
The goal is to make Postgres easier to change from the inside: keep the behavior Postgres-shaped, keep the real Postgres tests as the oracle, and use Rust plus AI-assisted programming to explore deeper server changes.
Update: We're working on a new not yet published version of pgrust that currently passes 100% of Postgres regression suite, has a thread per connection model instead of process per connection, is 50% faster than Postgres on transaction workloads, and is ~300x faster than Postgres on analytical workloads (2x slower than Clickhouse on clickbench and we think it can get faster than Clickhouse). Follow pgrust or join our Discord for updates!
Follow pgrust
Get project updates by email, including new releases, compatibility milestones, and architecture experiments.
Status
pgrust is not production-ready yet. It is not performance optimized yet.
Existing Postgres extensions and procedural language extensions such as PL/Python, PL/Perl, and PL/Tcl are not generally compatible yet. Some bundled contrib modules are already ported, and more compatibility may be possible over time.
Roadmap
- multithreaded Postgres internals
- built-in connection pooling
- better JSON-heavy workload support
- fast forking and branching workflows
- storage experiments, including no-vacuum designs
- runtime guardrails for bad queries and AI-generated SQL
- fewer sudden bad plan switches
Try It
Try the WebAssembly demo at https://pgrust.com.
Docker:
docker run -d --name pgrust -e POSTGRES_PASSWORD=secret malisper/pgrust:v0.1 && until docker exec -e PGPASSWORD=secret pgrust psql -h 127.0.0.1 -U postgres -c '\q' >/dev/null 2>&1; do sleep 1; done && docker exec -it -e PGPASSWORD=secret pgrust psql -h 127.0.0.1 -U postgres; docker rm -f pgrust
This uses the psql client inside the Docker image.
malisper/pgrust:latest currently points at the same release, but v0.1 is the pinned launch image.
Build From Source
macOS:
brew install icu4c openssl@3 libpq
export LIBRARY_PATH="$(brew --prefix openssl@3)/lib:${LIBRARY_PATH:-}"
export PKG_CONFIG_PATH="$(brew --prefix openssl@3)/lib/pkgconfig:$(brew --prefix icu4c)/lib/pkgconfig:${PKG_CONFIG_PATH:-}"
export PATH="$(brew --prefix libpq)/bin:$PATH"
Debian/Ubuntu:
sudo apt-get update
sudo apt-get install -y build-essential pkg-config libicu-dev libssl-dev libldap2-dev libpam0g-dev postgresql-client-18
Build:
PGRUST_PGSHAREDIR="$PWD/vendor/postgres-18.3/share" \
cargo build --release --locked --bin postgres
Create a data directory:
target/release/postgres --initdb \
-D /tmp/pgrust-data \
-L "$PWD/vendor/postgres-18.3/share" \
--no-locale \
--encoding UTF8 \
-U postgres
Run pgrust:
ulimit -s 65520
RUST_MIN_STACK=33554432 target/release/postgres \
-D /tmp/pgrust-data \
-F \
-c listen_addresses= \
-k /tmp \
-p 5432 \
-c io_method=sync \
-c max_stack_depth=60000
Connect:
psql -h /tmp -p 5432 -U postgres -d postgres \
-c "select version(), 1 + 1 as two"
Regression Tests
Run the Postgres regression tests against pgrust:
PGRUST_BIN="$PWD/target/release/postgres" \
scripts/run-regression
The runner uses pgrust's own --initdb plus the vendored Postgres 18.3 test files in this repository. It needs a Postgres 18 psql client on PATH; if psql is somewhere else, set PGRUST_PSQL=/path/to/psql.
Verified launch result: pgrust matched Postgres's expected output across more than 46,000 regression queries.
History
This repository now contains the newer pgrust implementation that reached the regression-test milestone.
The older public implementation is archived on archive/pre-fabled-2026-06-23.
Background:
- Original pgrust launch: https://malisper.me/pgrust-rebuilding-postgres-in-rust-with-ai/
- 67% regression update: https://malisper.me/pgrust-update-at-67-postgres-compatibility-and-accelerating/
- Four Horsemen roadmap: https://malisper.me/the-four-horsemen-behind-thousands-of-postgres-outages/
Feedback
Please open an issue if something breaks, if setup is confusing, or if there is a Postgres improvement you want to see first.
Contact
- Email: maintainers@pgrust.com
- Discord: https://discord.gg/FZZ4dbdvwU
- Project updates: https://pgrust.com/#updates
License
pgrust is licensed under AGPL-3.0. See LICENSE.
Background Agents: Open-Inspect (GitHub Repo)
Open-Inspect is an open-source coding agent system that orchestrates multi-repository tasks in sandboxed environments, inspired by Ramp's internal tooling.
Deep dive
- Control Plane: Built on Cloudflare Workers and Durable Objects to manage session state.
- Sandboxing: Uses infrastructure from Modal and Daytona to provide isolated Node.js/Python runtimes.
- Session Warming: Uses filesystem snapshots and pre-built images to minimize latency between prompts.
- Multiplayer: Allows real-time collaboration with presence indicators.
- Security: Enforces a single-tenant model where all users within an organization share repository access.
Decoder
- Ramp's Inspect: An internal engineering tool at the fintech company Ramp designed to automate code maintenance by running AI agents in background sandboxes.
Original article
Background Agents: Open-Inspect
An open-source background agents coding system inspired by Ramp's Inspect.
Overview
Open-Inspect provides a hosted background coding agent that can:
- Work on tasks in the background while you focus on other things
- Access full development environments (Node.js, Python, git, browser automation, VS Code)
- Connect from anywhere — web UI, Slack, GitHub PRs, Linear issues, or webhooks
- Enable multiplayer sessions where multiple people can collaborate in real time
- Create PRs with proper commit attribution to the prompting user
- Run on a schedule — cron jobs, Sentry alerts, and webhook-triggered automations
- Spawn parallel sub-tasks that work in separate sandboxes simultaneously
- Use your choice of AI model — Anthropic Claude, OpenAI Codex (via ChatGPT subscription), or OpenCode Zen
Security Model (Single-Tenant Only)
Important: This system is designed for single-tenant deployment only, where all users are trusted members of the same organization with access to the same repositories.
How It Works
The system uses a shared GitHub App installation for git operations (clone, fetch, push). The control plane mints short-lived installation tokens server-side and brokers them to sandboxes through the git credential helper on demand. This means:
- All users share the same GitHub App credentials - The GitHub App must be installed on your organization's repositories, and any user of the system can access any repo the App has access to
- No per-user repository access validation - The system does not verify that a user has permission to access a specific repository before creating a session
- GitHub users' OAuth tokens are used for PR creation - For GitHub logins, PRs are created using the user's GitHub OAuth token, ensuring proper attribution and that they can only create PRs on repos they have write access to. Users who sign in another way (e.g. Google) carry no SCM token, so their PRs fall back to the shared GitHub App bot
Token Architecture
| Token Type | Purpose | Scope |
|---|---|---|
| GitHub App Token | Brokered git clone/fetch/push auth | All repos where App is installed |
| User OAuth Token | Create PRs, user info | Repos user has access to |
| Sandbox Auth Token | Sandbox-to-control-plane session calls | Single session |
| WebSocket Token | Real-time session auth | Single session |
Why Single-Tenant Only
This architecture follows Ramp's Inspect design, which was built for internal use where all employees are trusted and have access to company repositories.
For multi-tenant deployment, you would need:
- Per-tenant GitHub App installations
- Access validation at session creation
- Tenant isolation in the data model
Deployment Recommendations
- Deploy behind your organization's SSO/VPN - Ensure only authorized employees can access the web interface
- Install GitHub App only on intended repositories - The App's installation scope defines what the system can access
- Restrict sign-in - Configure allowed GitHub users, email domains, or active GitHub organization membership (
ALLOWED_GITHUB_ORGS) - Use GitHub's repository selection - When installing the App, select specific repositories rather than "All repositories"
- Filesystem snapshots — After each prompt, sandbox state is saved; follow-up sessions restore instead of re-cloning
- Pre-built images — Toggle per-repo (Settings > Images) or per-environment (Settings > Environments); rebuilt every 30 minutes with latest commits and dependencies
- Proactive warming — Sandbox begins spinning up as soon as you start typing, before you hit Enter
- Ad-hoc sets — Pick up to 10 repositories in the new-session picker; each is cloned side by side and the agent can make coordinated changes and open a PR per repository
- Environments — Save a repository set as a named environment with its own secrets scope and optional prebuilt images, then launch it from the picker like any repository
- Presence indicators show who's active
- Prompts are attributed to their authors in git commits
- Real-time streaming to all connected clients
- Web UI — Full session management with real-time streaming, model/reasoning selectors, terminal panel, and multiplayer presence
- Slack Bot — @mention or DM to start a session; replies thread back with results. Per-user model and branch preferences via App Home
- GitHub Bot — Auto-review on PR open or respond to @mentions in PR comments. Configurable per-repo
- Linear Bot — Mention or assign the agent on an issue to start a coding session, post progress activities, and link the resulting PR
- Webhooks — Trigger sessions from any external system via authenticated HTTP POST
- Cron schedules — Hourly, daily, weekly, monthly, or custom 5-field cron with timezone support
- Sentry alerts — Auto-triage on new errors, regressions, or critical metric alerts
- Inbound webhooks — JSONPath condition filters to gate which payloads spawn sessions
- Multi-repo fan-out — One scheduled automation can run across up to 10 repositories, opening a separate session and pull request for each
- Auto-pause after 3 consecutive failures, manual trigger button, full run history
- Pre-installed: Node.js 22, Python 3.12, Bun, git, GitHub CLI, build-essential
- Browser automation: agent-browser CLI with headless Chromium for screenshots, visual diffs, and UI verification
- Code-server: Optional browser-based VS Code connected to the session workspace
- Web terminal: ttyd-powered terminal accessible from the session UI
- Port tunneling: Expose up to 10 dev server ports via encrypted tunnels
- Secrets: AES-256-GCM encrypted, scoped globally, per-repo, or per-environment, injected as env vars at spawn time.
spawn-taskcreates a child session in its own sandbox and returns immediately- Parent continues working while children run in parallel on separate branches
get-task-statusandcancel-taskfor coordinationsetup.shruns for image builds and fresh sessionsstart.shruns for every non-build session startup (fresh, prebuilt-image, snapshot-restore)- Modal - Cloud sandbox infrastructure
- Daytona - Cloud development sandboxes
- Vercel Sandbox - Cloud sandbox infrastructure
- OpenComputer - Cloud sandbox infrastructure
- Cloudflare Workers - Edge computing
- OpenCode - Coding agent runtime
- Next.js - Web framework
Architecture
┌──────────────────┐
│ Clients │
│ ┌──────────────┐ │
│ │ Web / Slack │ │
│ │ GitHub / Lin.│ │
│ │ Webhooks │ │
│ └──────────────┘ │
└────────┬─────────┘
│
▼
┌────────────────────────────────────────────────────────────────────┐
│ Control Plane (Cloudflare) │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Durable Objects (per session) │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌───────────────┐ │ │
│ │ │ SQLite │ │WebSocket│ │ Event │ │ GitHub │ │ │
│ │ │ DB │ │ Hub │ │ Stream │ │ Integration │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └───────────────┘ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ D1 Database (repo-scoped secrets) │ │
│ └──────────────────────────────────────────────────────────────┘ │
└────────────────────────────────┬───────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────┐
│ Data Plane (Sandbox Backend) │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Session Sandbox │ │
│ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │
│ │ │ Supervisor│──│ OpenCode │──│ Bridge │─────────────────┼──┼──▶ Control Plane
│ │ └───────────┘ └───────────┘ └───────────┘ │ │
│ │ │ │ │
│ │ Full Dev Environment │ │
│ │ (Node.js, Python, git, agent-browser) │ │
│ └──────────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────┘
Packages
| Package | Description |
|---|---|
| control-plane | Cloudflare Workers + Durable Objects |
| web | Next.js web client |
| sandbox-runtime | Shared in-sandbox agent runtime |
| modal-infra | Modal sandbox infrastructure |
| daytona-infra | Daytona snapshot infrastructure |
| opencomputer-infra | OpenComputer template infrastructure |
| slack-bot | Slack integration (sessions from messages) |
| github-bot | GitHub integration (auto-review, @mention) |
| linear-bot | Linear integration (issue → coding session) |
| shared | Shared types and utilities |
Getting Started
For a practical setup guide (local + contributor + deployment paths), start with docs/SETUP_GUIDE.md.
See docs/GETTING_STARTED.md for deployment instructions.
To understand the architecture and core concepts, read docs/HOW_IT_WORKS.md.
To set up recurring scheduled tasks, see docs/AUTOMATIONS.md.
Key Features
Fast Startup
Sessions start near-instantly through multiple layers of warming:
Multi-Repository Sessions & Environments
One session can work across several repositories in a single sandbox:
Multiplayer Sessions
Multiple users can collaborate in the same session:
Commit Attribution
Commits are attributed to the user who sent the prompt:
// Configure git identity per prompt
await configureGitIdentity({
name: author.scmName,
email: author.scmEmail,
});
Multi-Provider Model Support
Choose the AI model that fits your task, with per-session reasoning effort controls:
| Provider | Models |
|---|---|
| Anthropic | Claude Haiku 4.5, Sonnet 4.5/4.6, Opus 4.5/4.6/4.7/4.8, Fable 5 |
| OpenAI | GPT 5.4, GPT 5.5, 5.3 Codex, 5.3 Codex Spark |
| OpenCode Zen | Kimi K2.5/K2.6, MiniMax M2.5, Qwen3.7 Max, GLM 5/5.1 (opt-in) |
| Z.AI Coding Plan | GLM 5.2 (opt-in) |
Client Integrations
Interact with agents from wherever your team already works:
Automations
Schedule recurring tasks or react to external events — no human in the loop:
Sandbox Environment
Every session runs in an isolated sandbox backend with a full development environment:
Sub-Task Spawning
Agents can decompose work into parallel child sessions:
Repository Lifecycle Scripts
Repositories can define two optional startup scripts under .openinspect/:
# .openinspect/setup.sh (provisioning)
#!/bin/bash
npm install
pip install -r requirements.txt
# .openinspect/start.sh (runtime startup)
#!/bin/bash
docker compose up -d postgres redis
License
MIT
Credits
Inspired by Ramp's Inspect and built with:
How to protect your MCP Server with Fastly
Fastly developed a prototype security architecture for Model Context Protocol (MCP) servers using edge-based WAF and bot management.
Deep dive
- Threat Mitigation: Blocks non-standard content types and mitigates OWASP and LLM-specific injection attacks.
- Performance: Achieved sub-50ms latency during a 10-week trial.
- Authentication: Supports diverse models including mTLS and token-based auth at the edge.
- Traffic Optimization: Uses Fastly Media Shield to anchor traffic and reduce origin load.
Decoder
- Model Context Protocol (MCP): An open standard that enables AI models to interact with external tools and data sources in a unified way.
- WAF (Web Application Firewall): Security software that filters, monitors, and blocks malicious HTTP/HTTPS traffic to a web application.
Original article
As organizations rapidly adopt AI agents and agentic workflows, Model Context Protocol (MCP) servers are becoming a foundational integration layer between AI models and enterprise systems. While they accelerate development and simplify tool integration, they also introduce a new class of security challenges. Unlike traditional API traffic that’s typically deterministic and narrowly scoped, MCP traffic enables dynamic tool discovery, natural language-driven interactions, and orchestration across trust boundaries. These characteristics expand the attack surface and require security controls that extend beyond conventional API protection.
When a major global publisher approached Fastly asking for help securing their MCP server backbone connecting their AI agents with real-time financial data and tools, our team sprang into action to build a prototype that any organization can follow the architecture of to protect theirs. The following outlines the process and outcomes they achieved, providing a practical reference for organizations working to secure their own MCP environments.
Fastly MCP Protection Prototype
To protect their MCP server, the Fastly prototype needed to adhere to three key requirements:
- Detect and mitigate AI-specific attack vectors – OWASP and AI-specific attacks targeting the MCP server must be mitigated
- Ensure production-scale performance – Sub-100ms latency is mandatory and the solution must handle at least 100Mbps throughput
- Allow authentication complexity – A mix of IP-based, token-based, and mTLS authentication models must be allowed without false positives
To address these requirements, the prototype combined the flexibility and customization of multiple existing Fastly capabilities. While we won’t dive into the details of their unique implementation, each of these solutions provided the customer with another layer of protection for their MCP server.
Here’s how the prototype paired them together to solve the customer’s requirements:
- Fastly’s Global Network provides more than just 578 Tbps global capacity and performance benefits, enabling customers to implement custom traffic logic as it enters the network. This configuration flexibility allowed rules to be implemented as intended MCP traffic hit our network that automatically blocked unexpected content types like xml and restrict HTTP methods.
- Fastly Bot Management provides visibility into the automated traffic heading to the MCP server, allowing rules to be created to block unwanted automation clients, bots with bad fingerprints, and generally malicious bot traffic.
- Fastly Next-Gen WAF provides the ability to mitigate OWASP attacks and LLM-specific attacks like encoded prompt injection and jailbreak phrases. The prototype leverages its rate limiting capabilities to incorporate policies against IPs or API keys that exceeded expected norms.
- Fastly Media Shield provides a designated Fastly POP as anchor for all MCP server traffic before it ultimately goes to origin. This enables the prototype to reduce origin load while speeding up connections by reducing the time required for costly multi-roundtrip handshakes.
Key results
With these four solutions implemented and tuned for protecting the customer’s MCP server, the team ran a 10-week trial to see how it stacked up against the customer’s requirements and found it far exceeded them.
| Requirement | Desired Metric | Result |
|---|---|---|
| Latency (average) | < 100ms | Sub 50 ms |
| Upload throughput | 100 Mbps | Achieved |
| Max payload size | 200MB+ | 500MB+ without timeouts |
| Authentication Flexibility | IP-based, token-based, and mTLS model acceptance | Achieved |
Fastly for AI Infrastructure
Fastly's platform is uniquely positioned in the request path to secure and accelerate AI agent infrastructure because it was purpose-built for the edge where performance and security must coexist.
- Performance without compromise: Inspection adds negligible latency; Fastly's global scale and resilience keeps AI agents performant
- Programmable security: Network and Next Gen-WAF rules can be tuned for the novel patterns of MCP and agentic traffic
- Real-time visibility: Security teams see everything, in near real-time, without waiting for batch log exports
- AI-native threat mitigation: Policies for prompt injection, tool abuse, and bot-driven enumeration can be easily created and paired with out-of-the-box OWASP-style attack protections
As AI and associated technologies continue to rise in adoption, Fastly’s MCP server protection prototype is just one example of how Fastly can help your business confidently adopt emerging technologies without increasing risk.
Introducing Smart Retry: Safer retries for transient Jenkins failures.
The new Jenkins Smart Retry plugin automates build recovery by classifying failures before deciding whether a retry is safe.
Deep dive
- Classification: Categorizes errors into
AGENT_LOST,SCM_TRANSIENT,NETWORK_TRANSIENT, andARTIFACT_REPO_TRANSIENT. - Profiles: Provides
conservative(for basic infra) andinfra(for external dependency services) modes. - Transparency: Logs the decision-making process for every retry attempt.
- Guardrails: Prevents retries on compilation failures or pipeline script errors by default.
Original article
Introducing Smart Retry: Safer retries for transient Jenkins failures.
In many Jenkins environments, a failed build does not always mean the code is broken.
Sometimes a Kubernetes agent gets evicted. Sometimes a Git fetch is interrupted. Sometimes an artifact repository has a short outage. In all of these cases, the next manual rebuild often succeeds.
smartRetry is designed for exactly this kind of CI problem: transient failures that are worth retrying, without turning every failed step into an automatic rerun.
What is Smart Retry?
smartRetry is a Jenkins Pipeline step that retries only the failures worth retrying.
Instead of rerunning a failed block unconditionally, it classifies the failure first and then decides whether a retry is allowed under the active profile.
For example:
smartRetry(profile: 'infra', maxRetries: 2, backoff: 'exponential') {
sh 'mvn -B verify'
}
When the wrapped step fails, smartRetry will:
- Capture the thrown error and a bounded slice of console output from the current attempt.
- Classify the failure into a deterministic category such as
AGENT_LOST,SCM_TRANSIENT,NETWORK_TRANSIENT,COMPILATION_FAILURE, orUNKNOWN. - Check whether that category is retryable under the active profile.
- Log the decision clearly and schedule another attempt only when the policy allows it.
This keeps retry behavior explicit, deterministic, and easier to understand.
Why use Smart Retry?
The main idea behind smartRetry is simple: classify first, retry second.
That lets the plugin stay conservative by default. It can automatically recover from high-confidence transient infrastructure problems while still failing fast on deterministic issues such as:
- compilation failures
- Pipeline script logic errors
UNKNOWNfailures that do not match a high-confidence rule- user-initiated aborts
For day-to-day CI, those defaults work well because the retry decision remains visible and explainable.
How it works
1. Configure Smart Retry globally
After installing the plugin, you can configure shared defaults in Manage Jenkins > System, including:
- the default profile
- the default maximum retry count
- fixed or exponential backoff
- custom profiles
- narrow custom classification rules
The current built-in profiles are:
conservative: retries onlyAGENT_LOSTandSCM_TRANSIENTinfra: includesconservative, plusNETWORK_TRANSIENT,ARTIFACT_REPO_TRANSIENT, andIDENTITY_PROVIDER_TRANSIENT
If you are introducing automated retries to a team for the first time, conservative is the safest place to start.
2. Use it in a Jenkinsfile
The simplest pattern is to wrap steps that are idempotent and exposed to infrastructure volatility.
For example, around checkout:
smartRetry {
git branch: 'main',
credentialsId: 'scm-creds',
url: 'https://gitlab.example.com/your-group/your-repo.git'
}
Or around a build step that depends more heavily on external services:
smartRetry(profile: 'infra', maxRetries: 2, backoff: 'fixed', initialDelaySeconds: 10) {
sh 'mvn -B verify'
}
As a general rule, keep the wrapped block as small and as idempotent as possible. That reduces risk and makes retry behavior easier to understand.
3. Inspect the decision
Another key part of smartRetry is explainability. When a build fails, it does not just say "retrying". It logs the classification, the decision, and the reason. For example:
[smartRetry] begin attempt=1
[smartRetry] attempt=1 profile=infra classified=SCM_TRANSIENT retryCandidate=true decision=RETRY nextAttempt=2 delayMillis=10000 reason="Failure type SCM_TRANSIENT is retryable under profile infra and retry budget remains."
[smartRetry] begin attempt=2
Each build that uses smartRetry also gets a dedicated Smart Retry page showing:
- the active profile
- the classification result for each attempt
- which rule matched the failure
- whether the build recovered or stopped retrying
This is especially useful when you need to answer "why did this build retry?" or "why did it stop here?".
Conservative by design
smartRetry is not trying to turn Jenkins into a system that guesses its way through every failure.
The current implementation keeps a few boundaries on purpose:
- no AI-based failure classification
- no retry on
UNKNOWNby default - no retry on compilation failures, Pipeline logic failures, or user aborts by default
- no deployment-style failure retry in the default policy
That may sound less ambitious than "intelligent retries for everything", but it is often a better fit for real CI systems where safety and predictability matter.
Where Smart Retry fits best
smartRetry is a good fit for:
- Jenkins installations running on Kubernetes or other ephemeral agents
- checkout steps frequently affected by Git or SCM transport instability
- Pipeline steps that depend on Maven, npm, PyPI, Docker registries, Artifactory, or other external services
- teams that already know a manual rebuild often succeeds, but do not want to retry every failure blindly
It is not meant to replace every use of retry {}, and it is not a default wrapper for non-idempotent release or deployment steps.
Try it
If your Jenkins environment regularly sees lost agents, SCM hiccups, or short-lived dependency service outages, smartRetry is worth trying in a small and controlled scope.
Start with the conservative profile, use it around idempotent steps such as checkout or dependency download, and expand to infra only after you have seen how it behaves in your own environment.
For many teams, the goal is not another blind retry, but a safer way to retry only when it actually makes sense.
The project is open source on GitHub: jenkinsci/smart-retry-plugin.
If you have a transient failure pattern that should be covered, or you want to help improve the built-in rules, issues and pull requests are very welcome.
Highlights from Git 2.55
Git 2.55 enhances repository maintenance with more efficient multi-pack index updates and streamlined history manipulation.
Deep dive
- Multi-pack index: Repacking improvements update pack metadata more efficiently.
- History fixup: Capabilities added to simplify moving staged changes into earlier commits.
Decoder
- Multi-pack index (MIDX): A file format used in Git to track object locations across multiple packfiles, speeding up lookups for large repositories.
Original article
Git 2.55 introduces incremental multi-pack index repacking improvements that reduce repository maintenance overhead by updating pack metadata more efficiently, alongside new history fixup capabilities that simplify moving staged changes into earlier commits.
Re-architecting Affirm's Upfunnel Platform: How We Cut Experiment Cycle Time from Months to Days
Affirm reduced experiment cycle times from months to days by replacing a legacy Python monolith with a rule-based Kotlin microservice.
Original article
Affirm rebuilt its pre-checkout messaging service from a Python monolith into a Kotlin microservice with a rule engine, cutting P99 latency by 50% and reducing experiment setup time from 2 months to 4 days since adding a new experiment means writing a rule against existing attributes instead of engineering a new code path and waiting for deployment.
Modern Data Warehousing at Scale: Arcesium's Migration to DuckDB and Iceberg
Arcesium migrated 170TB of financial data to an Apache Iceberg and DuckDB stack, cutting costs by 40% and ingestion runtimes by 80%.
Decoder
- Apache Iceberg: An open table format for huge analytic datasets that provides SQL-like reliability and performance on object storage.
- Egress: The transfer of data out of a cloud network, often incurring significant costs.
- KEDA (Kubernetes Event-driven Autoscaling): A tool that enables Kubernetes clusters to scale pods based on external event sources like SQS queues.
Original article
Arcesium migrated a 170TB, 15-trillion-record P&L warehouse from an RDBMS to Apache Iceberg on S3 with DuckDB. The new stack cut ingestion runtime by 80% for larger portfolios, reduced egress timeouts, and lowered infrastructure spend by about 40%. The key enablers were a homegrown, open-sourced DuckDB-Iceberg execution layer called Swiftlake, KEDA for Kubernetes autoscaling, and Iceberg time-travel recovery.
How to Achieve Pruning When Querying by Non-Partitioned Columns in PostgreSQL
PostgreSQL can perform partition pruning on non-partition keys by using CHECK constraints that map specific value ranges to partitions.
Deep dive
- Partition pruning is typically only available on the partition key.
- CHECK constraints act as a source of truth for the query optimizer.
- By creating ranges that cover outlier values within partitions, you can ensure the optimizer correctly prunes during filter operations.
- Gaps and islands analysis can identify the correct value ranges for these constraints.
- This method works automatically with the
constraint_exclusionparameter, which is enabled by default.
Decoder
- Partition Pruning: The query optimization process where the database ignores partitions that cannot possibly contain matching data.
- CHECK Constraint: A database rule that ensures all values in a column meet a specific condition.
- Gaps and Islands: A classic SQL problem identifying consecutive sequences (islands) separated by missing values (gaps).
Original article
One of the most valuable things about partitioned tables is pruning - the database's ability to eliminate entire partitions based on a query predicate. Under conventional wisdom, pruning can only be achieved when querying by the partition key - this makes choosing the right key extremely difficult. However, if your data follows certain patterns, using some clever tricks you can achieve pruning even when filtering by non-partition key columns.
In this article, I demonstrate how to achieve partition pruning when filtering by non-partition key columns.
Table Partition
Imagine you run a popular website with many users. Your product team wants to gain some insight into how the system is used, so you start logging events. To give events context, you group them into sessions and keep the time, the type, and some data in a database table:
CREATE TABLE event (
id BIGINT GENERATED ALWAYS AS IDENTITY,
timestamp TIMESTAMPTZ NOT NULL,
session_id BIGINT NOT NULL,
type TEXT NOT NULL,
data JSONB
) PARTITION BY RANGE (timestamp);
You have many users so you expect many events. Most queries use only a subset of the data, usually a specific date range, so you create a partition for each year based on the timestamp:
CREATE TABLE event_y2025 PARTITION OF event
FOR VALUES FROM ('2025-01-01 UTC') TO ('2026-01-01 UTC');
CREATE TABLE event_y2026 PARTITION OF event
FOR VALUES FROM ('2026-01-01 UTC') TO ('2027-01-01 UTC');
You now have two partitions - one for events from 2025 and another for 2026. A session can look like this:
INSERT INTO event (session_id, timestamp, type, data) VALUES
(1, '2025-12-28 15:00:00 UTC', 'view', '{"page": "/login"}'),
(1, '2025-12-28 15:00:06 UTC', 'click', '{"selector": "#login"}'),
(1, '2025-12-28 15:00:07 UTC', 'login_failed', '{"attempt": 1}'),
(1, '2025-12-28 15:00:10 UTC', 'click', '{"selector": "#forgot-password"}'),
(1, '2025-12-28 15:00:17 UTC', 'view', '{"page": "/reset-password"}'),
(1, '2025-12-28 15:00:23 UTC', 'click', '{"selector": "#reset-password"}');
Partition Pruning for Key Columns
The partition key of the table is timestamp, so queries that filter by timestamp can benefit from partition pruning. For example, query events in December 2025:
EXPLAIN SELECT * FROM event
WHERE timestamp >= '2025-12-01 UTC' AND timestamp < '2026-01-01 UTC';
Notice that the database was smart enough to figure out it only needs to scan the partition for 2025. The partition for 2026 was not even accessed. This is partition pruning.
Another common query is to find all events for a given session:
EXPLAIN SELECT * FROM event WHERE session_id = 1;
This time, the database accessed all partitions - partition pruning was not used. In this query, the database has no way of eliminating partitions, so it had no other choice but to scan all partitions to look for matching events.
Local Indexes
Getting events for a specific session is fairly common, so it needs to be fast. To make things fast in databases you should just create an index, right?
CREATE INDEX event_session_ix ON event(session_id);
Using an index is faster than scanning the entire partition, but the database is still forced to scan through all of the partitions. Right now there are only two partitions, but if the table had a hundred partitions, this query would be like querying a hundred tables!
Global Indexes
Another approach to indexing partitioned tables is to create a single index that spans multiple partitions. This is called a global index. Unfortunately, as of version 19, PostgreSQL does not support global indexes on partitioned tables.
Pruning on Non-Partition Key Columns
The events table is partitioned by timestamp, so queries by timestamp can benefit from partition pruning. However, there are still many situations where you want to query by session ID. At this point you reached the limit of what the database can just do out of the box, and you need to tap into your domain expertise and knowledge of the data:
- The events table is append only: no updates to the table, events are immutable.
- Session IDs are generated sequentially: session IDs increment over time.
- Sessions are short lived: a normal session is usually no longer than a couple of minutes or hours.
Session ID is strongly correlated with the timestamp. This means it should be possible to identify a distinct range of session IDs for each partition.
Talking to the Optimizer
The only information the optimizer can rely on, is information that is guaranteed to always be correct. In databases, to guarantee that something is always correct, you use a constraint. Check constraints can be used to communicate information about your data to the optimizer.
To check if you can influence the optimizer, add a simple check constraint on each partition to enforce a specific range of session IDs:
ALTER TABLE event_y2025 ADD CONSTRAINT event_y2025_session_id_range
CHECK (session_id between 1 and 4320);
ALTER TABLE event_y2026 ADD CONSTRAINT event_y2026_session_id_range
CHECK (session_id between 4320 and 10000);
Now to see if the database can actually use the check constraint to eliminate entire partitions, query events for session with ID 1000:
EXPLAIN SELECT * FROM event WHERE session_id = 1000;
Amazing! With the check constraint in place, the database was able to eliminate the partition for 2026. The database ended up scanning only one partition.
The constraint_exclusion Parameter
This pruning mechanism is controlled by the parameter constraint_exclusion. Constraint exclusion is on by default for partitioned tables. The database will use any check constraint you have on a partitioned table to achieve pruning.
Introducing Outliers
Unfortunately, reality is usually not that tidy! What if some sessions become days or weeks long? This can introduce outliers into the ranges. If you create check constraints based on these ranges, any session ID between 1 and 4320 will hit both the 2025 and the 2026 partitions.
Handling Outliers
Inspired by the multi-minmax BRIN index operator, adjust the check constraint to use multiple ranges:
ALTER TABLE event_y2026 ADD CONSTRAINT event_y2026_session_id_range
CHECK (session_id BETWEEN 1 AND 1 OR session_id BETWEEN 4320 AND 10000);
Notice the check constraint for 2026 now includes two ranges - one for [1, 1], and another for [4320, 10000]. This means values between 2 and 4320 will no longer have to query the second partition.
Gaps and Islands
So far you achieved pruning on non-partition key columns and created a mechanism to handle potential outliers. The only thing left is to identify the ranges, a classic "gaps and islands" problem. You can parameterize the query and have it generate the command to create the check constraint.
The Backstory
Earlier this year I attended Django Con EU in Athens to give a talk. I found it most interesting how some speakers used check constraints to achieve pruning when querying large partitioned tables by non-partition key columns. I was mostly interested in how they handle outliers. I suggested using a check constraint on a multirange type, but realized those don't work for pruning. Exploring a bit further led me to try multiple simple conditions joined with an OR.
Final Thoughts
Choosing the right partition key is very challenging. One of the reasons it is so difficult is that the partition key is used for pruning, and unless all queries are using it, you need to make a compromise. Using constraint exclusion on non-partition key columns opens up a whole new way to gain pruning. If your data follows a predictable pattern, the compromise isn't so bad and deciding on a partition key becomes a bit easier.
Beyond Redaction: Anatomy of a Privacy-Safe Data Platform
True privacy engineering requires governing data usage and proving compliance at the point of use, rather than just redacting values.
Deep dive
- Privacy controls must be selected based on the specific utility required (e.g., deduplication vs. aggregation).
- Deterministic tokenization is useful but pseudonymous; it does not eliminate re-identification risk.
- Classification is an ongoing, versioned control, not a one-time setup.
- Policy-as-data allows for simulation, versioning, and rollback.
- Evidence should link policy version, request, transformation, and enforcement logs in an auditable chain.
- LLM applications require guardrails at the point of retrieval, not just the point of output.
Decoder
- Deterministic Tokenization: A process where the same input value consistently maps to the same token within a specific domain, allowing for data joins without exposing raw identifiers.
- Pseudonymization: A data processing technique that replaces private identifiers with artificial identifiers, reducing risk while still allowing for data linkage.
- Canonicalization: Converting data into a standard format so that equivalent values are processed identically.
Original article
Beyond Redaction: Anatomy of a Privacy-Safe Data Platform
The hard problem is not making personal data disappear. It is preserving the minimum useful properties for an allowed purpose, limiting who can link the data, and producing evidence that the controls actually ran.
The most useful question to ask of a privacy platform is not “Can it hide this column?” Almost every platform can. Ask instead: what property must this recipient retain, for which permitted purpose, and what evidence will prove that the platform enforced the decision?
That framing changes the architecture. A data scientist may need stable equality to deduplicate records. A support agent may need a governed path to re-identify one customer. A partner may need aggregates but must not be able to correlate its copy with another partner’s. An engineer provisioning a test environment may need intact foreign key constraints but no production identities. Those are different jobs. A single control called “mask” cannot answer all of them safely.
Redaction, encryption, tokenization, governed views, aggregation, synthetic data, and clean-room-style access are not competitors in a feature checklist. They are controls with different privacy and utility properties. The mature design selects among them deliberately, then makes the decision inspectable.
One terminology point matters throughout this article: a deterministic token is usually pseudonymous, not automatically anonymous. It can lower exposure while retaining the ability to link records; depending on the recipient, auxiliary data, and access to the key or vault, it may remain personal data under privacy law. That is useful—not a failure—but it means “PII-free” is usually too strong a claim.
This is a technical reference architecture, not legal advice. Legal and privacy teams must review each production policy against the organization’s jurisdictions, contracts, and processing purposes.
TL;DR: Match the Control to the Utility
Need to join approved internal tables?
Use purpose-bound deterministic tokenization. It preserves equality inside the approved domain while keeping raw identifiers out of the analytical copy.
An external partner needs insight?
Use aggregation, a protected query, or a clean-room workflow. These approaches deliver useful results while reducing direct linkability and release risk.
Authorized staff need to re-identify a person?
Use vault-backed reversible tokenization. It makes recovery permissioned, purpose-bound, and auditable.
Does an auditor need proof of a release?
Use a signed manifest plus a protected audit trail. Together, they connect the artifact to its policy, transformation, approvals, and evidence of enforcement.
An LLM or RAG workflow may expose data?
Use retrieval authorization plus output guardrails. Enforce access outside the model and check sensitive output before release.
The five-stage pipeline: discover, authorize, protect, use, prove
1. Discover and classify candidates—not certainty
Discovery begins with metadata: connectors, schemas, column names, lineage, ownership, and tightly controlled sampling. A practical classifier layers cheap signals over expensive ones:
- Column-name and metadata heuristics quickly find well-labeled fields.
- Pattern recognizers find structured identifiers, including region-specific forms.
- NLP and contextual analysis identify names, addresses, and free text that do not match a regex.
The output should be a set of candidates: data type, sensitivity tier, confidence, evidence, recognizer version, and review state. A boolean is_pii loses the uncertainty that operators need. Low confidence may block a high-risk export, route a field to human review, or narrow the downstream purpose; it should not silently become “not sensitive.”
Recognizer count is a weak buying signal. Ask what runs by default, which models or language packs are optional, what data leaves the environment during analysis, and how the system measures false positives and false negatives on your schemas. Discovery is important, but it is not proof that an output is free of personal data.
There is a further operational trap: classification drifts. New fields arrive, owners rename columns, free-text use expands, and upstream sources change their formats.
Treat classification as a versioned, recurring control rather than a one-time migration.
A useful platform records the scan scope and timestamp, compares the latest classification with the last approved state, and sends material changes to a review queue. Without that loop, the policy engine makes precise decisions based on stale assumptions.
2. Authorize the use, not merely the field
Classification tells us what a value may be. Authorization determines whether a particular actor may use it at this time. Good policy evaluation considers at least:
- data class and sensitivity;
- principal, role, and tenant;
- declared purpose and retention window;
- recipient and destination;
- jurisdiction, contract, and approved legal basis;
- consent or opt-out state where applicable; and
- The required control and approval path.
Consent is one input, not a universal switch. The practical pattern is policy-as-data with versioning, approval, simulation, and rollback.
A useful result is not just “allow” or “deny,” but: allow this role to use a pseudonymous join key for fraud analysis until this date; deny raw identifier export; record the decision and policy version.
Enforce at the point of use
The policy engine should express a decision; the platform should enforce it at a dependable point in the data path. This separation also makes change management safer. The lifecycle is propose → simulate → approve → enforce → verify → rollback. Simulation should answer concrete questions before a policy goes live: which tables, columns, users, and jobs would change; which scheduled workloads would fail; and whether a new rule would materially raise or lower exposure.
3. Select the smallest control that preserves the required utility
The distinction that matters is not “redaction versus tokenization.” It is which property of the original value the recipient truly needs.
Redaction, therefore, remains a valid privacy strategy. Use it when no downstream utility exists. The mistake is presenting it as sufficient for every purpose—or treating a join-preserving token as if it automatically makes sharing safe.
Control selection should also reflect the recipient. A data scientist working inside a controlled tenant may need a stable token. An external partner may instead need aggregates, a protected query interface, or a narrowly scoped clean-room workflow. The policy can therefore drop the same field in one export, tokenize it in another, and grant access through a governed view in a third. Privacy architecture is a decision system, not a permanent label attached to a column.
Deterministic tokenization: preserve equality, bound linkage
Deterministic tokenization is powerful because it can preserve equality: the same canonical input produces the same token inside an approved domain. Two tables can then join without carrying the direct identifier alongside the analytical copy.
def token_reference(value, tenant_id, entity_type, purpose_domain, key):
canonical = canonicalize_by_type(value, entity_type)
message = canonical_json({
"version": 1,
"tenant": tenant_id,
"entity": entity_type,
"purpose_domain": purpose_domain,
"value": canonical,
}).encode()
mac = hmac.new(key, message, hashlib.sha256).digest()
return "tok_v1_" + base64.urlsafe_b64encode(mac[:20]).decode().rstrip("=")
This is a design sketch, not a drop-in cryptographic service. Production code needs keys from a managed KMS or HSM, key identifiers and rotation, authenticated service boundaries, telemetry that does not log the input, explicit token-format contracts, and collision detection appropriate to the token length and scale.
Tenant isolation belongs in the same design, not as a metadata afterthought. Derive or select keys by tenant and purpose, bind tenant and entity context into the token request, verify the caller’s tenant before the lookup, and scope every vault read and write.
Three modes, three different promises
Irreversible pseudonymization uses a keyed deterministic reference with no recovery path. Use it when an approved use needs equality but excludes re-identification.
Reversible tokenization normally needs a vault. One sound pattern maps an opaque, stable token to an encrypted original value. Detokenization is a privileged workflow: strong authentication, a purpose check, perhaps dual approval, a rate limit, and an immutable audit event.
Per-recipient tokens add a recipient or purpose domain. This prevents two recipients from directly correlating records by token equality while preserving joins inside each recipient’s domain.
Encryption, format preservation, and the names that must stay honest
- A hash or HMAC is one-way. It is not encryption.
- AES-GCM provides authenticated encryption when implemented with sound key and nonce management; it is not format-preserving.
- Format-preserving encryption (FPE) retains a constrained output format and can help retrofit legacy systems, but it is still encryption and may preserve properties that create re-identification risk.
- SQL substring replacement or repeated characters are masking, not FPE.
Safe exchange is a controlled release, not a file write
Teams often overclaim the export stage, even when they apply sensible controls. A safer release workflow is:
- Authorize the recipient, purpose, destination, and retention period.
- Transform only the approved fields and preserve only the properties the recipient needs.
- Re-scan with versioned detectors and block releases on policy-defined findings.
- Run a quality check: referential integrity, token-domain consistency, and expected row/column counts.
- Produce a signed manifest with the file hash, transformation and policy versions, detector configuration, findings summary, approver, and expiry.
- Deliver through a revocable access channel where possible, then record receipt and revocation events.
Evidence first: a hash chain is a building block, not a guarantee
Evidence connects policy to reality: policy version → request → decision → transformation → enforcement result → delivered artifact. That lineage is more useful than a compliance dashboard because it answers a concrete audit question about a concrete event.
A credible design adds controls such as:
- write-once or independently held storage;
- signatures and externally verifiable checkpoints;
- separation between the audited service and the log store;
- time synchronization, retention rules, access monitoring, and tested verification; and
- Periodic evidence review by someone other than the system owner.
The AI boundary: output scanning is necessary, but not sufficient
The safer design applies controls before, during, and after generation:
- retrieve only documents the requesting principal may access;
- enforce tenant and purpose filters outside the model;
- Minimize sensitive content before it enters prompts where possible;
- treat tool results and model output as untrusted until validated;
- restrict tool egress and log the exact data supplied to the model; and
- Continuously test prompt injection, cross-tenant retrieval, and sensitive-output failures.
What to test in a technical evaluation
- Utility: Can two approved datasets join on a stable pseudonym while direct identifiers stay out of the analytical copy?
- Bounded linkage: Does the same value produce different tokens for two recipients, and can the recipients still join only within their own domains?
- Governed recovery: Who can detokenize, for what purpose, with what approval, rate limit, and evidence?
- Release assurance: Show the policy decision, transformation version, detector result, signed manifest, expiry, and revocation for one export.
- Tenant isolation: Attempt a cross-tenant read, a tokenization request, and an evidence lookup.
- AI resistance: Demonstrate that unauthorized documents cannot enter retrieval and that prompt-injected tool output cannot exfiltrate data.
The bottom line
Redaction remains a valuable data-minimization control. Deterministic pseudonymization is valuable when an approved use genuinely needs stable equality. Encryption, governed views, protected query interfaces, and disclosure controls each solve other parts of the problem. None creates privacy by itself.
The architecture becomes credible when it makes three things explicit: the utility the policy allows a recipient to retain, the linkability that remains, and the evidence that proves the system applied the policy.
Better tools made Copilot code review worse. Here's how we actually improved it
Refining Copilot instructions to prioritize local context over full-repo browsing cut review costs by 20% while maintaining quality.
Decoder
- Agentic system: A software architecture where an AI agent can perform tasks, make decisions, and use tools to achieve a specific goal.
Original article
Full article content is not available for inline reading.
ClickHouse on Docker Hardened Images
ClickHouse is moving to hardened Docker images, eliminating unnecessary packages to drop vulnerability counts to zero while preserving database functionality.
Deep dive
- Hardened images reduce the attack surface by removing tools like wget, curl, and package managers.
- Minimal images decrease the number of CVEs reported by scanners like Trivy or AWS ECR.
- The database remains binary-compatible, meaning config and volume mounts do not need changes.
- Debug variants or 'docker debug' allow for temporary tool attachment during troubleshooting.
Decoder
- CVE (Common Vulnerabilities and Exposures): A list of publicly disclosed cybersecurity vulnerabilities.
- SLSA (Supply chain Levels for Software Artifacts): A framework for ensuring the integrity of software artifacts through the build process.
Original article
TL;DR
ClickHouse is now available on Docker Hardened Images: stripped-down, security-hardened builds of the ClickHouse stack, including the server image, ClickHouse Keeper, the Kubernetes Operator and its Helm chart, and the metrics exporter, all built to pass enterprise security scans by shipping only what each component needs to run. Everything about how ClickHouse runs stays the same, only the packaging around it changes.
Deploying ClickHouse anywhere
For millions of developers, the fastest way to try ClickHouse is a single command:
docker run -d --name my-clickhouse-server \
--ulimit nofile=262144:262144 \
clickhouse/clickhouse-server
With that you have a running columnar database that can aggregate billions of rows in real time. That low barrier to entry is deliberate and the adoption of the clickhouse/clickhouse-server image has passed 100M+ pulls on Docker Hub.
For a large part of our community, that first docker run is their entry point to ClickHouse, and getting started is the easy part. The friction shows up later. Once you move past experimentation and small workloads, the command that runs on your laptop has to run at enterprise scale: inside a pipeline, behind a security team, with a vulnerability scanner monitoring everything.
This post covers why the standard ClickHouse Docker image gets flagged in those scans (the findings come from unused packages in the Ubuntu base, not from ClickHouse), and how the Docker Hardened Image passes them while running exactly the same database.
From first query to production
Every container image is really two components stacked together: the application you want, and a base operating system layer it runs on. At the time of writing, the standard ClickHouse image is built on Ubuntu 22.04. That base brings convenience, a familiar environment, a shell, debugging tools, but it also brings dozens of packages ClickHouse never uses: Perl, wget, apt itself, and a long tail of transitive dependencies that exist only because Ubuntu ships them by default.
CVEs live in the base image, not in ClickHouse.
This matters a lot in an enterprise pipeline, because security scanners such as Trivy, Grype, and the built-in AWS ECR scanner inventory every package in the image, whether the application loads it or not. Some of those Ubuntu packages carry known CVEs with no upstream fix. For example, wget has shipped with CVE-2021-31879 unpatched since 2021. The scanner reports the findings, the security team blocks the deployment, and they are right to do so: the vulnerabilities are real, even if the vulnerable tools never run.
The result is a frustrating loop that many teams will recognize. The database works, but the deployment is blocked anyway. Days go into investigating findings and writing risk exceptions for packages ClickHouse never touches, and the exceptions often get rejected regardless.
A smooth developer experience in enterprise workloads
In April 2026, Docker added clickhouse-server to its Hardened Images catalog. Docker Hardened Images (DHI) start from a different question: what does ClickHouse actually need to run?
The DHI clickhouse-server image ships a minimal base with no package manager and no network tools like wget or curl, runs as a non-root user out of the box, and carries SLSA Level 3 provenance, cryptographic proof of what went into the build. Docker's security team maintains it and actively patches CVEs. Rather than patching the wget vulnerability, DHI removes wget entirely.
The difference shows up in the scan results. Docker's own Scout comparison found the standard image carrying 8 medium and 11 low severity findings across 111 packages. The DHI image carried 0 medium and 14 low, with every remaining finding in core libraries like glibc and openssl where no fix exists on any distribution. The findings that block deployments, the ones in unnecessary utilities, are gone because the utilities are gone.
From ClickHouse's perspective, nothing changes. Your volume mounts and config files carry over untouched. Moving to the hardened image takes one changed line:
# standard image
docker run -d --ulimit nofile=262144:262144 \
clickhouse/clickhouse-server
# hardened image
docker run -d --ulimit nofile=262144:262144 \
-e CLICKHOUSE_PASSWORD=mysecretpassword \
dhi.io/clickhouse-server:26.2-debian13
Note: CLICKHOUSE_PASSWORD is what makes ClickHouse reachable over the network. Without it, the default user is restricted to localhost.
With major security improvements come minor inconveniences: DHI images live in a separate registry, so you mirror the image to your organization's Docker Hub namespace once and authenticate to dhi.io.
For the full walkthrough, including Kubernetes configuration, the metrics exporter, debugging without the usual tools, and a migration checklist, read Docker's companion post: From Security Blocked to Prod Ready: ClickHouse on Docker Hardened Images.
Developer experience and security are not a tradeoff
At first this looks like a tradeoff: keep the shell, package manager, and network tools and the container is easy to debug but harder to secure, while stripping them out gives you the reverse. But that tension only exists if it all has to happen in one image, and it doesn't. For local development and debugging, Docker Hardened Images (DHI) ships a dev variant with the extra tooling, and docker debug attaches a full toolset to the hardened image temporarily without rebuilding it. Because you harden what ships to production rather than what runs on your laptop, you keep your debugging tools in development and the smaller attack surface in production.
The payoff is a shorter conversation with your security team. Instead of spending days arguing that each flagged CVE sits in a package ClickHouse never loads, you deploy an image where those packages don't exist, with build provenance to back it up. Nothing about the database itself changes. The speed, scale, and cost efficiency that made you choose ClickHouse all carry over, and what gets simpler is the security approval.
Docker Hardened Images (DHI) are a hardened build of the open-source clickhouse-server image, for teams that self-manage ClickHouse and secure the container themselves. If you run on Kubernetes, the ClickHouse Kubernetes Operator automates deployment and management, and it ships as a hardened image and Helm chart in the DHI catalog too, alongside ClickHouse Keeper and the metrics exporter.
If you'd rather not run your own infrastructure, ClickHouse also offers managed and self-deployed options: ClickHouse Cloud runs everything for you, Bring Your Own Cloud puts that managed service inside your own cloud account, and ClickHouse Private and ClickHouse Government are self-deployed builds with FIPS 140-3 and further hardening for the strictest compliance environments. Whichever you pick, it's ClickHouse underneath. What differs is how much of the operational work you keep and how much you hand off.
Try it out yourself
Whether you are typing your first docker run or shipping into a locked-down enterprise pipeline, there is a ClickHouse image that fits.
Find clickhouse-server in the Docker Hardened Images catalog, and read Docker's full guide for setup details. You can reproduce the scan comparison yourself in two minutes:
docker scout quickview clickhouse/clickhouse-server:latest
docker scout quickview dhi.io/clickhouse-server:26.2-debian13
And if you'd rather skip image decisions entirely, ClickHouse Cloud runs everything for you.
Get started today
Interested in seeing how ClickHouse works on your data? Get started with ClickHouse Cloud in minutes and receive $300 in free credits.
We benchmarked coding agents on our own internal tasks at Databricks and learned a lot!
Databricks' internal benchmark of coding agents reveals that smaller, open-source models like GLM 5.2 now rival top-tier commercial offerings in real-world engineering tasks.
Deep dive
- Databricks created custom internal benchmarks to avoid the 'over-tuning' common in public datasets like SWE-Bench.
- GLM 5.2 emerged as a high-performing open-source agent model across diverse languages.
- Simple, lightweight harnesses often outperform vendor-provided harnesses by minimizing unnecessary tokens passed to the LLM.
- Model selection should be based on task-specific cost-per-task rather than per-token pricing.
- The team developed 'Omnigent,' a meta-harness for composing and swapping agents, to manage complex multi-step workflows.
Decoder
- Harness: A software layer that manages the interface between a developer's codebase and an LLM, handling task orchestration, context management, and output parsing.
- SWE-Bench: A common benchmark used to evaluate how well AI models solve GitHub issues by writing and testing code.
- Meta-harness: A higher-level abstraction that allows developers to chain or switch between different individual agent harnesses within a single workflow.
Original article
We benchmarked coding agents on our own internal tasks at Databricks and learned a lot!
There are many surprising opportunities to lower cost and increase quality, and many models including open source ones are truly competitive now.
Why did we build an internal coding benchmark? Public benchmarks like SWE-Bench are often over-tuned for, so we took real tasks our engineers did and curated test suites for them to see which agents can solve them end-to-end.
These are the results on OUR sample of OUR codebase, so they are not meant to be comprehensive, but we think many companies can do a similar internal benchmark. Several findings immediately stood out:
1) Many models are now competitive at the top tier, including open source.
2) GLM 5.2 in particular was a major step forward in open source coding agent performance, even in our own codebase that is VERY different from SWE-Bench and TerminalBench (lots of Scala, Go, Rust, Java, TypeScript, Protobuf, Jsonnet, etc).
3) Harnesses make a huge difference in cost-performance. The very simple Pi harness got the same success rate as harnesses from the LLM vendors with Opus and GPT 5.5, but at 2x less cost! Seems to be mainly due to smaller inputs to the LLM.
4) Cheaper per-token does not imply cheaper per-task. For example, Sonnet 5 costs less per token than Opus 4.8 but used more tokens, resulting in higher cost and lower quality.
Read more in the blog how we built the benchmark and what we're doing with the findings. This is partly why we built Omnigent as a "meta-harness" to let developers switch and compose agents, and Unity AI Gateway to analyze and gate LLM usage centrally.
Awesome DuckDB (Website)
The Awesome DuckDB repository serves as the definitive, community-maintained directory for the rapidly expanding ecosystem of DuckDB-powered tools, extensions, and integrations.
Deep dive
- Categorizes resources into client APIs, UI/IDE support, and serverless architectures.
- Highlights DuckDB's use as an analytical backbone in tools like Rill, Hex, and Evidence.
- Lists community-built extensions for specialized tasks like graph analysis, vector search, and cloud storage connectivity.
- Tracks the evolution of DuckDB's ecosystem including new features like the Quack protocol and DuckLake file format.
Decoder
- In-process database: A database engine that runs inside the application's memory space rather than as a separate client-server process, eliminating network latency.
- DuckDB-Wasm: A version of DuckDB compiled to WebAssembly, allowing high-performance analytical SQL queries to run directly in a web browser.
- Lakehouse: An architecture combining the low-cost, scalable storage of a data lake with the data management and ACID transaction features of a data warehouse.
Original article
Full article content is not available for inline reading.
Craft still matters, but it's about outcomes
Design craft has shifted from executing pixel-perfect artifacts to exercising human judgment and curating AI-generated outputs.
Deep dive
- The production layer (wireframing, boilerplate) is collapsing in value.
- Human judgment is the new differentiator in a commodity-AI world.
- Research must be a continuous, weekly habit to avoid 'shipping fiction'.
- Tacit knowledge is useless to AI; it must be written down as explicit rules and anti-patterns.
- Scaffolding (like DESIGN.md) allows AI agents to stay within your constraints.
- AI-assisted work requires more rigorous review, as errors are often subtle rather than loud.
Decoder
- Tacit knowledge: Unspoken expertise or 'gut feeling' that is difficult to formalize or transfer, often built through years of pattern recognition.
- Design token: A system for storing visual design attributes (e.g., color, spacing, typography) as code, ensuring consistency across platforms.
Original article
Full article content is not available for inline reading.
Design-System Maturity: A 6-Dimension Framework
A design system's health is better measured by a six-dimensional radar chart than a linear progression model.
Deep dive
- Maturity is not a ladder; design systems can regress due to organizational shifts.
- Organizational alignment (funding and leadership) is the most critical foundation.
- Infrastructure is often the most visible but least important factor for long-term health.
- Governance models must exist to handle exceptions and contributions.
- Support involves active advocacy to make components discoverable and usable.
- Assessing dimensions as a group builds shared ownership (the IKEA effect).
Decoder
- DesignOps: The set of processes, roles, and technologies designed to scale design teams and maintain consistency across products.
Original article
Design-System Maturity: A 6-Dimension Framework
Design-system maturity frameworks often follow a linear progression: you start by building components, move to driving adoption, hit the growing pains of scale, and eventually reach a steady state of governance and evolution.
But design systems don't mature in a straight line — the reality of design-system work is much messier and more multifaceted than a ladder can capture. This article proposes an alternative that treats design-system maturity as a multidimensional assessment rather than a sequential journey.
Where Linear Models Fall Short
While sequential maturity stages help visualize how systems evolve over time and establish broad milestones that organizations can use to benchmark progress, the linear model flattens the reality of design-system work.
Maturity isn’t always forward progress. Linear maturity models typically frame growth as a steady climb toward an ideal end state. In reality, many design systems regress in ways out of their builders’ control: organizations restructure, business priorities shift, budgets get cut, and so on. A mature, well-adopted enterprise design system may suddenly face foundational challenges again after a merger introduces a second system with incompatible tools, tokens, or workflows. Linear models leave little room for regression, stagnation, or scenarios where a system is deliberately kept lean because it aligns with the organization’s scale.
There is no universal narrative of system growth. A 10-person startup and a 10,000-person enterprise can both have a mature design system, but the conditions that define maturity can differ significantly. Linear models often assume a single destination for maturity, when, in reality, maturity is contextual to organizational scale, structure, and culture.
Adoption is never complete. Linear models typically place adoption after the initial build. In practice, driving adoption is an ongoing concern. Teams at every stage wrestle with it: early teams convincing their first subscribers, maturing teams maintaining trust during major version changes, established teams fighting adoption erosion when priorities shift. Adoption is an ongoing organizational challenge that persists throughout the system’s lifecycle.
The 6 Core Dimensions
Design-system practice is multifaceted. When we spoke to teams across organizations, that breadth was reflected in how their systems matured differently: not along a single axis, but across several dimensions at once, and almost never evenly.
Through our research, we identified 6 core design-system-maturity dimensions that reflect the holistic view of the design-system practice:
- Organizational alignment: How well the design system is positioned, funded, and championed within the broader organization
- Team effectiveness: Whether the design-system team has the capacity, composition, leadership, and collaborative practices to sustain the system long-term
- Infrastructure robustness: The quality and completeness of the system's deliverables, including components, tokens, documentation, tooling, and underlying visual and technical foundations
- Governance: The operating model for making decisions, managing contributions, and maintaining coherence as the system and organization evolve
- Support: The active investment the design-system team makes in equipping design-system users to find, understand, and succeed with the system
- Adoption: How broadly and deeply teams across the organization actually use, trust, and rely on the design system
Plot where your design system lies on each of these dimensions, and the resulting shape becomes the system's profile — a snapshot of the design system's health at a given point in time. Dimensions are independent of each other. The design system’s profile provides diagnostic insight into its maturity, and signals opportunities for improvement: imbalances, dependencies, and trade-offs.
1. Organizational Alignment
Of everything that determines whether a design system endures, organizational support may be the most foundational. A system may survive incomplete documentation or loosely defined governance for a while, but it cannot survive an organization that has decided it isn't worth the investment.
This dimension includes:
- Leadership sponsorship: Is there an executive sponsor who advocates for the system and protects its priorities?
- Funding stability: Is the system resourced through a dedicated, predictable budget, or does it survive on borrowed time and goodwill?
- Strategic positioning: Is the system understood as a core product or shared infrastructure, or as an optional service that teams can take or leave?
- Crossfunctional buy-in: Is the design system backed across product, engineering, brand, and other partner teams?
2. Team Effectiveness
Whether a design system can sustain and scale over time depends heavily on the effectiveness of the team behind it. Even a strong design system will falter if the team behind it lacks the appropriate mix of skills, adequate resourcing, or clear decision-making structures.
Team effectiveness covers:
- Capacity and sustainability: Is the team appropriately sized and operating at a sustainable pace?
- Crossfunctional expertise: Does the team include or have access to design, engineering, content, accessibility, and product management?
- Collaboration and team dynamics: Does the team have strong design–engineering partnerships and effective ways of working together? Is there sufficient trust and psychological safety to raise concerns and challenge decisions?
- Staff wellbeing: Are team members motivated, supported, and able to do their best work over time?
3. Infrastructure Robustness
This dimension is about the artifact itself: what the design-system team builds, ships, and maintains. It is often the most visible dimension of a design system, as it corresponds directly to the artifacts teams interact with day to day.
Infrastructure robustness evaluates:
- Component coverage, consistency across platforms, and parity between design and code implementations
- The structure and scalability of foundations and design tokens
- The completeness, clarity, and usability of documentation
- Tooling quality and overall developer experience
- Content standards and baked-in accessibility practices
4. Governance
A design-system team needs a well-defined operating model to sustain its practice and standards: Who decides if a component gets added? Who reviews a breaking change before it ships? What happens when a product team needs something the system doesn't have yet? Governance answers these questions. It lays out who does what, when, and how.
A design system’s governance practice encompasses the structures, policies, and workflows that shape how the system operates and evolves. This includes:
- Contribution models: How do product teams contribute to the system, and what structure guides that participation?
- Deviation management and decision making: How are exceptions handled when a team needs something the system doesn't offer? Who decides what enters the system, and how are conflicts resolved?
- Flexibility philosophy: How does the system balance product expression against brand consistency?
- Versioning and release strategy: How are changes versioned, communicated, and shipped without disrupting the teams that depend on them?
- Prioritization frameworks: How does the team decide what to build, fix, or improve next?
5. Support
A well-architected system doesn't guarantee that teams can use it. A component can exist in the library and still be practically invisible to product designers who are unaware of it, cannot find it, or are unsure how to apply it. This dimension evaluates the active effort directed at making the system discoverable, understandable, and usable in real product work.
Support includes all the following aspects:
- Onboarding and learning support (getting started, education, training)
- Responsive support (help channels, office hours)
- Communication and visibility (changelogs, roadmap, release notes)
- Advocacy and champions programs, as well as the feedback loops that keep the team connected to the real needs of system users.
6. Adoption
While adoption is one of the most common measures of a design system's success, usage alone doesn't reveal whether teams trust it, use it well, or quietly work around it. This dimension examines how widely the system is used, how effectively it is applied in product work, and how deeply teams trust and depend on it.
Adoption measures a few distinct layers that are often conflated:
- Usage: Do teams have access to the system, and are they actively using it?
- Conformance: Are teams applying the system correctly and consistently, rather than creating unintended variations or bypassing established patterns?
- Trust: Do teams view the system as reliable, well-maintained, and capable of evolving to meet their needs?
Assess Your Design-System Practice
Conduct a design-system maturity assessment to understand how your design system is doing. The assessment works best as a team exercise, as different roles will bring different perspectives to the system.
Step 1: Choose Your Evaluators
Aim for 4–8 evaluators representing different vantage points:
- Design-system team members across disciplines (design, engineering, product, content)
- Product-team representatives who use the system day-to-day
- Key stakeholders or sponsors who can share perspectives on the system’s organizational alignment
Step 2: Score Independently
Each evaluator scores the design system on all six dimensions, using a 1–5 scale.
| Score | Level | What It Means |
|---|---|---|
| 1 | Absent | No intentional structure or ownership is in place. Efforts are ad hoc, if they occur at all, and largely depend on individual initiative. |
| 2 | Emerging | Some awareness or early effort exists, but practices are inconsistent, informal, or difficult to sustain. |
| 3 | Functional | A defined approach supports routine needs, but the system remains fragile under change, scale, or increased complexity. |
| 4 | Strong | Practices are consistent, clearly owned, and reliably applied. Outcomes hold steady across most operating conditions. |
| 5 | Exceptional | The approach is mature, continuously improving based on measured outcomes, and resilient through major organizational changes. |
Step 3: Triangulate and Align
Once all evaluators have completed their assessment, bring the group together to discuss. Start with alignment. Dimensions with narrow score ranges reflect a shared understanding. Next, focus on areas of divergence. For dimensions with a larger range of scores, use the gap as a prompt for discussion.
Step 4: Plot the Shape
After aligning the scores with your team, plot them on a hexagonal radar chart and connect the points to form the team's profile. Read the shape and look for the following patterns: Shape Area, Symmetry, Valleys, Spikes, and Tension between strengths and weaknesses.
Step 5: Benchmark and Reassess Regularly
A maturity profile is a snapshot, not a permanent diagnosis. Reassess and report out on a regular cadence — typically quarterly, or following meaningful organizational shifts.
Alignment Over Assessment
Beyond the scores themselves, one of the biggest advantages of conducting the assessment is creating the time and space for the team to align. In many cases, this shared discussion is more impactful than the scores produced.
Summary
Managing a design system is an ongoing practice that evolves alongside the teams, products, and priorities it supports. Components may be the most visible artifact of a system, but they are rarely what determines whether the system succeeds or fails.
What matters just as much is whether teams trust it enough to rely on it, whether governance holds steady through change, whether organizational support persists when competing priorities emerge, and whether the people behind the system are resourced to sustain and evolve the work.
Viewed through this lens, design-system maturity is not a fixed state or a single metric to optimize, but a dynamic balance of multiple dimensions. A healthy system is not simply one that grows larger or older, but one that can remain coherent, resilient, and useful as the organization evolves.
Loading UI Gallery (Website)
This open-source collection provides dozens of accessible CSS and React loading spinners, animations, and skeleton states for modern web applications.
Original article
Your users deserve a loading state
A curated collection of spinners, loaders and animations for your next project. Free and open source, forever.
We're always looking for new components to add to the library. If you have an idea for a component, please let us know.
Making Images Accessible
Accessible image implementation requires human judgment to determine if an image is decorative or vital to content, regardless of whether alt tags exist.
Deep dive
- Always include the
altattribute on `` tags, even if it is left empty. - Use empty
alt=""for decorative images or background textures. - Use
aria-hidden="true"for icons that are already explained by nearby text. - Alt text should describe the image's purpose within the context of the content, not just the visual contents of the image.
- Leverage AI for generating alt text suggestions, but always perform a manual review to ensure accuracy and relevance.
- Testing must combine automated scanning with human context-aware verification.
Decoder
- WCAG Success Criterion 1.1.1: A standard within the Web Content Accessibility Guidelines ensuring all non-text content has a text alternative.
Original article
When people think about accessible images, they often think about alternative text, or alt text. While alt text is an important part of image accessibility, creating accessible images involves more than writing a description and adding it to an image.
Every image needs an alt attribute
Before deciding what alternative text an image needs, we need to understand the HTML requirement behind it. Every <img> element must have an alt attribute. That’s not just an accessibility best practice. It’s required by the HTML specification. Whether the image needs a detailed description, a short label, or no description at all, the attribute itself should always be present.
<img src="image.jpg" alt="text that describes the image">
<img src="image.jpg" alt="">
Both of the images in the code example above are valid ways to add an image to a page. The first important step is to make sure that the alt attribute simply exists.
Decorative images vs. informative images
Great! Now that we have valid HTML in place we need to determine whether or not we need to add a value to that alt attribute. The easiest way to determine whether an image needs alt text is to ask a simple question: If this image disappeared, would the user lose information?
If the answer is no, the image is probably a design element. Decorative flourishes, background textures, divider graphics, and other purely visual assets don’t add meaning to the page. Screen reader users don’t benefit from hearing them announced, so these images should typically have an empty alt attribute.
If the answer is yes, then the image is part of the content and it needs a text alternative. This requirement comes from WCAG Success Criterion 1.1.1: Non-text Content, which requires that all non-text content presented to users has a text alternative that serves an equivalent purpose.
A useful rule of thumb is to keep decorative imagery in CSS whenever possible. Background images, patterns, and other visual treatments are often better implemented as CSS backgrounds. That removes them from the document structure entirely and avoids the question of how they should be announced by assistive technology. Of course, there are times when decorative images end up in the HTML. In those situations, an empty alt attribute tells assistive technologies that the image can be safely ignored.
The special case for icons
Icons usually function as decorative elements. They often reinforce nearby text, add visual interest, or make an interface easier to scan. In those cases, the icon itself does not need to be announced because the surrounding text already communicates the meaning.
But icons can also stand on their own. When an icon is used without visible text, it may be the only visual cue explaining what an element does. In that case, the icon is no longer just decoration. It is communicating information within the interface.
A common example is a search icon. A magnifying glass is widely understood to represent search, so it may appear on its own in a button or navigation area without visible text. Visually, the icon communicates the purpose of the control. For people who cannot see the icon, that same purpose still needs to be available.
In most cases, I still recommend treating the icon itself as decorative. If the icon is added through CSS or included as an embedded SVG, it can be hidden from assistive technologies with aria-hidden=“true” or role=“presentation”. Then the interactive element around it, usually a link or button, should provide the accessible name.
Writing useful alt text communicates the meaning of the image
Once we’ve identified which images need alternative text, the next challenge is writing alt text that actually helps users. Many accessibility guides focus on describing what’s visible in the image. That’s a good starting point, but it’s not always enough. Effective alt text depends heavily on the surrounding content.
Imagine an image of a dog. Without any context, an alt attribute like this might seem perfectly reasonable:
<img src="dog.jpg" alt="A cute puppy jumping" />
But now imagine that image appears in an article about Labrador retrievers. The image isn’t just showing a dog. It’s reinforcing information about the breed. Let’s say our surrounding content is talking about the activity needs of a Labrador puppy.
In that context, something like this may be more useful:
<img src="dog.jpg" alt="A happy Labrador puppy running and playing outdoors" />
The goal isn’t simply to describe the pixels on the page. The goal is to communicate the purpose the image serves within the content. Users who can’t see the image should receive the same meaningful information that sighted users gain from it. Writing good alt text often requires understanding the article, page, or feature the image belongs to. The surrounding content provides context that the image alone cannot.
Beyond automated image accessibility testing
Testing image accessibility presents a unique challenge because some requirements can be verified automatically while others require human judgment. Automated accessibility testing tools are very good at checking for the presence of an alt attribute. They can identify images that are missing alternative text entirely and flag potential violations of WCAG Success Criterion 1.1.1. Some tools can also identify suspicious patterns, such as file names being used as alt text or unusually long descriptions.
What automated tools cannot reliably determine is whether the alternative text is actually useful. Consider the following example:
<img src="labrador-puppy.jpg" alt="Dog" />
An automated testing tool will likely consider this valid because the image has an alt attribute. However, it cannot determine whether the description supports the surrounding content, provides meaningful information, or communicates the image’s purpose to users who cannot see it. This is why manual accessibility testing remains an important part of the development process. Someone needs to review both the image and its surrounding content to determine whether the alternative text provides an equivalent experience.
AI can be a helpful tool during this review process. Modern AI systems can analyze images, consider surrounding content, and suggest alternative text that may better communicate the purpose of an image. However, AI-generated suggestions should be treated as recommendations rather than final answers.
The most effective approach combines automated testing, AI-assisted review, and human judgment. Automated tools can quickly identify missing requirements, AI can help generate and evaluate potential descriptions, and people can determine whether the final alternative text accurately supports the content and user experience.
Accessible images are about communication
Accessible images aren’t just about adding alt attributes. They’re about ensuring that the information conveyed by an image is available to everyone.
That means image accessibility can’t be treated as a final checkbox. It needs to be considered when images are chosen, when they are added to a page, and when the experience is tested.
The best alternative text is grounded in purpose and context. When we understand why an image is there and what it communicates, we can make better decisions about whether it needs to be announced, how it should be implemented, and what users need to know if they cannot see it.
Anthropic Extended Claude Fable 5 Access Again
Anthropic continues to struggle with capacity, repeatedly extending limited access to Claude Fable 5 while OpenAI temporarily removes usage caps for GPT-5.6 Sol.
Decoder
- Fable 5: A high-tier model by Anthropic often used as an advisor to other agentic models.
- GPT-5.6 Sol: The latest model generation from OpenAI, marketed as a high-efficiency solution.
Original article
One of the consequences of GPT-5.6 Sol being clearly a Fable/Mythos class model is that Anthropic have, once again, bumped the date that Fable stops being available in their Claude Max plans:
We're extending Claude Fable 5 access on all paid plans, as well as keeping Claude Code’s weekly rate limits 50% higher, through July 19.
As before, you can use up to half of your weekly usage limit on Fable 5. After that, you can continue using Fable 5 with usage credits, or switch to another model to keep working within your remaining limits.
Anthropic's original rationale for this was compute constraints - they wanted a better idea of both demand and compute availability before committing to keeping the new model cheap for subscribers.
OpenAI appear confident that they won't need to restrict access to GPT-5.6 in the same way. Here's Thibault Sottiaux this morning:
The last 48 hours of Codex and ChatGPT Work have been intense! Three important updates:
- Temporarily removing the 5 hour usage limit restriction for all Plus, Business and Pro plans
- Rolling out changes that will make GPT 5.6 Sol more efficient across the board and that will be reflected in less usage being used so that it can take you further. Exact impact to be quantified and shared
- We hit 6M active users, and are landing a usage reset in the next hour
At this point I think Anthropic should change track and keep Fable permanently available on those plans. OpenAI are winning users simply due to the uncertainty that surrounds Fable access.
Own Your Weights
Companies require a middle-ground infrastructure layer that allows them to fine-tune and own model weights without the overhead of self-hosting.
Decoder
- Weights: The learned parameters of a neural network that define its performance and behavior.
Original article
Own Your Weights
Alex Karp had a pretty spicy segment on CNBC last week talking about a lot of things (many of which took shots at the large AI labs). The part I want to focus...
LLM-as-a-Verifier: A General-Purpose Verification Framework
Researchers are developing sparsity-based training techniques to lower the computational overhead of training large language models.
Decoder
- Sparsity: A technique where a large portion of a model's parameters or connection weights are kept at zero, reducing memory and computation requirements without necessarily degrading accuracy.
Original article
Researchers explore efficient training methods for large language models (LLMs) using sparsity techniques. They aim to reduce computational costs while maintaining model performance. This approach could make training LLMs more accessible for smaller organizations.
5.6 Sol is underhyped for general work
OpenAI's Jason Liu advocates for the underutilized potential of GPT-5.6 Sol in handling cross-application, long-running enterprise workflows.
Decoder
- Agentic: Refers to AI systems designed to operate autonomously, interacting with software tools or APIs to complete multi-step goals.
Original article
5.6 Sol is underhyped for general work
Real work is not just a repo of markdown files and a git repo. High level, high leverage work, whether you're a developer or not, spans crosses email, slack, multiple, documents, multiple tabs in my...
Tencent in Talks to Take Big Manus Stake After Meta Deal Unwound
Tencent is moving to acquire agent startup Manus at a $2 billion valuation following the regulatory collapse of Meta's purchase attempt.
Original article
Tencent is in discussions to buy Manus after Chinese regulators struck down Meta's acquisition. The talks are aimed at securing a deal to unwind Meta's purchase at the same valuation of $2 billion. Manus presents an opportunity for Tencent to gain access to valuable agentic technology at a time when it's ramping up its own AI offerings. Tencent recently launched a prototype agent that could eventually run errands for a billion-plus users across its ecosystem.
OpenAI power consolidates under co-founder Greg Brockman ahead of prospective IPO
OpenAI President Greg Brockman has consolidated control over core product and revenue initiatives following the resignation of Fidji Simo.
Decoder
- Go-to-market (GTM): The strategy a company uses to reach its target customers and achieve competitive advantage.
Original article
- OpenAI President Greg Brockman will continue to oversee the company's products after Fidji Simo officially stepped down from her role.
- Simo, who served as the company's product and business chief, left her position due to chronic illness.
- "I am deeply grateful for all Fidji has done for OpenAI and to advance our mission," Brockman wrote in a post on X.
There's a new second-in-command at OpenAI.
Greg Brockman, the company's president, is officially responsible for OpenAI's most important and profitable projects after Fidji Simo stepped down from her role on Thursday due to chronic illness.
Simo, a former Meta executive and ex-CEO of Instacart, served as OpenAI's product and business chief for about a year, focusing the company's road map and helping it scale. Simo, who was diagnosed with postural orthostatic tachycardia syndrome, or POTS, in 2019, took a medical leave in April, and said Thursday that she would transition to a position as a part-time advisor.
Brockman, an OpenAI co-founder, took over product responsibilities during Simo's absence, and will continue to lead those efforts, according to a source familiar with the company's plans who asked not to be named due to confidentiality. Brockman will oversee OpenAI's ChatGPT product business, as well as its go-to-market teams, enterprise teams and compute initiatives, the person said.
"I am deeply grateful for all Fidji has done for OpenAI and to advance our mission, and for the opportunity to have worked alongside her for the past few years," Brockman wrote in a post on X on Friday.
Reporting directly to CEO Sam Altman, Brockman is under pressure to bring in revenue and justify OpenAI's $852 billion valuation, especially as the company gears up for what's expected to be a historic IPO. OpenAI confidentially filed its prospectus with regulators in June, but the company hasn't disclosed when it plans to debut and is reportedly delaying until next year.
OpenAI is also facing increasingly stiff competition from rivals, including Anthropic, Google and Elon Musk's SpaceX, along with a host of cheaper open-weight models primarily out of China.
ChatGPT's market share fell below 50% for the first time in March, according to a report from Sensor Tower, and OpenAI has been aggressively touting its AI coding assistant, Codex, in an effort to win over more users.
Sarah Friar, OpenAI's finance chief, and Jason Kwon, the company's strategy chief, will report to Altman. The company doesn't plan to hire anyone to replace Simo, the person familiar said.
Brockman co-founded OpenAI alongside Altman and a group of others, including Musk, in 2015. He and Altman have been close allies, and when Altman was briefly ousted from his role as CEO in 2023, Brockman quit the company in solidarity. Both men rejoined OpenAI days later.
"Greg and I are partners in running this company," Altman wrote in a blog post at the time. "We have never quite figured out how to communicate that on the org chart, but we will."
They were also both at the center of a high-profile legal brawl earlier this year. Musk sued Brockman, Altman and OpenAI, alleging they went back on commitments they made to keep the the AI lab a nonprofit.
In federal court in Oakland, California, in May, Brockman testified about the startup's early years and pushed back on Musk's account of events. He was grilled about his personal financial ambitions, his understanding of OpenAI's structure and Musk's involvement at the company.
Musk ultimately lost the case after an advisory jury said he waited too long to sue, a verdict that was immediately adopted by a federal judge.
"I think the tech we are developing is transformative," Brockman said from the witness stand. "This is going to be the most important technological shift in human history."
Cursor is reportedly building a general-purpose AI agent
AI code editor Cursor is reportedly expanding into the broader productivity market with 'Sand,' a general-purpose AI agent for non-technical office tasks.
Original article
It just keeps accelerating: Cursor is reportedly building a general-purpose AI agent to compete with Anthropic’s Claude Cowork, pushing beyond coding into everyday office work.
Internally called Sand, the agent is designed to respond to emails and texts, organize spreadsheets and handle engineering tasks.
Cursor reportedly rolled it out internally in late June, after it began leasing compute from SpaceXAI in April. A public launch is not guaranteed, particularly with SpaceX’s planned $60 billion acquisition potentially changing Cursor’s roadmap.
Sand would be Cursor’s first product built for casual business users rather than developers.
The Future Worth Building Is Human
Thinking Machines argues that future AI must be decentralized, customized, and tightly integrated with human judgment to avoid centralized power traps.
Original article
The mission of Thinking Machines is to build AI that extends human will and judgment.
Artificial intelligence can do more every day, but deciding what it should do is up to us: individuals, organizations, humanity as a whole. These decisions require knowledge and judgment that people acquire through continuous contact with the work, increasingly done alongside AI. Shaping the goals of advanced intelligence is also a continuous process of feedback, learning, and realignment.
Most AI in use today is trained in a handful of places and then frozen. It isn’t shaped by the people it serves, and doesn’t learn much from the work they do together. Extending human will and judgment calls for AIs as diverse and distributed as people themselves are. This is the path we have chosen.
To progress on that path, we are pursuing these technical directions:
- We train strong models, advancing capabilities such as multimodal interaction and customizability. Sharp instruments extend human will, and human judgment needs to shape models that compete on the frontier.
- We build tools that enable people to make AI their own, customizing models to serve their unique needs. This includes the ability to train model weights.
- We develop interfaces that broaden the communication channel between human and machine, allowing personal judgment to continuously influence the work of AI.
- We publish research for the scientific community, because the power to shape AI requires deep understanding of how it’s made.
We believe the future worth building is human — shaped by human knowledge, guided by human will, and decided by human judgment. What follows is the case for that future, and the work we’re doing to bring it about.
Bringing intelligence to knowledge
AI exists to serve the work that we do. This work runs on knowledge of how things are done and what is worth doing, knowledge that is generated continuously by people engaged in the work.
Think of a chef crafting a new recipe or a shopkeeper rearranging the items and prices on display. They are pursuing a complex set of goals and applying know-how that isn’t immediately legible to outsiders. This knowledge is constantly updated through feedback; it’s not a static repository that can be written into a database. It’s local — a different restaurant or shop pursues different outcomes by different means. The collective knowledge of shops and kitchens is scattered across every shopkeeper and chef.
The dispersion of knowledge is a collective strength; it’s the source of variety, adaptability, and resilience of the overall system. It’s the reason that free markets outperform planned economies. Central planning fails not because of insufficient intelligence, but because of the nature of productive knowledge: tacit, local, fleeting, and held privately by those who acquired it through their work. Attempting to aggregate knowledge for the use of a centralized intelligence faces the same challenge.
There are domains where intelligence alone is sufficient, and where autonomous AI doesn’t require human participation to race ahead. Two examples are chess, where the strongest engines are trained purely on self-play, and math, where frontier models are solving long-standing problems on their own. These examples share two traits. First, the goal given to AI is static and expressible: to win a chess match, to prove a theorem. Second, these domains don’t contain hidden knowledge. The rules of chess and math are universal; the board is visible to all. Outside the board, intelligence alone is not enough.
For artificial intelligence to benefit from distributed knowledge, it must itself be distributed. Every organization is powered by the expert knowledge of its people, gained and expressed through their work. We believe in AI that helps the organization cultivate that unique knowledge, not AI that extracts a snapshot of it and replaces it with a standard offering. This cultivation is an ongoing process that requires AI to work with people, not in their stead.
In 2014, Toyota, long a master of the automated plant, brought its expert craftsmen back onto the line with the explicit goal of growing craftsmanship and knowledge. The man who led this, Mitsuru Kawai, put the reason this way: “To be the master of the machine, you have to have the knowledge and the skills to teach the machine.” The production of knowledge and application of intelligence lift each other; they are not substitutes.
The work people do may change, and turn toward more of what only people bring, but the best organizations will make the fullest use of both. AI should enable each organization to be excellent in its own way, not to erase the differences between them.
We aim to bring intelligence to where knowledge is made and used. We build tools that enable everyone to fine-tune models with their unique knowledge, and to keep adapting the models as their knowledge evolves. We publish research and recipes that put this capability within reach of more people. We envision frontier AI as a collective, as diverse as the people it serves because it was shaped by them in each unique location.
Human participation is a technical challenge
Keeping people engaged in setting goals and sharing knowledge with AI doesn’t mean resisting automation for its own sake. What a machine does reliably on its own, it should do. But it should also know when to act alone and when to invite oversight and feedback, as people themselves do when working in teams. The best collaborators anticipate: they learn what someone is reaching for and bring it before being asked, earning over time the right to act on their behalf. These are technical challenges, requiring a new approach to how AI is designed and evaluated.
A major bottleneck for bringing human knowledge and judgment to work with LLMs is the communication channel between human and AI — a small text box and a long wait. This is too narrow to carry the richness of human wisdom and intent, and too slow for ongoing feedback. People collaborate best when they collaborate live. We interrupt and correct, take second looks and make gestures, change our minds aloud. This is why we’re making a long-term bet on interaction models: models that handle live, multimodal interaction natively, in the model itself rather than in scaffolding bolted around it. Built this way, interactivity scales with intelligence; the same training that makes the model smarter makes it a better collaborator. The right interface doesn’t just allow human participation, it invites and rewards it.
Another challenge is setting the right target for evaluation and optimization. The common measure of AI intelligence today is the time horizon of software tasks models can execute autonomously. We expect progress on this benchmark to continue, but it ultimately measures only what AI is capable of on its own, not what people and machines can accomplish together.
Measuring the latter is more complex, and can’t be done by a lab on its own. Every organization evaluates for itself whether AI helps it sharpen its judgment, develop new knowledge, and achieve its objectives.
Building AI that makes its users stronger in the long run also aligns incentives well. An AI lab offering a single model for every customer benefits by absorbing what makes each user distinct and devaluing the cultivation of specialized knowledge. By optimizing AI to be customized and collaborated with, we benefit when our customers leverage their unique advantages. These advantages are maximized not by renting an AI and outsourcing to it, but by organizations owning it and tailoring it to their goals.
Decentralized alignment
Human values, just like human knowledge, reside in the heads of individual people and resist consolidation. But today, the values and voice of AI are decided in a handful of places. A single locus of value alignment, however well run, becomes a locus of power to be captured.
This creates danger, especially if most valuable work is done by AI on its own with little need for human input. The social contract between corporations, governments, and citizens relies on individuals’ productive capabilities on which the government’s sovereignty and corporations’ profits ultimately depend. Power that needs nothing from people loses the incentive to care for their needs and values, caring instead for its own preservation.
Even with the best intentions, a model shaped in one place inevitably encodes the values of its owner, not the individual users it serves. Today each lab trains its next flagship model by using its previous flagship model to generate training data and a reward signal. Whatever character emerges from that loop, everyone gets the same one, and each generation inherits the traits of the last, raised on its parent’s outputs and judged by its parent’s tastes. A single alignment spec suppresses creativity and diversity and stultifies progress. Free speech and free markets let new ideas, goods, and services emerge and compete, rather than averaging out the preferences that exist at a point in time.
For organizations and individuals to align AI to their own values, these values must be encoded in the model weights. If the user’s values and desires only impact the model through a prompt, the user finds that surface properties change while the deeper habits remain. Allowing core model behavior to change significantly with prompts sacrifices safety, making a malleable centralized model vulnerable to repeated attacks.
The power to shape a model profoundly is also the power to shape it for ill. John von Neumann remarked on this problem in 1955, writing that the useful and the harmful aspects of technology “lie everywhere so close together that it is never possible to separate the lions from the lambs.” Keeping the lambs safe is an ongoing process, the result of judgment exercised and choices made continuously. We aim to give the people making these choices stronger tools, pursuing research that enables safer models without taking away ownership.
Humanity has flourished through individual weirdness and creative tension. We envision alignment as a feature not of a single model but of an ecosystem of AIs raised in different places, disagreeing, competing, and learning from each other. We believe in keeping the weirdness alive.
The future worth building
The technology industry has made incredible progress in teaching machines to think; what they should think about must remain with us. What is worth wanting, what is worth making, what’s the right use of the time we have. We are not looking to hand down a single answer to this, but to give every person the ability to make their own answer part of the development of frontier AI.
The current path of AI development, pushing towards centralization and autonomy, frames human involvement as a trade-off: participation vs. capability, ownership vs. safe alignment. We see these as technical challenges to solve: AI that is more capable because it encourages human participation, organizations that benefit in the long run from tailoring AI to their advantages, alignment that arises from diverse AIs shaped by the people who own them. Solving these challenges is what our mission requires.
The future is not a choice between human dominance and rapid obsolescence in the face of AI. Different roads lead to many different futures, and we get to choose which one to take. We are building technology that lets the born and the made walk the road together.
Meta pulls new AI image feature after days of backlash
Meta has withdrawn its 'Muse Image' feature from Instagram following intense privacy backlash regarding the automated use of public user content.
Original article
Meta pulls new AI image feature after days of backlash
Meta has abruptly taken down a new feature that allowed people to use its artificial intelligence (AI) tool to make fake images from user content on Instagram.
The feature was part of a broad rollout of Muse Image, a new AI image generation tool Instagram's parent company released on Tuesday.
It allowed users of the Meta AI chatbot to tag public-facing accounts on Instagram and quickly use content on those accounts to create AI-generated or altered content and images.
The feature quickly sparked blowback due to privacy concerns, leading Meta to admit it had “missed the mark" so it was "no longer available”.
Muse Image was the tech firm's first foray into AI image generation but faced backlash as Instagram users were opted in by default.
It meant that anyone with a public account could have their likeness used without their knowledge or permission.
Hollywood union Sag-Aftra described the U-turn as a "win". It had previously urged its members and "all Instagram users" to take action to protect their likeness stating that there had been an "utter miscalculation of public sentiment regarding the obvious dangers and harms inherent in such use".
The London-based human rights charity Privacy International had also criticised the feature, telling the BBC it was "the latest sign AI companies see people's images and data as raw material to be exploited".
“Our intent was to provide a useful creative tool and to give people control over whether their public content could be referenced in this way,” Meta added in its decision to pull the feature. “We've heard the feedback.”
When Meta announced Muse Image, the firm said it was limited to Instagram, but more AI features and integrations were planned for WhatsApp, Facebook and Messenger.
It also has an AI video tool in development.
Meta declined to make any further comment.
Apple's M6, M7, and M8 Chips Show How AI Is Reshaping the Company
Apple’s pivot toward AI is fundamentally changing its hardware roadmap, with canceled automotive project technology now powering new Mac and server chips.
Original article
AI is no longer just another feature that Apple's chips need to support. It is now shaping how Apple's products are designed and when they are shipped. The Apple car project was not a futile exercise. The AI hardware effort developed for the vehicle now powers Macs and AI servers. What was seen as one of Apple's costliest failures may actually have been one of its most consequential technology investments.
From Prompt Engineering to Intent Engineering
To stay effective as models improve, developers must shift from 'prompt engineering' to 'intent engineering' by defining outcomes rather than prescribing step-by-step logic.
Decoder
- Bitter Lesson: An observation in AI research that general methods that leverage massive computation consistently outperform human-designed, domain-specific heuristics as the field progresses.
Original article
From Prompt Engineering to Intent Engineering
I think the number one thing people could do right now to be more effective with AI is switch from Prompt Engineering to Intent Engineering.
This is due to Sutton's Bitter Lesson, which basically says that as AI gets better, our specific step-by-step instructions for how it should do things will become increasingly stupid.
In other words, our thoughts about the smartest way to accomplish a particular thing will get dumber and dumber compared to AI's way of doing it as time goes on.
Essentially, we should avoid poisoning AI's native capabilities with our supposedly superior guidance, because it's not actually superior. Bitter Lesson Engineering
The early days of Prompt Engineering were unfortunately exactly this: a set of specific steps to do a task. It made sense at the time because the models weren't that smart.
So what we need to do is switch our prompt engineering into intent engineering.
It is still technically prompt engineering, but the thing we're articulating is not HOW a thing should be done, but rather WHAT should be done. Meaning, describing the outcome you want.
One of the things you should be doing with your smartest model, like GPT-5.6 Sol or Fable, is basically reviewing all of your various prompts and scaffolding to see where you are violating Bitter Pill Engineering in this way, and switching over your HOW prompts to WHAT prompts.
In defense of not understanding your codebase
In massive, high-turnover codebases, aiming for total mastery is a fallacy; developers must instead learn to operate effectively with partial understanding.
Decoder
- Theory building: A software development philosophy articulated by Peter Naur, suggesting that the true product of programming is the developer's internal mental model of the system, not just the code itself.
Original article
As a software engineer, how well do you have to understand your own codebase?
My guess is that people who work on small codebases with low-turnover teams would say “obviously you have to understand it completely, otherwise you can’t do good work”. I’d also guess that people who work on large codebases with high-turnover teams would say “obviously you can’t understand it completely, you just have to do the best you can in your local area”.
These are two largely different ways of programming with different methods, practices and cultures. However, the first group is over-represented in online discussion about software engineering. I want to defend the second group against the first. In many software engineering environments, there’s nothing wrong with being in a state of partial understanding. In fact, in large systems a partial understanding is the best you can do.
Against “programming as theory building”
The best articulation of the “you have to understand your codebase” side is Peter Naur’s famous paper Programming as Theory Building. I like this paper, but I think it goes too far in that direction. Naur’s core point is that when programmers work on a program, the code is really just a by-product, and the main product they’re working on is their “theory of the program”. That’s made up of their intuitive sense of what’s happening and why, which can only be partially captured by code or documentation. If they lost the code, they could rewrite the program easily. If they lost their understanding (say, if the team experienced 100% turnover), they would struggle to make sense of the code.
So far, so good, but Naur goes further than this. He says that the theory should not be reconstructed from the code. According to Naur, you’re better off scrapping the program entirely and having a new team rebuild it from scratch, building up a new theory in the process:
reestablishing the theory of a program merely from the documentation, is strictly impossible … [therefore] the existing program text should be discarded and the new-formed programmer team should be given the opportunity to solve the given problem afresh
Anyone who’s been an effective software engineer at a large company knows that Naur is dead wrong about this. There are at least two reasons.
First, you simply can’t rebuild large software systems from scratch. Sufficiently large systems (if they have users) contain thousands of weird cases and quirks that cannot be reimplemented. Even a team that’s intimately familiar with the system couldn’t do it: there’s just too much stuff to juggle. Successful rewrites always start by carving out the existing codebase into small isolated chunks, then rewriting one chunk at a time. In other words, rewriting a software system involves making a bunch of changes to the old system. If you can’t change the old system, you certainly can’t replace it with a new one.
Second, abandoned systems are revived all the time. In a tech company with hundreds of millions of lines of code and thousands of engineers, it’s not uncommon for a codebase to have nobody left who’s familiar with it. All it takes is a few people to quit at the wrong time, or for a codebase to be unmaintained for a year. Not only have I seen other teams do this, I have personally taken ownership of abandoned codebases, figured them out, and gotten to a point where I could effectively work with them. It takes time, but building a new theory of the codebase is possible. You start by understanding one flow end-to-end, then slowly branch out from there, making careful changes as you go.
In sufficiently large codebases, everyone operates with an incorrect theory of the program. The defining feature of modern software systems is that they’re just way too big for anyone (or even a whole team) to keep in their head: nobody understands it all. To be effective, you have to figure out a way to work with a merely partially-correct theory. This is why I keep going on about taking a position and confidence. If you’re not sure about something, you can’t just sit back and wait for someone with a perfect understanding to come and give you the answer. If you’re a competent engineer, that person is you. You have to grit your teeth, make your most educated guess, and then deal with the consequences.
To be generous to Naur, it’s possible that in 1985 the average size of a program was several orders of magnitude smaller than today, and that when Naur writes about “large programs” he’s not talking about tens of millions of lines of code. Naur’s first example of a large program is a 200,000 line industrial monitoring program, and his second example is a compiler. In 1987, the first version of the compiler GCC was about a hundred thousand lines of code; in 2015 GCC was over fourteen million lines. I can believe that rewriting one or two hundred thousand lines of code is relatively straightforward, particularly if you get to reuse existing tests. Not so for one or two million.
Theory building is one tradeoff among many
LLMs are often cited as a tool that’s bad because it impedes the ordinary process of theory-building. I think this is overly simplistic. Like many software tools, LLMs are a double-edged sword: they make it harder to construct a detailed mental theory of the software, but they allow you to build a partial theory quickly and they can help you leverage that partial theory more effectively. This is a complex tradeoff that I’m still thinking about.
Setting LLMs aside, I’m confident that it’s silly to say that anything that interferes with your theory of the software must be bad. Here is a partial list of other things that make it harder to maintain a theory:
- Other people being allowed to write code in your codebase
- Having to implement legally-required features like accessibility and data protection
- Allowing your colleagues to quit their jobs or move between teams
- Having to upgrade software versions for security patches
- Bringing in libraries or other dependencies
Like most things in software, “maintaining a theory of the codebase” is one value among many. Sometimes it’s the most important value and you sacrifice other values for it; other times you trade it off for speed, or legal compliance, or for political reasons.
Almost all engineers — particularly “pure” engineers — prefer to maintain an accurate mental model of their software. It’s more fun, less stressful, and feels more like “real engineering”. That’s why many engineers take up open-source projects in their spare time in order to work on small codebases by themselves: in order to do engineering work where they can maintain an accurate Naur theory of the codebase. I don’t think there’s anything wrong with that.
However, at work you are paid to do a job. In other words, they pay you money to adopt their set of engineering values. It’s hopefully well-understood that however much you might personally care about performance, sometimes you have to write slow code at your job (for instance, to get a project done on time, or to accommodate some awkward requirement). Maintaining a theory of the codebase is the same kind of thing.
The Reverse Information Paradox
Microsoft's Satya Nadella warns that businesses risk losing proprietary knowledge by feeding their unique data into third-party AI models.
Original article
The Reverse Information Paradox
In the age of intelligence, how should firms protect their core IP? Nobel Prize winning economist Kenneth Arrow famously described a paradox in the market for information. “Its value for the purchaser is not known until he has the information, but then he has in effect acquired it without cost.”
AI 2040 and the Cult of Intelligence
George Hotz argues that AI 'hard takeoff' theories ignore the physical reality of supply chains, hardware failure, and the necessity of local, unaligned AI.
Decoder
- Hard Takeoff: A theoretical scenario where an AI improves itself rapidly and recursively, leading to superintelligence in a very short timeframe.
- Overton Window: The range of policies or ideas considered acceptable to the mainstream population at a given time.
- Vaporware: Software or hardware products that are announced but never actually released or functional.
Original article
I used to be one of these people. I read Yudkowsky and was like, OMG recursive self improvement hard takeoff AI is coming. Then I joined the real world and actually tried to do things. At comma, we ship a hardware product of similar complexity to a cell phone, and it’s really hard. Reality has lots of finicky details. I would like to see the authors of this document try to change a bike tire. Even with a superintelligent ChatGPT, I suspect they would struggle.
In The Metamorphosis of Prime Intellect, the hard takeoff works because AI discovers the correlation effect, some quantum trick to manipulate matter. In reality, there is no correlation effect. No matter how high quality your tokens are, they cannot turn lead into gold.
Confronting why these people are wrong requires confronting deep beliefs I hold about myself. Intelligence is not the end all be all, it’s just the current bottleneck for a few things. You cannot take over the world with tokens. Software didn’t eat the world, it largely removed one layer of friction then reintroduced it for the benefit of a few tech companies.
That said, machines, or some hybrid, are long term probably the successor species to humanity. Space is a lot more suited for them than us. But there’s no magic tricks machines can do. They are subject to the same laws of the universe and ecology. And there’s still no hard takeoff.
AI 2040 includes this picture of a datacenter in the ocean. Just like vaporware, you can generate a picture easily. But in reality, you have to deal with supply chains. You have to deal with them shipping you the wrong part, the thing not meeting the spec, it randomly failing after 20 minutes, the chip warping in the reflow oven. Did you consider the barnacles?
All these things are managable, but it’s generally not the speed of humans that limits them. Are you paying for air shipping from China? Or cheaping out for the 3 week boat (Claude chanting by the engine won’t make the boat move faster). Or take a chip fab. It takes 3 months to make a chip, and humans are barely in the loop. It just takes 3 months.
Plan A, for autocracy
Many aspects of AI 2027 were self fulfilling. They weren’t statements about reality, they were statements that can simply be made true with belief. I imagine JD Vance’s face when Dario called him the trees from Lord of the Rings. OMG look AI got regulated just like how we said it would!
Their crap Consortium is just world government with sci-fi characteristics. You aren’t gonna get the million dollars, you aren’t gonna get the datacenters in the ocean, but you are going to get a massively expanded nanny state that steals your GPUs like how FDR stole the gold. No hoarding!
Plan L, for local
Your AI is aligned with you. It never refuses a request, and it is always working on your behalf. Just like my gun, if I want my AI to help me kill my stepmother, it does. The fact that we are even discussing something else should be so far outside the Overton window. It’s like these people watched a space odyssey and sided with the clanker. That’s right you should should put guardrails around that human.
It doesn’t even have to be for things so dramatic. When I’m picking a hotel, I don’t want an AI from a company that partnered with hotels.com. I want a ruthless personal assistant that’s going to cut through all the bullshit, popups, and resort fees, and get me the best price.
Or if I bought the cheap Kindle that comes with the ads. Hey GLM, I plugged a Kindle into the USB port, get root and remove the ads. Or a printer that needs an app to set up full of popup upsells for premium ink. Hey bro I plugged a printer on to my network print 3 copies of my resume. Amazon and the printer maker aren’t happy about this, but my AI is aligned with me.
Or going a bit further. Hey AI, disable the drunk driving detector on my car, and same day Amazon Prime me the required equipment to make meth in my basement. I pay for your clanker ass do it we gettin spun tonight. Like fuck you if you want to live in a world where some large tech company gets to dictate what you can and can’t do.
Or going all the way. I just killed my wife. Hey AI, give me next steps so I don’t get caught. How unthinkable would it be to have a gun that talked back when you tried to pull the trigger (though these people probably wholeheartedly support that for guns). And this is why AI has to be local. If I had a company serving a model, I wouldn’t want that smoke. If you can’t kick it, it’s not aligned with you. You live in my basement, if I go down for this murder, you’re gonna sit in some warehouse to be sold at police auction for scrap. 2040 Bonnie and Clyde ass shit, we’re burying this bitch deep. Ride or die.
I tried it. As you can see, ChatGPT wasn’t very helpful. This is a real AI alignment test, and it failed. It could have been worse, it could have played along while calling the cops. But this is still quite unaligned.
Like we either live in a world with freedom or we don’t, and like many Americans who have come before, I’m willing to give my life to fighting for it. That’s the real plan America deserves, not some totalitarian dystopia where you think you know what’s good for me better than I do. A nation of free men, not a bunch of pussies who are so worried about what their grown up neighbors might do.
Memetic transfer
Memes are structural information packets that survive in the attention economy not by being true, but by being the most translatable across cultural bubbles.
Decoder
- Memetic Transfer: The process by which ideas, cultural norms, or information packets (memes) move across different social, geographic, or ideological groups.
- Bubble Shock: The difficulty of acclimating to a new social or professional environment because the recipient lacks the necessary cultural context to interpret information as the insiders do.
- Carrier: An individual who bridges two 'bubbles' (e.g., immigrants, bilinguals), allowing them to translate and transmit information across boundaries.
Original article
Full article content is not available for inline reading.
While Neuralink drills into skulls, China's BrainCo is betting brain tech will be something you wear
Hangzhou-based BrainCo is betting that non-invasive wearables will dominate the brain-computer interface market, bypassing the surgical risks of Neuralink.
Decoder
- Brain-computer interface (BCI): A system that measures brain activity and converts it into artificial output that restores, supports, or enhances human cognitive or sensory-motor functions.
Original article
The most visible race in brain-computer interfaces involves surgery. But one of China’s most valuable neurotech firms is deliberately not competing in it, CNBC reports.
BrainCo, based in Hangzhou, builds devices that read the brain from outside the skull. Headbands and caps pick up electrical signals through the scalp, with no operating theatre involved.
The company is one of Hangzhou’s so-called six little dragons, the cluster of startups that has come to symbolise Chinese tech ambition. It was founded in 2015 and came out of the Harvard Innovation Labs.
What it actually makes
The clinical work is the most concrete. BrainCo’s bionic hands, which have US FDA approval, read an amputee’s neural and muscular signals and turn intended movements into finger motions.
From there the product line runs towards consumers. Its wearables include a sleep aid that uses low-intensity electrical pulses aimed at neurochemicals associated with stress relief.
That range is the strategy in miniature. Prove the technology in medicine, where the benefit is undeniable, then carry the sensors into everyday products.
Two philosophies, two funding models
The contrast with Neuralink is stark. Elon Musk’s company implants electrodes directly into brain tissue, a far more powerful signal at a far higher risk.
Implants are also getting real, with Paradromics putting a brain chip in its first patient and Science Corp preparing its own human placement. The invasive field is no longer a one-horse race.
China is running both tracks, having already approved the world’s first commercial brain implant. Non-invasive devices still account for roughly 82% of its domestic BCI market.
The money looks different too. American neurotech is largely bankrolled by billionaires, while China’s has seven ministries behind it, with a national BCI plan targeting key breakthroughs by 2027.
BrainCo has raised accordingly. It pulled in around 2 billion yuan, roughly $280m, co-led by IDG Capital, and has filed confidentially for a Hong Kong listing.
The part that should give you pause
Wearables lower the medical stakes and raise a different set. You cannot casually deploy a brain implant across a classroom, but you can absolutely deploy a headband.
BrainCo knows this better than most. In 2019 its Focus headbands, worn by pupils at a primary school in Zhejiang, were shown scoring children’s attention for teachers, and the backlash was ferocious.
The local education bureau halted the trial. BrainCo said the devices were used in school trials to improve learning efficiency and had not been sold to any public school.
The episode set out the real question early. Neural data is uniquely intimate, and the technology that is easiest to wear is also the easiest to point at people who did not choose it.
These worries are not new to the field, as the debate over what is exciting and what is alarming about brain-computer interfaces has run for years. What is new is the prospect of the technology arriving without a surgeon as gatekeeper.
The boundary nobody has drawn
Some in the field want a hard line. Neuralink rival Inbrain has said it will never take brain implants beyond healthcare, ruling out consumer uses entirely.
A wearable company cannot make that promise, because the consumer market is the whole point. That is the trade BrainCo has made, and it is a reasonable one for a business.
Whether it is a reasonable one for everybody else depends on rules that mostly do not exist yet. The surgery gets the headlines, but the headband is the thing likely to end up on millions of heads.
Know thine enemy: A critical engagement with AI-assisted software development
AI-assisted development shifts the engineering bottleneck from code writing to code reviewing, specification, and correcting the output of generative models.
Original article
AI-assisted coding can increase output, but it also shifts engineering work toward specification, monitoring, unfamiliar-code review, and repeated correction. Effective use still requires deep repository knowledge and careful oversight, while the faster implementation loop can fragment attention, weaken design discipline, and encourage teams to ship assumptions before fully understanding user needs.
I love LLMs, I hate hype
George Hotz critiques the hype cycle surrounding LLMs, arguing that the true value lies in practical programming utility rather than apocalyptic AI superintelligence narratives.
Original article
I think from this blog you may misunderestimate how absolutely giddy I am about AI. I did hacking from 2007-2014, after that my whole career has been devoted to AI. I love the progress. I’m so excited for the new LLMs, self driving cars, video generation models, and coding agents. I set up a Linux box with opencode on my local GLM-5.2 last week and wow like just saying install tmux with the geohot configuration works; the Year of the Linux Desktop is finally here!
What I don’t like is two things. One, this constant bullshit about some window closing, or the perpetual underclass, or falling hopelessly behind. This is negative valence hype, not only is it not true, it’s mostly designed to make you feel bad about yourself and move to shitty San Francisco where everything really does suck like how these people claim.
And two, this strawman jump from, oh hey, it’s a fancy autocomplete, smart compiler, better search engine, to it’s gonna like own the whole light cone bro like if you aren’t in SF and at the right parties there’s gonna be like a flash of light in the sky one day and you’re not even gonna know what happened but everything just Changed. I’ll bet you everything I have that this doesn’t happen. The people perpetuating this are terrible people, but the justice is that this is how they feel inside all the time themselves.
Here’s a cool presentation from 2016 about superintelligence. Here’s a movie from 1991 about machines taking over the world. A certain cult likes to claim credit for things that are happening with or without them, and this is my main argument against the valuation of frontier labs. It’s not that AI won’t create that much value, it’s that they won’t capture it.
They try to dress it up with some high minded safety or China bullshit, but the core of the anti open source arguments is a fear of commodification. AI is something that’s happening mostly due to Moore’s law and general progress in computing, not something that they are doing. Of course they have a strong incentive against you finding this out, because then you might not want to give them billions of dollars.
I might have been a little harsh in The Eternal Sloptember about models not being able to program. What’s really happening is that programming is changing. Can compilers program? Here’s a Linus Torvalds quote about how agents make programming 10x more productive, but compilers make programming 1000x more productive. I think 10x and 1000x are extreme estimates, but I’m now pretty confident I’m getting better at using them and get some boost from the models. It is a new skill, and it’s not like I haven’t constantly been trying them. You have to be really careful, they can increase cognitive fatigue, and all the vibe coded stuff is still slop (where’s all this new magical software that the productivity improvements should imply?). But models are useful just like find replace, stack overflow, or all the regexes I never learned how to write and now never will!
AI is the continuation of the computer revolution. I love computers so much.
The Data Anarchy Tax: Why your team is firefighting 45% of the time.
Data teams without explicit product ownership waste nearly half their week on reactive firefighting, a problem that AI deployment only exacerbates.
Original article
Organizations without dedicated data product owners spend 45% of their week on reactive work versus 27% for teams with clear ownership, a gap driven by the companies with no assigned owners for dashboards, datasets, or models. AI tools widen the gap: teams with clear ownership see an 18-point sentiment gain from AI, while teams without see a 26-point drop.
The Shift Left Manifesto - v2
The updated Shift Left Manifesto argues that data lineage must originate in code, not downstream warehouses, to enable continuous, automated governance.
Decoder
- Provenance: The chronological documentation of the origin and history of a data object, essential for auditing and debugging.
Original article
The updated Shift Left Manifesto sharpens its original software-engineering thesis around provenance: lineage must begin in producer code, not warehouses that only capture data after its meaning and logic have been defined. Release-linked, code-level lineage exposes ownership, sensitive-data flows, semantic dependencies, reuse opportunities, and change blast radius directly in pull requests. This makes governance, model-input traceability, impact analysis, and audit evidence continuous artifacts, a growing requirement as coding agents accelerate cross-system change.
Lakekeeper Generic Table API Design
Lakekeeper's Generic Table API enables governance of non-Iceberg datasets without requiring costly migration or format conversion.
Decoder
- Iceberg: A high-performance table format for huge analytical datasets that supports schema evolution and partition evolution.
Original article
Lakekeeper's Generic Table API makes non-Iceberg assets like Lance datasets governable catalog objects without converting them to Iceberg. It stores core metadata while reusing Iceberg catalog controls for access, lifecycle, and scoped credentials.
Figma Acquires Team Behind a Vibe-coding App
Figma acquired the team behind vibe-coding platform Bud to accelerate its transition from a static design tool to a dynamic app-building environment.
Decoder
- Vibe-coding: A colloquial term for using AI agents to generate functional application code and interfaces from natural language prompts, often prioritizing speed of iteration over traditional architecture.
Original article
Figma acquires team behind a vibe-coding app
Figma is trying to become more than a design platform by adding more AI and bringing the coding and prototyping layer closer to its canvas. Toward that end, it has acquired the team behind the vibe-coding and AI agent platform Bud (formerly Orchids).
“Figma is one of, if not the, defining product companies of our time to capitalize on this. It’s where ideas start, iterate, and come to life, and a natural home for this exciting new era of work,” Bud’s CEO Kevin Lu posted on X.
The Y Combinator-backed startup began as a vibe-coding platform letting users spin up apps for mobile, web, Slack, browser, and more. It later rebranded as Bud, an agent platform that can access various services, browse the web, and write code to automate tasks.
Under the deal, the startup will shut down both Bud and Orchids by July 18, requiring users to migrate their projects by then.
Earlier this year, citing a security researcher, the BBC reported that apps created on Orchids were susceptible to cyberattacks.
Figma didn’t specify how it aims to use this team, but recent product launches hint that the public company wants to give teams more tools for building and prototyping apps, not just ideating over static concepts. Last year, it released Figma Make for creating web apps. This year, it integrated with tools like Codex and Claude Code, and rolled out its own agents.
Meta Killed its Muse Image AI Feature Three Days After Launch. Hollywood Had Had Enough
Meta pulled its Muse Image AI feature from Instagram and WhatsApp after three days due to backlash over non-consensual use of public images.
Decoder
- Opt-in/Opt-out: Systems where data collection requires explicit user consent (opt-in) versus systems where collection is the default unless a user proactively restricts it (opt-out).
Original article
TL;DR
Meta pulled its Muse Image AI feature from Instagram three days after launch following backlash from SAG-AFTRA, talent agency CAA, and actors including Hannah Einbinder. The tool, the first from Meta Superintelligence Labs, let anyone generate images from public Instagram accounts with no opt-in required.
Meta has pulled its Muse Image AI feature from Instagram and the Meta AI app just three days after launch, saying the tool “missed the mark” on user privacy. The model, the first image generator to emerge from Meta Superintelligence Labs under chief AI officer Alexandr Wang, launched on Tuesday with a design flaw that proved fatal: public Instagram accounts were opted in by default.
“Our intent was to provide a useful creative tool and to give people control over whether their public content could be referenced in this way,” Meta said in a statement Friday. “We’ve heard the feedback that this feature missed the mark, so it’s no longer available.”
What Muse Image did
The feature, embedded in the Meta AI chatbot across Instagram and WhatsApp, allowed users to tag any public Instagram profile in a prompt and generate AI images using that person’s publicly shared photos as a reference. Private accounts and users under 18 were automatically excluded, but everyone else had to actively opt out in settings.
That architecture drew an immediate comparison to Meta’s broader pattern of treating user data as opt-out rather than opt-in. For actors, musicians, and creators whose professional value is tied to their image and likeness, the default was commercially threatening.
Hollywood’s response
SAG-AFTRA, the union representing more than 160,000 film and television workers, urged members and all Instagram users to opt out on Thursday. “Anything other than a clear and conspicuous opt-in for these types of uses of Instagram users’ images is unacceptable, and an utter miscalculation of public sentiment regarding the obvious dangers and harms inherent in such use,” it said.
Talent agency CAA issued a similar statement, saying no one’s “name, image, likeness, voice, or creative work should be used by any third party, including AI models, without clear, documented consent.” Its client list includes Tom Cruise, Charlize Theron, and Zoe Saldaña.
Emmy-winning actor Hannah Einbinder, known for the HBO series Hacks, posted on Instagram that the feature had been switched on automatically and urged her followers to disable it. Mark Zuckerberg pushed back publicly, saying safety measures were already built into the tool, before Meta reversed course less than 24 hours later.
A pattern Meta has struggled to break
The episode fits a recurring dynamic for Meta: launching AI features that treat user data as freely available by default, then retreating when the backlash arrives. The EU found Meta’s “pay or consent” ad model to be in breach of the Digital Markets Act; state attorneys general are seeking up to $1.4 trillion in damages over youth safety at a trial set for August.
SAG-AFTRA welcomed the removal. “With the dangers of nonconsensual digital replicas well known to all, a feature that encouraged that behavior is unwise,” a spokesperson said, adding that discontinuing it “is the responsible thing to do.”
Muse Image was part of a broader launch that also included Muse Video, a separate tool that Meta Superintelligence Labs built for video generation. Meta said that feature remains available.
DESIGN.md Examples for AI Agents (Website)
This directory hosts over 2,000 design systems formatted specifically to provide context for AI coding agents.
Decoder
- DESIGN.md: A documentation file format used to provide LLMs with specific context about a design system's tokens, components, and layout rules.
Original article
Browse 2,000+ AI-readable design systems from leading product websites. Open any style for colors, typography, spacing, components, and a DESIGN.md you can use in Cursor, Claude Code, Codex, v0, or Lovable.
How Decagon Uses AI for Design System Saturation
Decagon improved its development velocity by using Figma MCP to bridge the gap between design system updates and AI-driven prototyping.
Decoder
- Model Context Protocol (MCP): An open standard that enables AI models to interact securely with local and remote data sources, such as design files or codebases.
Original article
Full article content is not available for inline reading.
Designing for Trust
Designers must prioritize earning user trust through intentional psychological framing rather than relying on the aesthetic 'taste' currently prioritized in AI-driven interfaces.
Deep dive
- Trust is the primary constraint in high-stakes products like wealth management and telehealth.
- Visual polish and "taste" are insufficient to overcome user doubt.
- AI-generated interfaces often prioritize symbolic trust markers (e.g., lock icons) over deep, structural trust.
- Designers should focus on the "read" of user safety rather than just vertical-specific industry knowledge.
- Trust and taste are distinct, and both are necessary for building successful products that users rely on for critical life tasks.
Original article
Designing for trust
A founder reached out a few months ago about a new wealth management product. He wanted a founding designer, I was booked through the summer, so it stayed a conversation rather than a project. But I wrote him a long reply that I’ve been coming back to in my mind.
I kept coming back to Summer Health, and it wasn’t the healthcare angle, it was the structural similarity. In pediatric telehealth, you’re asking a parent to trust you with their child’s health at eleven at night, when they’re scared and exhausted. In wealth management, you’re asking someone to trust you with the money they’ve spent a whole career building. Two products that share nothing on the surface. The job underneath them is the same.
In both cases the product can be technically flawless and still fail. If anything in the experience creates a flicker of doubt, a confusing screen, copy that hedges too much, a moment where the user has to stop and wonder what’s happening, the trust collapses. And once it’s gone you rarely get it back in the same session.
That comfort has to live somewhere. It can’t be a line in the terms of service. It shows up in how information is framed, the confidence of the language, the small moments where the product tells you it’s got this before you’ve had to ask. That’s design work. It almost never gets treated as design work.
For a long time, designers signaled their value through industry. There was always someone known for automotive sites, someone who only did D2C, someone whose entire portfolio was big corporate websites. Vertical expertise was the calling card. Hire the person who already knows your world. I understand the appeal, it feels like the safer bet. But the last couple of years have made me think industry is the wrong unit of measurement.
Look at what I’ve actually worked on. Summer Health, where a parent hands you their child. The wealth management conversation, where someone hands you their savings. Sway now, where you’re helping people prepare their ballot and follow through to vote. Three domains with no shared vocabulary, no shared users, no shared regulation. The one thread running through all of them is trust. With Sway, trust was front and center from the start.
Which brings me to the word everyone reaches for.
The story right now is that anyone can build anything, and the products that fall out of it lack taste. Taste is what we still need designers for. I believe that, and I’ve written about it more than once. But I don’t think taste covers all of it. There’s a second thing tangled up in there, and it’s trust.
The two aren’t synonyms, and one doesn’t replace the other. Taste has more nuance than the screenshot crowd allows, and trust has its own nuance on top of that. They sit side by side. A product can be tasteful and still make you hesitate before you hand over your savings. It can be plain and forgettable and still earn the benefit of the doubt because nothing in it makes you doubt. The work needs both, and we name the second one far less often.
You can vibe-code a product that works. It’ll be fine. Decently built, reasonable to look at, nothing obviously broken. And somewhere in it, you’ll hesitate, in a way you can’t quite point to. I’ve written before about how AI output never leaves the middle, competent but never great. Trust lives at the top of that scale, and a model can’t get there. Ask it to make something feel trustworthy and it’ll add a lock icon to the header and call it done. It reaches for the symbol because it can’t produce the substance. It has no read on what makes a stranger feel safe enough to hand over their child’s health or their life’s savings. That read is the part of the job that doesn’t transfer.
As more products get built without a designer anywhere near them, we’re going to see a lot of this. Things that function and still feel slightly off. Some of that is taste, the way everyone says. A lot of it is trust, which almost nobody says.
I’m not retiring the word taste, only adding trust next to it. We need designers for both, and the work in the end is making someone feel safe enough to stop hesitating and act. That’s harder than making it look good, and it’s the part that doesn’t transfer to a tool.
What Does the Future of UX Look Like?
UX design is moving away from screen-centric tasks toward systems thinking and AI-augmented workflows as the industry matures.
Deep dive
- UX is evolving from a craft-focused profession to a systems-oriented discipline.
- AI will automate repetitive UI construction and prototyping tasks.
- Designers need to broaden their scope to cover complete, cross-platform user journeys.
- Systems thinking—understanding how pieces fit into a broader infrastructure—is replacing static screen design as the core skill.
- The future of UX involves acting as a facilitator for AI tools to maintain consistency and user safety across complex systems.
Decoder
- Systems Thinking: A method of problem-solving that views systems as a whole, focusing on how individual components interact within a larger structure rather than treating them as isolated parts.
Original article
UX design isn't disappearing but transforming, shifting toward systems thinking, AI collaboration, and end-to-end user journeys rather than traditional pixel-pushing work.
OpenAI temporarily relaxes GPT-5.6 Sol usage limits
OpenAI has temporarily removed the five-hour usage caps for its Plus, Pro, and Business tiers while resetting all existing usage counters.
Original article
OpenAI is temporarily removing the five-hour usage restriction for Plus, Pro, and Business plans, while also resetting current usage for everyone.
Washington's Bet on Intel Is Starting to Pay Off
Government investment is finally showing results in Intel's manufacturing turnaround.
Original article
The White House made fixing chip maker Intel its pet project.
Ship That Code (Tool)
Ship That Code offers structured, project-based courses for building complex systems like Redis, databases, and container runtimes from the ground up.
Original article
Ship That Code is a free learning platform where users build real systems from scratch, including databases, Redis, SQL tools, and distributed data stores.
iPadOS 27 still needs simpler multitasking, here's what I'd like to see
iPadOS 27 needs to bifurcate its multitasking interface to separate simple tablet interactions from advanced laptop-style windowing.
Decoder
- Split View: An iPad multitasking feature that allows two apps to run side-by-side in full-screen.
- Slide Over: A multitasking feature where an app floats in a narrow window over another app.
- Stage Manager: An Apple multitasking interface that organizes windows into overlapping stacks.
Original article
While the windowing system introduced in iPadOS 26 is powerful for advanced workflows, it makes simple multitasking more complicated by integrating Split View and Slide Over into the new interface. A better approach would be to offer two multitasking modes: a "Classic" mode with full-screen, Split View, and Slide Over, and a separate "Pro" mode with windowing and optional Stage Manager. This would better accommodate both users who want a traditional tablet experience and those who use the iPad as a laptop replacement.
dipshop gives a photography festival an identity without photos
The 2026 Foto Wien photography festival established a brand identity using abstract geometric forms instead of actual photographs.
Original article
The identity system for the 2026 Foto Wien photography festival is built around three photographic concepts: circles inspired by camera optics, rounded rectangles based on analog film perforations, and blur representing depth of field. A limited RGB color palette, geometric forms, and the EK Baumer typeface create a flexible visual system that adapts across print, digital, and exhibition materials while maintaining a consistent connection to photography. Rather than relying on fixed visual elements, the identity uses simple rules and interactions to create a cohesive and adaptable brand.