Cover illustration

TheDaily Front

Issue No. #260917 Thursday, September 17 2026 #260917 — THURSDAY, SEPTEMBER 17, 2026
Proofs, processors, and a little wind in the wires.
Thursday, September 17, 2026 The Daily Front No. #260917 — Contents
30stories
8,350points
4,287comments
210kllm tokens
Assembled with 31 model calls — 149,602 tokens read, 60,837 written.

Highlights

Nvidia announces native GPU programming in Rust

Nvidia’s native CUDA Rust push puts the day’s favorite systems language directly on the GPU.

Astra for Law

Astra for Law brings a frontier model into the costly, consequential world of legal workflows.

Why I didn’t sign the Fields medallists’ letter

A mathematician’s refusal to sign an AI-era letter opens a wide argument about knowledge and stewardship.

Bonsai 2 27B: Near-Lossless Compression in a 9x Smaller Footprint

Bonsai 2 promises a 27B model in a dramatically smaller local footprint.

The Return of Sail Power: Cargo Ships Are Turning Back to the Wind

Modern cargo fleets are again looking to the wind—this time through rotor sails and aerodynamic hardware.

From the Editor

The machine room was crowded today: Rust entered CUDA, models shrank for local use, and proofs were pressed into service against software error. Elsewhere, the old world proved stubbornly modern—ships sought wind, telnet kept its bugs, and the nation kept its possessions in rented boxes.

  1. Nvidia announces native GPU programming in Rust3
  2. Astra for Law4
  3. Why I didn’t sign the Fields medallists’ letter5
  4. Bonsai 2 27B: Near-Lossless Compression in a 9x Smaller Footprint6
  5. Bend – A language that blocks AI mistakes via proof, on CPU and GPU7
  6. Developing provably correct Rust code with Verus8
  7. Infinite-Parameter LLMs: Generating and Adapting Weights from Live Data9
  8. Reverse-engineered Jev-like model10
  9. Show HN: Share your AI Setup, Learn from others11
  10. Launch HN: Skillsync (YC W26) – AI chat sessions made portable across agents12
  11. Hister: A private search engine for the pages you visit and the files you keep13
  12. Rate limits on GitLab.com are changing14
  13. A 32-year-old bug walks into a Telnet server15
  14. Cloudflare/Security-Audit-Skill16
  15. CrowdSec Source Code Leak17
  16. My temporary PHP fix from 2014 has nearly 20M installs. Today I'm deprecating it18
  17. One year of sponsored Servo development19
  18. Flet 1.0 – Build cross-platform apps in Python20
  19. This PCB is brought to you by Fable 521
  20. Wax motor22
  21. The Return of Sail Power: Cargo Ships Are Turning Back to the Wind23
  22. The American Religion of Self-Storage Facilities24
  23. Comparison of Malloc() Algorithms25
  24. CCC invites all model citizens to 40C326
  25. HarnessTax: How Much Does the Harness Matter for Coding Agents?27
  26. Fujitsu launches made-in-Japan next-generation CPU FUJITSU-MONAKA27
  27. How GLM built its own inference infrastructure27
  28. Keys Not Included: recovering the signing keys for US driver's license barcodes27
  29. The Relation Between Mathematics and Physics by Paul Dirac (1939)27
  30. TSMC revealing details about next gen A14 node27
The Daily Front Page 2 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — The GPU Rust Edition
article

Nvidia announces native GPU programming in Rust

by nonmaskable·▲ 942 points·393 comments·developer.nvidia.com ↗
More and more of it is written in Rust, which catches whole classes of bugs at compile time without giving up performance.

In September 2026, NVIDIA announced it is leaning into native GPU programming in Rust. CUDA C++ and CUDA Python are mature, enterprise-grade toolchains, and NVIDIA will be growing and maturing CUDA Rust into 2027 and beyond

The systems layer of AI spans inference engines, serving infrastructure, drivers, and agent runtimes, and it churns constantly as models and techniques change. More and more of it is written in Rust, which catches whole classes of bugs at compile time without giving up performance.

NVIDIA is part of that shift for the same reason. The Nova Linux driver is written in Rust. NVIDIA Dynamo is built on a Rust core. NVTX has Rust bindings.

The GPU kernel is the exception. You can launch kernels from Rust, but the kernel itself often has to be written in another language.

NVIDIA CUDA Rust closes that gap. GPU kernels can be written in Rust, compiled natively to PTX, rather than a wrapper around code from somewhere else.

There are two tracks to use Rust, matching the two tracks CUDA itself has. SIMT is the model you already write in CUDA C++ or numba-cuda. You indicate what one thread does, and launch thousands of them. Tile is a newer programming model, which is also available in C++ and Python. All of these frontends let you say what one tile of data does, and the Tile IR compiler does the rest.

When you are picking one to build on, reach for Tile first. The compiler decides how tiles map onto each architecture, so your source doesn’t encode architecture-specific choices, and you drop to SIMT when you need that control or want to manage memory and threads yourself.

Which language you reach for is a separate question from which model. Use the CUDA exposure that best fits the stack you already have. The two projects below are for when that stack is Rust. We plan to support inter-language interop, so the choice does not lock you out of the others.

Below is the same kernel on each track, which performs elementwise addition over 1,024 floats. Both are complete programs, both run, and both print the same line, so you can read them side by side and see what changes.

The SIMT track: cuda-oxide

cuda-oxide is a custom rustc codegen backend. It intercepts compilation, routes #[kernel] functions through Rust MIR, the community Pliron IR framework, and LLVM IR down to PTX, and hands everything else to the standard backend. The GPU dialects on top of Pliron are ours. The dialects and every transform stay in Rust until the standard LLVM backend takes over.

You will need Linux, a GPU with compute capability 8.0 or later, a CUDA toolkit (12.x or newer), clang with its libclang headers, and the pinned nightly toolchain. cargo oxide doctor checks all of it, including the optional system LLVM. Install cargo-oxide, the Cargo subcommand that drives the build:

cargo +nightly-2026-04-03 install --git https://github.com/NVlabs/cuda-oxide.git cargo-oxide

Then scaffold a project and run it. The template is a complete vector addition program:

cargo oxide new vecadd_demo
cd vecadd_demo
cargo oxide doctor
cargo oxide run

The first cargo oxide run builds the codegen backend, so expect it to take a while. Later runs reuse the cache.

It prints PASSED: all 1024 elements correct. This is the whole program that did it, exactly what cargo oxide new wrote, with comments added here:

use cuda_device::{kernel, launch_bounds, launch_contract, thread, DisjointSlice};
use cuda_host::cuda_module;
use cuda_core::{CudaContext, DeviceBuffer, LaunchConfig1D};
 
// === DEVICE CODE - everything in here is compiled to PTX ===
// The macro also generates the host-side API used further down:
// `load`, `prepare_vecadd`, and the safe `vecadd` launch method.
#[cuda_module]
mod kernels {
    use super::*;
 
    #[kernel] // GPU entry point
    #[launch_bounds(256)] // max threads per block; lets the compiler budget registers
    #[launch_contract(domain = 1, block = (256, 1, 1))] // indexes in 1-D, 256-thread blocks
    pub fn vecadd(a: &[f32], b: &[f32], mut c: DisjointSlice<f32>) {
        let idx = thread::index_1d();
        let idx_raw = idx.get(); // the plain usize, for reading the inputs
        if let Some(c_elem) = c.get_mut(idx) {
            *c_elem = a[idx_raw] + b[idx_raw];
        }
    }
}
 
fn main() -> Result<(), Box<dyn std::error::Error>> {
    // === HOST SETUP - device, stream, and buffers ===
    let ctx = CudaContext::new(0)?;
    let stream = ctx.default_stream();
 
    const N: usize = 1024;
    let a_host: Vec<f32> = (0..N).map(|i| i as f32).collect();
    let b_host: Vec<f32> = (0..N).map(|i| (i * 2) as f32).collect();
 
    let a_dev = DeviceBuffer::from_host(&stream, &a_host)?;
    let b_dev = DeviceBuffer::from_host(&stream, &b_host)?;
    let mut c_dev = DeviceBuffer::<f32>::zeroed(&stream, N)?;
 
    // === LOAD, PREPARE, LAUNCH ===
    // SAFETY: this package owns the embedded device bundle produced for the
    // kernels module above.
    let module = unsafe { kernels::load(&ctx)? };
 
    // 4 blocks of 256 threads, 0 bytes of dynamic shared memory. `prepare_vecadd`
    // checks that against the contract above and against the live device limits.
    // The safe `vecadd` below takes that token where a raw config would go.
    let prepared = module.prepare_vecadd(LaunchConfig1D::new((N as u32).div_ceil(256), 256, 0))?;
    module.vecadd(&stream, &prepared, &a_dev, &b_dev, &mut c_dev)?;
 
    // === READ BACK AND VERIFY ===
    // Copies down and synchronizes, so the launch has finished by the time
    // `c_host` can be read.
    let c_host = c_dev.to_host_vec(&stream)?;
    let errors = (0..N)
        .filter(|&i| (c_host[i] - (a_host[i] + b_host[i])).abs() > 1e-5)
        .count();
 
    if errors == 0 {
        println!("PASSED: all {} elements correct", N);
    } else {
        eprintln!("FAILED: {} errors", errors);
        std::process::exit(1);
    }
    Ok(())
}

Host and device code live in one file, build with one command, and need no separate kernel crate.

Read the kernel signature first, because it carries the whole safety argument. a and b are ordinary shared slices, readable by every thread. c is a DisjointSlice<f32>, a type that hands each thread exclusive access to its own element and nothing else. It exists because &mut [f32] is the wrong shape for the job. Every thread would need the same &mut, which Rust correctly refuses. DisjointSlice splits that one mutable borrow into per-thread pieces.

thread::index_1d() returns an index type, not a bare integer, and c.get_mut(idx) only accepts that type. You get back an Option, so the out-of-bounds case is a branch you handle rather than a memory error you find later.

The launch is checked rather than trusted. #[launch_contract] declares that this kernel indexes in one dimension with 256-thread blocks. prepare_vecadd validates your LaunchConfig1D against that declaration and the live device limits, and hands back a proof that the safe vecadd method requires. Kernels without a contract expose only raw unsafe launch methods, because a bare LaunchConfig says nothing about the kernel it is launching.

The Tile track: cutile-rs

cutile-rs works one level higher. You perform computations on tiles rather than scalars. Each tile block runs the kernel body once as a single logical thread over one sub-tensor of data, and the compiler decides how many real GPU threads back it. The #[cutile::module] macro embeds the kernel’s AST in the host binary and JIT-compiles it through CUDA Tile IR (the NVIDIA tile-level compiler IR) when the kernel is first needed.

Requirements are lighter than the SIMT track. You need a GPU with compute capability 8.0 or later, CUDA 13.3, stable Rust 1.89 or newer, and Linux, but no nightly toolchain and no LLVM of your own.

cutile is published, so there is nothing to clone:

cargo new vecadd_demo
cd vecadd_demo
cargo add cutile

Here is the same elementwise addition, written for tiles. Paste it into src/main.rs and cargo run:

use cutile::prelude::*;
 
// The macro captures this module's AST into the host binary. The kernel is
// JIT-compiled through CUDA Tile IR the first time it is actually launched.
#[cutile::module]
mod kernel {
    use cutile::core::*;
 
    #[cutile::entry()]
    fn add<const B: i32>(
        // B is the tile width, a static dimension. A different B produces a
        // different specialization.
        z: &mut Tensor<f32, { [B] }>, // exclusive output, one sub-tensor of B elements
        x: &Tensor<f32, { [-1] }>,    // shared input; -1 is a dynamic dimension, resolved at launch
        y: &Tensor<f32, { [-1] }>,
    ) {
        // This body runs once per mut sub-tensor, as a single logical thread.
        // Tile kernels load tiles, not scalars, from x and y.
        let tx = load_tile_like(x, z); // the slice of x lining up with this sub-tensor of z
        let ty = load_tile_like(y, z);
        z.store(tx + ty); // elementwise across the whole tile
    }
}
 
fn main() -> Result<(), Error> {
    let device = Device::new(0)?;
    let stream = device.new_stream()?;
 
    // These are lazy. Nothing has touched the GPU yet.
    let x = api::ones::<f32>(&[1024]);
    let y = api::ones::<f32>(&[1024]);
 
    // Partitioning does three things at once: gives each tile exclusive
    // ownership of its own 128-element chunk, fixes the grid at 1024/128 = 8
    // tiles, and supplies B.
    let z = api::zeros::<f32>(&[1024]).partition([128]);
 
    let c: Vec<f32> = kernel::add(z, x, y) // takes ownership of all three tensors
        .first()                           // ...and returns them; pick the output back out
        .unpartition()                     // drop the host-side partition wrapper; no data moves
        .to_host_vec()                     // record the copy back
        .sync_on(&stream)?;                // and only now does any of it run
 
    let errors = c.iter().filter(|&&v| (v - 2.0).abs() > 1e-5).count();
    if errors == 0 {
        println!("PASSED: all {} elements correct", c.len());
    } else {
        eprintln!("FAILED: {errors} errors");
    }
    Ok(())
}

PASSED: all 1024 elements correct

The Tile track reaches the same answer on stable Rust, and its signature makes the same safety argument. There is no DisjointSlice this time. Partitioning on the host is only needed for mutable tensors, and it hands each tile block one writable sub-tensor that no other tile block can overlap. That exclusivity is what &mut already guarantees.

The -1 in the input shapes is a sentinel rather than a size. That dimension is read off the tensor at launch, so the shape can vary without recompiling.

The interesting line on the host is .partition([128]), and it is doing three jobs at once. It makes the exclusivity real. Each tile owns its 128-element chunk and no other tile can touch it. It fixes the launch geometry, since 1,024 divided by 128 is a grid of 8 tiles.

The grid follows from the partition instead of being computed separately and checked against the kernel’s indexing. It also supplies B, which is never written at the call site because the launcher reads the tile width off the partition. That is why a &mut output has to be partitioned before it can be passed at all.

Then look at what the launch returns. The add you call on the host is a macro-generated launcher, not the device function above. It takes ownership of all three tensors and hands them back as a tuple when the GPU is done. That is what .first() is for, picking the output back out of it.

Nothing runs until .sync_on(&stream). Everything before it is a lazy description, recorded rather than submitted. That includes the ones, the zeros, the kernel call, and even the copy back to the host. The whole program is one chain with a single synchronization point.

What the compiler catches

Both kernels make the same claim about memory. Their inputs are shared, and their output belongs to one writer alone. They differ only in the level at which they make it, and in whether a purpose-built type is needed to make it at all.

That matters because thousands of threads reach the same buffers in no guaranteed order. When two of them hit the same address and one is writing, the ordering decides the result. Those bugs rarely reproduce on demand, and they pass tests before failing in production.

Passing the SIMT kernel’s output buffer as one of its own inputs does not compile, whether or not that kernel would actually race:

module.vecadd(&stream, &prepared, &c_dev, &b_dev, &mut c_dev)?;

error[E0502]: cannot borrow `c_dev` as mutable because it is also borrowed as immutable

The same aliasing on the Tile side does not compile either:

let z = api::zeros::<f32>(&[1024]);
kernel::add(z.partition([128]), z, y)

error[E0382]: use of moved value: `z`

Both examples catch the classic aliasing mistake at compile time, and they draw the line in different places. cuda-oxide checks each launch call. cutile-rs’s ownership follows the tensors across the launch boundary, which is the stronger of the two claims.

Tile gives you no shared memory or thread indexing to get wrong, because the compiler owns both. A tile block is a single logical thread, so there are no threads for you to race. That is what makes it safe by construction, and it is also what you trade away. SIMT keeps that control, and today shared memory there requires unsafe. Shared memory is the bedrock of fast SIMT kernels, so making that path safe is active work.

Where the projects stand

Both projects are early-stage and neither is production-ready. cuda-oxide is early alpha. cutile-rs is further along, published on crates.io and already used outside NVIDIA in HuggingFace’s Grout inference engine and in mistral.rs. Coverage is incomplete and APIs will move. Where you find rough edges, we want to hear about them.

Cargo and crates set an expectation that getting started is easy. GPU programming has historically been the opposite, and closing that distance is part of the work. The SIMT track still needs a pinned nightly toolchain, which is exactly the kind of thing we would like to stop asking you for.

Rust on GPUs is not new. There is good work in this space that predates ours and continues alongside it. The ecosystem appendix in the cuda-oxide book maps where we sit relative to Rust-GPU, rust-cuda, CubeCL, and the rest, and we have been working with the rust-cuda maintainers as both projects mature.

What is new is the engineering we are putting behind it, and a clear sense of where it is going.

What you can do today

Tinker with what is here and come work on it with us. It is early, it is open, and what you build now will shape what comes next.

The Rust community

NVIDIA is excited to be leaning in with the Rust community as we elevate native Rust GPU programming. Projects like rust-cuda, rust-gpu, and cudarc pioneered the marriage of GPUs and Rust, and the people behind them, including the team at VectorWare, continue to shape how we think about our own work as we build with the Rust community.

The Daily Front Page 3 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Law by Model
article

Astra for Law

by vertigoruntime·▲ 463 points·486 comments·openai.com ↗
Our most powerful model, configured into a new AI foundation for law.

Our most powerful model, configured into a new AI foundation for law.

Today, we’re introducing Astra for Law: a new foundation for law firms and legal technology companies to build AI products and workflows around their expertise. It combines GPT‑6 Astra, our latest and most powerful model, with settings, tools, and context tailored for professional legal work.

API customers including Harvey and Legora will be able to build on Astra for Law, bringing this intelligence into their own products and workflows. As our frontier models advance, we’ll bring these legal capabilities to our latest models.

We are also expanding our work on privacy and governance to give law firms specific controls for confidential client work. Firms can also customize Astra for Law using our 26 new ecosystem plugins that connect ChatGPT to the specialist tools firms already use, like Relativity and Clio.

Frontier intelligence for law

Astra for Law combines GPT‑6 Astra with a powerful legal search index and instructions for legal analysis and writing. Together, they amplify Astra’s capabilities across the legal practice, while giving firms and legal technology companies the freedom to build their own applications and workflows.

Legal research: from facts to a supported answer

Our new legal search index is one of the tools Astra for Law can use. Legal research often begins with finding the exact right authority, locating the relevant passages, and understanding how relevant and binding they are to the situation at hand. The index helps Astra for Law do that work, and complements the licensed content and specialist products firms rely on from providers such as Thomson Reuters.

By using the legal search index, Astra for Law can search U.S. case law, statutes, regulations, court rules, and administrative decisions across a corpus of more than 230 million URLs, with sources added daily. Our work with Free Law Project, the nonprofit behind CourtListener, brings its case-law collection covering more than 99.9% of published U.S. precedential case law⁠(opens in a new window) into this research experience.

To measure how this configuration improves legal research, we tested Astra for Law’s complete setup on 200 U.S. legal research questions from the private validation set of Vals AI’s Legal Research Bench⁠(opens in a new window). This benchmark measures how well the model can find relevant sources and passages, and how well its research answers meet the evaluation criteria.

At the highest reasoning effort for both systems, Astra for Law passed the evaluation’s overall correctness check on 54.0% of questions, compared with 38.7% for GPT‑6 Astra using web search alone – a 40% relative improvement. Astra for Law also produces more comprehensive answers.

On case-law-focused questions, Astra for Law found 24% more reference cases than GPT‑6 Astra using web search alone at the highest reasoning effort. On the audited set of target passages, it retrieved up to 54% more relevant passages from the correct court opinions, when comparing the systems at the same reasoning effort.

The result is a stronger research foundation for advising on a deal, assessing a dispute, or developing a legal strategy, with reliable authorities the lawyer can examine for herself.

Astra for Law and GPT‑6 Astra’s performance on the Vals AI Legal Research Bench validation set, across reasoning effort settings.

Improving performance on end-to-end legal workflows

Legal research is only the first step. Custom instructions for legal analysis and writing guide Astra for Law in applying that research to the client’s facts, developing arguments or deal terms, and identifying weaknesses and uncertainty. That can mean distinguishing a court’s holding from its other observations, addressing cases that weaken an argument, or explaining how a contract exception shifts risk between the parties.

For example, when prompted to identify good law with similar fact patterns, Astra for Law could both pinpoint relevant precedent and match fact patterns better than other frontier models:

Astra for Law will be initially offered to selected law firms through Trusted Access in ChatGPT and Codex, and will be coming soon to the API. It will appear in the model picker as “GPT‑6 Astra Law” and in the API as gpt-6-astra-law.

“We were grateful to preview early versions of Astra for Law, which were built with legal use-cases in mind. Across both litigation and transactional matters, the models demonstrated impressive research depth and sensitivity to authority. Even at this early stage, they felt like a significant step toward legal-focused AI that is carefully grounded in research that is both current and comprehensive.”

John Savva, Partner, Sullivan & Cromwell

“In our early testing, Astra for Law showed strength across key aspects of legal research: grounding answers in on-point authorities, citing with precision, and offering practical, advisory guidance.”

Niko Grupen, Head of Applied Research at Harvey

Legal-grade trust and controls

Law firms need to protect client confidences and control how AI is used in their practice. We’ve created a special Trusted Access Program for eligible law firms to give lawyers and people working under their supervision access to Astra for Law for professional legal work. For eligible firms, the offering includes Zero Data Retention (ZDR) on our API, and usage of ChatGPT Enterprise is excluded from human review by default.

We are also working with Latham & Watkins, a leader in AI governance, to design for information permissions, ethical walls, client instructions, and firm oversight.

“As AI becomes more capable, so too does the ability to deploy it in environments that demand rigorous governance, oversight, and accountability. This collaboration builds on Latham’s broader investments in AI development, governance, and infrastructure across the firm, which underpin our enterprise-wide strategy for responsible AI.”

Michael Rubin, Chair of Latham’s AI Strategy Committee

Build ChatGPT around your firm’s expertise

With frontier intelligence and the right controls, firms can turn their own precedents, methods, and judgment into AI tools and workflows built to their standards.

Working with selected firms, our forward-deployed engineers have been adapting ChatGPT Enterprise with custom interfaces and integrations to proprietary data, creating tools for each firm’s workflows:

  • Sullivan & Cromwell built an agreement analyzer that brings the firm’s negotiating playbooks and selected precedents into the review of a new deal. It helps lawyers spot risks that emerge when provisions are read together, then turns those findings into proposed redlines and draft client advice they can challenge and refine.
  • Ropes & Gray built a deal diligence system around how its lawyers work through a data room and decide what matters to the deal. It helps them trace findings back to the source and pinpoint questions that could affect an acquisition, such as whether key customer contracts require notice or consent.
  • Cooley built GO Public to bring its capital markets expertise into how companies prepare to go public, from drafting the IPO filing to identifying the risks that deserve management’s attention. When the deal changes, it carries that change across the filing so lawyers can review the implications together.

“Our collaboration with OpenAI has allowed us to rethink how this work gets done – moving lawyers and management teams more quickly through intensive preparation and into questions that require judgment, market experience and strategic thinking.”

Dave Peinsipp, partner and co-chair of Cooley’s global capital markets group

“AI is fundamentally transforming the way legal services are delivered, and Sullivan & Cromwell is committed to being at the forefront of that evolution. Our team is developing custom AI applications aligned with the way our lawyers work. OpenAI's world-class engineering expertise is helping us bring our vision to life through an initial test application. Our collaboration refined the application, enhanced its performance and prepared it for broad deployment. The experience demonstrated the value of purpose-built AI tools supported by a strong technology platform and shaped by our firm's standards. We are excited to continue exploring how such tools can enhance the way our lawyers work and help us deliver even greater value to our clients.”

Robert Giuffra Jr. and Scott Miller, Co-Chairs, Sullivan & Cromwell

“Our clients rely on us for judgment on the deals, disputes, and regulatory challenges that define their industries. We see an extraordinary opportunity in partnering with OpenAI on how its technology can enhance and elevate our capabilities. Together, we are shaping how frontier AI applies to the most demanding legal work, starting with transactional due diligence. Our goal is to put more of our lawyers' insight to work earlier in the process, so clients get faster execution, sharper analysis, and the industry-leading counsel they depend upon.”

Ropes & Gray

Firms can build with their own teams and partner products, with permitted sources and review processes defined for the work.

Frontier intelligence, connected to the most trusted tools in legal

We’re proud to work with the specialist companies who are advancing legal AI. Today, we’re launching 26 partner-built plugins⁠ that help firms go deeper with the tools and knowledge they already use. These plugins cover the practice and business of law. With iManage, a lawyer can draft a negotiation brief in ChatGPT and save it to the matter file; Intapp can surface activities that may need a time entry for review; DeepJudge can bring prior deals into a comparison. Thomson Reuters is bringing HighQ matter context into ChatGPT and previewing a forthcoming CoCounsel Legal connector.

“As AI becomes more open and interoperable, the value is not in connectivity alone. Legal professionals need more than access to information. They need trusted intelligence, relevant enterprise and matter context, purpose built legal capabilities, and the governance required for high stakes work. That is what Thomson Reuters delivers through HighQ and CoCounsel Legal. CoCounsel remains the trusted professional AI system designed to help complete that work. Our work with OpenAI helps make these capabilities available in the environments customers choose, while preserving the accuracy, confidentiality, and accountability they depend on.”

Joel Hron, Chief Technology Officer, Thomson Reuters

The launch includes 9 community plugins from lawyers and legal engineers at LegalQuants, LECG, and Skills.law, with 47 custom skills that practitioners can adapt, extend, or draw inspiration from to do their work in ChatGPT. Community plugins give the people closest to the work a way to keep setting the standard for what these skills can do. We’re also making ChatGPT for Word generally available today, so lawyers can proofread, get suggested edits, and flag formatting issues in the tool they already rely on for drafting.

Our approach is open and composable: firms can use specialist products, bring their own tools and knowledge, and adapt community-built skills to their practice. Partners can keep developing their own applications and workflows, while firms choose how those capabilities fit together. Building on OpenAI should mean getting more from the ecosystem, not replacing it.

Build with us

OpenAI is investing in law for the long term. We’ll keep advancing Astra for Law’s model, settings, tools, and instructions together, guided by rigorous evaluations and feedback from lawyers and legal technology partners. We’ll also keep improving ChatGPT so firms can build around their expertise and connect the tools they use.

Our work with Wachtell, Lipton, Rosen & Katz brings the firm’s litigation and corporate expertise together with our frontier research and engineering to explore how AI can support the work involved in providing sophisticated legal judgment.

“We’ve appreciated the technical depth and willingness to listen that OpenAI’s forward deployed engineering team has brought to our conversations about AI's role in supporting legal work, and are excited about the possibilities of AI to shape the next era of legal practice.”

Wachtell, Lipton, Rosen & Katz

The most ambitious applications will come from the people who practice law and the companies building alongside them. We’re committed to working with this ecosystem so firms can bring their own expertise, standards, and judgment to AI—and serve clients in ways only they can.

To explore early access to Astra for Law, build it into your product, or develop tools around your firm’s expertise, contact OpenAI.

The Daily Front Page 4 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — The Mathematician’s Dissent
article

Why I didn’t sign the Fields medallists’ letter

by simianwords·▲ 245 points·351 comments·gowers.wordpress.com ↗
I was immediately captivated by the problem statement, as well as by the accompanying story.

Why I didn’t sign the Fields medallists’ letter

[This post has been cross-posted to Terence Tao’s blog.]

When I was around 11 I heard for the first time about Fermat’s Last Theorem. I was immediately captivated by the problem statement, as well as by the accompanying story, and made a fairly serious attempt to prove it. And while, unsurprisingly, I failed, I learned a lot from the attempt. Blissfully ignorant of the fact that the n=3 case had been proved by Euler over 200 years earlier, I decided that that would be a good place to start: once I had sorted that out, I was optimistic that I would be ready to tackle the general case.

Since I still couldn’t really see where to start, I decided to simplify the problem further and concentrate on successive differences of cubes, with a view to showing that such a difference could not itself be a cube. At the time I did not know how to express what I was doing in algebraic language, so I did not explicitly try to prove that the Diophantine equation 3n^2+3n+1=m^3 had no solution. Rather, I just worked out some successive differences and stared at them, trying to get some idea of why none of them was a perfect cube. (I should be clear that this story is a reconstruction of what I think probably happened given the few memory traces that remain half a century later rather than a completely reliable account.) At some point, I had the idea of taking the difference sequence of the difference sequence, and discovered that it formed an arithmetic progression. That felt like progress, so I investigated difference sequences a bit more and discovered, purely empirically, the rule that if you start with nth powers and keep taking successive differences, then eventually you get to the constant sequence n!, n!, n!, \dots.

Somehow I never managed to turn this observation into a proof of Fermat’s Last Theorem, and later on my dream of solving it got replaced by other mathematical dreams. However, when I reached the point in my mathematical education where I was taught about taking difference sequences and about what happened to polynomials, I understood those topics much better than I would have if I had not discovered difference sequences for myself and spent happy hours playing around with them. I mention this story just as an illustration of the phenomenon that was strongly emphasized in this letter signed by 25 Fields medallists, that one learns a lot from thinking about a problem, regardless of whether one solves it.

In the end, however, I felt that I could not sign the letter, despite agreeing with much of what it said. Instead, it seemed better to do what I did with the Leiden Declaration and set out my own position in a blog post. But it should be understood that by doing that I am not setting myself up as a member of some opposing camp: indeed one of my worries at the moment is that the mathematical community might become bitterly divided, something I would very much like to avoid. Also, I agree on the fundamental point that we are facing a crisis: I just want to offer a slightly different analysis of what that crisis is. I don’t claim full originality for this analysis, as I know that several other mathematicians have already put forward thoughts that are similar to the ones I have, though (for what it’s worth) I have largely come to these conclusions independently.

On the subject of independence, it will perhaps help if I clarify that while I have contacts in the mathematics group at OpenAI, and have also been given early access to some of their models (typically only a few days before they have been released), and have been given free access to their Pro models once released, I have never been paid by OpenAI. I mention this in the hope, perhaps naive, that what I write will not be dismissed for ad hominem reasons. Another potential reason for my being regarded as “pro-AI” is that, as I have stated publicly several times, I have a group in Cambridge devoted to automatic theorem proving. However, that is actually more of a reason to be anti-AI, since our group has been trying to attack the problem of getting computers to prove interesting theorems by understanding as well as possible how humans prove interesting theorems, so now that LLMs can clearly do it without the help of such insights as we have had, one of the main motivations for our work has disappeared. To put it another way, we have had to swallow the bitter lesson (which of course we were always aware was a distinct possibility, even if the speed at which it happened has taken us by surprise). I do in fact think that it is still a very interesting and valuable intellectual exercise to try to gain this understanding, even if we can use LLMs as black boxes, but that’s a topic for another blog post.

So why didn’t I sign the letter? Let me extract a couple of sentences from it that express what I see as the principal argument being put forward.

But solving problems is only a tool and proxy for achieving the primary goal of conceptual understanding and insight. Forgetting this in the world of AI may turn the tool against the primary goal. Indeed, the mass production at faster and faster pace of “true/false” statements could destroy fertile ground instead of breathing life into new ideas.

Perhaps the main reason I didn’t sign is that I don’t fully subscribe to this view. Instead, I have a more complicated view, which I actually expressed in my essay The Two Cultures of Mathematics a quarter of a century ago, and which can be summarized by saying that there is a spectrum of attitudes in mathematics to the relationship between problem-solving and conceptual understanding. At one end of the spectrum you have mathematicians who are primarily motivated by the wish to solve problems, who see conceptual understanding as a very important means to that end. At the other you have mathematicians who are primarily motivated by the wish to attain conceptual understanding, who see problem-solving as a very important means to that end. I worry that the severe-misalignment letter could be seen as saying that the “right” attitude is to focus on conceptual understanding as the main priority — indeed, the above sentences say that more or less directly. But I think that there are mathematicians all across the spectrum, and that that is a good thing (or perhaps I should say that it has been a good thing up to now — the future is much less certain), and I don’t want to suggest to a large fraction of mathematicians, including myself, that their mathematical temperament is somehow “wrong”.

My own particular mathematical attitude is very similar to one that was beautifully articulated in a Twitter post by Jacob Tsimerman (another non-signatory of the letter), which, now that I look at it, says a lot of what I will be saying here. And that post in turn is a response to Daniel Litt, who is in my opinion one of the wisest commentators on mathematics and AI. His views are expressed in a later post here, which I deliberately didn’t read until finishing this one, and then found, as I expected, that there was significant overlap. I would also like to take this opportunity to recommend an excellent post by Noah Smith entitled The End of the Age of Heroes, in case you haven’t read it.

I have been talking so far about individual mathematical understanding, but I suspect that what concerns most of the signatories is less that than the collective understanding that results at least in part from the human activity of problem solving. My guess is that they would argue, completely coherently, that even if collective understanding is the primary goal, if many individuals are primarily motivated by the wish to solve problems, that’s absolutely fine and contributes to that collective understanding.

With that interpretation, the issue becomes slightly different: is it more important that the collective understanding of the mathematical community should be as advanced as possible or that there should be answers to as many problems as possible? Or are those two aims valuable in different ways, so that there is no point in declaring one of them more important? Or are they so inextricably linked that it makes no sense to argue that one is more important than the other? And when we say “important”, for whom are we saying it is important: for mathematicians, or for society as a whole?

I find these hard questions, so I don’t want just to declare an answer to them. (Do you see what I did there?) Instead, I’d like to try to offer at least some argument for any conclusions I come to, even if they are tentative. So let’s compare two scenarios. In the first, which I think is the more likely actually to happen, models become publicly available that are better at solving problems than virtually all mathematicians. If there are a few residual mathematicians who can do things the models can’t, even they work far faster if they make heavy use of the models. Thanks to this, in a short time we get answers to many questions that we have deeply cared about, but the rate at which we receive these answers far exceeds the rate at which the mathematical community can absorb them. In particular, most of the answers are obtained with zero effort from human mathematicians — just prompts such as “Thank you — please continue”.

In the second scenario, there has been an international agreement, for entirely other reasons, to block the public release of models significantly more powerful than the ones we currently have, and the mathematicians within the tech companies agree to hold off from getting their internal models to solve major problems. Instead, they take guidance from the mathematical community, solving problems only when asked to do so by some suitably representative body that decides that the benefit of receiving a solution of a certain problem outweighs the benefits of humans struggling to solve it over a much longer timescale.

I’d like to consider what the difference would be between these two scenarios both for individual and collective understanding. I’ll begin with individual understanding.

One might argue that for individual understanding, not too much would change if we are suddenly flooded with large numbers of big new results. There is already far more mathematics out there than I have any hope of understanding (for example, despite being fascinated when Fermat’s Last Theorem was proved, I have made no attempt to understand the proof), and even among the parts that I do understand, the parts that I understand because I myself discovered them form a very small fraction, though a fraction that I understand more deeply than anything else (at least temporarily — after a while I forget things and lose quite a lot of the understanding I built up). However, one change, which seems positive, from the perspective of the building up of individual understanding, would be that we would have a much bigger choice of results that we could choose to study. Also, if we found ourselves stuck on some point, AI would be able to help us. The main likely negative change is that we would probably cease to exercise that part of our brains that we use when spending months or years struggling with a difficult research problem, which can be hugely helpful in developing understanding.

I say “likely” because in principle there would be nothing to stop us thinking about very hard problems without consulting LLMs, but in practice it seems unlikely that people would put in the same level of effort that they do now. The situation might a bit like what happened with satnavs, where one could always decide not to use them, to keep the part of the brain active that can look at a map, learn a route, and follow it, but in practice most people succumb to the temptation to use a satnav. (In fact, I myself do try to keep that part of my brain active, and was rather proud of finding my way somewhere recently when I had briefly looked up the route on my phone but then forgotten to bring the phone with me when I actually went there.) But even if all we were doing was reading AI output, I think that the problem-solving muscles in the brain wouldn’t atrophy completely. When students are reading maths papers, I strongly advise them (and I think this is pretty standard advice) to read “actively” rather than “passively”, doing things like trying to prove the result for yourself, looking at the paper only when you feel stuck and need a hint, and even then just trying to get the hint and as little extra as possible. If one reads a paper that way, then one is constantly solving problems, some just exercises and some quite a bit harder. It seems likely that an LLM could get to know what our mathematical background is and feed us with just the right hints to allow us to work our way through a mathematics paper in this active way. Yes, we would lose the particularly deep level of understanding and ownership that comes with having solved a hard problem oneself, but it isn’t clear to me that progress in mathematics would suffer as a result. I would be very interested to hear counterarguments to precisely this point. That is, I would be interested to know what use that level of deep involvement with a proof might have in a world where AI is much better than we are at finding proofs.

How about collective understanding? Let me quote a bit more of the letter.

Indeed, the mass production at faster and faster pace of “true/false” statements could destroy fertile ground instead of breathing life into new ideas.

Often these solutions are announced in a rush, leaving no time for a proper writeup, the isolation of new methods and ideas, and citing relevant previous work of others. As in all creative professions, this raises severe attribution and plagiarism questions. Moreover, without the willing mathematicians who must take care of their development and integration into the mathematical canon, AI-conceived ideas would never become fully alive and the crucial human transmission chain between mathematicians would be lost.

I’ll come back to questions about proper citation and focus on what I take as the core worry here: that if results are proved too quickly, then the digestion process will become impossible. I am definitely worried that results will not be properly digested, but for different reasons.

A first remark is that what AI is producing is not just true/false statements: we now know not just that the Navier-Stokes equation with smooth forcing admits finite-time blow-up, but we have a proof of that, which builds on a great deal of wonderful work done by human mathematicians. Many people used to express the worry that AI would solve our favourite problems with utterly opaque proofs, but that has not turned out to be the case, even if their write-ups often leave plenty to be desired. (Incidentally, I see these inadequate write-ups as almost certainly a temporary annoyance and therefore not as a fundamental threat to mathematical practice or future mathematical understanding.)

Secondly, even if the volume of new results is large, mathematics is a highly specialized discipline, so mathematicians can work in parallel. If, for example, we had to digest 1000 important results in a year that were roughly uniformly distributed across mathematics, then most sub-communities of mathematicians would probably want to understand around 30 of them, and for each individual problem there might well be only a small handful of specialists who would be obvious people to take the lead in reaching this understanding, with that handful varying from problem to problem. So it would be a big task, but not necessarily an impossible one.

In this context, it is worth thinking about the huge volume of output of human mathematicians, which seems to have been increasing recently, even before AI. While I have sometimes heard complaints about this, I have certainly not heard suggestions that human mathematicians should slow down the rate at which they prove interesting theorems. That may be partly because the authors of those theorems take the trouble to write their papers well and give good talks. But what about the large quantity of papers, including important ones, that are not written well and whose authors give incomprehensible talks? That can be annoying, but it is a familiar annoyance and not one that we think of as a crisis.

A third point is that even if the volume of AI output is too big for us to be able to digest it properly, that is not necessarily a bad thing. To draw an imperfect analogy, there is now more content available on streaming services than anyone could possibly watch, with the result that there is almost certainly some very good content out there that is hardly watched at all. But that isn’t obviously a worse situation than if there were far less content and all of it received the attention it deserved. Returning to mathematics, if there were too much AI-generated content for us to be able to digest it, then we could choose which parts of it we wanted to digest.

For that we would need to have some idea what was there (a situation a little similar to how human mathematicians typically learn quite a lot about what results are known in their area even when they do not understand their proofs in any detail). One way one could try to achieve that would be to create a well-designed database, probably with AI help. But perhaps that would be unnecessary, and instead one could simply talk to an LLM and ask it to give a bird’s-eye view of whatever area of mathematics one wanted to understand in that knowing-what’s-there way.

The fear seems to be that some very interesting and important parts of mathematics will be discovered by AI and then overlooked, when had they been discovered by human mathematicians they would not have been overlooked. And that may even be the case, but what matters is whether the amount of interesting and important mathematics discovered by AI that is not overlooked will exceed the amount of interesting and important mathematics that would have been discovered and properly digested by humans with AI having played a more modest role.

In short, it seems to me that while a flood of “big” AI results would be likely to increase the amount of important mathematics that was not properly digested, it would also be likely to increase the amount that was properly digested, which seems like a pretty good bargain.

Let me quickly discuss the problem of AI not properly crediting human mathematicians. I agree that this is a serious problem right now, but it is another problem that I see as temporary. Very soon, the whole “credit system” will surely collapse, since finding an amazing proof will be no more of an intellectual achievement than when a citizen scientist spots through their telescope an object that turns out to be a new comet. Until that happens, it is important to give humans the credit they deserve, since careers can depend on it, but that will soon cease to be the case as well. I have to say that I’m puzzled that this problem exists, since I would have thought that if you asked an LLM to look at a proof and tell you which ideas in it are close to ideas that are in the literature already, it would be extremely good at that task. I hope the answer to this conundrum is not that people have been in such a hurry that they have simply not taken the trouble to do this, but I fear that it might be, at least in some cases. If so, then those who have been careless deserve to be criticized, but it is a minor matter compared with the survival of mathematics, especially if the lack of citations is swiftly put right.

Does all this mean that I am optimistic that mathematicians will end up digesting at least as much mathematics in a post-AI world as it would have if AI had not been able to prove major theorems? Not exactly. But my worry is not that we would be unable to do it, but rather that the social structures that currently support this digestion process will be destroyed and not adequately replaced.

One way that might happen is that AI disrupts society so much, or even kills vast numbers of us, that the preservation of something like the current mathematical tradition ceases to be of any concern: all that will matter is the survival of the human race. But that again is a topic for a different blog post (which in fact I am in the middle of writing).

Let’s assume instead that we get lucky and that AI remains more or less under control. My worry then is that we do not manage to transmit what we know to a new generation of mathematicians. Speaking for myself, my main motivation for becoming a mathematician was the dream that I would solve unsolved problems — the more famous the better. I have also always greatly preferred directly thinking about a problem to reading books and papers and generally learning the mathematics of other people. (I’m not saying that’s good, but just stating a fact about myself.) If the dream of solving a famous problem had not existed, I’m not sure whether I would have become a mathematician. I don’t completely rule it out: maybe what really motivated me was that I had an aptitude for the subject and that solving problems was a way of getting respect from a small group of peers. And maybe I could have tried to gain that respect in a different way, such as thinking very hard about an area of mathematics until I was able to demonstrate to others just how well I understood it. But I’m not sure how motivating that would have been for me. I very much hope that there is a pool of young people for whom it will be a powerful motivation, because I think the survival of a human mathematical tradition may well depend on it.

Thus, the primary risk, as I see it, is that a lot of people who would have done a PhD in mathematics and gone on to become custodians of the mathematical tradition will no longer wish to do so. Those of us who have PhD students, including me, need to try as hard as we can to come up with imaginative ways for them to use their time productively (in consultation with the students themselves, obviously). Whether or not we do a good job with that could make a huge difference to the future of mathematics. A related risk is that the perception among policy-makers will be that mathematicians are no longer needed and that funding will become much harder to come by: we urgently need to come up with good ways of explaining the value of having a large pool of human mathematical experts, even if it is no longer part of their role to find new proofs of theorems.

A final reason that I didn’t sign the letter is that I wasn’t really sure what it was demanding that isn’t happening already. It seems likely that in a matter of not very many months LLMs will be released that are able to solve major mathematical problems, and they will presumably have no trouble at all with more run-of-the-mill problems. However much we might regret that, there is no chance that the impact of such models on mathematics will persuade AI companies to stop their release, though perhaps concerns about safety will lead to some delay and give us a bit more time to work out how to adapt. Assuming that they are released, there will be a flood of new results, whether we like it or not, and it will no longer be the AI companies producing them, though perhaps the pattern will continue that the AI companies will have access to more powerful models and so will obtain more than their fair share of headline results. So I felt that there was nothing to be gained from criticizing AI companies for generating too many solutions too quickly. In fact, it may well be that all that does is bring forward by a couple of months what was going to happen anyway, and perhaps it will even allow the results to be released in a more controlled way than they would have been if they had been discovered by random people once the models were publicly available. Under the circumstances, I think the best we can do is recognise the changes that are coming and try to work out the least unsatisfactory way of dealing with them.

The Daily Front Page 5 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Small Models, Large Claims
article

Bonsai 2 27B: Near-Lossless Compression in a 9x Smaller Footprint

by JonSchneider·▲ 403 points·117 comments·prismml.com ↗
Near-Lossless Compression in a 9x Smaller Footprint

Two months ago, we released our first Bonsai 27B models and showed that a 27B-class multimodal model could be compressed enough to run efficiently on a local device. Today, we’re releasing Ternary Bonsai 2 27B, our most capable model yet.

Based on Qwen3.8 27B, Ternary Bonsai 2 27B brings stronger reasoning, coding, vision, and agentic capability to the Bonsai series while preserving the deployment profile that defines it: a dramatically smaller memory footprint, high local throughput, and better energy efficiency.

Ternary Bonsai 2 27B uses ternary {−1, 0, +1} weights with FP16 group-wise scaling, for 1.76 effective bits per weight and a total model footprint of 5.9GB. The low-bit representation is applied end to end across the language model. It supports a 262K-token context window, multimodal text-and-image input, and is released under the Apache 2.0 license.

Against its full-precision counterpart, Ternary Bonsai 2 27B is more than 9x smaller while retaining 98.2% of aggregate benchmark performance. At this level of retention, compression becomes a deployment unlock: nearly the same capability, in a footprint that can run in far more places.

What changed from the first Bonsai 27B release

Our first Bonsai 27B release was an important milestone, offering a practical way to run 27B-class intelligence on local devices. Bonsai 2 27B focuses on the next step: improving the model quality and runtime performance needed for real-world local applications. Compared with the previous Bonsai 27B generation, Bonsai 2 27B brings:

  • a stronger base model, Qwen3.8 27B
  • higher aggregate capability retention of 98.2% against the full-precision model
  • improved reasoning, coding, vision, and long-horizon agentic performance

Higher capability at the same deployment point

Across a benchmark suite spanning reasoning, math, coding, instruction following, vision, and agentic tool use, Ternary Bonsai 2 27B scores 83.9, retaining 98.2% of Qwen3.8 27B’s aggregate performance.

Capability Ternary Bonsai 2 27B Qwen3.8 27B Qwen3.6 27B
Agentic & Tool Calling τ²-bench, BFCLv3 77.57 79.74 80.05
Coding HumanEval+, LiveCodeBench v6, MBPP+, BigCodeBench 81.58 82.17 82.57
Instruction Following IFBench, IFEval 82.66 81.25 74.53
Knowledge & Reasoning MMLU-Redux, GPQA Diamond, AA-LCR 83.95 86.66 84.71
Math AIME 2026, AIME 2025, GSM8K, MATH-500 96.57 97.06 94.64
Vision CharXiv, A-OKVQA, OmniDocBench v1.6, RealWorldQA, OCRBench v2 78.59 81.64 79.82
Overall 83.9 85.4 83.6

Figure I: Benchmark scores of Ternary Bonsai 2 27B (thinking mode) compared with the full-precision Qwen3.8 27B and Qwen3.6 27B baselines. Full per-benchmark results are in the whitepaper*.*‍

The key result is not only the aggregate score, but where the capability is retained. Coding agents, tool-use systems, multimodal workflows, and long-horizon tasks are particularly sensitive to model degradation because small errors can compound over many steps. Bonsai 2 27B preserves much of the full-precision model’s performance in exactly these areas while operating at a fraction of the memory footprint.

Compared with the full-precision model and other low-bit alternatives, Bonsai 2 27B stands out as an outlier on intelligence density. Many low-bit alternatives become deployable only by giving up meaningful capability in coding, vision, or agentic tool use. Bonsai 2 27B pushes the frontier toward both higher capability and lower memory usage.

Figure II: Intelligence density (per GB) of Ternary Bonsai 2 27B compared to other models in the same parameter class.

Demo I: Coding agents with Cline, powered by Ternary Bonsai 2 27B on NVIDIA GeForce RTX 5090.

Demo II: Computer use powered by Ternary Bonsai 2 27B model on NVIDIA GeForce RTX 5090.

With Bonsai 2 27B, local models can start to take on real knowledge work: coding-agent loops, computer-use workflows, private document analysis, multimodal debugging, and hybrid orchestration where local models handle sensitive or high-frequency tasks while escalating selectively to the cloud.

Throughput and energy efficiency

Ternary Bonsai 2 27B reaches up to 143 tokens/second on NVIDIA GeForce RTX 5090 and 46.8 tokens/second on M5 Max. On an RTX 4090, Ternary Bonsai 2 27B consumes just 0.714 mWh/token, making it 40% more energy-efficient than an 8B model running in full-precision.

For coding assistants, higher throughput means faster edit-debug loops. For multimodal agents, it means quicker iterations over screenshots, documents, and tool calls. For private local workflows, better energy efficiency means more useful inference on the same device, longer battery life, and a more realistic path to assistants that can stay available in the background without constantly calling the cloud.

Why this release matters

Compared to Ternary Bonsai 27B, the new Ternary Bonsai 2 27B has closed the retention gap between the full precision model from 95% to over 98%. This is a significant improvement that makes the current release practically “lossless”. It further cements the notion that low-bit models can be the best way to deploy AI. 

That has implications well beyond local inference. Low-bit models can change the economics and architecture of AI systems across devices, workstations, and datacenters: fitting larger models into the same memory envelope, serving more users on the same hardware, reducing energy per inference, and enabling hybrid systems that dynamically decide what should run locally and what should run in the cloud.

The question will increasingly be not just how capable a model is, but how much useful intelligence can be delivered within a given memory, compute, and power budget. If capability can continue to scale while those requirements fall dramatically, the deployment envelope for future models expands across the stack: from personal devices to large-scale datacenters.

Platform Coverage

Bonsai 2 27B runs on NVIDIA GPUs via CUDA and on Apple devices (Mac, iPhone, iPad) via MLX, through custom low-bit kernels. Model weights are available today under the Apache 2.0 License.

Full technical details of our compression, evaluation, and benchmarking processes are available in our whitepaper.

Work with Us

We work with teams to tailor Bonsai models to their applications, from post-training on domain-specific data to optimizing inference for target hardware. If you’re building AI products with tight memory, latency, or power requirements, we’d love to explore how Bonsai can help. Reach out at contact@prismml.com.

Join Us

PrismML emerged from a team of Caltech researchers and was founded with support from Khosla Ventures, Cerberus, and Google, with continuing support from Samsung. We've spent years tackling one of the field's hardest problems: compressing neural networks without sacrificing their reasoning ability.

If you want to help build the next generation of state-of-the-art AI, we'd love to hear from you. Check out our careers page.

The Daily Front Page 6 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Proof Against Mistakes
article

Bend – A language that blocks AI mistakes via proof, on CPU and GPU

by nicolas-siplis·▲ 434 points·205 comments·bend-lang.com ↗

a fast language that blocks AI mistakes via proof

C speed · CUDA parallelism · Lean proofs · Python syntax

In the post-AGI economy, humans will eventually stop writing and reading code, but we still need an ambiguity-free way to tell the AIs building the world around us what we want done.

With laws, our intents can be much more precise than natural language. With proofs, we can verify that the AI implemented our prompts correctly. And a fast compiler runs it at speed.

That's Bend - and nothing else.

1.Bend runs FAST.

Bend compiles to native code. On one core, it runs nearly as fast as C. The same binary also runs on sixteen cores, or on the GPU, running up to a hundred times faster than one core.

Apple M4 Max · lower is better

2.Bend compiles FAST.

Bend's type checker is a proof checker, as in Lean and Rocq. Those can take minutes on a mid-sized codebase. Bend takes a second at most, so an AI agent can check after every change.

Apple M4 Max · lower is better

3.Bend is PARALLEL.

No threads, no locks, no kernels to write. Split the work in two, and Bend spreads the calls over every core it can find, then joins them back. Now watch pow2 run on 4,096 GPU cores:

pow2.bend running on the GPU

4.Bend BLOCKS mistakes - with proof

How can you trust code you never read? By demanding a proof. LAWS.bend is where you declare laws. From then on, no AI can ship one line that breaks them, ever. Watch it guard a game:

Law: winning is impossible

So far, it works!

New feature:

“Claude, make the board wrap around”

Without LAWS.bend:

Laws broken. AI mistake: merged.

With LAWS.bend:

Laws intact. AI mistake: blocked!

Without LAWS.bend, the bug went live. With LAWS.bend, the AI had to retry until it built a wall and proved the law holds. Merging a bug is mathematically impossible: it is a theorem.

LAWS.bend

# LAW: no move sequence leads to victory.
law you_cant_win:
  for moves: List<Move>            # any sequence of moves
  board = replay(start(), moves)   # replayed from the start
  is_won(board) == False{}         # never leads to victory

PROOF.bend

# PROOF: you_cant_win holds.
def Laws.you_cant_win(moves):
  # ... written by the AI

LAWS.bend is AGENTS.md backed by proof. “Make no mistakes” is now type-checked.

Skeptical? Try breaking the game.

5.Get started.

5.1.Install

curl -fsSL https://bend-lang.com/install.sh | sh

5.2.Tell your agent to use Bend

Add this to your AGENTS.md:

When using Bend:
- run `bend guide` to learn it
- use `LAWS.bend` to keep important rules
- run `bend PROOF.bend` before committing
- parallelize the code whenever possible

Then, just say: "use Bend"!

5.3.Enjoy bug-free, fast vibe-coded apps!

Hints: ask it to write laws for whatever should never break, and to parallelize everything you want running fast. Bend is young: if anything goes wrong, ask it to open an issue. Bend works best on the back-end, on Linux and on macOS. Enjoy! <3

6.References.

Guide: GUIDE.md is the whole language; bend guide prints it. Paper: BendTT, an affine dependent type theory, Bend's core. Paper: BendRT, a parallel runtime for CPUs and GPUs, the VM.

Bend is still evolving. Expect bugs, and please report them.

The Daily Front Page 7 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Proof Against Mistakes
article

Developing provably correct Rust code with Verus

by Betelbuddy·▲ 159 points·74 comments·amazon.science ↗
Verus is an open-source automated program verifier for Rust that mechanically checks code against formal mathematical specifications for all possible inputs.

How the Verus "program verifier", which automatically checks code against a mathematical specification of its functionality, helps increase security assurance in software projects.

Key takeaways

  • Verus is an open-source automated program verifier for Rust that mechanically checks code against formal mathematical specifications for all possible inputs, going beyond traditional testing to catch corner cases.
  • Developers annotate Rust source code directly with preconditions and postconditions using Rust-like syntax, enabling fast feedback loops (under one second) and allowing AI agents to assist in proof generation.
  • Verus enables mathematical verification of Rust's "unsafe" code blocks and concurrent code with custom locking schemes, re-establishing machine-checked safety guarantees for performance-critical implementations like AWS's Nitro Isolation Engine.
  • Amazon uses Verus to prove correctness of key primitives in critical infrastructure, and the tool has been adopted by open-source projects including certificate validation libraries, data format parsers, and distributed systems like Kubernetes controllers.

Many open-source and industry software projects, including several here at Amazon, are embracing the Rust programming language, since it provides performance and flexibility similar to that of the C programming language, while its clever type system automatically prevents a variety of bugs and security vulnerabilities. The result is fast code that's more correct and secure than average.

However, "more correct and secure" is not the same as "actually correct and secure". For example, in C, accessing an array out of bounds — indexing into an array past the boundary of the memory allotted to it — is a dangerous mistake that can have unforeseeable consequences. In Rust, it will halt the program, which is definitely safer, but a correct program would never perform the out-of-bounds access in the first place. Similarly, Rust cannot guarantee that your program will compute the results you were expecting or that it won't leak the secrets it has access to. That's where Verus comes in.

Verus-16x9.gif

Accessing an array out of bounds is a dangerous mistake that can have unforeseeable consequences. A correct program would not permit it.

What is Verus?

Verus is an open-source, automated program verifier for Rust. A "program verifier" takes in a formal mathematical specification of how your code should behave and mechanically checks that your code matches that specification for all possible inputs.

For example, your code might implement an optimized binary-search algorithm to look for a particular value within a sorted array. The specification might state that when the code successfully returns an index, the corresponding element in the array matches the target value. The verifier checks that this specification holds for all possible input arrays and target values.

In contrast, traditional testing techniques might try a few specific arrays but can miss corner cases (e.g., what if the target value is the last element in the array or not present at all?). A key aspect of program verification involves constructing a mathematical proof that the code matches its specification. In an automated program verifier like Verus, the tool automatically handles many of the boring, low-level steps of proof construction, while the human developer provides high-level guidance (e.g., setting up an inductive proof or supplying a loop invariant). As we discuss below, these days, even the high-level steps can often be automated by AI.

At Amazon, we're proud to have been a founding member of the Rust Foundation, and we use Rust extensively for projects like Firecracker, which powers AWS Lambda and AWS Fargate, our serverless distributed SQL database, and the Nitro Isolation Engine, which enforces virtual-machine isolation for the Nitro hypervisor, the software that manages virtual-machine allocation for Amazon Web Services (AWS). Amazon's excitement about Rust, combined with more than a decade of work on automated reasoning, makes it natural to adopt Verus to provide even stronger guarantees for the Rust code we're writing. Indeed, we've used Verus to prove the correctness of key primitives used by the Nitro Isolation Engine, as well as a number of critical pieces of infrastructure used within Amazon. We'll explore these use cases in future posts, but for now, we want to tell you more about what it means to verify Rust code with Verus.

Verifying Rust code with Verus

With Verus, a Rust developer can add specifications (and proofs) for existing Rust code directly in the Rust source files. To extend the binary-search example, consider the following Verus specification (written as a Rust annotation) of the search function's existing Rust implementation:

verus-spec.png

A Verus specification of a search function's Rust implementation, written as a Rust annotation.

The precondition (indicated by the “requires” keyword) states the conditions that must be true before the function executes. In this case, since the code implements a binary search, we require that the array is sorted. The postcondition (indicated by the “ensures” keyword) states the conditions that must be true after the function executes. In this case, it says that if the function returns “Some(index)”, then “index” is within the bounds of the array, and the value at that index matches the value we were looking for.

Importantly, it also tells us that if the function returns “None”, then the target value is not in the array. Without this second clause, the specification could be satisfied by an implementation that always returned “None”! Note that normal Rust compilers ignore these Verus annotations, so Verus-annotated code can be consumed by both verified and unverified projects, including those that use Rust's build tool, Cargo.

This example also illustrates a key design decision that Verus makes, one that distinguishes it from many other Rust verification approaches. With Verus, developers write specifications and proofs in their source code, using Rust-like syntax. When a proof fails, they see Rust-style error messages expressed at the source level. This approach keeps the proofs in sync with the actual code and saves developers from needing to learn a brand-new language and tool for specifications and proofs. It also enables the developers who write the code (and hence know it best) to be involved in the process of proving it correct.

Verus also focuses on providing fast, powerful automation. To do so, it uses a variety of solvers to discharge the proof obligations generated from the programs and their specifications. In practice, this means that developers typically get feedback on their code and proofs in under a second, fast enough to provide an interactive development loop (including "red squiggles" inside interactive development environments like VS Code).

At the project level, Verus can verify complex projects with thousands of lines of code and proof in the time it took some prior automated program verifiers to verify individual functions. This powerful automation and quick feedback loop obviously help humans, but they also help AI agents develop Verus proofs, since the automation means the agent has less work to do and can iterate faster on its proofs.

Rust's type system provides strong safety guarantees, but sometimes it prevents developers from writing high-performance code. Hence, Rust also allows developers to write explicitly labeled "unsafe" code. This code must still uphold all of Rust's expectations for safe code, but the compiler no longer mechanically checks those expectations; it's up to the developer to get it right. With Verus, however, developers can mathematically prove the safety of their unsafe Rust code, re-establishing machine-checked safety guarantees.

Similarly, Rust famously offers "fearless concurrency", meaning that the type system will prevent various mistakes that other programming languages allow when developers write concurrent code — i.e., programs that execute in parallel at least part of the time. Verus builds on this foundation to enable developers to prove that their concurrent code is not just safe but correct.

For example, concurrent execution generally involves locks, which grant a processor thread exclusive access to data items it’s currently manipulating. Verus allows developers to add an invariant property to a lock, meaning that anyone who acquires the lock obtains a value that satisfies the invariant's property (e.g., the value is always even), and when they release the lock, they must prove that the value behind the lock still satisfies that property. Moreover, Verus supports proofs that the lock implementation itself is correct. This is particularly important for programs like the Nitro Isolation Engine, which rely on complex, custom locking schemes to achieve high performance.

Like all program verifiers, Verus's guarantees rely on the correctness of Verus itself, the "top-level" specifications of the program's intended behavior, the "bottom-level" assumptions made about the underlying run-time (e.g., the Rust standard library), and the compiler toolchain that converts source code into executable programs. In future posts, we'll go into more detail on the ways we increase our confidence in these components.

Verus in the open-source ecosystem

In addition to its use at Amazon, Verus has been used to prove interesting properties for a variety of open-source projects. Here are some examples:

  • Vest takes in a description of a binary data format and automatically generates Rust code to parse and serialize data in that format, including Verus proofs of correctness and security.
  • Verdict provides a provably correct and secure certificate validation library for the x.509 public-key cryptography standard, one that supports user-supplied validation policies.
  • The CapybaraKV project verifies the correctness and crash safety of persistent-memory logs, which preserve data in a well-formed state even if the system crashes or loses power unexpectedly.
  • The Atmosphere microkernel is a microkernel (minimal operating system) developed in Rust and verified for correctness with Verus.
  • Anvil proves the correctness and “liveness” of controllers for Kubernetes, an open-source system for managing cloud computing. Anvil shows that under reasonable assumptions, the controllers will eventually bring the system into a stable state.
  • The CortenMM memory management system includes a novel transactional interface with scalable locking protocols, and the correctness of its concurrent code is verified with Verus.

Verus itself is a free, open-source project developed by a distributed collaboration of academic and industrial researchers.

The Daily Front Page 8 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Models That Adapt
article

Infinite-Parameter LLMs: Generating and Adapting Weights from Live Data

by Betelbuddy·▲ 139 points·39 comments·arxiv.org ↗

Abstract

The scaling laws hold that a language model grows more capable with more parameters and more training data, and Mixture-of-Experts (MoE) architectures have ridden these laws to remarkable results, activating only a fraction of an enormous stored parameter bank for each token. That success is built on static pretraining data. A deployed model faces a different world, where much of the data that would make it more useful is not in its training set but in the live interaction it is currently handling, such as the facts a user supplies or the corrections they give. A conventional model cannot learn from this data, because its weights are frozen after training. Instead, the knowledge and behaviour supplied at run time are placed in the prompt, by retrieval or instruction, and re-read on every request only to be discarded once the request ends. We ask how an architecture could learn from live interaction by writing it into its weights. Taking inspiration from MoE, we propose the \textbf{Infinite-Parameter LLM}. A compact hypernetwork turns the data given at run time into a low-rank modulation of a shared base network, so the feed-forward weights are generated from live data rather than stored in a fixed bank. Where prior weight generators read the context once and freeze, we carry a Bayesian belief over the generator's latent code and update it online, so the effective weight is re-derived from that evolving belief as the session proceeds rather than fixed after one read. The stored footprint stays fixed, yet the weights the model can compile are effectively infinite. For the knowledge and behaviour supplied at run time, carrying them in the weights rather than the prompt is amortized in compute, frees the context window, persists across turns, and can generalise better than in-context use. We specify an evaluation protocol that tests exactly this against in-context learning and retrieval.

The Daily Front Page 9 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Models That Adapt
repository

Reverse-engineered Jev-like model

by rochansinha·▲ 160 points·23 comments·github.com ↗
★ 765⑂ 71 forks Python

Train a small model that chooses among a changing list of text options.

A Jev-like model takes a piece of text and a list of N text options. It returns one probability for each option. It does this in one pass instead of writing an answer word by word. Jev is TypeSafe's commercial model for this kind of task. TypeSafe has not published its design. This repository is an independent starter model with the same input and output shape.

Demo

The same option-attention head can score controller buttons from image patches. This ten-second film joins two selected five-second windows: live deadly_corridor combat on the seven Doom buttons, then a chess controller walking to and playing moves with five keys. The diagram shows the tensors used for each decision. The Doom window came from the supplied joint checkpoint, which averaged 0.60 kills and -97.50 reward across its ten recorded episodes. The chess window came from the stronger chess-only checkpoint, which scored 4 wins, 46 draws and 0 losses in 50 sampled games against a random mover, but 0 wins, 2 draws and 48 losses against Stockfish level 0. The windows were selected for activity and are not typical-play or competence claims.

Install the game extras and record a fresh 640 by 480 Doom trace from the released joint checkpoint:

uv pip install -e '.[games]'
python examples/doom/play.py examples/checkpoints/joint-imitation.pt --episodes 10 --game-seconds 35.3 --device cpu --capture-resolution 640x480 --output runs/doom.mp4 --trace runs/doom-trace.json

Render the trace in the same visual layout. This writes a silent film because the author-owned soundtrack source is not part of the repository.

(cd examples/film && npm install && npx playwright install chromium)
examples/film/make-film.sh runs/doom-trace.json runs/doom-film.mp4 10

The release includes the Doom example, the chess example, the single-game checkpoints and the shared 12-option checkpoint. Both games import the visual scorer from jevlike.vision; there is no second model copy in either example.

Architecture

Each option becomes a query vector, which is a short list of numbers representing its text. The query assigns attention weights to the context tokens. Those weights make one context vector for that option. A shared dot product turns each option and context pair into one score. A softmax, which converts scores into probabilities that sum to one, runs across the options.

Each option queries the context, receives an attended context vector, and becomes one probability.

The default encoder learns byte embeddings from scratch. An encoder is the part that turns text into vectors. The optional Hugging Face path uses a frozen pretrained encoder, whose existing weights stay fixed while the small scorer learns.

Data format

Use one JSON object per line:

{"context":"The customer needs a refund.","options":["refund","sales","technical support"],"label":0}

label is the zero-based index of the correct option. Each row may have a different number of options, with a minimum of two.

Quickstart

Run these commands from the repository root. They create local synthetic data, train on it, evaluate the saved model and score one new menu.

uv venv
source .venv/bin/activate
uv pip install -e '.[dev]'

jevlike-data synthetic --output data/synthetic
jevlike-train data/synthetic/train.jsonl \
  --validation data/synthetic/validation.jsonl \
  --output runs/synthetic.pt
jevlike-eval runs/synthetic.pt data/synthetic/test.jsonl
jevlike-predict runs/synthetic.pt \
  --context "Choose the exact badge amber badger. Badge: amber badger." \
  --option "azure crane" \
  --option "amber badger" \
  --option "gold heron"

The evaluation prints top-1 accuracy, which is the fraction of correct first choices. Top-3 accuracy is the fraction with the right answer among the three highest scores. Expected calibration error compares confidence with observed accuracy. The command also prints a shuffled-context control, which pairs each menu with the wrong context. A useful model should beat that control.

Use your own data

  1. Export train, validation and test JSONL files in the format above.
  2. Keep all options that the model will see at prediction time in each row.
  3. Split related records together. For example, keep all records for one customer or one target page in one split. This prevents near-duplicates from leaking into the test set.
  4. Run jevlike-train with your train and validation files.
  5. Run jevlike-eval once on the held-out test file. Held-out means the file was never used for training or model selection.

The default byte encoder truncates context to 192 bytes and each option to 32 bytes. Raise --context-tokens or --option-tokens when your text needs more room. Training supports CPU, Apple MPS for a Mac GPU, and CUDA for an NVIDIA GPU through --device.

Use a frozen pretrained encoder

Install the optional dependency and name any compatible encoder from Hugging Face:

uv pip install -e '.[transformers]'
jevlike-train data/synthetic/train.jsonl \
  --validation data/synthetic/validation.jsonl \
  --output runs/qwen-head.pt \
  --encoder hf \
  --hf-model Qwen/Qwen2.5-0.5B \
  --rank 256 \
  --batch-size 8

The checkpoint stores the trained scorer head and the encoder name. It does not copy the frozen encoder weights. Loading the checkpoint therefore needs access to the same Hugging Face model.

--rank sets the width of the small scorer head. A wider head has more trainable weights and uses more memory.

Wikispeedia example

scripts/get_wikispeedia.sh downloads the public SNAP archives and builds next-click JSONL files. The data stay outside this repository.

scripts/get_wikispeedia.sh
jevlike-train data/wikispeedia/jsonl/train.jsonl \
  --validation data/wikispeedia/jsonl/validation.jsonl \
  --output runs/wikispeedia.pt

Cite Robert West and Jure Leskovec, Human Wayfinding in Information Networks, WWW 2012. Review the source data terms on the SNAP dataset page.

What to expect

In the experiments that led to this starter, the one-pass scorer reached about 98% accuracy on synthetic menus. On target-disjoint Wikispeedia next-click data, a frozen Qwen2.5-0.5B encoder plus the scorer reached 26%, against about 8% for shuffled and random-encoder controls. A small model trained from scratch on 40,000 clicks reached 29%. At eight options, one pass was about 100 times faster than a small decoder forced to write 400 tokens.

These numbers describe local experiments, not this quickstart run. We did not show equal quality with Jev or reproduce TypeSafe's private training method.

Limitations

  • This is a research starter, not a copy of Jev.
  • Accuracy depends on data quality, split quality and the encoder.
  • The byte encoder is cheap but weak on language meaning.
  • The pretrained path may download a large model and needs more memory.
  • One-pass scoring requires the complete option list before prediction.
  • The speed comparison used a small local decoder rather than a large commercial model.

Licence

Code is released under the MIT License. Downloaded datasets and pretrained models keep their own terms.

The Daily Front Page 10 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — The Agent Workshop
show hn

Show HN: Share your AI Setup, Learn from others

by steveybrown·▲ 210 points·119 comments·mysetup.ai ↗

I haven’t got my AI setup figured out either. Let’s compare.

What have they figured out that I haven’t?

I kept seeing other engineers, makers and builders post on Twitter X. Often getting snippets of their setups, and it left me wondering: What have they figured out that I haven’t? What tools are they using? Why did they switch to that agent harness? What skills are they using? And now graph engineering? What the **** is that?

I’m finding it a little overwhelming.

I wanted a dedicated space to see the tools, workflows and systems behind how others build. And somewhere to keep my own setup up to date and easy to share with my friends and colleagues.

That’s why I built this. A community to share how we're working with AI, learn from others, and feel a little more comfortable knowing we don't all have it figured out.

Realistically, It'll be my agent that keeps my setup current and maybe this ends up as a community of one - me, but I hope you’ll take something useful away from my setup and I'd appreciate if you could share yours. Thank you!

The Daily Front Page 11 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — The Agent Workshop
discussion

Launch HN: Skillsync (YC W26) – AI chat sessions made portable across agents

by cat-whisperer·▲ 55 points·53 comments·news.ycombinator.com ↗

Hey HN, we're Nars & Nishant, founders of Skillsync (https://skillsync.com)

Skillsync lets you move your AI chats across every coding agent. Most of our work exists as conversations, which are currently scattered across our agents. Though stored locally, these conversations use different formats. This is annoying because you cannot simply switch between agents without starting over. We get locked into a single provider and their agent as we invest in skills and memories over time. Skillsync acts as a universal converter. It moves the entire session, including all the messages, reasoning and tool calls so you can pick up right where you left off.

Skillsync collects all your sessions in one place and makes them searchable. It breaks down what each session is carrying, including which loaded skills the agent is actually using, making stale context easy to spot. You can also create shared workspaces to sync sessions across your team. You can build your own closed loop systems. Everything runs locally except when you share to workspaces.

The core is an open-source Rust engine called txcript (https://github.com/skillsynchq/txcript). It translates a session from one agent's on-disk format into another's, mapping conversation, reasoning, and tool history. Think ffmpeg or pandoc, but for agent sessions.

On top of that engine is a local-first desktop app. Your agent sessions are normally scattered across different tools' folders in formats you'd never read by hand; the app surfaces them in one place with a UI that makes them actually readable, the conversation, the reasoning, and the tool calls, so you can revisit what happened, move a session into another agent, or share it with a teammate.

Skills and memory are stored as portable, human-readable markdown you own, and exposed to any agent over MCP for search and selective retrieval.

Sessions and translation run locally on your machine. The one thing that leaves is what you explicitly share into a team workspace.

It’s been surprising to us to see how locked-in people already are without realizing it. You don't notice you're trapped in one agent or harness until you try to leave, and by then you've got months of sessions stuck in a format only that tool can read. The lock-in is invisible right up until it's expensive.

Once sessions are portable, they stop being disposable logs and become something you can actually build on, spotting patterns in how you work, handing a session off to someone else, letting a non-technical teammate pick up where an engineer left off. The session turns out to be the unit of collaboration, and right now it's being thrown away.

Before Skillsync, Nars and I built an open-source payment orchestrator that let merchants route across many processors instead of getting locked into one (30k+ GitHub stars). Fighting vendor lock-in by making incompatible systems interoperate was the whole job. We came into YC with a different idea, but the more we lived inside coding agents the more we saw the same problem from the other side: your context is locked into whatever agent you start with, because every agent stores sessions differently and none of it moves.

Some of the things we’re seeing people do with Skillsync are:

  • Moving a session between Claude Code, Codex, and Cursor mid-task, including when you hit a usage limit on one and want to keep going on another.

  • Thinking through a problem in a browser Claude chat, then handing the whole thread to Claude Code or Codex to build.

  • Sharing research sessions with a team. Everyone uploads their sessions, so teammates and their agents can build on each other's work instead of repeating it.

It's available as a Mac app, CLI and MCP. Here's the demo: https://youtu.be/7hVhSnSKGl8. Would love to hear your feedback and answer questions!

The Daily Front Page 12 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Private Tools & Public Platforms
repository

Hister: A private search engine for the pages you visit and the files you keep

by bookofjoe·▲ 578 points·155 comments·github.com ↗
★ 4,522⑂ 193 forks Go

Your own search engine

Your own search engine

Hister is a private search engine for the pages you visit and the files you keep. It indexes their full contents so you can find information again from the web interface, terminal, or an AI assistant connected through MCP.

Try the demo · Download Hister · Read the quickstart · Documentation

Hister web interface

Quickstart

  1. Download the binary for your platform from the latest release, then rename it to hister (hister.exe on Windows).

  2. On Linux or macOS, make it executable:

    chmod +x hister
    
  3. Start Hister on Linux or macOS:

    ./hister listen
    

    On Windows, run .\hister.exe listen in PowerShell.

    Keep this terminal open while using Hister. The server must be running to index pages and search them.

  4. Open http://127.0.0.1:4433 and install the browser extension for Firefox or Chrome.

  5. Visit a web page with the extension enabled, then return to Hister and search for a phrase from that page to find your first indexed result.

No configuration is required for a local personal setup. See the complete quickstart to choose what Hister indexes.

To search existing content, import browser history, index local directories, or import files.

Alternative installation methods include Homebrew (brew install hister), Docker, and Nix. See the installation guide for instructions.

Features

  • Privacy focused: No telemetry or mandatory cloud service. Run Hister locally or on infrastructure you control.
  • Full text indexing: Search the actual contents of visited pages and local files, not only titles and URLs.
  • Automatic browser indexing: Save newly visited pages with the Firefox or Chrome extension.
  • Powerful queries: Use field filters, phrases, wildcards, negation, aliases, and result priorities.
  • Optional semantic search: Find documents by meaning through an embeddings endpoint you configure.
  • Crawler and browser import: Index websites or bring in existing browser history.
  • Web, terminal, and MCP clients: Search from the browser, TUI, command line, or an AI assistant.
  • Multi user support: Keep each user's documents and search results separate on a shared server.

Hister terminal interface

Privacy

By default, Hister has no telemetry and no cloud sync. The browser extension sends indexed page content only to the Hister server you configure, apart from downloading page favicons. The server stores documents and search indexes on that server.

Optional semantic search sends document text to the embeddings endpoint you choose. Review the privacy overview and semantic search configuration before enabling remote integrations.

Why Hister?

Unlike traditional search engines, Hister builds a personal search index from the web pages and files you choose to keep. Your content stays on your Hister server, making it useful for finding information you've already encountered without relying on a third-party search provider.

Development

Requirements are Go 1.26, npm, and a C compiler for CGO dependencies.

git clone https://github.com/asciimoo/hister.git
cd hister
./manage.sh build

To work on the web app with hot reload and automatic Go rebuilds:

npm run serve:app

This starts a Vite development server and the Go backend with automatic rebuilds through air.

Community and contributing

Join us on IRCNet in #hister or on Discord.

Read CONTRIBUTING.md before submitting a change. Bugs and suggestions belong in the issue tracker. For security reports, see SECURITY.md.

Sponsors

Uruky

License

AGPLv3 or any later version

The Daily Front Page 13 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Private Tools & Public Platforms
repository

Rate limits on GitLab.com are changing

by darkwater·▲ 164 points·116 comments·about.gitlab.com ↗

Starting October 19, GitLab.com rate limits will align with your subscription. Sign in to unlock higher limits. Premium/Ultimate changes arrive in January.

GitLab.com hosts millions of projects for teams of every size that need a platform they can rely on. Demand is climbing quickly, and we expect platform load to grow several times over this year. Predictable limits are what keep GitLab.com fast for everyone on it, including the automation and agent workloads teams are building on the platform.

To hold that as we scale, we're updating how rate limits work. Starting October 19, 2026, rate limits on GitLab.com will align with your subscription tier. Free accounts and unauthenticated requests happen first, on October 19. Premium and Ultimate move in January 2027.

What is changing

Limits align with your subscription. Free, Premium, and Ultimate subscription plans get their own limits, applied per user and per top-level group. Free takes effect October 19; Premium and Ultimate in January 2027.

Signing in gets you the full limit. An authenticated request is governed by your subscription plan below. A request that arrives with no credentials gets 60 requests per hour per IP address.

The per-plan limits are published in the rate limits documentation.

What happens on October 19

There will be two preview windows for Free and unauthenticated traffic, on October 7 and October 14 from 15:00 to 19:00 UTC. Signed-in Premium and Ultimate requests are not affected, since those limits do not change until January. Unauthenticated requests are capped no matter where they come from, including automation running against a paid account without credentials. A preview window (engineers call these brownouts) is a short, planned window where we switch the new limits on and then switch them back off. Nothing else about the service changes while it runs. The point is to give you a real look at how your own workloads behave under the new limits, weeks before they apply for good.

On October 19 the new limits take effect.

We set these limits by looking at how GitLab.com is actually used. Almost all users are already inside the new limits and won't notice any change. We also looked at what similar platforms allow. The Free limit and the anonymous allowance match the industry norm, while Premium and Ultimate are more generous, at levels other platforms reserve for their enterprise tiers or don't publish at all.

If you're close to a limit

If you find that you are nearing a limit, authenticate your requests. It's usually a small change: Invoking a personal access token, an OAuth token, or the CI/CD job token all move a request off the anonymous 60 requests per hour and onto your plan's limits, which are much higher.

Next, look at how you're calling the API. Batching, caching, and pagination go a long way, and polling in a tight loop burns through your allowance fast. When you do cross a limit, you get an HTTP 429 back with a Retry-After header saying how long to wait, so a client that reads its own response headers mostly fixes itself. Backing off exponentially recovers faster than retrying immediately.

Upgrading to Premium or Ultimate increases the limits, too, per user and per top-level group.

If you need a higher limit on an ongoing basis, we are working on a way to purchase capacity above the standard plan limits, with details coming later this year. If that sounds like you, reach out to your account team or email limits@gitlab.com and tell us what you need.

What changes and what doesn't

These limits are set so no single workload can slow the platform for everyone else. Ordinary signed-in work isn't the target, and, for almost all users, a normal day looks identical. Browsing the UI, working in your editor, pushing and pulling with git, and running CI/CD within your plan all carry on exactly as they do today. Some heavy automation and a small number of Free-tier workloads will reach the new ceilings.

What doesn't change:

  • You can always reach and export your own data and repositories.
  • GitLab Self-Managed and GitLab Dedicated limits stay with your operator. This is only a GitLab.com change.
  • We'll notify you before we make additional changes.

A reminder: Make sure to authenticate your requests to GitLab.com so your limits are higher.

FAQ

How do I know whether this affects me?
Compare your busiest minute against the published limits for your plan. Most customers are not close. The quickest signal in the meantime is the RateLimit-Remaining header on your API responses, which tells you how much of your current window is left, and we are building a view in the product for release later this year that shows your usage against your plan's limits.

My project is public and busy. What are my options?
Three things help. Ask the automation that calls your project to sign in, which moves it onto its own limits rather than the anonymous allowance. Make the project private if the traffic is not coming from the audience you built it for, which stops anonymous callers reaching it at all. Or upgrade to Premium or Ultimate for much higher limits.

What if I am a member of several top-level groups?
Your user limit will be the highest subscription tier available to you. If you are a member of an Ultimate group, you will have access to the Ultimate limit.

What happens when I hit a limit?
You get 429 Too Many Requests with RateLimit-* headers and a Retry-After. Wait the interval it gives you, then retry.

My integration genuinely can't authenticate. What now?
Reach out to us at limits@gitlab.com. There are legitimate anonymous patterns, a public status badge being the obvious one. If you are concerned that an integration you own may be affected, contact us.

Does this apply to GitLab Self-Managed or GitLab Dedicated?
No. This is a GitLab.com-only change.

Additional resources

The Daily Front Page 14 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Security Desk
article

A 32-year-old bug walks into a Telnet server

by paimapi·▲ 107 points·45 comments·labs.watchtowr.com ↗
This vulnerability was born so long ago (way back in 1994) that it may even be older than you.

A 32-Year-Old Bug Walks Into A Telnet Server (GNU inetutils Telnetd CVE-2026-32746 Pre-Auth RCE)

A long, long time ago, in a land free of binary exploit mitigations, when Unix still roamed the Earth, there lived a pre-authentication Telnetd vulnerability.

In fact, this vulnerability was born so long ago (way back in 1994) that it may even be older than you. To put the timespan in perspective: it came into existence the same year the seminal movie Hackers was released.

That was so long ago that RISC was still a distant dream.

Come to think of it, maybe it was even the product of Zero Cool himself?

Anyway. Recently, this vulnerability was brutally put to rest.

What Are We Looking At Here?

If you're not familiar with Telnet, that's okay.

Telnet is a network protocol that provides a command-line interface for communicating with a remote server over TCP/IP. In other words, remote code execution as a service. Typical setups do have an authentication barrier, requiring you to log in before you can access the system's shell. It also operates over plaintext, which means yes, it transmits your username and password across the network in the clear.

The de facto replacement these days is SSH, and Telnet is becoming increasingly uncommon.

What Is CVE-2026-32746?

CVE-2026-32746, discovered by the DREAM Security Research Team, is a BSS-based buffer overflow that allows an attacker to corrupt roughly 400 bytes of adjacent variables.

It resides in the LINEMODE SLC (Set Linemode Characters) negotiation handler. While strictly speaking it affects 'just' GNU inetutils, most vendors have based their Telnetd implementations on the same code, making the blast radius vast and somewhat difficult to estimate. It definitely includes all the major Linux distributions (we checked).

With a vulnerability like this, we expected the Internet to explode with excitement - yet it’s been almost a week now with no good analysis. We thought we might as well publish where we got to.

We’ll go through a few things - how we isolated the vulnerability, what it enables attackers to do (and under what circumstances), and we’ll talk about why this particular vulnerability is more of a Pandora's box to exploit than you might think.

But let's start with the obvious question, which we're sure is on the lips of everyone living in a magical Unicorn land where legacy technologies simply don't exist: why use Telnet in the first place?!

What’s Affected?

Well, this is a tricky one. The patch was applied to inetutils-telnetd, but many forks exist, and changes have been made throughout the years, copying and pasting this vulnerability from system to system.

We have identified this CVE in at least the following:

It’s 2026, Why Telnet? Where Is The MCP?

Telnet has been around since the dawn of time. Many of you will be screaming at your screen right now - ‘who would use such an insecure protocol?!’.

Well, as some of you may be surprised to learn, the venerable Telnet is still very much present on production systems, for a surprisingly wide variety of reasons. Maybe it's the only thing the vendor supports ('This CNC machine costs $X thousand a minute in downtime if it breaks, and you want to add... what?! An SSH client?! Dude, it runs on an 8-bit microcontroller!'). Maybe there's some deeply technical reason migration isn't possible.

The fact remains: people still run it, as evidenced by its strong presence in the repositories of every major distribution. It has truly stood the test of time.

A Vulnerability In Telnet?! Isn't Telnet Just, Like, The Same As Netcat?

Some of our readers, blissfully unaware, may be under the impression that Telnet is simply a TCP stream at the protocol level. Indeed, some implementations are exactly that: a TCP socket connected to a shell. Simple, impossible (?) to break.

This, however, is not the case. Telnet supports a range of features: terminal control (want to turn on echoing? turn it off?), client window size negotiation, authentication, and even encryption. We're sure that somewhere, some poor soul is tasked with maintaining enterprise security across all of these features.

As everyone knows, 'more features' means 'more attack surface'. Everyone remembers CVE-2026-24061, right? In that bug, a Telnet protocol feature intended to share environment variables with the server could be abused for RCE. Pretty painful, and less far-reaching than today's vulnerability, though considerably easier to exploit.

This particular vulnerability resides in the 'LINEMODE' feature of the Telnet protocol. As RFC 1184 puts it:

While in Linemode with editing enabled for the local side, network traffic is reduced to a couple of packets per command line, rather than a couple of packets per character typed. This is very useful for long delay networks, because the user has local response time while typing the command line, and only incurs the network delays after the command is typed. It is also useful to reduce costs on networks that charge on a per packet basis...

Yes, the vulnerability is so old, it dates from a time when networks charged on a ‘per-packet basis’.

The real details of the feature itself aren’t super-important to us (our priority is simply ‘hack all the things’). However, to get to the vulnerable code, we’ll need to know how to enable it, which means we need to learn a little about how Telnet negotiates connection parameters.

Tense Negotiations

For interoperability, the Telnet client and server won't enable these fancy options by default. When a connection is first established, some in-band signaling takes place (ho ho ho, whenever did that go wrong) via the IAC, or 'Interpret As Command', byte, defined as 0xFF.

There’s a whole bunch of things that can be negotiated, like local echo, for example, or the speed of your teletype (remember those? We don’t). As previously alluded to, however, the feature we’re interested in is the ‘LINEMODE’ option.

One of the things defined by this feature, named SLC (or ‘Set Linemode Characters’), is particularly interesting. It enables the server to communicate with the client and inform it that certain special features - whizz-bang new technology like ‘backspace’, for example - should be represented by specific control codes.

To zoom in a little, let’s take a look at a hypothetical negotiation. First, we connect to a Telnet server via TCP. The server immediately sends the following data:

IAC DO LINEMODE (or 0xFF 0xFD 0x22, for those that prefer hex)

Here, the ‘DO’ is indicating that the server is requesting the capability. To enable it, the client responds with a ‘WILL’:

IAC WILL LINEMODE (0xFF 0xFB 0x22)

Once that’s sorted, the server sends a list of three-byte triplets, each indicating a special character to be replaced, the ‘support level’, and the actual character value. The client can then take a good look, decide if it wants to modify any, and if so, send a reply containing new values - again, a list of three-byte triplets.

IAC SB LINEMODE LM_SLC <triplets> IAC SE (0xFF 0xFA 0x03 <triplets> 0xFF 0xF0)

The server will duly store all these values in a global array of a fixed size, without doing any bounds checking. Wait, what?!

Yes, that’s the vulnerability. Undetected since 1994, people. The patch is as close to modern art as information security will ever get.

But wait! It gets even ‘funnier’!

What could be funnier, you ask?

Well, what if exactly the same vulnerability was present in the Telnet client, rather than the server, way back in 2005?

Yes, it’s true, folks. CVE-2005-0469 is this vulnerability’s doppelganger - essentially the same, but on the client side, where a function named slc_add_reply was missing a bounds check. The fix is an identical bounds check patch to today’s vulnerability.

Thankfully, twenty years later, somebody thought to check the server end for the same vulnerability.

They say history doesn't repeat, but it sure does rhyme.

On To Exploitation

Of course, as many of our readers know, this isn’t the end of the story - nay, this is merely the beginning of our odyssey of pain.

  • Yes, it’s a new vulnerability.
  • Yes, it’s a CVSS three squillion.

But can baddies actually exploit it to do something useful?

Well. That’s the question we’re here to answer.

Unfortunately, though, the answer is somewhat muddy and requires a little bit of nuance. Yes, we can overflow a global variable with data we control (and thus corrupt the memory locations that follow it). But that’s where the happy days end, and the real world sets in.

Firstly, the data we can send to the server is somewhat limited. As mentioned before, it is in the form of triplets: a function, a flag, and a value, each 1 byte long. Each of these has its own restrictions, mostly found in the process_slc function.

Let’s take a look at it.

void
process_slc (register unsigned char func, register unsigned char flag,
	     register cc_t val)
{
  register int hislevel, mylevel, ack;

  /*
   * Ensure that we know something about this function
   */
  if (func > NSLC)
    {
      add_slc (func, SLC_NOSUPPORT, 0);
      return;
    }

Here’s our first restriction - if the func byte is greater than the NSLC constant (which comes to 0x1e), then the rest of the triplet will be discarded. While the first byte makes it through unscathed, the remaining bytes are set to SLC_NOSUPPORT (which is zero) and zero itself. This triplet is then added to the global variable via add_slc.

Not ideal, but we can work with it, right?

What’s the rest of the function look like?

  /*
   * Process the special case requests of 0 SLC_DEFAULT 0
   * and 0 SLC_VARIABLE 0.  Be a little forgiving here, don't
   * worry about whether the value is actually 0 or not.
   */
  if (func == 0)
    {
      if ((flag = flag & SLC_LEVELBITS) == SLC_DEFAULT)
	    {
    	  default_slc ();
    	  send_slc ();
    	}
      else if (flag == SLC_VARIABLE)
    	{
    	  send_slc ();
    	}
      return;
    }

Ah. This is also somewhat troublesome - if the function is zero, then our triplet also doesn’t make it to the global buffer. Hm. What about the rest of the triplet, though? Surely they don’t also have similar constraints?

Well, the good news is that the process_slc function gives us no more trouble. However, it does hand off to change_slc, which does some further mutilation of our formerly so nice triplets.

Intended to transform the values sent by the client, based on the server’s capabilities, the server will perform some modifications before accepting the SLC:

hislevel = flag & SLC_LEVELBITS;
mylevel = slctab[func].defset.flag & SLC_LEVELBITS;
  /*
   * If client is setting a function to NOSUPPORT
   * or DEFAULT, then we can easily and directly
   * accomodate the request.
   */
if (hislevel == SLC_NOSUPPORT)
{
      slctab[func].current.flag = flag;
      slctab[func].current.val = (cc_t) _POSIX_VDISABLE;
      flag |= SLC_ACK;
      add_slc (func, flag, val);
      return;
}

What’s going on here?! Well, the server is taking the bottom two bits of the ‘flag’ - the second byte in our triplet - and using this to set ‘hislevel’. This indicates the level of support that the client has (who, it seems, the Telnet server has determined to be male). If this is SLC_NOSUPPORT - zero - then the flag has SLC_ACK (0x80) set, and is added to the SLC array.

The end result is that if the bottom two bits of the flag byte are zero, the top bit is set.

Hm.

0xFF, too, get special handling - a blessing or a curse, depending on what is needed at that particular point. As you can see, each byte in the triplet is checked, and if it is found to be 0xff, then it is doubled to 0xff 0xff. This enables us to expand our triplet from 3 to 4, 5, or even 6 bytes.

This has a critical consequence for the exploitability of the vulnerability.

  if ((*slcptr++ = (unsigned char) func) == 0xff)
    *slcptr++ = 0xff;

  if ((*slcptr++ = (unsigned char) flag) == 0xff)
    *slcptr++ = 0xff;

  if ((*slcptr++ = (unsigned char) val) == 0xff)
    *slcptr++ = 0xff;

This does prevent us from sneaking in an odd number of consecutive 0xff bytes - we can’t represent 0x11 0xff 0x22 , although we can represent 0x11 0xff 0xff 0x22 or even 0x11 0xff 0xff 0xff 0xff 0x22 . This is a major hurdle, particularly on 64-bit x86 systems, which often have repeating 0xff bytes in specific positions.

However, this cloud does come with a silver lining: alignment. Since each of the three bytes in a triplet has a different set of constraints, we can pad the buffer with 0xff to align our triplets slightly differently, and maybe - just maybe! - squeeze the data we need into the place we like it.

0xFF In Triplet size Bytes written Alignment shift None 3 [F, flag, V] +0 func 4 [0xFF, 0xFF, flag, V] +1 val 4 [F, flag, 0xFF, 0xFF] +1 func + val 5 [0xFF, 0xFF, flag, 0xFF, 0xFF] +2

This technique comes in very useful when trying to align a particular func, flag or val inside a particular offset within an adjacent variable.

For example, the val byte could be aligned to overwrite the least significant byte (LSB) of a pointer for a partial overwrite.

From there, the code becomes a little more difficult to explain so succinctly, but the end result is that we can be assured that a fair amount of ingenuity is required to find malicious inputs that meet all the requirements.

AND THEN THINGS GET EVEN HARDER.

The data that we send must fit into a single Telnet ‘subnegotiation’ packet, which is 0x200 bytes. The slcbuf variable itself, which we overflow, is sized at 0x6C bytes. It already contains four header bytes, which is fortunate, but this restricts us to overwriting the immediate 0x190 bytes.

It does seem like a lot, but let’s see what that gets us.

What We Tried

From here on, everything is specific to a particular Telnetd binary. With each compilation, the compiler places global variables as it sees fit, meaning that global variables that fall within our window of overwriting on one system may differ on another system. We invested some time reviewing implementations we had to hand.

What we found was somewhat interesting, although also a harsh dose of reality. It’s worth noting upfront that we didn’t find a direct route to exploitation on any of the systems we observed, though we did observe varying degrees of exposure. We also found that exploitation on 64-bit x86 systems was significantly more difficult than on other systems due to the constraints we’ve enumerated above.

For example, on 64-bit systems, pointers typically have many consecutive NULL bytes, such as 0x0000000802215180 . In this case, to perform a full overwrite of the pointer, we need to write 3 consecutive NULL bytes, which is not possible as no aligned func/flag/val allows us to write this. Therefore, the only way to overwrite a pointer on 64-bit systems is to do a partial overwrite when targeting little-endian.

In other cases of Telnetd being compiled, the adjacent variables within the overwrite range had no security impact, either they changed a value that never gets used, or the value was overwritten by the server before being used.

Rather than try to explain the relative vulnerability of each OS, we’ll stick to the one that seemed the most interesting - although it is somewhat vintage.

Debian - 32bit Edition

After some difficulty attempting to exploit a 64-bit x86 system for RCE [not pictured], we started to wonder - perhaps a lot of the legacy systems that run Telnet are of the 32bit x86 variety. Would exploitation be more convenient on those?

We turned to Debian - which interestingly, dropped support for 32bit x86 systems some time ago, meaning this vulnerability is forever - and installed bookworm, a relatively old version, but the newest to support a 32bit environment. We threw the Telnetd binary into our favourite disassembler, and found that things were much more interesting.

IDA Disassembly of slcbuf and adjacent variables

Here you can see the slcbuf variable, which we can overflow, and a handful of variables following it (there are more not shown above - rest assured, they are irrelevant for our purposes). There’s slcptr - a pointer into the slcbuf - and then slcchange, a relatively boring boolean. After a length variable, there’s an innocent-looking variable named def_slcbuf. Let’s take a look at the source and see what this variable does.

void do_opt_slc (unsigned char *ptr, int len)
{
  ...
  if (terminit ())
  { 
	  /* actual processing logic omitted */ 
  }
  else
	{
		/*
		 * save this slc buffer if it is the first, otherwise dump
		 * it.
		 */
		if (def_slcbuf == (unsigned char *) 0)
		{
		  def_slclen = len;
		  def_slcbuf = (unsigned char *) malloc ((unsigned) len);
		  if (def_slcbuf == (unsigned char *) 0)
		    return;		/* too bad */
		  memmove (def_slcbuf, ptr, len);
		}
  }
}

void deferslc (void)
{
  if (def_slcbuf)
    {
      start_slc (1);
      do_opt_slc (def_slcbuf, def_slclen);
      end_slc (0);
      free (def_slcbuf);
      def_slcbuf = (unsigned char *) 0;
      def_slclen = 0;
    }
}

Well, it's pretty obvious (or maybe we’ve just been staring at this codebase too long?). If terminit isn’t set when the SLC triplets are received, no actual processing is done - rather, the def_slcbuf buffer is allocated (via malloc), and the packet is copied into it. Later on, once terminit is satisfied and the terminal is initialised, deferslc is invoked, which then does the processing ‘for real’, and releases the def_slcbuf via free.

Sounds fairly mundane, right?

Well, actually, it’s not - it’s a gateway to [almost] exploitation.

Our first step is triggering this ‘defer’ behavior in the first place. To do this is straightforward - when the server advertises supported features, we can simply send a response to the LINEMODE feature before we send a response to the TTYPE feature. Once the server receives the TTYPE data, it will consider terminal initialisation complete, terminit will return true, the LINEMODE will be processed (including our overflow!), and finally, the def_slcbuf will be released via free.

[SERVER] ← IAC DO TTYPE
[SERVER] ← IAC DO LINEMODE
[CLIENT] → IAC WILL LINEMODE
[CLIENT] → IAC WILL TTYPE
[SERVER] ← IAC SB LINEMODE 0110 IAC SE
[SERVER] ← IAC SB TTYPE 01 IAC SE
[CLIENT] → IAC SB LINEMODE (…) IAC SE <save SLC into def_slcbuf>
[CLIENT] → IAC SB TTYPE (…) IAC SE <_terminit = 1, do_opt_slc(def_slcbuf)>

Aha, did you spot that? We snuck in the meat of our technique right under your nose, there. The def_slcbuf will be released via free. Since we control def_slcbuf - we overwrote it with SLC triplets - we can cause free to be invoked on any memory location we choose. This is a very powerful primitive.

Of course, exploitation from here on out depends heavily on the libc being used on the target. On many lighter embedded systems, this will quickly lead to RCE via an arbitrary write. On a Debian system, however - even one as outdated as the 12.13.0, which we were forced to use for 32bit support - the heap is less naive, and will perform a fair amount of checks on the data before actually unlinking chunks.

In a full-featured codebase, there would be a plentiful supply of function pointers conveniently located in heap chunks, just waiting to be overwritten. However, the Telnetd source is an artifact of a different time, and that shows in the coding style [please don’t come for us Unix greybeards, we love you]. Dynamic allocations are not something that are found often here, and when they are, they are defensively checked with a rigor unheard of by modern-day JavaScript engineers - perhaps this is part of why the code has survived for so long without requiring many additions.

However, as we noted earlier, complexity slowly creeps in with the protocol's more advanced functions. If you’re unlucky enough to maintain a Telnet server that uses Kerberos authentication - yes, that’s a real thing! - then the opportunities presented to attackers for exploitation are much more frequent. Even the complexity introduced by the libc may be enough for sufficiently skilled attackers to exploit to pry open the application.

This is a really good example of the nuance involved in this vulnerability. A seemingly benign choice made entirely at the whim of the compiler, run years ago, has just transformed our vulnerability from “huh that looks hard” to “oh wow, arbitrary free!” and pushed it a lot closer to the feature-complete status of RCE.

Detection Approaches

Here at watchTowr, we love providing complete end-to-end Detection Artifact Generators for interested parties to use to prove the status of their own systems. This vulnerability, however, is not so simple - we’re bereft of a functional exploit for the systems we tested, and even if we had one, it would probably be worthless for any other systems.

We can, however, provide a detection artifact generator that performs almost the same thing. For this, we can leverage the ‘negotiation’ part of the process.

If you take another look at the patch above, you’ll see that it deals with an overflow condition in a very minimalist way - if the provided data would overrun the slcbuf buffer, it is simply ignored. This is effective and prevents exploitation, but it doesn’t give the client any feedback - if the server sent some kind of error message, or even terminated the connection, it would be trivial to detect, but alas, we don’t have that luxury here.

However, when we discussed negotiation earlier, we left out one relatively minor detail: once the client sends SLC data to the server, the server will respond by sending its own SLC list back to the client, generated from the client's requested inputs and merged with its own environment. Since the server will silently ignore everything that won’t fit in the buffer, we can simply send junk data to fill the buffer, followed by some unusual value. A vulnerable server will store the unusual data, even though it overflows the buffer, while a patched server will silently drop it. If we see the ‘unusual value’ in the response, we know the target is vulnerable.

There is one thing we need to point out before directing our beloved readership to our detection artifact generator. We have carefully engineered our detection artifact generator to perform the most minimal, non-invasive overflow, overwriting a single byte beyond slcbuf. It would take a truly unlucky individual, but it is possible that - if a server is indeed vulnerable - this wayward byte could cause a segfault, or possibly something even worse (the greybeards reading this post direct us to use our newfangled internet search engine to look up the term ‘nasal demons’ for an example of the possible consequences).

The server process is typically (we want to say ‘always’, but we’re not that dumb) spawned under the careful ownership of inetd , which means that even a segfault wouldn’t cause any visible harm - the Telnet session would drop, sure, but the daemon itself (and even other concurrent users) would not be affected.

Of course, all this logic assumes that the server even supports the LINEMODE feature. Many embedded applications are simple enough that they don’t provide this function. Some don’t even offer any form of negotiation. It’s a good ‘first test’ to very quickly assess the exposure of an estate - sure, the CNC shop floor looks terrifying when you see 200 hosts with Telnet open, but if all they do is pipe to some dodgy C app, they’re not going to be exposed to this particular vulnerability (although we’re sure they have some nice vulnerabilitys all of their own).

For these two reasons, we’ve equipped the Detection Artifact Generator with a simple ‘probe mode’ in addition to the ability to actually overflow the target buffer. This ‘probe mode’ will simply connect to a server and wait to see if the LINEMODE feature is advertised. It will then print a message indicating if the feature is enabled, and immediately exit, without sending any overflow attempt to the target. This should be enough to placate even the wobbliest of Telnet-sporting antique industrial machinery (but we’re still not paying to fix it if it catches fire).

To demonstrate, here’s a screenshot of the test in action, detecting a vulnerable 32bit x86 Debian install:

For the techies who want to know what’s happening under the hood, run the script with --verbose and see the underlying bytes:

python3 watchtowr-vs-Telnetd-CVE-2026-32746.py --rhost 192.168.0.154 --verbose
...
[#] Triggering overflow with SLC subnegotiation...
[>] IAC SB LINEMODE (
    010041 010041 010041 010041 010041 010041
    010041 010041 010041 010041 010041 010041
    010041 010041 010041 010041 010041 010041
    010041 010041 010041 010041 010041 010041
    010041 010041 010041 010041 010041 010041
    010041 010041 010041 010041
) IAC SE
...
[<] IAC SB LINEMODE (
    03
    018041 018041 018041 018041 018041 018041
    018041 018041 018041 018041 018041 018041
    018041 018041 018041 018041 018041 018041
    018041 01800d 0a4c69 6e7578 20362e
    312e30 2d3434 2d3638 362d70 6165  (2864
    626961 6e3131 292028 7074 732f3129 0d0a0d
    0a6465 626961 6e3131 206c 6f67 696e 3a20
) IAC SE
...
--------------------
[+] LINEMODE is supported
[!] Telnetd vulnerable

You can see here that we’ve sent a large SLC table, enough to just slightly overflow the target buffer. Note, however, that something unexpected has happened - rather than the SLC table we expect to see returned, we see lots of random-looking bytes returned. That’s not even what we sent! What’s gone on here?!

This is a good example of the ‘nasal demons’ to which the greybeards alluded. We’ve hit a different codepath, causing internal values to be added to the SLC table.

Other commonly-seen behaviors include returning heap pointers in the place of SLC data (usually because the slcptr global has been overwritten). This is another very useful primitive, and something that attackers will find invaluable in building exploits:

$ python3 watchTowr-vs-Telnetd-CVE-2026-32746-leak.py --rhost 192.168.0.154
[+] Leaked Heap slcptr: 0x004b1a38
[+] Leaked Heap slcptr: 0x00468a38
[+] Leaked Heap slcptr: 0x004f4a38
[+] Leaked Heap slcptr: 0x00478a38

As we say, this is specific to the binary on the system. A further demonstration of the complexity involved in successful exploitation of the (extremely diverse) install base of Telnetd.

Conclusion

Well, we haven’t achieved the coveted RCE, although we’ve discovered a huge amount of probably-not-ideal behavior, such as our nice arbitrary free alongside a pointer leak. We’d love to have spent more time on this vulnerability, analysing more and more builds of Telnetd, but unfortunately, no one lives forever, and we all have other things to do.

The most striking thing about this vulnerability is its sheer reach. A good portion of the huge number of systems running some kind of Telnet server includes this vulnerable code. It’s been around forever - heck, Kurt Cobain was still alive when this hole was introduced! - so it’s had plenty of time to worm its way into all the nooks and crannies of any network worth caring about.

We’re convinced that instances of this specimen are going to crop up for years to come.

The other interesting property is that, in stark contrast to the homogeneous install base of, say, an SSLVPN appliance, or even an operating system, there are countless builds of a myriad of codebases that have included this blunder.

Given the class of the vulnerability - memory corruption - any successful exploit is required to be tailored to the environment that the target runs on.

This is good news for most of us, who are not targeted by large, well-equipped organisations. While it’s somewhat easy for us to check if our office TV is vulnerable (spoiler: it’s not), it’s unlikely anyone will invest the time and effort into crafting a functional exploit for it. This, however, is unlikely to comfort those defenders who are maintaining the sort of equipment that requires a Telnet daemon, and who may well be in the sights of exactly that class of attacker.

There is, of course, always a chance that a popular product will be found to sport a memory layout just right for clean exploitation, and if an exploit for that goes public - well, all bets are off. But then there is a somewhat limited overlap between people who use such mainstream equipment and those who really need to accept untrusted (or any, really) Telnet traffic.

Of course, the real answer here is ‘patch immediately, especially if downtime is so expensive that you can’t afford to take the machine down to patch it’. While we’d love to give out the version number of patched software, this simply isn’t possible, for two reasons (one much more sensible than the other).

Given the breadth of affected software, this would be a little redundant; anything based on a vulnerable version of inetutils is affected, which is a list far too long to enumerate.

Shamefully, the inetutils project hasn’t actually released a fixed version of their software (at least at the time of publishing). The newest version available for download - 2.7 - is still vulnerable. You’ll need to make sure you clone a fixed commit from git (this one or newer) and build from source.

Following on from this slothful lead - or rather, the lack of any real security response - most Linux distributions have not yet shipped packages.

Who can blame them? If the maintainers don’t think it’s important enough to justify a release, it must be minor, right?

At the time of writing, only the sid/forky track carries a fix - every other Debian release remains vulnerable.

The Daily Front Page 15 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Security Desk: The Tools
repository

Cloudflare/Security-Audit-Skill

by donk8r·▲ 198 points·37 comments·github.com ↗
★ 11,350⑂ 611 forks JavaScript

A coding-agent skill for multi-phase security audits with independently verified, machine-readable findings

A coding-agent skill that turns your agent into a security auditor. It orchestrates isolated agents through reconnaissance, coverage-led hunting, candidate validation, structured output, independent record verification, and target-neutral reporting.

This is the skill that seeded Cloudflare's vulnerability discovery harness, described in Build your own vulnerability harness. The harness grew into a multi-stage, fleet-wide system; this skill is the single-repo starting point it evolved from.

What it does

The skill runs a structured audit in six phases:

  1. Reconnaissance -- map architecture, trust boundaries, input surfaces, prior evidence, and deterministic coverage in architecture.md and coverage-ledger.json.
  2. Coverage-led hunting -- assign isolated hunters from ledger units, record their checks, and use coverage critics to find gaps.
  3. Candidate validation -- give every unique candidate to a fresh verifier that tries to disprove it.
  4. Structured output -- write confirmed, needs_validation, and rejected records to findings.json and validate them against report-schema.json.
  5. Independent record verification -- fresh agents verify final source claims. Material replacements receive another independent verifier.
  6. Target-neutral reporting -- derive REPORT.md, FINDINGS-DETAIL.md, and NEEDS-VALIDATION.md from the verified records and coverage ledger.

The parent runs validate-coverage-ledger.cjs after creating the ledger and after each later ledger update. It runs validate-findings.cjs in Phase 4 and again after every Phase 5 replacement.

The verdicts are distinct: confirmed has a complete source trace and bounded observed result, needs_validation has an exact unresolved fact and no severity, and rejected records a disproved candidate.

Multiple runs against the same repo are additive. The skill uses prior ledgers and findings to target gaps, revalidate changed source, and carry forward current-source evidence without treating stale or unresolved work as covered.

Files

File Purpose
SKILL.md Setup, core principles, platform terminology, workflow overview, and audit anti-patterns
RECONNAISSANCE.md Phase 1 reconnaissance prompts and synthesis instructions
HUNTING.md Phase 2 orchestration, hunting methodology, and validation rules
ATTACK-CLASSES.md Core, wildcard, and obvious-things attack prompts
MEMORY-SAFETY-AND-BINARY.md Memory-safety, binary, and kernel hunting classes for native targets
AI-AND-LLM.md Prompt-injection, agent/tool, and output-handling hunting classes for LLM-backed targets
WEB-PROTOCOL-AND-AUTH.md HTTP request-framing, cache, and authentication-protocol hunting classes for HTTP-protocol and auth targets
CLIENT-SIDE.md DOM-injection, messaging-trust, UI-redress, and prototype-pollution hunting classes for client-side/browser targets
SUPPLY-CHAIN-AND-RELEASE.md Dependency, CI, release, signing, update, plugin, and extension hunting classes
CLOUD-AND-DEPLOYMENT.md IAM, infrastructure-as-code, container, serverless, ingress, and runtime-configuration hunting classes
PROTOCOLS-RPC-AND-MESSAGING.md RPC, serialization, queue, broker, webhook, and streaming-protocol hunting classes
RESOURCE-EXHAUSTION-AND-AVAILABILITY.md Shared resource, quota, queue, worker, and operator-spend hunting classes
DATA-ISOLATION-AND-LIFECYCLE.md Tenant isolation, cache, search, export, backup, migration, deletion, and restore hunting classes
DESKTOP-MOBILE-AND-LOCAL-IPC.md Native app, deep-link, webview, exported-component, helper, daemon, and local-IPC hunting classes
VALIDATION-AND-REPORTING.md Phases 3–6 candidate validation, structured output, record verification, and reporting
report-schema.json JSON schema for all three findings.json verdicts
validate-findings.cjs Zero-dependency validator for findings.json in Phases 4 and 5
validate-findings.test.cjs Findings-validator tests and producer-compatible fixture checks
validate-coverage-ledger.cjs Zero-dependency validator for coverage-ledger.json in Phases 1–5
validate-coverage-ledger.test.cjs Coverage-ledger validator tests

Installation

Install the skill with the Skills CLI:

npx skills add https://github.com/cloudflare/security-audit-skill \
  --skill security-audit

Use --global for a user-level installation:

npx skills add https://github.com/cloudflare/security-audit-skill \
  --skill security-audit \
  --global

Run npx skills --help for agent-selection and non-interactive options.

Usage

Start your coding agent in (or pointed at) the codebase you want to audit, then ask it to do a security audit:

security audit this codebase
find security vulnerabilities in ./src
do a security review, output to ~/audits/my-project

The skill activates automatically when the request matches its trigger (security audit, find vulnerabilities, pen-test the code, etc.). A direct codebase audit or pen-test request uses full audit mode. Security questions and focused vulnerability work use guidance mode unless you request report artifacts. In full audit mode, an unspecified output directory defaults to ~/security-audit-skill/<repo-name>/run-<N>. The workflow writes inside the target repository only when you explicitly select a directory that version control ignores.

Requirements

  • A coding agent with a model that supports tool use and parallel sub-agents
  • Node.js for the zero-dependency findings and coverage-ledger validators
  • An OS-enforced sandbox for target-controlled builds, tests, processes, browsers, emulators, fuzzers, and fixtures. It must disable external networking, use a sanitized allowlisted environment, enforce resource limits, and allow writes only to assigned scratch paths. Without these controls, the workflow keeps the lead as needs_validation instead of executing target code.

Design principles

  • Only confirm established boundary failures. Keep a source-grounded blocked lead as needs_validation with its exact unresolved fact.
  • Adversarial validation. The agent that checks a finding is never the agent that found it.
  • Severity requires impact. Likelihood x impact, not deviation from a checklist.
  • Defense-in-depth gaps are not vulnerabilities. If Layer A prevents the attack, the absence of Layer B is a hardening note.
  • Multiple runs improve coverage. In our test runs, a single run found roughly half of the vulnerabilities that repeated runs found in total.

Contact

Questions, feedback, or comparing notes on AI-driven security tooling: security-ai-research@cloudflare.com

License

MIT -- see LICENSE.

The Daily Front Page 16 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Security Desk: The Tools
article

CrowdSec Source Code Leak

by eccgecko·▲ 150 points·44 comments·crowdsec.net ↗

On September 16, CrowdSec was informed of a source code leak involving our GitHub repository, which occurred in May 2026. Our team verified and confirmed the report. CrowdSec source code consists of two parts: a private one and another that hosts our Free Open Source Software (i.e., the Security Engine), which is public by design and therefore out of scope. The private part, though, contains the source code for our SaaS console, some AWS Cloud routines, some connectors, and automations. 

The news headline claiming 300 different repositories is accurate (when you include the 130+ public ones), though that number mostly reflects the code’s subdivision rather than a specific volume. We do not confirm any “other file contained” or “internal development material”, since all the code is published in these repositories. The API related information is the token used by the CI/CD component itself. (see below)

No client data, login/password, name, organization, or anything else was leaked, and CrowdSec doesn’t store PII or client logs; the impact is limited to CrowdSec. Our team quickly hunted for any token, credential, or sensitive leak that could enable lateral movement but found none so far.

The code contained in these private repositories has value but cannot really harm CrowdSec, since our efficiency depends on our network effect and size, which code alone can’t replicate. We regularly audited the SaaS source code, and its leakage shouldn’t pose an immediate threat either. Most of the leaked code has evolved significantly over those four months, but we will closely monitor for any abnormal activity. Also, using it outside of CrowdSec seems unlikely because it only interacts with our data and tools and cannot really be leveraged in another context. 

We will keep you updated as we continue investigating, but the Tanstack compromise is very likely to have been the leak vector (more about it here), as in the case of the Mistral AI case. This component was used in our organization in May and appears to have been backdoored to extract an API key with authorization to read the private codebase. The leak was only exploitable during a short timeframe in May 2026.

We nevertheless immediately rotated all required tokens & credentials to prevent further incidents.

The team would like to thank Fuites Infos for their timely, professional outreach in reporting the issue.

The Daily Front Page 17 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Software’s Long Tail
article

My temporary PHP fix from 2014 has nearly 20M installs. Today I'm deprecating it

by jakeasmith·▲ 331 points·101 comments·jakeasmith.com ↗
There is nothing as permanent as a temporary fix that works.

Twelve years ago, I wrote 174 lines of PHP as a stopgap for AOL’s content management system. I put it on Packagist in case anyone else needed the same patch, and somehow it’s been installed nearly 20 million times since. Today I marked it deprecated.

A temporary shim

In 2014, we were in the middle of upgrading AOL’s CMS from PHP 5.2 to 5.3. Part of that upgrade was dropping version 1 of the pecl_http extension, which gave us a function called http_build_url(). A CMS deals with a lot of URLs, and ours called that function in dozens of places. I wasn’t touching those. The function seemed straightforward enough to reproduce, so I wrote my own http_build_url(), defined only if the real one didn’t already exist. The old code never knew anything had changed.

Composer was just taking off at the time, which made sharing it easy. I figured it would earn its keep for a year or two, until the PHP community moved on to something better.

That’s a lot of installs

Well, it wasn’t temporary. It’s been installed from Packagist nearly 20 million times, and it still picks up over 400,000 installs a month.

Packagist install statistics for jakeasmith/http_build_url as of September 15, 2026: 19,864,271 total installs and 401,308 in the last 30 days. Daily installs climb steadily from near zero in 2014 to about 13,000 a day in 2026.

And it turns out Composer is only part of the picture. WPML, the market-leading multilingual plugin for WordPress, bundles the polyfill directly in its codebase, and WPML says it’s installed on over 1.5 million sites. The domain-name library idna-convert depends on it too, which is how it ships inside the source of SPIP, a French content management system, and how it ended up packaged in Debian and Ubuntu. Between all of them, there’s a pretty good chance you’ve visited a website that is still running my code.

I never imagined it would go this far.

Coming back to it

I didn’t grasp how far it had spread until a few months ago, when I looked at the package for the first time in years. I knew it had users. By 2021 I’d been out of PHP for a while, and the downloads were surprising enough that I asked for a new maintainer. Three people offered. Shortly after I asked, we lost a family member unexpectedly, and it turned our world upside down for a while. I never followed up, and that’s on me. By the time things settled, other goals had taken over, and I forgot about the package for years.

Along with the numbers, there were a handful of GitHub issues, including one where joining a path onto a URL with a trailing slash strips every letter “a” out of the path. So much for straightforward. Under a comment that reads // Workaround for trailing slashes, my code tacks an “a” onto the path so there’s always a last segment to cut off, then cuts it off with a find-and-replace. When the path ends in a slash, that last segment is just the “a”, and the find-and-replace takes every other “a” in the path with it. I can’t believe the bug went unnoticed for as long as it did.

So I had a decision to make. I could dive back into PHP after almost a decade away, hand the package to one of the people who’d offered, or let it keep sitting there.

None of the above

It was always meant to be temporary, so I’m retiring it. The PHP League’s URI library has been the community’s answer for years, and PHP 8.5 now ships a standards-compliant URI API in the language itself (thanks to jawira for pointing me at it). Both are better than a 174-line shim from 2014. Maintaining the package would only delay the move everyone should be making, and handing it over would add a risk on top of that. I don’t doubt anyone who offered, and ozh has kept a fork going for YOURLS. But a widely installed package with a new maintainer nobody downstream has vetted is exactly what attackers look for. Veritasium’s video on the xz Utils backdoor is the best telling I’ve seen of how that plays out.

The package will keep installing, but it won’t get new fixes, including for the missing-”a” bug. After this long without a change, even a one-line fix could have unintended consequences for someone, with no one around to support it. The README shows how to switch.

I wrote this code to ease a painful migration, for myself and anyone else going through the same one. Thank you to everyone who sent a pull request or offered to take it over, and to the people who kept filing issues long after I’d stopped reading them. It was a good run for a temporary fix.

P.S. We never migrated AOL’s CMS off the “temporary” polyfill. It ran there until the whole platform was shut down around 2020.

The Daily Front Page 18 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Browser Engine, One Year On
article

One year of sponsored Servo development

by AshleysBrain·▲ 348 points·140 comments·servo.org ↗

Last September, the Servo project announced that long-time maintainer Josh Bowman-Matthews (@jdm) would work part-time on improving the Servo contributor experience, entirely funded by the monthly donations on OpenCollective and GitHub. In his own words, here is a look back over the past year!


First of all, I am enormously grateful to everyone who financially supports Servo, as those donations have enabled me to devote significant time to a project that I care a lot about. Some highlights from that funded work that I’m proud of:

On top of that, I spent time diagnosing unexpected failures in others’ PRs and fixed numerous intermittent test failures that made merging PRs more difficult for everyone.

A few pieces of work from this period that stand out to me:

  • supporting a large scale rewrite of Servo’s JS engine integration to address intermittent panics related to garbage collection—I reviewed lots of pull requests, but also filed many issues that enabled the work addressing the panics to be spread across many other contributors
  • getting tagged in to help understand test failures, uncovering our broken window.open behaviour, and eventually making a lot of flaky tests more stable
  • supporting another contributor’s grant proposal to work on Servo that was approved!

This role I’ve carved out means a lot to me—I’ve found a healthy balance that allows me to spend time with my family as well as make meaningful contributions to Servo, and I get to spend a lot of time looking for ways to make the project more accessible for others. A big thank you to everybody supporting the project and my work; each individual monthly donation makes a big difference! I’m excited to see what’s possible in the coming year.

The Daily Front Page 19 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Python on Every Screen
article

Flet 1.0 – Build cross-platform apps in Python

by absqueued·▲ 107 points·50 comments·flet.dev ↗

Build beautiful web, desktop, and mobile apps from one Python codebase.

Try online ↗Read the docs →

No frontend experience required. Just Python.

A to-do app built with Flet, with editable tasks and completion filters

Flet Gallery running on an iPhone

Real apps. All Python. ↗

One codebase.
Make yourself at home.

  • iOS
  • Android
  • Windows
  • macOS
  • Linux
  • Web

Your first Flet app.

Start with a simple counter to see how Flet turns Python into an interactive app.

  1. Build the interface

    Use ready-made controls for the text and button. Arrange them with Python.

  2. Add the behavior

    Connect the button to a Python function that increases the count.

Try online ↗

Open Flet Studio.
No installation needed.

Try locally ↗

Follow the installation guide for uv or pip.

counter.py

Imperative

Imperative: update the controls directly when the button is clicked.

Compare the two styles ↗

import flet as ft


def main(page: ft.Page):
    counter = ft.Text("0", size=50, data=0)

    def increment(e):
        counter.data += 1
        counter.value = str(counter.data)

    page.floating_action_button = ft.FloatingActionButton(
        icon=ft.Icons.ADD, on_click=increment
    )
    page.add(
        ft.Container(
            content=counter,
            alignment=ft.Alignment.CENTER,
            expand=True,
        )
    )


ft.run(main)
$ flet run counter.py

More than a pretty interface.

The controls, libraries, and tools to take your app from an experiment to something you ship.

Controls

Good-looking Python GUIs

150+ controls and services. Layouts, navigation, forms, and dialogs, with customizable colors, typography, and themes.

Explore the controls ↗

Python packages

Your Python libraries. On mobile.

Bring NumPy, pandas, Pillow, and cryptography along. Prebuilt packages for iOS and Android save you the work of compiling native dependencies.

Browse Python packages ↗

Packaging

Ready to ship

Package your app for desktop, mobile, and web with flet build. Prepare it for distribution, including the App Store and Google Play.

Build and publish ↗

Web support

The web, your way

Run Python in the browser with Pyodide and WebAssembly, or keep your code on a server and send real-time UI updates.

Explore web deployment ↗

App testing

Test your app

Write pytest tests that tap buttons, enter text, and check user flows in your packaged app. Catch visual changes with screenshots on iOS and Android.

Test your app ↗

AI assistance

Give your AI the right context

Connect your coding assistant to Flet MCP for version-specific API information and tools to find examples, icons, and CLI options.

Connect Flet MCP ↗

Extensible

Make it your own

Compose custom controls in Python or wrap Flutter packages in extensions to add new UI components and platform integrations.

Build an extension ↗

Accessible

Build for more people

Support screen readers with labels and custom semantics. Add keyboard shortcuts and inspect the accessibility information your UI exposes.

Explore accessibility ↗

An idea is a great place to start.

Open your browser. Pick an example, write some Python, or ask the AI agent for a hand. Run your app and share what you make.

Find your starting point

Explore the Gallery and make an example your own.

Make it work your way

Edit the code, get help from AI, and see your app run.

Share what you made

Send a link, or download your project and keep building locally.

Explore the Gallery ↗

Your app. Our community.

Share an idea, ask a question, or help shape what comes next. Flet is open source, and you're invited.

Contribute on GitHub ↗ Join us on Discord ↗ Discover community projects ↗

The Daily Front Page 20 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — The Physical Machine
article

This PCB is brought to you by Fable 5

by jasonpeacock·▲ 158 points·103 comments·a6mzero.com ↗
An experiment to design a cute PCB (without touching any tools) in plain English

An experiment to design a cute PCB (without touching any tools) in plain English

The board I will be journaling about.

I have been wanting to design a simple PCB for the last couple of years now. The thought of converting a design idea into a physical board and programming it to do things is fascinating to me. Long story short, I procrastinated until I tried to vibe-generate a dead simple PCB with Claude Opus 4.8 and it was terrible ! It had no idea about the orientation of the components, it did not do any proper routing. I was disappointed and accepted the fact that these tools were not there yet.

Then arrived the Fable 5. At first I was not that hopeful. One Thursday evening, around 10 hours before my weekly reset for Claude, I decided to give it another try; this time with Fable 5.

I had two rules:

  1. No manual edits or verification of the board.
  2. Every problem I face before manufacturing will be solved by Fable.

This meant I was going to trust Fable with my wallet. I decided to describe the board I want it to generate, and I was not going to be involved in the design phase. I was the end customer.

This is the prompt I gave it:

the First prompt

▎ I would like you to design me a pcb that will have the rpi pico 2350 four buttons (2 on the left and 2 on the right, watchy buttons(or drop in replacement)), GDEY0154D67-FL04 display. The size of the pcb will be same as the size of the GDEY0154D67-FL04. The rpi pico will drive the screen and the buttons will control the rpi pico. Also have an i2c, and some gpio pins out. Use the kicad mcp, let me know when the schematic design and placement are ready

That was it, a short description of a RPI 2350 based development board which can drive an E-ink display. After working autonomously for a couple of hours it came up with the design shown in the video below.

The board as it freshly came out of Kicad ⃰.

Board

31.8 × 37.32 mm, 4 layer

MCU

RP2350A

Display

1.54" E-ink, 200×200

Flash

8 MB QSPI

Cost

26€ per board

A closer look to some errors

The design process was not error free of course. When I showed the initial design (Claude was still working on it) of the PCB to my colleague, the first thing he wanted me to check (after recovering from the pain of seeing them tracks) was the DRC (Design Rule Checking) errors. I did not know what it was, and when we looked at it, there were indeed 65 DRC errors. Following the rule, I only mentioned the errors to Fable and did nothing else.

Front copper render

Front: Beautiful placement, with two mistakes

Back copper render

Back: horrendous tracks

Fable was amazing at component selection, except for the two components I highlighted above. The big one on the top left is the SPI flash which stores the firmware and other data that you want to save. The SPI flash memory Claude chose was W25Q128JVS. It comes with the SOIC-8 wide package, but the pads designed for the memory was for a SOP-8 package, meaning the chip is too big for the pads. The bottom left component on the other hand is the transistor that switches the boost converter for the E-ink driver circuitry. As you can see it also chose the wrong package, as it is too small for the pads. I did not realise these until I uploaded the required files to JLCPCB. There I could see the issues, and I discussed it with Claude. For the W25Q128JVS it insisted that there was a SOP-8 package but I could not find it in LCSC's library. Eventually we settled at the P25Q64SH chip.

But wait a minute, how did it even route ?

The design had 65 footprints, 54 nets and 118 unconnected lines. It is not a complex PCB by any means :P. Fable decided to use the Freerouting open-source project. The tool worked for 2 minutes, and after seventeen passes it plateaued at sixty nine connections, leaving 49 disconnected, and it could not finish the job. The remaining connections were hand-routed by Claude.

Freerouting doing its job

After I ordered the board my colleague mentioned to me the KiCadRoutingTools open-source project. It ran for 1.25 seconds and it could route all the connections with no problem. I will try this tool out for my upcoming hardware projects.

Freerouting versus KiCadRoutingTools

Same placement, two routers

Ordering with JLCPCB

I had never ordered anything from a PCB manufacturer before. It seemed complex and I was reluctant to take the first step. Upon Claude's compilation of the project, I asked it to prepare the required files for JLCPCB, and tell me what to select on their GUI. Man am I satisfied with JLCPCB. It was so straight forward, easy to interact with and there was no bloat. I uploaded the files, some components Claude selected were not available, we did a back and forth and voila we were done. For five fully assembled boards I paid 130 Euros, ordered the E-ink displays from a local shop and now it was the waiting game.

Some cool animations while we are waiting for the PCBs

The four layers, pulled apart.

Assembly of our board

The boards have arrived !!!

I received the PCBs and the first thing I wanted to do was to plug it in to my laptop. I have broken multiple USB modules for my Framework earlier, hence I thought checking for a short between 3v3 and ground was a no-brainer, although my colleague was suggesting me to just yeet it since this was a fully vibe-generated board. There was no short and I just plugged it in. There it was, the board was recognized and it was ready to be used.

What do I do with it ?

I already wrote some proof-of-concept apps, and they worked perfectly fine. I can read on that beautiful 1.54 inch display :D Stopwatch is quite handy if i need some focusing, and the album is my favourite feature since even after powering the board off, the images stay on the display thanks to E-ink.

The watch face

The watch face.

The menu

The menu. Two buttons used for up and down, and the other two used for select and back.

The e-reader

The e-reader. You can read .txt files stored on the SPI flash.

The album

The album. Pictures dithered to one bit.

Hands on with the finished board.

How do I feel all about this ?

Great and meh. I love how I was able to just describe the board I want in plain English, send the files overseas and then receive a fully functional board without knowing any proper PCB design knowledge. The possibilities are limitless here, and I will certainly continue doing this in the future.

That said, I was not feeling much of an accomplishment, rightfully so. I used to enjoy the learning and the struggle that came with it. Although we are in the best era to learn about something, the fact that you can make things without knowing anything about a subject puts you in an uncomfortable spot.

The future I wish to have

Yes it does suck that the joy we had while building has been sucked out of us and now we are told to enjoy building from a higher abstraction level. I am trying to adjust to this, especially at work. At work I can't just YOLO stuff so I meticulously review all the time. It is tiring but knowing the fact that my input still matters, is rewarding. For my hobby projects tho, I will continue to YOLO it and build stuff fast without necessarily knowing about the details.

I hope one day JLCPCB or PCBWAY will have a chat-box where I can dump all my ideas and some of my illustrations, and two days later they will ship me the board. I want them to remove the middle man, and make PCB generation so much simpler and safer.

Sneak Peek

I already started working on my next project. Using Fable 5.1 with KiCAD and KiCADRoutingTools I am building an NVIDIA Jetson Orin Nano based tablet. The same rules I mentioned earlier will apply and I will let you know about the results(if I get to order it :P) .

NVIDIA Jetson Orin Nano based Tablet

Thank you for reading my journal, sharing is the most fun part of tinkering and building. I appreciate that you are part of this fun journey :)

The Daily Front Page 21 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Wax, Wind & Work
article

Wax motor

by mhb·▲ 365 points·63 comments·en.wikipedia.org ↗
A wax motor is a linear actuator device that converts thermal energy into mechanical energy.

A photo of iSwell Thermoactuator P21.6T

A wax motor manufactured by iSwell

A wax motor is a linear actuator device that converts thermal energy into mechanical energy by exploiting the phase-change behaviour of waxes.[1] During melting, wax typically expands in volume by 5–20% [2].

A wide range of waxes can be used in wax motors, ranging from highly refined hydrocarbons to waxes extracted from vegetable matter. Specific examples include paraffin waxes in the straight-chain n-alkanes series. These melt and solidify over a well-defined and narrow temperature range.

Design

The principal components of a wax motor are:

  • An enclosed volume of wax
  • A plunger or stroke-rod to convert the thermo-hydraulic force from the wax into a useful mechanical output
  • A source of heat such as:
    • Electric current; typically a PTC thermistor, that heats the wax
    • Solar radiation; e.g. greenhouse vents
    • Combustion heat; e.g. excess heat from internal combustion engines
    • Ambient heat
  • A sink to reject heat energy such as:
    • Convection to cooler ambient air
    • Peltier effect device arranged to transfer heat energy away

When the heat source is energized, the wax block is heated and it expands, driving the plunger outwards by volume displacement. When the heat source is removed, the wax block contracts as it cools and the wax solidifies. For the plunger to withdraw, a biasing force is usually required to overcome the mechanical resistance of seals that contain the liquid wax. The biasing force is typically 20% to 30% of the operating force and often provided by a mechanical spring or gravity-fed dead weight applied externally into the wax motor (Duerig 1990, p. 214).

Depending on the particular application, wax motors potentially have advantages over magnetic solenoids:

  • They provide a large hydraulic force from the expansion of the wax in the order of 4000 N (corresponding to roughly 400 kg or 900 lb at standard gravity) (Tibbitts 1988, p. 13).
  • Both the application and the release of the wax motor is not instantaneous, but rather, smooth and gentle.
  • Because the wax motor is a resistive load rather than an inductive load, wax motors controlled by TRIACs do not require snubber circuits.
  • Wax motors can be operated entirely passively by exploiting ambient sources of energy. Given that a variety of melting-points are possible for the wax used inside the motor, one can be selected to match the range of ambient operating temperatures in a given application. In this way the wax can be melted and solidified within this range by the transfer of thermal energy. When co-located with the heat source, wax motors can be operated without the need for an additional external power source.

Applications

Aerospace Controls

Wax motors are used heavily in the aerospace industry where they are utilized to control fuel, hydraulic, and other oils critical to safe flight today in modern airplanes.[3]

Mixing Valves - HVAC

Wax motors are contained inside "self actuating" thermostatic mixing valves, where the wax motor senses thermal change and responds accordingly to yield a desired mixed fluid temperature.

Laundry washing machines

Some front load washing machines use wax motors to engage the door lock assembly. When a cycle is started, a wax motor is actuated pushing a pin outward and locking the door. This design has cost, reliability and safety advantages. In moist conditions a wax motor costs less for equivalent reliability than an electromagnetic solenoid or motor latch. It has a predictable passive release delay. If power is lost the door remains briefly locked, designed to be longer than the high speed spin cycle coast-down time, then reliably unlocks as the wax cools.

Heating systems

Wax motors are also commonly used to drive zone valves in hydronic (hot water) heating systems.

Cutaway model of a thermostatic radiator valve. A wax motor concealed within the spring actuates the water valve at right.

Dishwashers

They are used in many dishwashers to release the detergent dispenser door latch. The wax motor acts like a solenoid when activated by the dishwasher's timer or control, and the piston operates the mechanism which then releases the catch for the dispenser door. They are also used to control the exhaust vent for the drying cycle.

Greenhouse vents

Wax motors are widely used to operate the temperature regulating vents of greenhouses.

In this application, as the ambient temperature within the greenhouse increases, the wax melts, activating the plunger and opening the vents. When the greenhouse temperature has cooled sufficiently, the wax cools and solidifies, allowing the vents to close again.

Paraffin microactuator

A paraffin microactuator is a type of wax motor, often fabricated by microelectromechanical systems (MEMS) technology or sometimes precision mechanics.[4]

See also

References

  1. Setright, L. J. K. (1976). "Cooling". In Ian Ward (ed.). Anatomy of the Motor Car. Orbis. pp. 61–62. ISBN 0-85613-230-6.
  2. Freund, M.; Csikos, R.; Keszthelyi, S.; Mozes, Gy. (1982). Paraffin products: properties, technologies and applications. Budapest, Hungary: Hungarian Academy of Sciences. ISBN 963-05-2680-8.
  3. Ruggiero, Tom (October 2018). "Thermostatic Solutions for Temperature Control Applications". www.aerodefensetech.com. Retrieved 2021-03-15.
  4. Ogden, Sam; Klintberg, Lena; Thornell, Greger; Hjort, Klas; Bodén, Roger (30 November 2013). "Review on miniaturized paraffin phase change actuators, valves, and pumps". Microfluidics and Nanofluidics. 17: 53–71. doi:10.1007/s10404-013-1289-3. S2CID 85525659.
  5. Duerig, T.W. (1990). Engineering aspects of shape memory alloys. Oxford: Butterworth-Heinemann. ISBN 0-7506-1009-3.
  6. Tibbitts, Scott (1988). "High output paraffin actuators: Utilization in aerospace mechanism". NASA Technical Reports Server. Hanover, MD: NASA Center for AeroSpace Information (CASI). Retrieved May 31, 2019.
The Daily Front Page 22 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Wax, Wind & Work
article

The Return of Sail Power: Cargo Ships Are Turning Back to the Wind

by gumby·▲ 181 points·127 comments·gcaptain.com ↗
Commercial shipping steadily moved away from sails. Now they are coming back.

Rendering of a Maersk containership fitted with a 35-meter Anemoi Rotor Sail for wind-assisted propulsion.

Rendering of a Maersk containership fitted with Anemoi Marine Technologies’ 35-meter Rotor Sail. Image courtesy Anemoi Marine Technologies

For more than a century, commercial shipping steadily moved away from sails. Now they are coming back.

Across the global fleet, shipowners are installing towering rotor sails, rigid wings and suction-based systems on everything from bulk carriers and tankers to containerships. LNG carriers could be next.

The idea is not to turn modern cargo ships back into sailing vessels. Instead, these systems are designed to work alongside conventional engines, using the wind to reduce fuel consumption whenever conditions allow.

What was once a niche experiment is beginning to look more like a real segment of commercial shipping.

The International Windship Association says more than 100 large merchant ships are now equipped with modern wind propulsion systems, representing more than 5 million deadweight tons of carrying capacity.

That is still a tiny share of the world fleet, but the ships are getting bigger, the owners more familiar and the projects more ambitious.

And 2026 has brought several signs that wind-assisted propulsion is moving beyond the demonstration stage.

One of the biggest came this month from Maersk. The company plans to install a 35-meter rotor sail on one of its 8,700-TEU containerships, with testing expected to begin in 2027 on regular Atlantic services.

The project is expected to mark the first rotor sail installation on a containership.

Rotor sails look more like giant vertical cylinders than traditional sails. They spin as wind passes around them, creating aerodynamic lift through the Magnus effect and generating thrust that reduces the load on the ship’s engines.

The concept is more than a century old, but modern controls and materials are making it practical on ships of a scale that would once have been difficult to imagine.

Vale’s 400,000-dwt Sohar Max, one of the largest ore carriers in the world, is already fitted with five 35-meter rotor sails. The system was expected to cut fuel consumption by as much as 6%. Vale is also planning to use rotor sails on future ethanol-powered very large ore carriers.

Vale Sohar Max with-Anemoi Rotor Sails

Anemoi Marine Technologies completed the installation of five Rotor Sails onboard the 400,000 dwt Very Large Ore Carrier (VLOC), Sohar Max, making it the largest vessel to receive wind propulsion technology to date. Photo: Anemoi Marine Technologies/Vale

Oil tankers are next.

Two VLCCs being built for Japan’s Idemitsu Tanker are scheduled to receive Norsepower rotor sails when they enter service in 2028, bringing wind-assisted propulsion to some of the largest ships afloat.

LNG shipping may not be far behind. Korean Register, HD Hyundai Heavy Industries, BAR Technologies and the Liberian Registry recently announced plans to study a 174,000-cubic-meter LNG carrier fitted with BAR Technologies’ WindWings.

The design moves the ship’s accommodation block forward, creating space for large rigid sails on deck. The project will examine the technical, safety and regulatory challenges of applying the system to LNG carriers.

That is significant because LNG carriers are among the most sophisticated and tightly scheduled ships in commercial service.

If wind propulsion can work there, it would further strengthen the case that the technology is moving into the mainstream.

Not every project is designed simply to assist an engine.

France’s Neoliner Origin, delivered in 2025, uses two 76-meter carbon-fiber masts carrying about 3,000 square meters of sail area, with wind intended to provide the ship’s primary propulsion across the Atlantic. The 136-meter ro-ro vessel can carry cars, containers and other cargo between Europe and North America.

Neoliner Origin departs the RMK Shipyard in Turkey for sea trials

Neoliner Origin departs the RMK Shipyard in Turkey for sea trials. Photo courtesy NEOLINE

Airbus is taking a similar approach with a new generation of ro-ro ships designed to carry aircraft components across the Atlantic using a combination of wind propulsion, alternative fuels and optimized routing.

The result is a strange mix of old and new: some of the world’s most advanced supply chains are beginning to rely once again on one of shipping’s oldest sources of propulsion.

The sails themselves are also changing quickly.

Some systems use spinning cylinders. Others resemble aircraft wings mounted vertically on deck. Bound4blue’s eSAIL uses suction to increase aerodynamic lift, while other developers are working with rigid foils, automated wings and soft-sail systems.

Maersk Tankers has been rolling out eSAIL systems across a group of MR tankers, while the juice carrier Atlantic Orchard has been fitted with four 26-meter suction sails.

In most cases, crews are not standing on deck trimming sails by hand. The systems are heavily automated, adjusting themselves based on wind speed, direction, vessel speed and heading. Weather-routing software can also help ships alter course slightly to capture more wind without significantly disrupting schedules.

That integration is becoming increasingly important. Norway recently launched the WINTEGRATE program, bringing together companies including Kongsberg Maritime, DNV, Odfjell, Norsepower and bound4blue.

The idea is to stop treating wind propulsion as a standalone piece of equipment bolted onto a ship and instead integrate it with engines, batteries, power-management systems and voyage planning.

That shift may be critical to the technology’s future.

The physics behind wind propulsion have not changed. The economics have.

Shipowners are under growing pressure to reduce fuel consumption and emissions, while many low-carbon fuels remain expensive, scarce or unavailable at scale.

Wind, by comparison, is free.

It also offers something relatively unusual in shipping’s decarbonization push: a technology that can often be retrofitted to ships already in service.

Savings depend heavily on the vessel, route and weather.

Industry estimates generally put fuel savings for retrofit projects somewhere in the single digits to low double digits, while purpose-built ships designed around wind propulsion can potentially achieve much more.

That may not sound revolutionary.

But on a large oceangoing vessel burning thousands of tons of fuel each year, even modest savings can add up quickly.

There are still plenty of limitations.

Wind is unpredictable. Sails take up deck space. Systems need to withstand heavy weather, corrosion and cargo operations. Bridges, cranes and terminals can restrict how tall or where equipment can be installed.

Some routes are also far better suited to wind propulsion than others.

Regulation is still catching up as well.

The International Maritime Organization has begun work on interim safety guidelines for wind propulsion and wind-assisted systems, with the first guidelines expected later this decade.

But the industry now has something it lacked only a few years ago: real operating experience.

Tankers, bulkers, ro-ros and general cargo ships are accumulating commercial sea time with these systems. Shipyards are learning how to install them. Classification societies are writing rules around them. Manufacturers are scaling up production.

That does not mean commercial shipping is heading back to the age of sail.

Engines will remain essential for schedules, maneuvering, adverse weather and port operations. Many ships will also rely on alternative fuels, batteries and other efficiency technologies.

Wind will simply become another part of the propulsion mix.

And that may be the most important change.

After spending more than a century trying to escape its dependence on the wind, shipping is starting to realize there is little reason to ignore free energy when it is blowing in the right direction.

The Daily Front Page 23 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — The Storage Republic
article

The American Religion of Self-Storage Facilities

by pseudolus·▲ 224 points·386 comments·newyorker.com ↗
Why are we so obsessed with putting our belongings in metal boxes and then never looking at them again?

Why are we so obsessed with putting our belongings in metal boxes and then never looking at them again?

During the summer of 2019, not long before COVID shut the country down, I spent three and a half days driving from Connecticut, where I live, to Kansas City, where I grew up, and three and a half days driving back. My routes in both directions were lazy and circuitous, and they included not even one mile of interstate highway. I ate roast turkey with all the trimmings at a restaurant in upstate New York that offers Thanksgiving dinner every day of the year; stood at the northern end of a puddle representing the Dead Sea in a grassy park created, a century and a half ago, as a walk-over relief map of the Holy Land; saw surprisingly many sex-toy superstores near billboards promoting belief in Jesus Christ; and visited the birthplace of the Western novelist Zane Grey, who, it turns out, was also a minor-league baseball player and a practicing dentist, and whose real first name was Pearl. Mainly, though, I spent long hours alone in my car thinking about our remarkable country. By the time I got home, I had concluded, based on a multitude of examples, that the two great pillars of American culture are church and self-storage.

A self-storage facility is a business that rents lockable space to people who own more stuff than they know what to do with. (A 2022 survey by the Craftsman tool division of Stanley Black & Decker found that more than a third of the country’s residential garages were so full of overflow possessions that their owners were unable to park cars in them.) “The history of self-storage probably goes back a long way, but the seventies is when it really got started, mostly with mom-and-pop-type operations,” Patrick Lemp, an appraiser and broker who focusses on the industry, told me. “Later, it became an accepted institutional-quality asset class.”

The United States is the world leader, with roughly ninety per cent of global capacity. Texas, of the fifty states, has the most facilities, Hawaii the fewest. Among cities, New York ranks third, after Dallas-Fort Worth and Houston, although on a per-capita basis many smaller municipalities are comparably served. Reno, Nevada, is home to a number of operations that pick up, store, and redeliver tents, chairs, bicycles, and other gear for repeat Burning Man attendees, and Wichita, Kansas, was once named the Self-Storage Capital of the U.S. Units range from closet-size to cavernous, including spaces that are large enough to hold entire houses. Most of the facilities I saw on my road trip were single-story structures with lots of closely spaced roll-up metal doors; some, owned or operated by national chains such as Public Storage, Extra Space Storage, and CubeSmart, looked like office buildings. According to the co-founder and C.E.O. of Neighbor, an industry marketplace that works like Airbnb, there are more self-storage facilities in the U.S. than there are Starbucks, McDonald’s, Walmart, Home Depot, Domino’s, Dunkin’, and Costco locations combined. Annual revenues are estimated to be more than forty billion dollars.

People who work in self-storage often say that their market is driven by “the four D’s”: death, displacement, divorce, and downsizing, all life events that entail sudden collisions between stuff accumulation and reality. Years ago, Paul Roossin, an A.I. technologist and former neuroscientist, moved from a house in the suburbs to an apartment in Manhattan, and, because he thought he might want to move back to the suburbs someday, he rented a twenty-by-forty-foot storage space in Queens, for things that he no longer had room for. The facility was accessible by subway, and he visited from time to time. “Literally, though, years would pass,” he told me. Among the items he stored were a synthesizer, a piano, and a Hammond organ. At some point, he donated all three to a nonprofit, and once they were no longer blocking his view of the interior of his unit he was reminded of possessions that he had forgotten he owned. He later downsized from his downsizing, over a period of months, with help from a friend.

There’s probably a fifth D: the delusion that your children will want the items you’re planning to bequeath to them, especially the kind of furniture that used to be called antiques but that young people for some time have referred to derisively as “brown.” My wife and I moved from a large house to a smaller one a few years ago, and, as we were debating what to get rid of, we rented a portable storage unit from a company called Pods. Our pod cost about a hundred and fifty dollars a month, plus pickup and drop-off fees, and we kept it for a couple of months. (We also could have paid the company to store it for us, indefinitely, at one of its big warehouses.) Our plan was to fill it with redundant household items, including furniture that we no longer had room for, and send it to our daughter and her family, who live a hundred and fifty miles away. We did eventually send it to her, although she was interested in so few of our things that we had trouble filling it. Two items she did want—an Eames chair that had belonged to my father and a mid-century Danish desk that had belonged to my wife’s parents—I wouldn’t have minded keeping, but by that point I was so relieved that she wanted anything at all that I happily parted with them.

The most American of America’s recent contributions to the global built environment—joining Egyptian pyramids, Greek temples, domed Byzantine churches, and so forth—are the fulfillment centers of major retail corporations. The buildings are easy to spot from the air, because they’re immense, low, rectangular, flat-roofed, windowless, and, typically, clustered in industrial parks near airports and other transportation hubs. Self-storage facilities are almost always smaller, and they’re less likely to be encircled by eighteen-wheelers, but they’re similar in design and construction. Recently, it occurred to me that the ideal place to open a self-storage facility might be in the middle of one of those industrial parks, surrounded by fulfillment centers. That way, when you bought something from Amazon, it could be delivered directly to your storage unit, bypassing your cluttered home and sparing you the embarrassment of not remembering what you’d ordered the day before.

My friend Ray Underwood used to run an excavation company founded by his father. (I once watched him use a backhoe to retrieve a ballpoint pen that a health-department official had accidentally dropped into a deep test hole. He brought it up in one try, along with maybe a teaspoonful of dirt.) Underwood also owned a good-sized piece of commercial property in our town, on which he built a gas station and convenience store. He was thinking about adding a car wash, but a friend told him that he really ought to build a self-storage facility. This was in the nineties, before real-estate investment trusts and private-equity firms had fully appreciated the cash-cow potential of housing people’s stuff, so there weren’t many similar facilities around. Winning zoning approval wasn’t easy—partly my fault; I was on the commission—but eventually he got permits, in three phases, for six prefabricated metal buildings.

Underwood’s facility contains a hundred and forty-five units, varying in size from twenty-five to three hundred square feet. “In the third phase, we added mostly ten-by-thirties, because people kept asking for bigger and bigger,” he told me. Most of his customers store what you’d expect: ordinary garage overflow, gently used exercise equipment, out-of-season sporting goods, and furniture made superfluous by moving, renovation, or winter. About a quarter of the customers are local contractors or business owners, who store small machinery, tools, supplies, merchandise, or paperwork that they’re legally required to hang on to. The smallest units go for about eighty dollars a month, the largest for about three hundred. The facility has a website, but if you want to learn about rates or reserve a unit you have to call or e-mail Underwood’s sole employee, who is married to a former resident state trooper and used to be the town’s treasurer. If you don’t live or work nearby, she may ask you a few questions. (An occasional issue for self-storage operators is people who rent units with no intention of paying for them, in order to get rid of stuff that would be expensive to dispose of properly.) The buildings require virtually no maintenance. “It’s as simple as I could make it,” Underwood said.

Newer self-storage facilities are often bigger, fancier, and more technologically advanced. Recently, I visited a four-year-old Extra Space location in Wildwood, Florida, an hour northwest of Orlando. It’s one of many facilities on the outskirts of the vast, golf-cart-dependent gerontopolis known as the Villages, which covers nearly sixty square miles in three counties, has some two hundred and fifty pickleball courts, offers live music and walker-friendly dancing every night of the week, and is growing as fast as the universe is expanding. People who retire to the Villages almost always come from houses where they had more space, and if they don’t off-load their surplus possessions before they move they need a place to stash them. Kerry Copeland, who oversees twenty Extra Space locations in that part of Florida, showed me around. “There are about seven hundred and fifty units here, all climate-controlled,” he said. The building is three stories tall, and customers can drive right into it by means of a ground-level tunnel. Some of the biggest units open directly onto the tunnel and are large enough to park trucks in. Copeland punched a code into a keypad, and we rode an elevator to the second floor. Motion-activated lights came on as we walked through a maze of air-conditioned aisles. Fire sprinklers were visible overhead. Every surface was pristine. Almost all the units we passed were rented.

Something I didn’t encounter during my tour with Copeland was other human beings. (People who have storage units tend to visit them about as often as they visit elderly relatives in nursing homes.) Earlier that day, I’d stopped by a competing facility, a few miles away, where I did see some renters—an older couple who had parked their pickup truck in front of a row of non-climate-controlled units. They had opened the doors of two of them, and the man, who wasn’t wearing a shirt, was talking on his phone and using his free hand to move stuff around. The woman was only intermittently visible, behind tall, jumbled piles: Christmas decorations, including an artificial tree and a toddler-size nutcracker-type figure; two big grills, one charcoal and one propane; a compound miter saw and an assortment of other large power tools; several plastic garment bags; hard-to-identify pieces of folding furniture, probably chairs. The bed of their truck contained what looked like a radio-controlled toy car, so it’s possible that they were either preparing for or recovering from a visit by grandchildren.

Many of the items that the couple had stored were of the type that people keep in basements, but the high water table in most of Florida makes basements a rarity. A useful tip I got from Copeland is that, if you expect to visit your unit reasonably often, or if you’ve hired other people to fill it for you, it makes sense to rent one that’s larger than the volume of your possessions, so that you have room to maneuver. I can confirm from experience that this is sound advice. A few years ago, my wife and her siblings moved their mother from a large one-bedroom apartment to a single room, and they rented a storage unit to hold her surplus stuff while they debated what to do next. Everything fit, barely, but removing items from the back was like working a Rubik’s Cube.

One of the most significant innovations in the world of finance has been the automatically recurring credit-card charge. Like many people, I never pay bills anymore in the old-fashioned sense of sitting down at the dining-room table with a month’s worth of ominous-looking envelopes, a letter opener, a checkbook, and a roll of stamps. Fees for my phone, internet, streaming services, media subscriptions, in-car satellite radio, trash pickup, post-office box, cloud storage, and who knows what else all quietly appear on one or another of my credit-card statements. Other monthly payments, including car loans, electric bills, and Medicare and Medigap fees, disappear automatically from what I still think of as my checking account, even though I hardly ever write checks.

Enabling people to pay for things without consciously paying for them is good for the business of many businesses. Last year, two professors from Stanford and one from Texas A. & M. published a paper in the American Economic Review in which they conclude, based on transaction data from a large payment-card network, that “cancellation frictions roughly double seller revenues on average.” In large part, this is because credit and debit cards have made it easier for people to become what the professors call “inertial consumers.” An increasingly popular remedy for such people, they point out, is using services that “help subscribers find and cancel unwanted subscriptions”—for a subscription fee, of course.

Cancellation frictions are a boon to the self-storage industry. The annoying, time-consuming, and often expensive chore of emptying a junk-filled storage unit is easy to postpone for a month, and then for one more, especially if an unnerving paper bill never arrives. (Some facilities increase retention by offering discounts for automatic payments, or requiring them outright. Credit-card billing also makes it easier for customers to overlook rate increases.) My wife and I have a friend whose mother died in 2006. She and her siblings decided to sell their mother’s furniture and donate the proceeds to a charity that she would have approved of. “We put everything in storage temporarily, and it’s all still there,” our friend told me. She figures that they’ve spent at least fifty thousand dollars in rental fees so far—more than they could get from selling the furniture.

Sometimes customers simply stop paying. One of the attractions of self-storage as a business is that evicting stuff is easier than evicting people. A facility owner can overlock a delinquent unit and, after meeting certain statutory requirements, sell the abandoned contents at a public auction. This past spring, at the Inside Self-Storage World Expo, an annual trade show in Las Vegas, I met Chris Rosa, the director of business development at StorageTreasures, one of many companies that conduct such auctions. He told me that he had originally planned to become a high-school history teacher, but after graduating from college he worried that teaching didn’t offer enough financial security and decided to become an auctioneer instead. He attended auction school (“mind-numbingly boring”) and is now licensed in twenty-five states.

In 2010, while Rosa was learning the art of “bid calling”—the rhythmic patter that auctioneers use to keep bidders bidding—the reality show “Storage Wars” premièred, on A&E. “Behind these doors are some of the world’s best-kept treasures,” a voice-over on the show says. “But when storage bills go unpaid the contents within are put up for auction.” In an early episode, father-and-son bidders named Darrell and Brandon discover that buried deep in an unpromising-looking unit they’ve just bought for a hundred and forty-five dollars is a pair of handmade boots worn by Shelley Duvall in the movie “Popeye,” accompanied by a certificate of authenticity. An acquaintance who buys and sells movie props tells them that the boots are worth at least fifteen hundred dollars—a tenfold return on their investment. Windfalls like that made some viewers believe that buying other people’s forsaken stuff could be an easy path to riches. “At my first storage auctions, three, four, or five people would show up,” Rosa said. “Two weeks later, it was ten people. By the end of the year, at the height of the show, it was a hundred and fifty.”

The auctions on “Storage Wars,” which is now in its eighteenth season, are conducted in person, on the premises, but in recent years almost all non-reality-show auctions have taken place online. Whether the auctions are live or virtual, people bidding on a unit can examine its contents only from the outside, without opening boxes or rummaging around, and if they win they have to clear out everything. Genuine treasures do turn up, but auction winners inevitably discover that someone who has stopped paying the rent on a five-by-ten wasn’t using it to store gold bullion and that, for every certified pair of Olive Oyl boots, there are bushels of broken toys, outdated computer cables, spit-up-stained baby clothes, and greasy car parts, all of which they have to haul away. The regular bidders on “Storage Wars,” whom the producers tend to portray as scheming rivals, are experienced at judging and unloading junk, since many of them have run secondhand stores, consignment shops, auction companies, or other resale outlets. They also have trucks.

Last year, a retired Episcopal priest I know was asked to perform an exorcism at a storage facility. “A man told me after church one Sunday that for a couple of weeks he had felt an evil physical presence on his chest in bed at night, and that it was trying to kill him,” he said. The man also heard noises in the walls, at home and at work, and he had decided that the cause was a demon inhabiting an antique wardrobe he had bought: a large piece of brown. The Episcopal Church’s “Book of Occasional Services” has a section on exorcisms, which priests can perform as a last resort in certain circumstances. The man’s situation didn’t qualify, but the liturgy for “Celebration for a Home,” in the same book, includes the invocation “Let the mighty power of the Holy God be present in this place to banish from it every unclean spirit.” The priest and a colleague went from room to room in the man’s house, reading prayers from that liturgy and sprinkling holy water, and then did the same in his storage unit, to which he had banished the wardrobe. His wife later told the priest that her husband had felt relief for a few days, but that the real cause of his torment had probably been a brain tumor.

Five years ago, self-storage was one of the most profitable segments of the real-estate industry, with higher annual returns than multifamily housing, office complexes, and retail stores. Growth and revenues got a big boost from COVID, partly because people who were trapped at home suddenly realized that they needed to make room for remote working, remote schooling, and staying out of one another’s way. (A sixth D might be disease.) So many new facilities were built that some of the most desirable markets are now saturated or close to it, but people still buy stuff that they don’t have room for, and rising mortgage rates have forced many people to defer plans to move into larger living spaces.

Speakers at the Inside Self-Storage expo sessions that I sat in on were divided in their assessments of the industry’s near-term prospects, but they all agreed that technology and A.I. have become increasingly important. Andrew Capranos, the president (at the time) of a self-storage company based in North Carolina, said, “There is nothing that I can do better than A.I.” Facility owners use it to determine what their competitors are charging, and developers use it to streamline their permit applications. Technology is transforming the management side, too. A customer can now often price, rent, and access a unit using just a phone, without interacting directly with another person—a make-or-break feature for many younger renters.

Armaan Premjee, whom I also met at the expo, owns two self-storage facilities, in Texas and Louisiana, and, with the help of A.I., he can run them from Barcelona, where he now lives. “Claude handles our rental-rate increases,” he told me. He also uses A.I. to answer phone calls and e-mails. New tenants receive an automated text containing their unit’s padlock combination. Premjee pays people to check the properties once a month. (Break-ins are an issue in some areas, especially outside the prime markets. A profitable sideline for a growing number of facility owners is selling personal-property protection.)

Premjee was born in California in 1997, grew up in Mumbai, moved back to the U.S. for college, and earned a graduate business degree in London. He told me that he had become interested in real estate after Googling “how to get rich” and that his father had helped him make his first purchase, a small commercial lot, which he bought for twenty-six hundred dollars and sold three days later for forty-four hundred. More deals followed. “I knew flipping was a good way to make active income,” he told me. “But I needed something that made me money in my sleep.” Self-storage appealed to him, he said, partly because it didn’t involve “toilets and tenants.”

I asked Premjee whether he saw possibilities for growth in Europe, where, compared with Americans, people are less likely to accumulate excessive quantities of stuff. “I think there’s a massive opportunity,” he said. The average home in Europe is half the size of the average home in the U.S., and Amazon delivers there, too. (I asked a Welsh facility manager I met in Las Vegas what his customers keep in their units, and he said, “It’s . . . it’s . . . rubbish.”) “When they look at the U.S., they kind of laugh,” Premjee continued. “Europeans are getting double the rent per square foot.” There are also opportunities in Asia and the Middle East. Premjee recently visited a multistory facility in Dubai. “It had a huge staff on site, and they did valet storage, with pickup and drop-off,” he said. “There were eight or ten people in the office just doing sales and customer-support issues. And, to give you an idea of the rents there, a ten-by-twenty goes for seven hundred dollars a month, and they’re ninety-eight per cent occupied.”

Inside Self-Storage was founded in 1991 by Troy Bix, who had previously worked as a classified-ad salesman. In 2017, convinced that the golden age of self-storage had passed, he sold the company. “I’m not that smart, but I listen to my grandkids,” he told me. “And they don’t give a shit about hanging on to stuff.” At any rate, Bix is still a prominent figure at the expo. I met him at a booth promoting his current enterprise, Toy Storage Nation, which he founded in 2020 as the “voice of the RV and boat storage industry.” Sales of R.V.s and boats surged during COVID, because the pandemic made many other forms of vacationing difficult, but first-time purchasers often discovered that their homeowners’ associations prohibited them from keeping their new toys in their driveways or yards. According to an information sheet that Bix and his wife were handing out, the U.S. now has forty-eight hundred dedicated R.V.-and-boat-storage facilities and more than twenty-eight thousand hybrid facilities. Toy Storage Nation conducts seminars, produces podcasts, and advises owners, operators, and potential investors. Bix said, “They’re building half a million new boats and R.V.s a year now, and seventy per cent of them are beholden to an H.O.A. Ding!”

Among the more recent additions to the storage universe are car condos, which are units capacious enough to fit entire toy collections. They frequently include what are known in the industry as mezzanines, upper levels outfitted like living spaces. When I was young, my father owned a succession of serious R.V.s, the last of which was thirty-five feet long and had features that he had designed, among them cup holders large enough for liquor bottles. He parked it on a thick concrete pad that he’d had added to the end of our driveway. (No H.O.A. in our neighborhood.) He liked travelling in it, but what he really liked was hanging out inside it while drinking cocktails with friends and family, and if he could have done that while parked in an air-conditioned man cave he might never have taken it on the road.

The fanciest car condos sell for well over a million dollars, even though they’re often just big metal boxes. A developer I met in Florida showed me photos of a huge one whose owner used it to store and display his collection of German sports cars, one of which he’d mounted on a wall, like a decoration. The unit had a kitchen, a bathroom, a wet bar, and a carpeted mezzanine that included an office, a pair of Formula 1 racing simulators, a zebra-skin rug, a pool table, a sitting area, and a tripod-mounted rifle that seemed to be aimed at a big-screen TV. Katherine D’Agostino, who lives in Lincoln, Nebraska, and owns a consulting firm called Self-Storage Ninjas, told me, “The first really crazy car condo I ever saw was at a facility called Monte Carlo Garage Suites, in Indian Land, South Carolina. I told the owner it was amazing, and he said, ‘This is just the one my wife knows about.’ ”

D’Agostino has an M.B.A. from the University of Nebraska, and she used to own a housecleaning business. “I grew the revenue to, like, $1.3 million a year, but I got tired of employees calling me at 10 P.M. to tell me they were sick or their grandma had died,” she said. D’Agostino sold the cleaning business, built storage facilities in Nebraska, Illinois, and Texas, and learned so much about the industry that she began doing feasibility studies for others. She’s now developing “small-bay flex” spaces, which are similar in construction to self-storage buildings but are occupied by small businesses and light manufacturers—coffee roasters, last-mile deliverers, microbrewers, plumbing contractors, the occasional gastropub. D’Agostino’s business partner is a self-storage designer from Wisconsin, who showed me renderings for an upscale facility that they’re hoping to build. I would describe the structure as a strip mall reconceived by a storage ninja. He and D’Agostino are pursuing sites for two separate projects near the Villages.

One afternoon during the expo, I boarded a bus for a field trip to an R.V.-and-boat facility next to a Love’s Travel Stop, about twenty-five miles from the Strip. It’s directly across Highway 93 from Apex Regional Landfill, which covers roughly two thousand acres and, at the area’s current rate of stuff-dumping, is said to have two hundred and fifty years’ worth of remaining capacity. During the bus ride, I sat across the aisle from a talkative man in his early sixties who was wearing a big hat. I overheard him telling someone next to him that he’d had a liver transplant and was “making up for lost time” by building a storage facility in Virginia for two hundred R.V.s.

The site we visited had been built by a company called Baja Carports. It consisted of ten covered but unenclosed structures of various sizes on a seven-and-a-half-acre asphalt lot adjacent to the truck stop. The facility had its own security fence, gated entrance, and office. A man from California, who was used to dealing with that state’s stringent environmental regulations, asked how the facility handled oil leaks in its drainage system, and the manager said, in effect, “Come on, man! This is Las Vegas!” (The facility is flanked by desert.) Three of the structures had solar panels on the roof—a Baja specialty—and the manager said that they produced enough electricity to meet most of the needs of the truck stop while also providing a five-amp trickle charge for many of the tenants.

Almost all the toys parked at Love’s were R.V.s, plus an assortment of boats, trucks, and cars. The shade provided by the canopies made the spaces noticeably cooler than the uncovered pavement, which felt hot enough to melt truck tires. The man with the hat and the new liver told me that, if it had been up to him, he would have installed vertical shading along the western end of the lot, too, to block the setting sun. I walked around with identical twin sisters from Alabama, one a lawyer and the other a real-estate broker. They told me that they were getting ready to take over three storage facilities owned by their father, a developer, who had been occupied for some time with buildings of his that were severely damaged by thunderstorms and a tornado in 2025. The sisters had come to Las Vegas to listen to experts and gather ideas. Self-storage isn’t necessarily the bonanza that it has been at certain times in the past, but they were by no means the only attendees I met who believe that there are still fortunes to be made.

“We’re a stuff society,” the lawyer twin said. ♦

The Daily Front Page 24 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Memory Allocation
article

Comparison of Malloc() Algorithms

by egberts1·▲ 136 points·39 comments·egbert.net ↗
Multithreaded programs often do not scale because the heap is a bottleneck.

Memory Allocation

Problems

Limit Memory Allocation (if not necessary)

Multithreaded programs often do not scale because the heap is a bottleneck.

When multiple threads simultaneously allocate or deallocate memory from the allocator, the allocator will serialize them. Programs making intensive use of the allocator actually slow down as the number of processors increases.

Malloc (libc) is the worst memory allocation API to use.

Programs should avoid, if possible, allocating/deallocating memory too often and in particular whenever a packet is received.

In the Linux kernel there are available kernel/driver patches for recycling skbuff (kernel memory used to store incoming/outgoing packets).

Using PF_RING (into the driver) for copying packets from the NIC to the circular buffer without any memory allocation increases the capture performance (around 10%) and reduces congestion issues.

Design Evolution

Basic design of malloc() is to dynamically pre-allocate a pool of memory from the OS in which applications can then take smaller pieces from. malloc() is a standard API having a choice of different allocation algorithms and to mitigate the expensive OS system calls (typically done at program initialization time) during allocation of its system memory. The first memory allocation scheme started with a stack-based memory allocation.

Next came the dynamic-based memory allocation scheme where linked-list and bucket-heap mechanism are used to divide the private-heap using size class approach.

Soon, garbage collection algorithm introduced the initial backend of the memory allocation scheme. Frontend covers the usual malloc() API, et al.

In 2006, a third pool was introduced (after operating system memory pool and library-based memory pool) called the “arena”. Arena is a jemalloc-term and is intended to deal with different memory types such as different-speed memory bank or NUMA-architecture, as well as memory tied to specific to each of the multiple CPU core or even CPU infinity.

Frontend Evolution

Frontend manages the memory being given to the application.

Within the frontend of the memory allocation system, the evolution went in the following order:

  1. link-list free space
  2. heap-bucket size classes (eliminating an object header)
  3. (Process) Owner encoding
  4. single core local allocation buffers (CLABs)
  5. Epoch encoding
  6. Large-size class memory block by direct mmap()
  7. Hazard pointers (safe memory reclamation for lock-free objects) (M.M. Michael, 2004)
  8. Arena memory pool (CPU/core and thread, separately)
  9. thread-specific local allocation buffers (TLABs)
  10. constant-time modulo synchronization (early return to OS pool, or FreeBSD madvise call)

Backend Evolution

Backend of the memory allocation system manages the empty, straggling, fragmented or no-longer used memory blocks back to the OS (thereby reducing RSS).

  • Pool semantic: Remote f-list encoding, using Treiber stack), (R.K. Treiber, 1986)
  • buddy algorithm
  • binary buddy algorithm
  • BIPOP Table (span-based allocator)(S. Schneider, 2006) aka local free list and remote free list
  • segment queue (Quasi-linearizability, Y. Afek, 2010)
  • multi-core distributed queue (A. Haas, 2013)
  • k-FIFO queue (T.A. Henzinger, 2013)

Competition

There are better ones out there that does not worsen as more threads/processes performs memory allocation system calls; they are listed in best-to-good performance order [seed with source]:

Comparison of malloc design

Allocator Origin / Maintainer Thread Safe Per-Thread Cache Multi-Arena / Heaps Lock-Free Fast Path NUMA Aware Fragmentation Control Notes
dlmalloc Doug Lea No No No No Low Single global heap; basis for many later allocators
ptmalloc2 / ptmalloc3 glibc Yes Limited Yes No Medium glibc default; arena locks cause contention
glibc malloc (current) GNU Yes Limited Yes No Medium Wrapper around ptmalloc with tunables
jemalloc FreeBSD / Meta Yes Yes Yes Partial High Thread-arena affinity reduces CAS contention
tcmalloc Google Yes Yes Yes Partial Medium-High Per-CPU caches; central freelists still exist
mimalloc Microsoft Yes Yes Yes Yes High Designed to minimize atomic ops and false sharing
Hoard Emery Berger Yes Yes Yes Partial Medium Focus on scalability and false-sharing avoidance
nedmalloc NEDMALLOC Yes Yes Yes No Medium dlmalloc-derived with thread caching
phkmalloc FreeBSD Yes Yes Yes No Medium Early FreeBSD allocator family
libumem Solaris Yes Yes Yes Yes Medium-High Solaris allocator with debugging and locality support
mtmalloc Solaris Yes Yes Yes Yes Medium Solaris multithreaded allocator
snmalloc Microsoft Research Yes Yes Yes Yes High NUMA-aware security- and scalability-focused
lockless malloc (research) Academic / Experimental Varies Yes Varies Yes Low Often CAS-heavy; not production ready
ltalloc Academic

CAS, Atomic Contention Characteristics

CAS / Atomic Contention characteristics

Allocator Estimated Atomics per alloc/free Shared Cacheline Risk CAS Contention Sensitivity Notes
dlmalloc High High Very High Global structures and locks dominate
ptmalloc2 / ptmalloc3 Medium-High High High Arena locks cause cacheline bouncing
glibc malloc (current) Medium-High High High Wrapper around ptmalloc
jemalloc Low Low Low Arena-local metadata; minimal shared CAS
tcmalloc Low-Medium Medium Medium Per-CPU caches; central freelist CAS
mimalloc Very Low Very Low Very Low Designed to minimize atomic ops
Hoard Medium Medium Medium Reduces false sharing but still synchronized
nedmalloc Medium Medium Medium Thread caches reduce but don’t eliminate CAS
phkmalloc Medium Medium Medium Older FreeBSD design
libumem Low Low Low Lock-free fast paths on Solaris
mtmalloc Low Low Low Per-thread structures reduce atomic sharing
snmalloc Very Low Very Low Very Low Message-passing model avoids shared CAS
lockless malloc (research) High High High Often CAS-heavy despite no locks

NUMA, Memory Locality characteristics

NUMA / Memory Locality characteristics

Allocator Explicit NUMA Support First-Touch Friendly Cross-NUMA Traffic Risk Locality Preservation Notes
dlmalloc No Yes Very High Poor Single heap across nodes
ptmalloc2 / ptmalloc3 No Partial High Fair Arenas not NUMA-bound
glibc malloc (current) No Partial High Fair Relies on OS placement
jemalloc Partial Yes Medium Good Optional NUMA arena tuning
tcmalloc Limited Yes Medium Fair CPU caches not NUMA-aware
mimalloc No Yes Low Very Good Strong thread locality
Hoard No Yes Medium Good Per-processor heaps help
nedmalloc No Yes Medium Fair Thread caches but global fallback
phkmalloc Partial Yes Medium Fair Early locality optimizations
libumem Yes Yes Low Very Good Solaris NUMA policies
mtmalloc Yes Yes Low Very Good Designed for NUMA Solaris systems
snmalloc Yes Yes Very Low Excellent NUMA-first architecture
lockless malloc (research) No Varies High Poor Locality rarely addressed

Benchmark-Oriented Practical Performance

Benchmark-Oriented Practical Performance

Allocator Small Alloc Throughput Large Alloc Throughput Latency Under Contention Memory Overhead Fragmentation Risk Notes
dlmalloc Low Medium Poor Low High Not suitable for multithreaded loads
ptmalloc2 / ptmalloc3 Medium Medium Poor Medium Medium glibc default
glibc malloc (current) Medium Medium Poor Medium Medium Tunable but limited
jemalloc High High Very Good Medium-Low Low Excellent all-around allocator
tcmalloc Very High Medium Good Medium Medium Optimized for small objects
mimalloc High High Excellent Low Low Great latency predictability
Hoard Medium Medium Good Medium Low Designed for scalability
nedmalloc Medium Medium Fair Medium Medium Older but usable
phkmalloc Medium Medium Fair Medium Medium Historical FreeBSD allocator
libumem High Medium Very Good Medium Low Strong debugging support
mtmalloc High Medium Very Good Medium Low Enterprise Solaris workloads
snmalloc High High Excellent Low Very Low Security + scalability focus
lockless malloc (research) Varies Varies Poor Low High Often unstable in practice

Allocator Recommendation

Allocator Recommendation

Workload Type Primary Bottleneck Key Risks Recommended Allocator Why It Fits Alternatives Avoid
Highly Contended Multithreaded Atomic/CAS latency Cacheline bouncing jemalloc Multi-arena + thread affinity minimizes shared CAS mimalloc, snmalloc dlmalloc, ptmalloc
Low-Latency / Tail-Sensitive Allocation jitter Lock convoying mimalloc Very low atomic count and predictable fast paths snmalloc, jemalloc tcmalloc
NUMA / Multi-Socket Servers Cross-node memory access Remote cache ownership snmalloc Explicit NUMA awareness and locality control jemalloc (NUMA tuned) libumem, glibc malloc
Small Object Heavy (RPC / Web) Allocator throughput Central freelist contention tcmalloc Per-CPU caches optimized for small allocs jemalloc, mimalloc ptmalloc
Large Object / Mixed Sizes Fragmentation TLB pressure jemalloc Excellent fragmentation control and extent management mimalloc glibc malloc
False-Sharing Sensitive Cacheline ping-pong Metadata sharing Hoard Designed to avoid false sharing jemalloc, mimalloc dlmalloc
Security-Hardened Use-after-free exploits Heap corruption snmalloc Isolation + security invariants mimalloc (secure) ptmalloc
Debugging / Leak Detection Memory misuse visibility Silent corruption libumem Strong runtime diagnostics jemalloc (profiling) tcmalloc
Embedded / Low Memory Footprint size Overhead dlmalloc Small and simple if single-threaded nedmalloc jemalloc
Real-Time / Deterministic Unbounded latency OS interference mimalloc Low variance fast paths snmalloc jemalloc, tcmalloc
HPC / Scientific NUMA Memory bandwidth Remote NUMA hits snmalloc NUMA-first design and low CAS traffic jemalloc + mbind glibc malloc
Legacy / Compatibility ABI stability Toolchain issues glibc malloc System default and safest fallback ptmalloc

Decision Chart for Malloc Selection

Decision Supertree for Malloc Selection

Graphviz DOT file

References

  • R. J. Maher, Problems of storage allocation in a multiprocessor multiprogrammed system, Communications of the ACM, 4(10):421-422, October 1961
  • A fast storage allocator, Kenneth C. Knowlton, Communications of the ACM, 8(10):623-625, October 1965.
  • Statistical properties of the buddy system, P.W. Purdom and S. M. Stigler, Journal of the ACM, 17(4):683-697, October 1970
  • Statistical investigation of three storage allocation algorithms, P. W. Purdom, S. M. Stigler, and Tat-Ong Cheam, BIT, 11:187-195, 1971.
  • A note on an optimal-fit method for dynamic allocation of storage, J. A. Campbell, Computer Journal, 14(1):7-9, February 1971.
  • Worst-case analysis of memory allocation algorithms, M. R. Garey, R. L. Graham, and D. W. Ullman, In Fourth Annual ACM Symposium on the Theory of Computing, 1972
  • A class of dynamic memory allocation algorithms, D. S. Hirschberg, Communications of the ACM, 16(10):615-618, October 1973
  • Dynamic storage allocations of arbitrary sized segments, J. S. Fenton and D. W. Payne, In Proc. IFIPS, pages 344-348, 1974
  • Worst-case of Memory Allocation Algorithms, Garey 1972
  • A simplified recombination scheme for the Fibonacci buddy system, B. Cranston and R. Thomas, Communications of the ACM, 18(6):331-332, July 1975.
  • Buddy systems, J. L. Peterson and T. A. Norman, Communications of the ACM, 20(6):421-431, June 1977.
  • Worst case fragmentation of first fit and best fit storage allocation strategies, J. M. Robson, Computer Journal, 20(3):242-244, August 1977.
  • Fast-fit: A new hierarchical dynamic storage allocation technique, M. Tadman, Master’s thesis, UC Irvine, Computer Science Dept., 1978.
  • The double buddy-system, David S. Wise, Technical Report 79, Computer Science Department, Indiana University, Bloomington, Indiana, December 1978
  • Memory fragmentation in buddy methods for dynamic storage allocation, A. G. Bromley, Acta Informatica, 14(2):107-117, August 1980.
  • Optimal fit of arbitrary sized segments, Ivor P. Page, Computer Journal, 25(1), January 1982.
  • Parallelizing the usual buddy algorithm, A. Gottlieb and J. Wilson, Technical Report System Software Note 37, Courant Institute, New York University, 1982.
  • Fast fits: New methods for dynamic storage allocation, C. J. Stephenson, In Proceedings of the Ninth Symposium on Operating Systems Principles, pages 30-32, Bretton Woods, New Hampshire, October 1983. ACM Press. Published as Operating Systems Review 17(5), October 1983.
  • On the asymptotic optimality of first-fit storage allocation, E. G. Coffman, Jr., T. T. Kadota, and L. A. Shepp, IEEE Transactions on Software Engineering, SE-11(2):235-239, February 1985.
  • Efficient implementation of the first-fit strategy for dynamic storage alloca- tion, R. Brent, ACM Transactions on Programming Languages and Systems, July 1989.
  • Fast allocation and deallocation of memory based on object lifetimes, David R. Hanson, Software Practice and Experience, 20(1), January 1990.
  • Dynamic Storage Allocation: A Survey and Critical Review, very useful chronological order of malloc(), 1995
  • The Memory Fragmentation Problem: Solved? Johnstone 1997
  • A Memory Allocator, 2000
  • Solaris mtmalloc (archived), 2003
  • Anatomy of a Program in Memory, 2009
  • A History of malloc, 2010
  • Heap and allocators, 2015
  • Understanding glibc malloc
  • The Origins of Malloc, 2017
  • GrapheneOS hardened_malloc, 2019
  • Simulation of High-Performance Memory Allocators, Risco-Martin, 2024
The Daily Front Page 25 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Congress Call
article

CCC invites all model citizens to 40C3

by antonly·▲ 356 points·185 comments·events.ccc.de ↗

CCC invites all model citizens to 40C3

CCC invites all model citizens to 40C3

The word is on the street: the Chaos Computer Club is hosting 40C3 from 27 to 30 December 2026 – Europe’s biggest hacker party, conference and platform for technology, society and civil liberties. We understand the Congress to be a huge shared stage and therefore invite you to help shape it. The Call for Participation for talks, the entertainment programme, art, punk and music opens today.

Everything is getting bigger, more colourful and more beautiful. Following our moving to the Hamburg Exhibition halls, there is once again plenty of space for creative ideas. Obviously, we want to make the most of this new space, which is why we are inviting all galactic beings to the 40th Chaos Communication Congress from 27 to 30 December 2026.

With the idea of this year’s motto ‘Model Citizens’ in mind, we want to work together to find new models for society, now that the ‘Model Citizens’ of the past have left the planet in a precarious state. There are loads of ways to go about this. For example, the Congress is the biggest non-commercial hacker conference, organised by volunteers, supported by thousands of unpaid helpers and over 16,000 visitors who don’t just passively consume the event, but actively help to shape it.

Times have become harsher. The consensus that, in a democratic society, we should work in solidarity towards a shared, better future is increasingly giving way to the model of an authoritarian state, in which the stronger impose their views on the weaker. Personal commitment and a sense of responsibility are taking a back seat to the call for a strong hand that is supposed to make everything ‘great again’. The remaining liberal forces are fighting rearguard actions and no longer attempt to create something new, but merely to prevent things from getting worse.

We see things differently, with a more combative spirit: the Congress was and remains the model for how things can be different. Differences are seen as an asset, the unfamiliar as a source of inspiration, and mutual needs as an opportunity to create a sense of community in which everyone feels comfortable and welcome.

For our time-honoured lecture programme at 40C3, we are calling for speakers to respond to our Call for Content; we are also reaching out to DJs and musicians to bring their talents to our lounge and party stages. Artists and designers can apply via our Call for Art with exhibits, sculptures and performances that do not require a stage. For our Punk-Späti, we’re looking for accomplices and fellow troublemakers for anarchic and anti-fascist performances in our usual warm yet rough-and-ready atmosphere.

Links und weiterführende Informationen

The Daily Front Page 26 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Also on the Front Page
The Daily Front Page 27 of 28
Thursday, September 17, 2026 The Daily Front No. #260917 — Colophon

That's the Front for Today

Issue No. #260917 — Thursday, September 17, 2026 — went to press 2026-09-18 at 08:53 UTC.

About This Magazine

The Daily Front is a daily digital magazine assembled from the stories that reached the front page of Hacker News on Thursday, September 17, 2026. Headlines, points, and comment counts are recorded as they stood at press time. All articles remain the property of their original authors — every piece links back to its source and its discussion thread.

How It Was Made

Fetched, cleaned, and typeset by an automated pipeline. An editor model laid out the pages and chose the highlights; a second read a handful of the day's stories and briefed the cover illustrator — 31 model calls and 210k tokens in total. Set in Jacquard 12, Playfair Display, Source Serif 4, and IBM Plex Mono, all served via Google Fonts under the SIL Open Font License.

The Cover

The cover illustration was commissioned with this prompt:

In a quiet law library, a barrister in rolled sleeves leans over an open workstation beside towering shelves of bound case files. On the desk, a large graphics card glows beneath a transparent cooling shroud while fine copper wires stream upward into a small brass courtroom model, where a metal gavel rests beside neatly stacked blank briefs. A powerful fan turns overhead, sending loose paper corners fluttering and lifting a tiny red thread tied around the processor’s exposed circuit board.

Render the cover as a strict modernist wayfinding map on uncoated paper: use a deep navy grid with acid chartreuse, copper orange, signal red, and warm ivory as the deliberate palette. Reduce the law-library setting, rolled-sleeve leaning barrister, towering bound-case-file shelves, open workstation, glowing graphics card beneath its transparent cooling shroud, upward-streaming fine copper wires, small brass courtroom model, adjacent metal gavel and stacked blank briefs, overhead turning fan, fluttering loose-paper corners, and red thread lifting from the exposed processor circuit board to the smallest clear route-and-node symbols; preserve every spatial and causal relationship through aligned paths, junctions, directional arrows, and elevation markers. Keep the composition quiet, diagrammatic, and rigorously gridded, with flat color fields, restrained typography-like labels, visible paper grain, and no ornamental detail.

Absolutely no text, letters, numbers, readable symbols, or logos anywhere in the image.

Production Ledger

StageModelCallsTokens InTokens Out
extractgpt-5.6-luna 27 128,541 56,944
layoutgpt-5.6-terra 1 19,186 2,090
covergpt-5.6-luna 2 1,579 431
covergpt-image-2.5-flare 1 296 1,372

The Publisher

Published by Johnny.

Support the Press

If The Daily Front brightens your morning, consider supporting its publisher.

Credits & Contact

All content — articles, posts, comments, and the images within them — belongs to its original authors and is reproduced here to point readers back to the source. Full credit goes to those creators; every item links to its original and its Hacker News discussion.

If you are an author and would like your content removed from an issue, write to hi@johnnys.page and it will be taken down.

Feedback is always welcome at the same address: hi@johnnys.page.

Credit where credit is due.

Every page of this issue began as someone else's work — these are the original sources, linked in full.

  1. Nvidia announces native GPU programming in Rust by nonmaskable — developer.nvidia.com·HN discussion ↗
  2. Astra for Law by vertigoruntime — openai.com·HN discussion ↗
  3. Why I didn’t sign the Fields medallists’ letter by simianwords — gowers.wordpress.com·HN discussion ↗
  4. Bonsai 2 27B: Near-Lossless Compression in a 9x Smaller Footprint by JonSchneider — prismml.com·HN discussion ↗
  5. Bend – A language that blocks AI mistakes via proof, on CPU and GPU by nicolas-siplis — bend-lang.com·HN discussion ↗
  6. Developing provably correct Rust code with Verus by Betelbuddy — amazon.science·HN discussion ↗
  7. Infinite-Parameter LLMs: Generating and Adapting Weights from Live Data by Betelbuddy — arxiv.org·HN discussion ↗
  8. Reverse-engineered Jev-like model by rochansinha — github.com·HN discussion ↗
  9. Show HN: Share your AI Setup, Learn from others by steveybrown — mysetup.ai·HN discussion ↗
  10. Launch HN: Skillsync (YC W26) – AI chat sessions made portable across agents by cat-whisperer — news.ycombinator.com·HN discussion ↗
  11. Hister: A private search engine for the pages you visit and the files you keep by bookofjoe — github.com·HN discussion ↗
  12. Rate limits on GitLab.com are changing by darkwater — about.gitlab.com·HN discussion ↗
  13. A 32-year-old bug walks into a Telnet server by paimapi — labs.watchtowr.com·HN discussion ↗
  14. Cloudflare/Security-Audit-Skill by donk8r — github.com·HN discussion ↗
  15. CrowdSec Source Code Leak by eccgecko — crowdsec.net·HN discussion ↗
  16. My temporary PHP fix from 2014 has nearly 20M installs. Today I'm deprecating it by jakeasmith — jakeasmith.com·HN discussion ↗
  17. One year of sponsored Servo development by AshleysBrain — servo.org·HN discussion ↗
  18. Flet 1.0 – Build cross-platform apps in Python by absqueued — flet.dev·HN discussion ↗
  19. This PCB is brought to you by Fable 5 by jasonpeacock — a6mzero.com·HN discussion ↗
  20. Wax motor by mhb — en.wikipedia.org·HN discussion ↗
  21. The Return of Sail Power: Cargo Ships Are Turning Back to the Wind by gumby — gcaptain.com·HN discussion ↗
  22. The American Religion of Self-Storage Facilities by pseudolus — newyorker.com·HN discussion ↗
  23. Comparison of Malloc() Algorithms by egberts1 — egbert.net·HN discussion ↗
  24. CCC invites all model citizens to 40C3 by antonly — events.ccc.de·HN discussion ↗
  25. HarnessTax: How Much Does the Harness Matter for Coding Agents? by matt_d — harnesstax.github.io·HN discussion ↗
  26. Fujitsu launches made-in-Japan next-generation CPU FUJITSU-MONAKA by my123 — global.fujitsu·HN discussion ↗
  27. How GLM built its own inference infrastructure by whiteros_e — z.ai·HN discussion ↗
  28. Keys Not Included: recovering the signing keys for US driver's license barcodes by Ryan5453 — ryan.science·HN discussion ↗
  29. The Relation Between Mathematics and Physics by Paul Dirac (1939) by rramadass — damtp.cam.ac.uk·HN discussion ↗
  30. TSMC revealing details about next gen A14 node by osnium123 — iedm26.mapyourshow.com·HN discussion ↗

Browse all issues in the archive →