Cover illustration

TheDaily Front

Issue No. #260803 Monday, August 3 2026 #260803 — MONDAY, AUGUST 3, 2026
All the news fit to verify before forwarding.
Monday, August 3, 2026 The Daily Front No. #260803 — Contents
30stories
10,779points
5,794comments
212kllm tokens
Assembled with 33 model calls — 156,210 tokens read, 55,336 written.

Highlights

Don't be a meat proxy

A plea to stop forwarding raw chatbot output and restore the human contribution to human conversation.

Prevent cognitive debt by manually retyping LLM-generated code

A proposed ritual of retyping generated code argues that speed without understanding accumulates cognitive debt.

SQLite Critical CVEs or LLM Slop?

Dubious SQLite advisories expose how automated security reporting can flood trusted systems with convincing noise.

Ten advances in mathematics and theoretical computer science

OpenAI presents ten mathematical and theoretical-computer-science advances, inviting scrutiny over methods, credit, and cost.

Wind and solar overtake fossil fuels in Germany for the first time

Germany’s wind and solar generation passes fossil fuels over a full year, a milestone with plenty of caveats.

From the Editor

The machines have offered to do the thinking, the coding, the filming, and perhaps even the vulnerability reporting. Today’s better counsel is less breathless: keep your hands on the wheel, inspect the work, and know enough to ask the right question. The old copy desk would call that good sense.

  1. Don't be a meat proxy3
  2. Prevent cognitive debt by manually retyping LLM-generated code4
  3. SQLite Critical CVEs or LLM Slop?5
  4. LLMs reward expertise6
  5. Ten advances in mathematics and theoretical computer science7
  6. Devtools must be open source8
  7. Bonsai: Janestreet's UI Library9
  8. AirLLM 70B inference with single 4GB GPU10
  9. MiniMax H3 Day-0 Support in ComfyUI: Open Weights, Native Audio, and 2K Video11
  10. How Hollywood stopped making movies in Hollywood12
  11. Andy Pavlo joins ClickHouse to establish ClickHouse Labs13
  12. Rust project goals: Immobile types and guaranteed destructors14
  13. Decades-old fish sauce at abandoned factory in Canada finally being removed15
  14. Smaller, faster, safer: running Kimi and GLM at scale16
  15. CP/M-386 – CP/M for 386 protected mode, derived from CP/M‑68K17
  16. More German than many Germans18
  17. Why we write our own C and C++ inference engines19
  18. Why Book Corners won't sync contributions back to OpenStreetMap20
  19. Massively Parallel Postgres Backups21
  20. What DMARC Protects You From, and What It Does Not22
  21. Replacing the Kobo Libra H2O Battery23
  22. Show HN: ssh ssh.place24
  23. The myth of Snow Leopard25
  24. Qwen3.8-Max: A New Bar for Coding and Cowork26
  25. Launch HN: Hoplite (YC S26) – Effortlessly deploy cloud coding agents26
  26. Wind and solar overtake fossil fuels in Germany for the first time26
  27. Show HN: Isopolis – Isometric pixel map of SF26
  28. Show HN: A Handwritten Blogging Platform26
  29. Celebrating 45 Years of Kermit with the First New C-Kermit Release in 15 Years26
  30. 200 Milliseconds26
The Daily Front Page 2 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — Lead: The Human Reply
article

Don't be a meat proxy

by ngruhn·▲ 1,731 points·700 comments·gruhn.me ↗
I can talk to Claude myself.

Too often I ask a question in Slack or leave feedback under a merge/pull request or argue with friends in a WhatsApp group and get back:

Claude said: [giant response verbatim]

Please don't do this. I mean, I've done this. But I've been on the receiving end too many times now. This is not adding value. I can talk to Claude myself. It's going to be faster and I get to control the context. I don't need a meat proxy in between.

Reading AI output is extra effort. It's verbose, frequently contains all too plausible nonsense, and is increasingly jargon dense. I recently got this sentence from Claude:

NATS control-plane events: stream leader election / R3 quorum re-form during pod churn.

Jesus. I had to lookup almost every word to make sense of this.

By all means, prompt AI. But don't just relay the output. Read it, understand it, validate it, and then write a response in your own words (a decent certificate that you've done the prior steps). Making that effort is value you can add.

Take code review in particular. Shipping some code can be done with close to zero effort now: Copy/paste the ticket description into Claude Code. Don't look at the code or read what Claude has written. If there's any feedback from reviewers, copy/paste that into Claude Code as well. If necessary, iterate.

That works. But who has done the implementation? The reviewers did, using Claude Code, and you as a meat proxy.

The Daily Front Page 3 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — Code, Retyped
article

Prevent cognitive debt by manually retyping LLM-generated code

by mpweiher·▲ 469 points·379 comments·ankursethi.com ↗
allowing my coding assistant to roam free in my projects leaves me with a colossal amount of cognitive debt.

Despite what I said in April, I'm still using coding assistants on my personal projects.

Using them to one-shot entire features leaves me unsatisfied and disoriented, but I do enjoy using them to fast-forward through the boring parts of my projects.

However, allowing my coding assistant to roam free in my projects leaves me with a colossal amount of cognitive debt. I might hate the idea of poring over the Django documentation to figure out how to add tagging to my website, but I still fundamentally want to understand how it works. Just because a problem is boring doesn't mean I want to fully offload my understanding of the solution to a machine.

Of course, I could review every single line of code the LLM produces. That's what most developers are expected to do in this cursed year of 2026. Robots raise PRs, humans review them. It's a brave new world.

But I don't enjoy reviewing AI-generated PRs. Poring over hundreds of lines of overly-defensive, badly-commented, subtly incorrect code is not fun. I might grudgingly do it for an employer—while making sure said employer becomes an ex-employer as soon as possible—but I'm sure as hell not doing it for my personal projects. Personal projects must be fun above all else. The joy of working on personal projects comes from the process, not from the outcome.

So what's a boy to do? How do I offload the boring work to LLMs without ceding control of my own work and cognition to the slop machine?

I've come up with a solution that's grossly inefficient and perhaps slightly comical: I ask my coding assistant to generate code in the chat, then manually make all the edits myself.

I have these instructions in all the agents files in my personal projects:

I want to understand every line of code that goes into this project. Never create, edit, move, rename, or delete project files unless I explicitly ask you to do so. Instead, show me every proposed edit in the chat so I can type it in manually.

Do not run commands that modify project files, install dependencies, or change repository state unless I explicitly request that action. Instead, show me those commands in the chat so I can run them manually.

I'm an experienced developer. Do not explain syntax, APIs, programming concepts, or implementation details unless explicitly asked.

Using LLMs this way allows me to work faster than not using LLMs at all, but I'm still slower than those who are willing to allow the machine to think for them. Instead of being 10x faster, I'm probably only 2x faster. But what I lose out on in terms of speed, I gain in terms of a deeper understanding of my code.

As I manually type every single line of LLM generated code into my editor, I build up a mental model of how it works and fits into my existing codebase. If I don't understand an API or algorithm, I can stop to look it up, or just ask the LLM to explain it.

Typing the code myself forces me to slow down, which means I'm more likely to detect hallucinations or bad design choices the LLM might have made. I can clean up the code as I go, reorganizing it, refactoring it, adding comments, and generally adapting it to my own taste.

Most importantly, this workflow allows me to build a spatial map of my codebase. I know where every bit of functionality lives in the codebase. When I need to make a change, I know exactly where I need to make it. It not only helps me work faster within my projects, it also makes it easier for me to better prompt and instruct the LLM in the future.

When I was learning to code as a teenager, experienced programmers would often tell me to never copy and paste code into my projects. If I was learning from a book, I was advised to copy all the examples into my computer and make sure I could run them. If I was learning from a blog post or forum answer, I was advised to type it out and adapt it to my codebase so I understood it completely.

Manually typing LLM-generated into my codebase feels like the exact same learning process. It might not be the most efficient way to work with an LLM, but I value comprehension over productivity. I've been doing this for a few months now, and it's been working well for me. I plan to continue using this workflow for as long as I can.

I fear the software industry is taking on a large amount of cognitive debt that we'll have to pay back very soon. There will come a time when we no longer understand how large parts of our digital infrastructure are put together. I might not personally be able to change the course of the entire industry, but I can at least make sure I completely understand the software I put out into the world. Anything else would be professional malpractice.

The Daily Front Page 4 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — The Security Noise Problem
article

SQLite Critical CVEs or LLM Slop?

by ymir_e·▲ 708 points·360 comments·research.jfrog.com ↗
the claims fell apart

Over the past few days, a newly created GitHub repo (programmervuln/cveadvisory-) published a batch of SQLite vulnerability advisories (as part of other 50+ CVEs which we believe are also LLM slop except from one). NVD quickly flagged these as critical, and CISA's ADP agreed. But when JFrog security researchers dug in to verify, the claims fell apart:

  1. The cited code didn't even exist in those versions or referenced unrelated logic.
  2. When testing the PoC payloads they didn’t work (not triggering any crash).
  3. None of these CVEs are listed on SQLite’s official advisory page (which is a gold standard for tracking actual vulnerabilities).
  4. All advisories in this repo seem AI generated when testing them with Gptzero

Combining all advisories into one file triggers AI-generated content warnings

This made us question the reliability of these CVEs as well as understanding that these CVEs may be LLM slop.

While investigating one of the CVEs yesterday, CVE-2026-51302, we saw that Red Hat initially assigned it a 10.0 Critical severity score:

Looking at the CVE again today, we noticed that the score has since been downgraded to 7.6 High.

Analysis Matrix

CVE Reported Flaw CVSS NVD Metadata Audit Finding
CVE-2026-51302 UAF in exprComputeOperands() 9.8 CRITICAL Pinned CPE: 3.41.0 The advisory mentions non-existing functions.
CVE-2026-51303 UAF in ExprListDelete() back-refs 9.8 CRITICAL Contradictory metadata The advisory said there are non-existent fixes.
CVE-2026-51300 UAF in sqlite3ExprDelete() 9.1 CRITICAL n/a placeholders Advisory cited lines that are unrelated to the vulnerability.
CVE-2026-51297 UAF via jsonBlobEdit() 8.8 HIGH Pinned CPE: 3.41.0 The advisory mentions non-existing functions.
CVE-2026-51296 UAF in jsonRemoveFunc 7.5 HIGH Populated CPE: 3.41.0 Advisory cited lines that do not exist.
CVE-2026-51304 UAF via pOrderBy->nExpr post-free 7.5 HIGH Vendor/Product: n/a Advisory showed a real function with a wrong argument number.

Investigation Methodology

To verify these reports thoroughly, we established an isolated testing workflow:

  • Source Inspection: We cloned the official sqlite/sqlite repository and checked out the target tags (version-3.41.0, version-3.51.2, and version-3.51.3). We compared the reported vulnerability mechanics against the actual source code.
  • Clean Environment Build: Compiled the official SQLite releases directly inside isolated Docker containers to prevent environmental contamination.
  • PoC Execution: Feed each advisory's PoC SQL statements verbatim into the compiled SQLite binaries under AddressSanitizer (ASan) instrumentation to detect memory bugs.
  • NVD & Metadata Audit: Evaluated the CPE patterns and advisory metadata across NVD and GHSA feeds to cross-check tracking accuracy.

Detailed Technical Breakdown

1. CVE-2026-51302: Non-Existent Logic (9.8 Critical)

Reported Vulnerability: The advisory claims a heap use-after-free occurs when sqlite3ReleaseTempReg() leaves a dangling pointer in regFree1, which is later dereferenced by exprComputeOperands().

Finding: The primary issue here is that exprComputeOperands() didn't exist in SQLite 3.41. It was added in the middle of 2025 (commits e24f20a, 280559b). Furthermore, the mechanics of sqlite3ReleaseTempReg() do not involve heap deallocation. The function simply recycles register indices into an array for reuse, making a UAF impossible by design.

/* expr.c:6562, SQLite 3.41.0 */
void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
  if( iReg ){
    sqlite3VdbeReleaseRegisters(pParse, iReg, 1, 0, 0);
    if( pParse->nTempReg < ArraySize(pParse->aTempReg) ){
      pParse->aTempReg[pParse->nTempReg++] = iReg;
    }
  }
}

PoC Testing: The query ran successfully without triggering a crash because the bug does not exist.

2. CVE-2026-51303: Ghost Fixes (9.8 Critical)

Reported Vulnerability: Claims that ExprListDelete() fails to clear back-references in parent structures when releasing child nodes, allegedly patched in version 3.51.3.

Finding: There is no evidence of back-reference pointers in the Expr, Select, or Window structures that could lead to such a state. Most tellingly, a diff between 3.51.2 and 3.51.3 shows absolutely no changes to src/expr.c. The "patch" was entirely fabricated.

PoC Testing: The PoC is invalid SQL and fails at the parser stage, never actually hitting the execution logic.

3. CVE-2026-51300: Misdirected Call Sites (9.1 Critical)

Reported Vulnerability: Claims a UAF occurs in sqlite3ExprDelete() because a left-hand expression pointer is not cleared, referencing specific line numbers in expr.c.

Finding: The cited line numbers (1012 and 1026) are a comment and a memory allocation call respectively, neither has anything to do with pLeft or deletion logic. While the function is called during OOM error handling, it occurs at the end of a scope where the pointer is never reused, preventing any potential UAF.

/* expr.c:1330, SQLite 3.41.0 */
void sqlite3ExprDelete(sqlite3 *db, Expr *p){
  if( p ) sqlite3ExprDeleteNN(db, p);
}

PoC Testing: Executed successfully as a valid SQL query, returning expected output with zero memory leaks or errors.

4. CVE-2026-51297 (8.8 High)

Reported Vulnerability: Claims jsonParseFree() leaves dangling references that are later accessed by jsonBlobEdit().

Finding: Similar to the first case, jsonBlobEdit() was not present in the reported target version (3.41.0). It was only introduced later as part of the JSONB implementation. In the target version, jsonParseFree() is used strictly in destructors where the surrounding structure is immediately discarded.

PoC Testing: The PoC hits a malformed JSON error immediately, meaning the code never reaches the JSON modification logic where the vulnerability supposedly exists.

5. CVE-2026-51296: Impossible Line Numbers (7.5 High)

Reported Vulnerability: Reports a UAF in jsonRemoveFunc specifically at lines 3555 and 3575 of json.c.

Finding: In version 3.41.0, src/json.c is only 2706 lines long. The cited line numbers don't exist. The actual implementation of the function was found roughly 2000 lines earlier, and an audit of that code showed no memory management flaws.

PoC Testing: The payload fails during JSON parsing, leaving the memory untouched.

6. CVE-2026-51304 CVSS 7.5 (HIGH)

Reported Vulnerability: Claims sqlite3ExprListDelete(pOrderBy) frees the ordering list while subsequent code reads pOrderBy->nExpr.

Finding: The single-argument signature reported in the advisory does not exist. the actual signature requires a pointer to the database context (sqlite3 *db). Furthermore, SQLite explicitly nulls pointers immediately after deletion:

/* select.c:3761, SQLite 3.41.0 */
sqlite3ExprListDelete(db, pPrior->pOrderBy);
pPrior->pOrderBy = 0;   /* Pointer immediately cleared; impossible to dereference */

PoC Testing: The PoC payload executed against a 20-column ORDER BY query processed normally, returning sorted results with no issues.

How Can AI Slop CVEs Happen

The CVE submission process via MITRE's public form lacks any real identity verification, meaning virtually anyone can submit a vulnerability description and propose a CVSS score.

Historically, NIST acted as a reliable safety net for this system, experts at the National Vulnerability Database (NVD) manually analyzed, validated, and enriched incoming CVEs before giving them a stamp of approval. But that safety net broke in February 2024.

Hit by a massive surge in vulnerability reports, NIST effectively hit pause on deep analysis. CISA and other Authorized Data Publishers (ADPs) tried to step in with their own enrichment efforts, but the global pipeline is now fragmented and drowning in a massive backlog. Because no step in today's system actually requires a proof-of-concept or bug reproduction, a plausible-sounding fake advisory can slide right through the pipeline and end up in GHSA, downstream databases, and enterprise scanners.

Key Takeaways

This incident demonstrates a systemic issue with automated vulnerability ingestion. A broader audit of 55 advisories published by the same GitHub account revealed that 54 were completely fabricated, while one contained a real bug wrapped in unverified CVE metadata.

Red Flags to Spot Slop CVEs:

  • Missing Vendor Corroboration: No mention of the issue on official maintainer security pages (e.g., sqlite.org/cves.html).
  • Absent Commit History: No commit hash or pull request linked in reference fields.
  • Metadata Contradictions: Empty CPE product definitions or version ranges that conflict with the advisory narrative.
  • Non-existent Code References: Citing functions that do not exist in the claimed target version or line numbers past EOF.

These LLM slop CVEs can cause organizations to waste time investigating and patching vulnerabilities that do not actually exist, as well as polluting vulnerability databases. In environments where Critical vulnerabilities are automatically prioritized or tickets are opened based on vulnerability scores, such fabricated CVEs can turn into a real burden.

In environments where AI is used to automate vulnerability triage and remediation this becomes even more concerning. An AI agent that encounters a fabricated CVE may attempt to locate the vulnerable function, generate a patch, or recommend changes based on code that does not even exist. Instead of helping security teams remediate real vulnerabilities, it can lead them down a completely wrong path, potentially introducing unnecessary changes and wasting time.

To avoid being affected by this kind of vulnerability noise:

  • Don't blindly trust newly published CVEs by unknown/unvalidated sources.
  • Investigate such critical CVEs to understand whether the score matches the vulnerability.
  • Check if your environment is truly affected by the CVE.
  • Reproduce the reported issue with the provided PoC whenever possible in a safe environment.

Reported Findings

We have also formally reported these findings to GHSA, Redhat and NVD to assist in the remediation of these records.

The Daily Front Page 5 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — Expertise Still Counts
article

LLMs reward expertise

by MaxMussio·▲ 844 points·348 comments·seangoedecke.com ↗
LLMs make everybody into a generalist.

In the 2010s, if you had technical gaps (say, you couldn’t write CSS), you had to either rely on a skilled colleague or just hope that the answer to your exact problem was out there on the internet. Today, everyone can write sort-of-okay CSS by delegating the task to an LLM. LLMs make everybody into a generalist.

Because of this, lots of people don’t think there’s any skill involved in working with LLMs. If you want the product that LLMs can deliver — PhD-level mathematics, pretty good but sometimes tasteless computer code, or awkward LinkedIn-style writing — you can simply ask for it. Since everyone is talking to the same models, “skilled prompters” are getting the same results as people touching LLMs for the first time.

This is wrong. The most important skill in prompting is expertise in the domain you’re prompting for.

A good illustration of this is Terence Tao’s conversation with ChatGPT about the recently-discovered counterexample to the Jacobian Conjecture. This is not the same ChatGPT I talk to! I couldn’t get to where Tao gets, even with unlimited tokens to burn.

There’s a lot to learn about good prompting from Tao’s conversation. Here are a few observations:

  • Tao’s messages are very short and to-the-point. He doesn’t respond point-by-point to the model, just to the gist
  • The model outputs are much more concise than when I try and talk to GPT-5.6 Sol about mathematics. By signalling expertise, Tao shunts the model into “talking-to-mathematicians” mode, not “explaining-to-amateurs” mode
  • Tao pushes back when the model’s responses look wrong, but he doesn’t directly contradict; instead, he says things like “this looks more complex than I was hoping for”
  • Tao makes several leaps and suggestions himself. He almost never takes the model’s advice about where to go next

However, you can’t prompt like Tao on mathematical questions just by following these tips. The key to his technique is actually understanding the mathematics: pulling the relevant idea out of ChatGPT’s multi-paragraph response, suggesting alternate approaches or formulations, and identifying what “looks weird”.

Terence Tao is a better mathematician than I am a programmer. But the idea here — that domain knowledge makes you better at using LLMs — is something I’ve also experienced in my own work. If you have a good theory of your codebase, you can push the LLM much harder than if you have no familiarity. Because you have your own sense of what a good solution might look like, you can say “no, I think it could be simpler here”, or “but don’t we already do X?”, or “can we express this problem in these familiar terms?“.

This touches on an idea I’ve written about before: that system design problems are dominated by concrete specifics, not generic principles. Of course both are useful, but I’d rather have familiarity with the codebase than a deep general understanding of software systems. In his conversation, Terence Tao asks a lot of specific questions like “does X work here?”, or “given Y and Z, why A?“. I can’t ask those questions about the Jacobian Conjecture, but I can ask them about the systems I own at GitHub.

If you have no domain knowledge, you can cling onto the LLM to at least get something. That’s not bad! But if you have domain knowledge, you can wring far more value out of the same LLM by steering it hard in the direction you want. Most of us will have to do a mix of both these approaches, since we have domain knowledge in some areas but not others.

The usefulness of domain knowledge suggests that human expertise will continue to be useful even as models get stronger. For many tasks, the human is the bottleneck, not the model, because the difficult part is in communicating to the model exactly what kind of solution the human wants. The information is “in the model” already, but it takes a very smart human to pull it out.

edit: this post got many comments on Hacker News. Some commenters share their anecdotes about how expertise has helped and lack of expertise has hurt. Other commenters say it’s plausible, but they have a sensible suspicion of a view that’s reassuring them about how they’re still valuable. I agree with that, though I suspect by the time we get around to studying this, the landscape will have changed under our feet again. Some commenters point out that OpenAI’s math prompts were inexpert, and so expertise isn’t required. Here I’d respond that OpenAI do have a team of expert mathematicians that checked and filtered the model’s suggested discoveries, and that you cannot currently skip that step.

The Daily Front Page 6 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — Proofs and Promises
article

Ten advances in mathematics and theoretical computer science

by milkshakes·▲ 524 points·802 comments·openai.com ↗
We want to empower scientists and mathematicians with tools that accelerate discovery.

We want to empower scientists and mathematicians with tools that accelerate discovery. That is why we recently announced ChatGPT for Academic Researchers⁠, an initiative providing 100,000 scientists and mathematicians with free access to our best ChatGPT models. We also continue to evaluate our models on open research problems during development.

In May, we shared an AI-generated disproof⁠ of the Erdős unit-distance conjecture, discovered while evaluating an unreleased model. This work has already inspired further developments in mathematics and theoretical computer science1. Today, we are sharing a selection of ten results, each of which resolves or makes substantial progress on a long-standing open problem. These problems span high-dimensional geometry, coding theory, arithmetic circuit complexity, group theory, operator algebras, quantum complexity, lattice cryptography and extremal combinatorics. All of these problems are of substantial interest to their respective mathematical communities, and several are of broad interest across mathematics as a whole.

The results

We provide new results for the following problems. The results were achieved by an internal version of Astra, our next major model. The total number of tokens needed to find solutions to these problems would cost roughly $2,000 at Sol API rates. These arguments were then prepared into manuscripts by humans with the same model. Afterward, the model formalized each argument in a Lean certificate⁠(opens in a new window). We are also releasing for each solution a model’s narration of its thinking process.

  1. High-dimensional sphere packing. New upper bounds on sphere-packing density down to the Cohn–Elkies threshold.
  2. Binary and spherical codes. Exponentially improved bounds on the maximum size of binary codes at any prescribed minimum distance, with analogous results for high-dimensional spherical codes.
  3. Non-sofic groups. A construction establishing the existence of non-sofic groups, addressing a central open question in group theory.
  4. Connes’s rigidity conjecture. Disproof of a longstanding conjecture that certain groups are uniquely determined by their von Neumann algebras.
  5. Arithmetic circuit complexity. New lower bounds for computing the permanent using arithmetic circuits and formulas, including an arithmetic-formula lower bound of order n4/log n.
  6. Quantum parallel repetition. An exponential parallel repetition theorem for general two-player quantum games, extending a foundational principle from classical complexity theory.
  7. Closest vector problem. Polynomial-factor hardness of approximation for the closest vector problem, a foundational lattice question related to post-quantum cryptography.
  8. Ehrhart’s volume conjecture. Determining, in every dimension, the maximum possible volume of a convex body whose centroid is its only interior lattice point.
  9. Multicolor Ramsey numbers. A superexponential lower bound for multicolor triangle Ramsey numbers, resolving Erdős problem 183.
  10. Extremal number conjectures. Results on the compactness and degeneracy conjectures in extremal graph theory, resolving Erdős problems 146 and 180.

Responsibility to the mathematical community

The emergence of systems capable of contributing to mathematical research raises questions that cannot be answered by a technology company alone. There are many views as to the role of AI in mathematics, and we have deep respect and understanding for those concerned with its impact, including the signers of the Leiden declaration on AI and Mathematics⁠(opens in a new window). We believe attribution should honestly reflect how a result was produced: claiming human authorship for a proof generated entirely by an AI system would misrepresent both the system’s contribution and the nature of genuine human intellectual work. We helped prepare the manuscripts and formalize the proofs in Lean, and we take responsibility for their correctness, while the mathematical arguments themselves were generated by our system. We hope the mathematical community will engage deeply with these results, place them in context, and bring the ideas behind them to life through new research and discovery.

As AI systems evolve into more sophisticated research collaborators, ensuring widespread access is fundamental to supporting scientists and mathematicians as they navigate and define the future of their disciplines during this transformative era.

Footnote

  1. Subsequent research includes Bloom, Sawin, Schildkraut, and Zhelezov, “The sum-product conjecture is false for real numbers⁠(opens in a new window)”; Pohoata, “Split primes and the Elekes-Rónyai problem⁠(opens in a new window)”; Saha, Xu, and Ye, “Furthest Pair Requires Quadratic Time in Superconstant Dimension under SETH⁠(opens in a new window)”; Goh and Hatami, “Communication complexity of point-line incidences over the reals⁠(opens in a new window)”; and Lee, Pohoata, and Zhu, “The Minkowski grid has robustly many repeated distances⁠(opens in a new window).”
The Daily Front Page 7 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — Tools Belong to Their Users
article

Devtools must be open source

by bryanmikaelian·▲ 586 points·198 comments·blog.exe.dev ↗
devtools must be open source

Five years ago, most software engineers I spoke to had no programs they had written for themselves. (I was asking this question a lot as part of trying to understand how Tailscale could fit into engineers’ lives.) All day, every day, engineers use programs written by others to write programs for others. Many of us customized the programs we used, through config files or plugins or extensions, and many of us used the programs we wrote for others, as users. It was always an unusual treat to ask someone what they had written for themselves and learn about the bespoke software behind their blog, or their home automation, or their homelab, instead of an off-the-shelf, almost-the-right-size static site generator or Zigbee appliance.

This state of things made a lot of sense to me. Over the years I have written plenty of software for myself, and the return on doing so was always questionable. I could only write so much in a day. There were always more important things to do (Something Was Wrong At Work), and coming back to a project after a year to do maintenance on it was always extraordinarily painful. There were plenty of years in my career where I had thrown out all my custom software and used the most bog-standard environments I could to produce code. In my early years as an engineer at Google I did not even own a personal computer.

That was then. Things are different now.

How to Personalize Software

It is astonishingly easy to personalize software today. There are two general categories of prompts to an agent that make all of this possible:

  1. Download the source for <software> and build it for local use. Modify <whatever memory your agent uses> to know that any future changes to this software mean changing the sources and replacing the current version. Record in version control the original motivation behind the change.

    and, more importantly:

  2. Set up a nightly cron job that executes the prompt: fetch upstream changes to the <software> and rebase all local changes on top of upstream. Check that the software works as intended and replace the current version.

At the heart of this is the realization that agents can not only hack up some code for a specific use but also automatically manage the process of synchronizing changes with upstream releases. This means agents change the ROI on customizing software on two fronts simultaneously: it is much easier to get started personalizing, and much easier to keep going.

Another astonishing thing about the two prompts above for editing software is that you can build them right into an agent. As long as the agent is open source, it does not even require programming. The two prompts can be loaded into a skill (i.e., some text instructions) put somewhere discoverable to the agent. We built this into Shelley, so now if you want to edit Shelley you don’t even need the preamble or to configure the timer. It takes care of it for you. You can type in a prompt like “make Shelley’s UI high-contrast” and you have personalized your agent.

A Worked Personalization Example: Shelley and Meat

I have a personal project I have been idly toying with for the last month: meat.dev. The principle is that while agents write code, I still read it before pushing to our serious systems. As the underlying models improve, what I look for has changed. The humans I have spent twenty years reviewing code for have always struggled with edge cases: do the errors report useful information; are nil-checks handled, etc. (We all do it; when writing code, I am one of the worst offenders.) One of my roles as a reviewer was looking for these details. Over the past six months, I have discovered I don’t need to read for edge cases like that any more: models are far more diligent than humans at rote correctness. Their errors are isolated to architecture, unexpected use cases, visual output their test environment is not feeding back to them, etc. This means most of the lines of code I review are not very useful. So I wrote a tool that takes diffs and uses LLMs to strip out the unimportant stuff. I almost never need to see the import blocks, or the nil-checks, or the error handling any more, so get it off the screen so I can focus on the meat.

I like this tool, but it has two downsides: first, I like to read my diffs in Shelley with a good UI, not in a terminal. Second, it takes a couple of minutes for an LLM to digest and minimize a diff, and I don’t want to wait. So ideally I would not run meat on the command line, but have it built into Shelley and have it pre-processing commits the moment they are created. It turns out I can do that with a single prompt:

Please build meat.dev into Shelley. Install the latest version in the PATH. When a git commit is created by Shelley, start meat processing in the background on the commit. Add a toggle to the Shelley Diffs view for meat. If the commit is still being processed, so the user it is in process.

This single prompt was all it took not just to add meat to Shelley, but to appropriately pre-process commits in the background before I came back to session to review the diff, saving me waiting for a model to reduce the diff. The only unfortunate choice the model made was using the 🥩 emoji for the toggle button.

Imagine the convoluted misery it would be trying to plug that into the VS Code extensions API! Or trying to get it into vimdiff. It would certainly be possible, but the machinery to start pre-processing the commits as soon as they appear would be nigh-on impossible. I would be better off implementing an out-of-band meatd that listened to the file system and provided a cache for the meat tool that a customization API could use, because the points of extension and configuration would not be the right shape.

And that is the fundamental difference between classic configuration/customization and agent-driven personalization: you can do so much more. The agent will do the hard work of understanding the source and changing it to suit the particular task you have in mind. The software we live with is far more powerful with personalization. All you need is the source code.

The Age of Personalized Software

The pre-agent development costs meant it was rational for complex software to ship with large configuration files, extension systems, and plugin systems. The core code of even a moderate project like Vim is huge and baroque, and takes weeks for a human to digest. The thought that, on wanting line numbers to print by default, an engineer would learn the code base and add it just for themselves is unreasonable. Better to design it for sharing with others, which justifies the expense of implementing it by amortizing it over many users. As features in a code base grow, it makes sense to look for common abstractions where you can break out an extension or plugin system.

Now the expense of learning the code and making a change has dropped dramatically. Agents do the heavy lifting. For a single user—which implies extremely constrained conditions under which the program runs—a top-end agent can usually now add a feature in a single shot. For single-user software, the need for careful code review can often be replaced by “does it seem to work?”

The result is that software that can be personalized doesn’t need a plugin system or a config file. Want to change the font size in your text editor? Give the agent the source and tell it to. If it is a hardcoded value it will find and edit it. If it’s a hardcoded bitmap font it will download another and replace it, or it will use Monobit to make you one! You have incredible capabilities on tap.

Whole Categories of Software Products Need to Be Reinvented

Personal software applies well to small teams too. Why would an engineering team purchase an extremely configurable task manager (or a CMS or CRM), spend time learning and configuring it, and contort their team to its limits, when they can assemble just the features they want from common building blocks?

Both the upfront fixed costs and the ongoing costs of personalizing software have disappeared.

The blog you are reading is bespoke software, written in Shelley, because it was easier to piece together and personalize libraries like Tiptap than it is to try and customize traditional software products. For end-user products to make sense in a company today, they need to be personalizable. Which means we need the source code.

Where Codex and Claude Code Diverge

This same skill-based technique that was applied to Shelley to make it personalizable can be trivially applied to other open-source agents like Pi. (So much so that I am left wondering why Pi needs an extension system built into it. The source code is the extension system.) It would require a lot more tokens, but you could do the same to Codex, which is an open-source agent.

Where you would hit a wall, however, is Claude Code. It is closed-source software, so you don’t get to personalize it. There are a lot of old-fashioned customization hooks in Claude Code. Hopefully, how you want an agent to work fits in their hooks. If not, switch to an agent that lets you personalize it.

The Daily Front Page 8 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — Repository Desk: Bonsai
repository

Bonsai: Janestreet's UI Library

by KolmogorovComp·▲ 343 points·143 comments·github.com ↗
★ 1,264⑂ 53 forks OCaml

A library for building dynamic webapps, using Js_of_ocaml

Bonsai

Bonsai is a UI library for building performant, reactive web applications in OCaml, partly inspired by Elm. It is used to build almost all web applications inside Jane Street, everything from the corporate directory to tools that monitor and interact with our trading systems. A simple Bonsai component with a little interactivity looks like this:

module Dice = struct
  let faces =
    [ "⚀"; "⚁"; "⚂"; "⚃"; "⚄"; "⚅" ]
  ;;

  let component (graph @ local) =
    (* Components are implemented as purely functional state machines. *)
    let face, set_face = Bonsai.state (List.hd_exn faces) graph in
    (* Components are incrementally rendered, only when the relevant parts of the state change. *)
    let%arr face and set_face in
    {%html|
      <div>
        You rolled a #{face}
        <button
          style="" on_click=%{fun _ ->
            let index = Random.int (List.length faces) in
            set_face (List.nth_exn faces index)}
        >
          Roll the dice
        </button>
      </div>
    |}
  ;;
end

A web app built with Bonsai A web app built with Bonsai

Most internal Jane Street web applications are built with Bonsai

Components are implemented as purely functional state machines, and are easily composable. Incrementalization inside the framework means that values don’t get recomputed until necessary. This applies to every value, not just the view.

Why Bonsai?

Other web frameworks tend to lump together state, incrementality, and rendering into a single abstraction, the UI component. By contrast, Bonsai allows you to compose state and incrementality primitives a la carte. The same primitives that prevent re-rendering the entire page during user interaction can also be used to incrementalize an expensive business logic computation on a live-updating dataset. (If you're used to React, imagine if everything used something very similar to hooks, and state was managed outside of the component hierarchy.)

Since state is not associated with explicit components, there is an extensive API for managing the lifecycle and scoping of state as users interact with the page. For instance, if you wanted to embed a collection of stateful UI components inside another UI component (in a tabbed interface, say), Bonsai will handle the state management for you instead of requiring that you manually hoist every internal component's state to the app's top-level model. For more examples of how state is composed, see this composition comparison written by the creator of Bonsai.

And because Bonsai is written in OCaml, it becomes possible to use the same language and types on both the backend and frontend. It's hard to overstate the impact this has on legibility and keeping a large web app's codebase manageable, especially when you make pervasive use of OCaml's type system to reduce errors. At Jane Street, many internal systems previously only had terminal UIs, and the framework has made it easy to port the existing types and business logic to the web.

Bonsai also comes with a powerful templating language, support for component-specific stylesheets, and a system for whole-app automated tests.

Expressive tests that save you from manually clicking through your app

One of Bonsai’s most powerful features is its ability to let you easily write realistic tests, in which you programatically manipulate UI elements and watch your DOM evolve.

In the following example, we’re testing the behavior of a user-selector. Whatever you type in the text box gets appended to a little “hello” message:

let%expect_test "shows hello to a specified user" =
  let handle = Handle.create (Result_spec.vdom Fn.id) hello_textbox in
  Handle.show handle;
  [%expect
    {|
    <div>
      <input oninput> </input>
      <span> hello  </span>
    </div> |}];
  Handle.input_text handle ~get_vdom:Fn.id ~selector:"input" ~text:"Bob";
  Handle.show_diff handle;
  [%expect
    {|
      <div>
        <input oninput> </input>
-      <span> hello  </span>
+      <span> hello Bob </span>
      </div> |}];

Notice that there are two expect blocks. (This allows you to make multiple assertions within a given scenario and to scope setup/helper code to just that scenario.)

The first makes our UI visible, and the second---which contains a diff---shows some behavior after you programatically input some text. Bonsai will even show you how html attributes or class names change in response to user input. Tests can include mock server calls, and can involve changes not just to the UI but to the state that drives it. With tests like these you can write an entire component without opening your browser.

Documentation

The Bonsai Quick Start and Thinking in Bonsai provide a hands on introduction to Bonsai and are the best places to start learning about it. There's also:

  • A series of how-to articles.
  • A short series of posts about Bonsai's history.
  • An episode of our Signals & Threads podcast about "Building a UI Framework." Another episode on "Building Tools for Traders" discussed some of the benefits of using Bonsai.
  • A library filled with example websites built with Bonsai.
  • API documentation can be found in the cont.mli file.

Bonsai is really a collection of libraries

Er, one wrinkle: Bonsai itself -- this library -- is actually more generic than the above makes it sound. It allows you to build general-purpose incremental, composable state machines. Bonsai_web builds on top of that core library, specializing it for interactive browser-based UIs, but we also have Bonsai_term for building interactive terminal-based UIs. There was even a prototype for April Fools' Day of Bonsai_vr for reactive virtual-reality UIs.

The full suite of Bonsai libraries:

General-purpose libraries

Bonsai is a library for building incremental, composable state machines.

Browser-based UI Libraries

Bonsai_web is a library for building interactive browser-based UI using bonsai.

Terminal-based UI Libraries

Bonsai_term is a library for building interactive terminal-based UIs using bonsai.

Pre-processors

Bonsai web applications often use the following preprocessors:

  • ppx_html is a preprocessor for writing HTML that is similar to JSX.
  • ppx_css is a preprocessor for writing CSS.
The Daily Front Page 9 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — Repository Desk: Tiny-VRAM Giants
repository

AirLLM 70B inference with single 4GB GPU

by Anon84·▲ 216 points·77 comments·github.com ↗
★ 27,676⑂ 3,006 forks Jupyter Notebook

AirLLM 70B inference with single 4GB GPU

AirLLM dramatically reduces inference memory usage, letting 70B large language models run on a single 4GB GPU card — without quantization, distillation, or pruning. You can even run 405B Llama 3.1 on 8GB, DeepSeek-V3 (671B) on ~12GB, and Kimi K3 (2.8T) — the largest open-source model released to date — on under 4GB, because sparse MoE models stream one expert at a time rather than a whole layer.

Updates

[2026/07] Kimi K3 (2.8T) support: the largest open-source model runs on a single card in 3.72GB of VRAM, measured end to end on one RTX 6000 Ada. Per-expert streaming loads only the experts a token actually routes to. K3 brings three requirements of its own: pip install compressed-tensors flash-attn (its model code mandates flash attention regardless of what you request), a CUDA 12 build of torch, since no prebuilt flash-attn wheel exists for CUDA 13 yet, and transformers 4.56.x, as its remote code does not load on 5.x.

[2026/06] v3.0: FP8 model support + the latest models. Run DeepSeek-V3 (671B) on ~12GB and Qwen3-235B on ~3GB, plus Qwen3, Llama 3.x/4, DeepSeek V2/V3, Phi-4, Gemma and more — all through a single AutoModel.

[2024/08/20] v2.11.0: Support Qwen2.5

[2024/08/18] v2.10.1 Support CPU inference. Support non sharded models. Thanks @NavodPeiris for the great work!

[2024/07/30] Support Llama3.1 405B (example notebook). Support 8bit/4bit quantization.

[2024/04/20] AirLLM supports Llama3 natively already. Run Llama3 70B on 4GB single GPU.

[2023/12/25] v2.8.2: Support MacOS running 70B large language models.

[2023/12/20] v2.7: Support AirLLMMixtral.

[2023/12/20] v2.6: Added AutoModel, automatically detect model type, no need to provide model class to initialize model.

[2023/12/18] v2.5: added prefetching to overlap the model loading and compute. 10% speed improvement.

[2023/12/03] added support of ChatGLM, QWen, Baichuan, Mistral, InternLM!

[2023/12/02] added support for safetensors. Now support all top 10 models in open llm leaderboard.

[2023/12/01] airllm 2.0. Support compressions: 3x run time speed up!

[2023/11/20] airllm Initial version!

Quickstart

1. Install package

First, install the airllm pip package.

pip install airllm

2. Inference

Then, initialize AirLLMLlama2, pass in the huggingface repo ID of the model being used, or the local path, and inference can be performed similar to a regular transformer model.

(You can also specify the path to save the splitted layered model through layer_shards_saving_path when init AirLLMLlama2.

from airllm import AutoModel

MAX_LENGTH = 128
# just pass a hugging face repo id — works with almost any popular model:
model = AutoModel.from_pretrained("Qwen/Qwen3-32B")

# go bigger with the exact same one line:
#model = AutoModel.from_pretrained("Qwen/Qwen3-235B-A22B")     # 235B, runs in ~3GB
#model = AutoModel.from_pretrained("deepseek-ai/DeepSeek-V3")  # 671B, runs in ~12GB

# or use a model's local path...
#model = AutoModel.from_pretrained("/home/ubuntu/.cache/huggingface/hub/models--Qwen--Qwen3-32B/snapshots/...")

input_text = [
        'What is the capital of United States?',
        #'I like',
    ]

input_tokens = model.tokenizer(input_text,
    return_tensors="pt", 
    return_attention_mask=False, 
    truncation=True, 
    max_length=MAX_LENGTH, 
    padding=False)
           
generation_output = model.generate(
    input_tokens['input_ids'].cuda(), 
    max_new_tokens=20,
    use_cache=True,
    return_dict_in_generate=True)

output = model.tokenizer.decode(generation_output.sequences[0])

print(output)

Note: During inference, the original model will first be decomposed and saved layer-wise. Please ensure there is sufficient disk space in the huggingface cache directory.

Model Compression - 3x Inference Speed Up!

We just added model compression based on block-wise quantization-based model compression. Which can further speed up the inference speed for up to 3x , with almost ignorable accuracy loss! (see more performance evaluation and why we use block-wise quantization in this paper)

speed_improvement

How to enable model compression speed up:

  • Step 1. make sure you have bitsandbytes installed by pip install -U bitsandbytes
  • Step 2. make sure airllm verion later than 2.0.0: pip install -U airllm
  • Step 3. when initialize the model, passing the argument compression ('4bit' or '8bit'):
model = AutoModel.from_pretrained("garage-bAInd/Platypus2-70B-instruct",
                     compression='4bit' # specify '8bit' for 8-bit block-wise quantization 
                    )

What are the differences between model compression and quantization?

Quantization normally needs to quantize both weights and activations to really speed things up. Which makes it harder to maintain accuracy and avoid the impact of outliers in all kinds of inputs.

While in our case the bottleneck is mainly at the disk loading, we only need to make the model loading size smaller. So, we get to only quantize the weights' part, which is easier to ensure the accuracy.

Configurations

When initialize the model, we support the following configurations:

  • compression: supported options: 4bit, 8bit for 4-bit or 8-bit block-wise quantization, or by default None for no compression
  • profiling_mode: supported options: True to output time consumptions or by default False
  • layer_shards_saving_path: optionally another path to save the splitted model
  • hf_token: huggingface token can be provided here if downloading gated models like: meta-llama/Llama-2-7b-hf
  • prefetching: prefetching to overlap the model loading and compute. By default, turned on. For now, only AirLLMLlama2 supports this.
  • delete_original: if you don't have too much disk space, you can set delete_original to true to delete the original downloaded hugging face model, only keep the transformed one to save half of the disk space.

MacOS

Just install airllm and run the code the same as on linux. See more in Quick Start.

  • make sure you installed mlx and torch
  • you probably need to install python native see more here
  • only Apple silicon is supported

Example [python notebook] (https://github.com/lyogavin/airllm/blob/main/air_llm/examples/run_on_macos.ipynb)

Example Python Notebook

Example colabs here:

Open In Colab

example of other models (ChatGLM, QWen, Baichuan, Mistral, etc):

Details

  • ChatGLM:
from airllm import AutoModel
MAX_LENGTH = 128
model = AutoModel.from_pretrained("THUDM/chatglm3-6b-base")
input_text = ['What is the capital of China?',]
input_tokens = model.tokenizer(input_text,
    return_tensors="pt", 
    return_attention_mask=False, 
    truncation=True, 
    max_length=MAX_LENGTH, 
    padding=True)
generation_output = model.generate(
    input_tokens['input_ids'].cuda(), 
    max_new_tokens=5,
    use_cache= True,
    return_dict_in_generate=True)
model.tokenizer.decode(generation_output.sequences[0])
  • QWen:
from airllm import AutoModel
MAX_LENGTH = 128
model = AutoModel.from_pretrained("Qwen/Qwen-7B")
input_text = ['What is the capital of China?',]
input_tokens = model.tokenizer(input_text,
    return_tensors="pt", 
    return_attention_mask=False, 
    truncation=True, 
    max_length=MAX_LENGTH)
generation_output = model.generate(
    input_tokens['input_ids'].cuda(), 
    max_new_tokens=5,
    use_cache=True, 
    return_dict_in_generate=True)
model.tokenizer.decode(generation_output.sequences[0])
  • Baichuan, InternLM, Mistral, etc:
from airllm import AutoModel
MAX_LENGTH = 128
model = AutoModel.from_pretrained("baichuan-inc/Baichuan2-7B-Base")
#model = AutoModel.from_pretrained("internlm/internlm-20b")
#model = AutoModel.from_pretrained("mistralai/Mistral-7B-Instruct-v0.1")
input_text = ['What is the capital of China?',]
input_tokens = model.tokenizer(input_text,
    return_tensors="pt", 
    return_attention_mask=False, 
    truncation=True, 
    max_length=MAX_LENGTH)
generation_output = model.generate(
    input_tokens['input_ids'].cuda(), 
    max_new_tokens=5,
    use_cache=True,
    return_dict_in_generate=True)
model.tokenizer.decode(generation_output.sequences[0])

To request other model support: here

Supported Models

AirLLM works out of the box with virtually every popular open LLM — just pass its Hugging Face ID to AutoModel.from_pretrained(...). That covers all the major families:

Llama (2 / 3 / 3.1 / 3.3 / 4) · Qwen (1 / 2 / 2.5 / 3, including MoE and FP8) · DeepSeek (V2 / V3 / R1) · Mistral & Mixtral · Phi · Gemma · ChatGLM · Baichuan · InternLM · Yi — and most new models the day they're released.

Tiny GPU, huge models

The trick: AirLLM only ever keeps one layer on the GPU at a time, so the VRAM you need depends on the model's layer size — not its total size. That's how a 671B model fits on a hobbyist card:

Same one line of code for all of them — no special setup.

Acknowledgement

A lot of the code are based on SimJeg's great work in the Kaggle exam competition. Big shoutout to SimJeg:

GitHub account @SimJeg, the code on Kaggle, the associated discussion.

FAQ

1. MetadataIncompleteBuffer

safetensors_rust.SafetensorError: Error while deserializing header: MetadataIncompleteBuffer

If you run into this error, most possible cause is you run out of disk space. The process of splitting model is very disk-consuming. See this. You may need to extend your disk space, clear huggingface .cache and rerun.

2. ValueError: max() arg is an empty sequence

Most likely you are loading QWen or ChatGLM model with Llama2 class. Try the following:

For QWen model:

from airllm import AutoModel #<----- instead of AirLLMLlama2
AutoModel.from_pretrained(...)

For ChatGLM model:

from airllm import AutoModel #<----- instead of AirLLMLlama2
AutoModel.from_pretrained(...)

3. 401 Client Error....Repo model ... is gated.

Some models are gated models, needs huggingface api token. You can provide hf_token:

model = AutoModel.from_pretrained("meta-llama/Llama-2-7b-hf", #hf_token='HF_API_TOKEN')

4. ValueError: Asking to pad but the tokenizer does not have a padding token.

Some model's tokenizer doesn't have padding token, so you can set a padding token or simply turn the padding config off:

input_tokens = model.tokenizer(input_text,
   return_tensors="pt", 
   return_attention_mask=False, 
   truncation=True, 
   max_length=MAX_LENGTH, 
   padding=False  #<-----------  turn off padding 
)

Citing AirLLM

If you find AirLLM useful in your research and wish to cite it, please use the following BibTex entry:

@software{airllm2023,
  author = {Gavin Li},
  title = {AirLLM: scaling large language models on low-end commodity computers},
  url = {https://github.com/lyogavin/airllm/},
  version = {0.0},
  year = {2023},
}
The Daily Front Page 10 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — The Local Video Machine
article

MiniMax H3 Day-0 Support in ComfyUI: Open Weights, Native Audio, and 2K Video

by vblanco·▲ 290 points·85 comments·blog.comfy.org ↗
Feed it text, images, video, or audio and it generates video with real stereo sound.

An open-weights omni-modal video model with real stereo sound and 2K output — this powerful model is greatly optimized in ComfyUI and can run locally on a 3060.

MiniMax H3 dropped today with open weights, and it’s natively supported in ComfyUI as of this morning. Day zero.

This is a next-generation open-weights video model. Feed it text, images, video, or audio and it generates video with real stereo sound, up to 2K, up to 15 seconds a clip. It is MiniMax’s third-generation video model, following Hailuo 01 and Hailuo 02, and the first the company has released with open weights.

Try on Comfy Cloud

Model Highlights

  • Text-to-video — prompt only.
  • Image-to-video — bring an image to life.
  • First-and-last-frame — control the opening frame, the closing frame, or both, and let the model fill in the rest.
  • Reference-to-video — supply reference images, video, or audio and carry a subject, a motion, or a voice through the clip.

Output runs to 2K and up to 15 seconds. Audio is generated with the video in the same pass, in stereo, not bolted on afterward.

Multimodal context understanding

This is the capability MiniMax leads with, and it’s what collapses five separate tasks into one model. Real work rarely draws on one modality. H3 takes images, audio, and video together and resolves them against a prompt that explains how they relate. Describe the relationship between your inputs and the shot you want, and the model handles the cross-modal work itself.

Native stereo audio

Audio is a property of the model, not a post-process. Every audio output is native stereo.

Editing and motion transfer

Motion transfer is the one that matters most for graph work. A reference video can supply movement — a camera move, a performance, a cutting rhythm — while the subject and style come from elsewhere. Combined with in-place editing, that means iterating on a shot.

Example Outputs

Bold comic-book ink style, heavy linework, red and blue-black palette, night city. Use <Picture 2> and <Picture 1> as reference frames and <Audio 1> exactly as it is.
CUT 1: top-down view of the little boy superhero on the rooftop — red cape fluttering in the wind, hands planted on his hips, freckles and a cocky grin as he looks straight up into the camera. The camera slowly descends toward him as he delivers his line — as he speaks, comic-book graphic overlay text word by word in sync with his voice: "GET READY TO" - "MEET" — "YOUR" — "MAKER" — huge jagged comic lettering, white with heavy black outlines and red drop shadows, tilted at scrappy angles, until the three words hang stacked in the air above him between his face and the lens.
TRANSITION: a violent WHIP PAN off the rooftop that SMEARS the floating words away with it, motion-streaked —
CUT 2: low hero angle on the colossal black mech-kaiju towering over the skyline as it rears back and unleashes a GIANT terrifying ROAR — jaws wide with fangs, red eyes and chest-core flaring blinding bright, blue lightning arcing off its head, the roar's shockwave rippling dust and rattling windows down the buildings, comic-style speed-lines and ink splatter bursting from the impact of the sound. It leans INTO the camera as the roar peaks. Hold on the roar.
Editorial tech product film. The transparent gaming mouse from <Picture 1> in its original scene: a pitch-black studio void with a dark, subtle reflective surface, lit by dramatic duotone vibrant blue and warm neon orange rim lighting, deep soft shadow falloff into pure black. Monochromatic dark palette with electric blue and amber accents. Material motif: glowing internal metallic micro-components and glossy acrylic refractions. The environment is constant throughout.
SHOT 1: The scene opens exactly on image 1, the mouse resting confidently on the dark surface; the blue and orange lights slowly pulse brighter, refracting deeply through the transparent acrylic shell as the camera executes a slow, deliberate push-in to reveal the intricate circuitry.
SHOT 2: Cut to an extreme macro profile of the ridged scroll wheel and layered internal micro-components; the camera glides slowly along the side as a sharp beam of warm orange light sweeps across the metallic textures, contrasting perfectly against the deep blue ambient glow.
SHOT 3: Cut to a low-angle beauty shot: the mouse levitates weightlessly a few centimeters above the dark reflective surface, rotating in a slow, precise orbit; the duotone lighting flares gently along the glassy transparent edges before fading slowly into a sleek silhouette.
Audio: deep pulsing sub-bass room tone, sharp tactile mechanical clicks, a sweeping glassy whoosh on cuts, and a rising electronic swell that resolves to near-silence on the final fade.
High-fashion editorial film, luxurious slow motion throughout, soft gradient studio sky. 
MUSIC & SFX: a cinematic score fusing deep taiko drums, shimmering koto plucks and modern sub-bass drives the film

SHOT 1: beside her, the mask hangs BROKEN — shattered into the floating shard formation of <Picture 2>, every kintsugi piece suspended and slowly rotating in place, the gold seams between them dim and waiting. She turns her eyes to it.
SHOT 2: THE ASSEMBLY, with enormous energy — the gold seams IGNITE, arcs of molten light leaping shard to shard like welding fire, and the pieces snap together one by one, accelerating from slow to rapid-fire, each snap flaring gold, molten droplets spinning off, the surrounding liquid ribbons shuddering with shockwave ripples — until the final shard slams home and the whole mask fuses, its kintsugi veins blazing.
SHOT 3: the golden dragon of <Picture 3> SWOOPS through the frame in one huge serpentine fly-through — red glass antlers first, its coils wrapping the space around her and the mask, scales throwing golden light, its wake dragging the crimson liquid into a spiral behind it.
SHOT 4: in the dragon's wake the mask magnetically RIPS across the air onto her face — a fast, hard, perfectly straight pull — seating with a deep flare as every gold crack lights, and glowing kintsugi veins spread from the mask's edge down her neck and across the sunset jacket, embroidery igniting thread by thread.
SHOT 5: she descends and lands softly ON the dark liquid wave, snapping into a poised warrior stance and holding it like a lookbook frame — the dragon coiled behind her shoulder, both liquids spiraling upward around her into a double helix. Held editorial poster frame as the camera settles.
Use <Picture 1>, <Picture 2>, <Picture 3> as reference images. 
Vibrant fisheye product commercial, hyper-saturated summer light, the woman from <Picture 1> in a yellow raincoat crouched by a jungle waterfall holding a rainbow-gradient soda can toward the lens, condensation dripping.
MUSIC: an upbeat tropical house track drives the entire film — punchy kick drum, bright steel-drum plucks, warm bass groove.

CUT 1 : the fisheye hero frame — as she looks into the lens, GIANT BOLD TYPOGRAPHY stamps across the background behind her, one word per beat: "STAY" then "HYDRATED" — massive clean white block letters spanning the whole scene, curving with the fisheye distortion, sitting behind her but in front of the waterfall. She reaches her opposite hand towards the can and hooks a finger under the tab.
TRANSITION: extreme close-up of the tab — it OPENS with a crisp CLICK-hiss, and exactly on the click the fisheye lens iris shutters closed to black, like a camera blinking.
CUT 2: the iris reopens on a new POV — the can EXTREMELY distorted in the foreground, huge and warped by the fisheye, she smiles and dumps the liquid out of the can onto the floor, droplets scattering weightlessly, sunlight refracting rainbow through the stream, the waterfall soft behind her.
TRANSITION: she lowers the can and one fat droplet falls toward the lens, filling the frame —
CUT 3: through the droplet into the final wide: the rainbow can floating upright and serene in the turquoise waterfall pool, label facing camera, bobbing gently in the mist, the waterfall thundering softly behind — and "STAY COMFY" shimmering as a reflection on the water's surface beside it. Hold the product hero frame.
Crisp, joyful, premium product-ad energy. Fisheye distortion in every shot.

Optimized for local inference in ComfyUI

Getting H3 to run well on consumer hardware took significant machine learning engineering. We found that the model's modulation weights (~40% of the total parameters) could be pruned and replaced with a functionally equivalent lookup table, dramatically shrinking the memory footprint with no loss in output quality.

On top of that, the weights ship with an accurate and efficient int8 convrot quantization, and custom kernels reduce the peak VRAM use during inference.

The result gives a total memory footprint reduced by 66%, from 123.6 GB in full precision to 42.5 GB with the smallest models variants. Combining this with our dynamic VRAM offloading enables a next-generation 2K video model to run locally on a GPU like the RTX 3060.

Getting started

  1. Update ComfyUI to the latest version 0.30.0 or go to Comfy Cloud

  2. Download the workflows below, or find them in the template library.

    Download MiniMax H3 I2V Workflow

    Download MiniMax H3 R2V Workflow

    Download MiniMax H3 T2V Workflow

  3. Follow the note in the workflow to download the models and save them in the correct model directory.

  4. Write your prompt, connect any frame or reference inputs, and run.

Model weights: 🤗 Comfy-Org/MiniMax-H3

As always, enjoy creating!

The Daily Front Page 11 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — Hollywood Elsewhere
article

How Hollywood stopped making movies in Hollywood

by speckx·▲ 192 points·236 comments·statsignificant.com ↗
many of Hollywood’s problems can be traced back to a single economic theory of everything: the rent is too damn high.

The economics behind where movies are filmed, why Hollywood left Los Angeles, and whether audiences can tell the difference.

La La Land (2016)

La La Land (2016). Credit: Warner Bros.

Intro: #StayInLA

The past decade has not been kind to Los Angeles’ entertainment industry. The combined shock of the 2023 labor strikes and the 2025 wildfires intensified fears that film and television production is migrating overseas, threatening a fragile ecosystem of below-the-line workers based in Hollywood.

In the days after the wildfires, filmmaker Sarah Smith and writer Alexandra Pechman organized a WhatsApp group of showrunners and industry workers, drafted a petition, and launched the grassroots #StayInLA campaign. What began as an emergency effort to help Los Angeles rebuild grew into a broader political movement, drawing more than 20,000 petition signatures, endorsements from prominent actors and filmmakers, and even the fleeting attention of Donald Trump—an actor himself, best known for his performance in Home Alone 2: Lost in New York.

Having worked in the entertainment industry and lived in Los Angeles, I have long wanted to investigate this often-vague anxiety: to understand exactly where these productions are migrating and quantify the extent of Hollywood’s flight from, well, Hollywood itself.

So today, we’ll examine Hollywood’s great production migration, explore how these logistical shifts have reshaped the filmmaking process, and investigate whether outsourcing production has any measurable impact on the quality of the movies themselves.

How Hollywood Stopped Making Movies in Hollywood

The American film industry began concentrating in Los Angeles in the 1910s, drawn to the city’s year-round sunshine, varied landscapes, inexpensive land, and distance from Thomas Edison’s patent enforcement on the East Coast. By the 1920s, Hollywood had become the global center of filmmaking, with studios, skilled workers, and supporting businesses clustered together in a self-renewing ecosystem.

For decades, most American films were produced on Los Angeles backlots, where studios provided filmmakers access to turnkey sets and skilled crews. This mechanized approach kept costs low and enabled directors to crank out four to six movies a year. During this era, Hollywood operated much like Henry Ford’s Model T assembly line; studios were maniacally focused on speed and frugality.

LA’s stranglehold over movie production would ultimately be tested by two filmmaking trends:

  1. The rise of the blockbuster: In the 1970s, box-office smashes like The Godfather and Jaws demonstrated the commercial potential of event cinema. By the 1980s, corporatized studios like Paramount-Gulf-Western were actively manufacturing blockbusters, pouring ever-growing budgets into spectacle-driven stories. Films like Predator, First Blood, and Raiders of the Lost Ark were shot on location in jungles, deserts, and other far-flung settings, as exotic locales amplified their sense of scale.
  2. The rise of IP and tax credits: The 2000s and 2010s brought a surge in big-budget filmmaking built around familiar IP. Marvel’s vaunted Cinematic Universe and other franchises required considerable financial investment, leading studios to offset costs by relocating production to incentive-rich cities such as Vancouver and Atlanta.

The result of these production strategies was a slow-building migration out of Los Angeles and California altogether.

So where did all the movies go?

So where did all the movies go? Hollywood’s production exodus has benefited a small group of filmmaking hubs offering some combination of established infrastructure and financial incentives. London, for example, boasts world-class facilities such as Pinewood Studios, while cities like Atlanta and Vancouver provide generous tax credits and rebates that reimburse studios for their local spending.

The savings these destinations offer are substantial

The savings these destinations offer are substantial, making them an obvious choice for a superhero movie whose story could unfold almost anywhere—be it a generic cityscape or somewhere in outer space. For a major blockbuster, tax incentives equate to tens of millions of dollars, freeing up money for name-brand actors, elaborate set pieces, and unremarkable CGI effects.

As such, the larger a film’s production budget, the more likely it is to be filmed entirely outside the United States.

As such, the larger a film’s production budget, the more likely it is to be filmed entirely outside the United States.

In some cases, this globe-trotting appears directly on screen

In some cases, this globe-trotting appears directly on screen, like when Mission: Impossible stages an elaborate car chase through Rome. In other cases, location choice is driven entirely by financial considerations.

The latter trend has created a widening gap between where stories are set and where they are filmed, as productions increasingly follow tax incentives and lower costs rather than narrative necessity.

Look closely, and you’ll spot Toronto’s skyline standing in for New York

Look closely, and you’ll spot Toronto’s skyline standing in for New York, or Prague’s streets masquerading as nearly every other European city. With each passing year, filming locations have become untethered from the places depicted on screen.

This disconnect has become a persistent grievance among film critics, particularly when it comes to streaming movies shot far from their narrative setting. Nearly every week, the hosts of my favorite movie podcast complain about some disposable Netflix rom-com ostensibly set in New York but unmistakably filmed in New Orleans. After hearing this criticism ad nauseam, I began to wonder whether shooting on location actually has a discernible impact on a film’s quality—at least in the eyes of viewers.

As a cinema purist, I believe movies should be filmed where they are set, even when that setting is outer space. Most audiences, however, either cannot tell the difference or simply do not care.

Perhaps I have gone to great lengths to prove something studio executives already know

Perhaps I have gone to great lengths to prove something studio executives already know: the average viewer is not scrutinizing every frame for telltale glimpses of the Toronto skyline. More likely, they are glancing at Instagram while the film’s protagonists laboriously explain the plot for the narrative comprehension of multitasking viewership—at which point the authenticity of the location becomes irrelevant.

Final Thoughts: Cost Disease

Guardians of the Galaxy Vol. 3

Guardians of the Galaxy Vol. 3. Credit: Marvel.

My junior year of college, I scored an internship at Conan O’Brien’s late-night talk show. So, like Miley Cyrus circa 2009, I hopped off the plane at LAX with a dream and an unpaid internship.

Within a week, I’d discovered three things:

  1. Entertainment internships are often glorified daycare for the children of industry executives: I could be classified as many things, but “nepo baby” is not one of them—which made me an exception among my intern class.
  2. There was no work to do: The show had far more interns than meaningful tasks. I never even earned the privilege of fetching coffee.
  3. The Warner Bros. backlot was eerily empty: I had grown up on movies like The Player and Singin’ in the Rain, where Hollywood appeared as a bustling factory of overlapping productions squeezed onto compact studio lots. Instead, I found emptiness.

This combination of things led to a bizarre summer where me and a posse of underutilized unpaid interns wandered a near-vacant Warner Bros. studio as if it were the Backrooms. This meant hanging out in the Central Perk set from Friends or cart-racing other interns from The Ellen DeGeneres Show on the street where they filmed Gilmore Girls.

My lasting impression was that Hollywood had become a collection of offices where white-collar workers decided how the sausage got made, while remarkably little sausage was actually being made there.

It was also during this summer that I learned of the hazards of cost disease.

Cost disease is an economic phenomenon in which labor-intensive industries with limited productivity gains—healthcare, education, live theater, filmmaking—become steadily more expensive over time. The quintessential example of this is Broadway, where the cost of living in New York City increases, leading wages to rise, but there remains a fixed set of theaters for Broadway shows to be staged, thereby limiting revenue growth. The end result is economic unsustainability, as these productions either curtail spending by employing fewer people or pass higher costs along to consumers through ticket pricing, often both.

My summer in LA was cost disease in miniature. I was paid exactly $0 to relocate to Los Angeles, where I then paid thousands of dollars to live in America’s third most expensive city. And this was the very bottom rung of entertainment’s corporate ladder.

Higher up the corporate hierarchy, cost disease takes different forms. For entry-level assistants, it means accepting low wages and paying high rent for the possibility—however remote—of eventually joining the executive class. For camera crews and VFX artists, it means becoming part of a traveling circus that chases tax incentives to Atlanta, Prague, and Vancouver. For studio executives, it means making do with smaller crews, outsourcing production overseas, and, eventually, using AI to replace some human labor.

If this has all drifted into bummertown, it’s because many of Hollywood’s problems can be traced back to a single economic theory of everything: the rent is too damn high. From there, everything else starts to unravel.

The end result is a peculiar version of Hollywood: a place increasingly devoid of physical production, populated instead by executives, AI art, and unpaid interns drag-racing golf carts through empty studio streets.

The Daily Front Page 12 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — Database Research Moves In
article

Andy Pavlo joins ClickHouse to establish ClickHouse Labs

by nikolay_sivko·▲ 305 points·63 comments·clickhouse.com ↗
The goal of ClickHouse Labs is to establish a best-in-class industry research organization focused on databases.

andy pavlo clickhouse headshot

I am excited to announce that I am joining ClickHouse to establish and lead a new research team called ClickHouse Labs. I want to share how it came about and what we plan to do.

How It Started #

I started as a professor in the Computer Science Department at Carnegie Mellon University in 2013. I have spent my career seeking to understand the science of modern database management system (DBMS) internals. I make it a priority to track every new system that comes along, both in industry and academia, to understand their implementations.

I have known about the ClickHouse DBMS since it was first announced as open-source software in June 2016. My initial reaction to this news was that it had to be vaporware because it seemed too good to be true. ClickHouse had features that at the time were only found in a handful of closed-source, commercial analytical DBMSs. For example, ClickHouse was written in C++ and supported vectorized query execution using SIMD in 2016. Most prominent open-source analytical DBMSs in 2016 were JVM-based and did not support SIMD optimizations until years later.

Since then, I have followed ClickHouse's development closely. It has always been a leading system that was highly relevant to our academic research projects. You can even see me wearing my original ClickHouse shirt in my first remote lectures in 2020, when the pandemic forced us to move our database courses online.

Given this history, I was honored when the ClickHouse co-founders invited me to establish this new research group at ClickHouse. The chance to work with one of the strongest engineering teams on the next generation of database technology was an opportunity that I could not pass up. This will be a next-level collaboration like when Killer Mike hooked up with El-P to create a hip-hop supergroup.

What Is ClickHouse Labs? #

The goal of ClickHouse Labs is to establish a best-in-class industry research organization focused on databases. It will not operate as an isolated research organization that throws ideas over the wall to engineering. Instead, we will work closely with ClickHouse engineers, customers, collaborators, and industry partners to develop and disseminate new ideas that keep ClickHouse at the bleeding edge.

We will also work with ClickHouse's PostgreSQL team to help establish its burgeoning managed service as a market leader in performance and reliability. PostgreSQL and ClickHouse serve different workload requirements, but the combination gives us a broad foundation for investigating both transactional and analytical database problems.

Our objective is straightforward but ambitious: conduct research with scientific value and then help transform the best ideas into technology that matters to users. I want to achieve the same level of impact associated with pioneering industry research organizations, such as IBM Research and Microsoft Research. Those groups demonstrated that industry laboratories can simultaneously advance fundamental computer science, influence commercial products, and train generations of database researchers. That is the tradition we want to continue.

What is Next? #

The ClickHouse team already has an exceptional record of publishing deep technical material about its work. Since the establishment of the company in 2021, its engineers have produced detailed articles that explain the DBMS's implementation. There is also the 2024 VLDB paper that describes ClickHouse's core architecture. These works are so thorough that I assign them as readings to my students at Carnegie Mellon. At the same time, there is a backlog of interesting ideas and optimizations that the ClickHouse engineering team has explored but has not yet had the time to validate fully and push into production. One of my immediate priorities is to help accelerate this process. We will then use that as a springboard to explore new ideas that push ClickHouse even further.

One larger question we will investigate is how DBMSs like ClickHouse and PostgreSQL fit into emerging AI and agentic technologies. There are two sides to this problem. The first is determining what a DBMS should look like to better support agents. The second side is determining how agents can improve and automate the development of DBMSs themselves. Everything is on the table: new hardware, new algorithms, new data structures, new execution strategies, and new ways of building and operating DBMS software. Although I do not have answers to these problems yet (this is why it is research), the one thing I am certain about is that ClickHouse's solid relational model foundation positions it well to evolve alongside these data-intensive workloads.

I have spent my career studying how database systems are built and helping train the people who build them. With ClickHouse Labs, we now have the opportunity to create an organization devoted to advancing both.

The Daily Front Page 13 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — Rust’s New Guarantees
repository

Rust project goals: Immobile types and guaranteed destructors

by paavohtl·▲ 235 points·95 comments·github.com ↗
We propose to introduce new traits that describe what operations are possible on a type.

Summary

We propose to introduce new traits that describe what operations are possible on a type. Today Rust assumes all types can be moved (relocated in memory) and forgotten (via mem::forget). We will introduce traits like Move and Forget that make these capabilities explicit, allowing types to opt out. This follows the precedent set by the Sized hierarchy work, which relaxes the assumption that all types have a compile-time-known size. We will implement MVPs in the compiler, write RFCs, and validate viability through real-world testing in the Linux Kernel.

Motivation

The status quo

Rust has historically assumed that all values can be moved (relocated in memory) and forgotten (via mem::forget, without running destructors). These assumptions are baked into the language: assignment moves values, and mem::forget is safe. But some types need to opt out of these capabilities:

Immobile types: A lot of async futures want to be self-referential, but self-referential types can't be safely moved. The current solution is Pin, which encodes immovability as a property of places rather than types. This leads to significant complexity. As The Safe Pinned Initialization Problem describes, Pin struggles to safely encode self-referential types in systems like the Linux kernel.

Guaranteed destructors: Some types need their destructors to run. A Transaction type might require commit() or rollback() before cleanup. A scoped task handle must join before the scope exits. But mem::forget is safe, so Rust can't guarantee destructors run. This blocks patterns like safe scoped spawn for async, where the spawned task borrows from the parent scope.

What we propose to do about it

We propose to generalize Rust's type system with new auto-traits that describe what operations are possible on a type. The framing is positive: traits represent capabilities. At the base layer, types may have no special capabilities. We then layer on the things we need:

  • Move: The type can be relocated in memory.
  • Destruct: The type can be implicitly dropped (destructor runs when it goes out of scope).
  • Forget: The type can be forgotten via mem::forget without running its destructor.

This follows the precedent set by the Sized hierarchy work. Just as that work relaxes "all types have compile-time-known size" to support scalable vectors, this work relaxes "all types can be moved" and "all types can be forgotten."

The Move trait encodes movability as a property of types rather than places:

#[lang = "move"]
unsafe auto trait Move {}

Types implementing !Move cannot be moved and must keep a stable address for their entire existence. This is simpler than Pin because immovability is a type property, not a place property. Construction of !Move types will rely on work from #t-lang/in-place-init.

The Forget trait lets types opt out of being forgettable:

// Types implementing !Forget must have their destructors run
unsafe impl !Forget for ScopedTaskHandle {}

With !Forget, we could build safe scoped spawn: the handle's destructor joins the task, and because the handle can't be forgotten, the join is guaranteed. This unblocks patterns that are currently impossible in safe Rust.

Work items over the next year

Move trait

Let types opt out of being relocated in memory, encoding immovability as a type property rather than a place property.

Task Owner(s) Notes Compiler implementation for Move @lcnr and @nia-e Write the Move RFC @yoshuawuyts Test in Linux kernel @BennoLossin RfL is an important Rust user which uses a lot of self-referential data structures. Test interactions between Iterator and !Move @yoshuawuyts It's important to prove that generator-based effects can be desugared to impl Trait + !Move so they can support self-references.

Guaranteed destructors

Explore letting types opt out of mem::forget, enabling patterns like safe scoped spawn for async.

Task Owner(s) Notes Design exploration for guaranteed destructors @nikomatsakis Explore trait hierarchy options and interaction with existing features

What is concretely out of scope for this year is anything related to changing or updating the Future trait. This is the only stable trait in Rust which depends on Pin, and would need a migration story to be able to use Move. However depending on Pin is not the only shortcoming Future has (1 + 2 + 10 more issues), and so fixing the Future trait is best treated as a standalone project.

Team asks

Team Support level Notes [lang] Large Design session needed to work through design [types] Large Involved in implementation + review

Frequently asked questions

How does this relate to the Sized hierarchy work?

The Sized hierarchy work establishes the pattern: Rust can relax assumptions that were previously universal by introducing trait hierarchies that let types opt out. That work relaxes "all types have compile-time-known size" to support scalable vectors and extern types. This goal applies the same pattern to "all types can be moved" and "all types can be forgotten."

How does this relate to the "pin ergonomics" initiative?

This work is an alternative to Project Goal 2025H2: Continue Experimentation with Pin Ergonomics, which includes the following extensions:

  • A new item family pin in lvalues, e.g. &pin x, &pin mut x, &pin const x.
  • A one-off overload of Rust's Drop trait, e.g. fn drop(&pin mut self).
  • A new item kind pin in patterns, e.g. &pin <pat>.

Notably this work does not solve pin's duplicate definition problem, meaning that even with these extentions we still end up with Trait and PinnedTrait variants of existing traits. The Drop trait being the exception to this, since the initiative is proposing to special-case it using a one-off overload.

Rather than trying to change the language to make Pin work, we believe the problem is with Pin and we should improve the way immovable types are encoded in Rust instead. With the eventual goal to deprecate Pin in Rust entirely.

Because Rust promises to stay backwards-compatible forever, making pin a language-item on par with & and mut is something we'll forever need to keep supporting. Given our eventual goal is to deprecate Pin, we do not believe that we should make pin a part of the language. Which is why Move is not just a complimentary proposal, but intended as an alternative.

What enables safe scoped spawn?

Safe scoped spawn requires guaranteed destructors. The pattern: spawn returns a handle whose destructor joins the task. If you could mem::forget the handle, the task could outlive the scope and access dangling references. With !Forget, the handle's destructor is guaranteed to run, making the pattern safe. This is one of the key motivations for the guaranteed destructors portion of this goal.

Where can I read more about this design space?

Several blog posts explore this area:

The Daily Front Page 14 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — The Fish Sauce Reckoning
article

Decades-old fish sauce at abandoned factory in Canada finally being removed

by ohjeez·▲ 238 points·247 comments·defector.com ↗
The resulting stench might haunt an entire community.

20-year-old fish sauce spews out of a rupture in a vat at an abandoned plant

Image via CBC

Take capelin, a small silvery fish in the smelt family. Now add salt. Then throw those two ingredients in 110 vats, each of them about 10 feet tall, and let them sit in a defunct factory for over two decades. The resulting stench might haunt an entire community, as it has the people of St. Mary's, a coastal town of about 300 people in the Canadian province of Newfoundland and Labrador. In 2019, one resident described the ritual of abandoning her home every summer, boarding up the windows and doors so the smell doesn't permeate her belongings. The people of St. Mary's have long fought for the fish sludge to be cleaned up; after an aborted attempt in 2016, that work finally began in earnest this week.

There are 900,000 liters of fish sauce to remove—some of it just liquid, some of it with fish solids. The province of Newfoundland and Labrador budgeted $2 million for the job, which was taken up by a local engineering firm and is expected to be completed in October. As workers cut open the vats, viscous brown fish goo shot out onto the factory floor. It will be mixed with peat moss, hauled out in about 200 truckloads, and thrown in a landfill lined with polyethylene, after which it will be sealed up "like a Ziploc," according to the lead engineer on the project. St. Mary's Mayor Steve Ryan reportedly teared up while describing new hope. "To be known as the 'sauce plant mayor' … it's time for that to be over," he said.

Even in ideal circumstances, the creation of good fish sauce is a stinky process, but the resulting umami bomb is well worth it. The Atlantic Seafood Sauce Company began in 1990 with the (sound!) idea to make use of someone else's waste product. A processing plant in St. Mary's was sending female capelin to Japan so their eggs could be used for masago; the male capelin were of no use to them. Vietnamese immigrant Sahn Ngo saw in these castoff fish an opportunity to brew one of the signature sauces of his cuisine. But after his company was blocked by regulators—check out this Eater feature for nuance—it closed up shop in 2001, leaving behind the vats of sauce in progress. I can't be the only person out there staring at these torrents of fish mud and wondering about the tasting notes. In fact, I know I'm not, having spoken to food scientist Bryan Quoc Le earlier this week. Given his background in chemistry and Vietnamese cuisine, he was the ideal expert to unpack this horrifying and possibly delicious situation.

Our conversation has been edited and condensed for clarity.


I wanted to start off and take a more normal scenario and understand the chemistry in a more traditional fish sauce, where we start with the fish and the salt. My understanding is that enzymes from the gut of the fish do the work of digesting the proteins, and breaking them down into amino acids, which have tasty properties, and that's why we like the fish sauce. And the high salt content helps keep this process safe and makes sure that the right kinds of bacteria are able to outcompete the harmful kinds.

That's exactly right. Basically what's happening is in the intestines of the fish, the enzymes are being released, and the enzymes start to break down the proteins. First, they chop them up into fairly large chunks, but then over time they start to liquefy as you get down to the amino acid content. And most proteins are about 30 percent or 40 percent glutamic acid, and so a lot of the initial flavor profile is from that glutamic acid content that gives you the umami flavor.

The salt helps protect the fish. It protects it from the presence of pathogens. That's the really important part of that process. But it also protects it from bacteria and yeast that might cause some kind of rancidification that is undesirable, right? Then it serves as a sort of amplifier of the flavor, too. In order to have glutamic acid be experienced as umami, you also need sodium ions. Together, it's necessary—pure glutamic acid actually tastes like soap.

Fish sauce is typically made on something like a yearlong time frame. This is a very, very different situation, and I doubt there's any literature on long-term fish fermentation.

I would want to fly there and just see what happens.

That's how I feel.

There are studies to be done.

Definitely. This is an incredible resource. Based on your knowledge of the underlying chemistry, what else do you think is happening once the process extends for this long?

Within that one- to two-year time frame, generally speaking, a lot of the process is the enzymatic breakdown [that produces amino acids].

Now, there are certain yeasts and bacteria that are super slow, but they tend to work their magic on the same timescales as something like a wine or a whiskey. There are these 100-year-old soy sauces that are made in Korea, these monasteries that just have this continuous soy-sauce broth going on and on. Apparently it's supposed to be really good. I haven't tried it myself, but I would imagine something similar is happening, where you have these 20-year-long timeframes, and the initial strong fermentation action, because there is going to be some bacteria or yeast that lives on the skin of the fish, these are not necessarily sterile conditions.

This bacteria or yeast that exists can tolerate really high levels of salt. But because what salt really does, and why it prevents the growth of pathogens, is it inhibits the breakdown of a lot of enzymes. With these long timescales, the yeast is able to not only grow, but they'll die and then release the contents of their enzymes. So there's this ongoing forever process that's happening, as well as the more conventional chemistry that would occur.

An example: There's the reaction between amino acids and very minute amounts of sugars. That's why soy sauce is black, right? It's a chemical reaction that occurs called the Maillard reaction, and is accelerated when you heat or roast something. The baking of bread or roasting of coffee gives you those dark compounds. But if you give something a year or two, or 10, the darkening occurs so long as there's some kind of sugar in the vat. So that would be an interesting thing to see: What are the flavor profiles that form because of this Maillard reaction? Again, you can also see that in wine. The chemical reaction that changes the profile of the really rich, strong flavors that you see in 10-year-old or 20-year-old wines is because of this Maillard reaction that takes forever to occur at room temperature.

That's a good detail to point out, because this abandoned factory isn't climate-controlled in any way. It's just been exposed to the elements, and I imagine it's basically refrigerated for a huge chunk of the year, based on where it is. So this is probably very unusual fermentation playing out: every few months, going back in the fridge, and then getting warmed up again.

Exactly. You have that seasonality to it.

The locals in the town have reported scents so strong that they board up their house in the summer, they can't hang their laundry out. Do you know what compounds might be produced by fermentation of this time length?

It's primarily amines, a class of compounds that basically come from the breakdown of amino acids. So the amino acids—there's some kind of biological reaction with the bacteria. They sort of split off a carbon dioxide, that breaks off that acid portion of the amino acid. The amines themselves, generally speaking, humans are extremely sensitive to them because they're indications of death, right? A corpse, a dead animal or a dead fish, it's giving off amines, and a lot of them tend to be toxic to humans. Even if it's minuscule concentrations that are going into the air, people are going to sense it a lot more, especially if you're not used to it. The people who live in this island Phu Quoc in Vietnam, the fish sauce capital, I'm sure they can tolerate quite a high heavy dose versus, you know, if your cuisine doesn't really have it.

People are describing rancid odors, too. Is there something about the fat content of the fish?

Yeah, definitely. That's the same sort of process with the enzymes, but with the added bonus of oxygen. [The fat is] oxidizing, and then as it's breaking down, which is still a slow process, those molecules are really, really volatile. Aldehydes and ketones that form from the breakdown of fatty acids, that's gonna give you that smell. Again, humans are very sensitive to that. We don't tolerate it very well.

I've seen footage of the workers cutting open these vats, and it's not a pretty sight. It's this gray-brownish sludge hitting the factory floor, but obviously real fish sauce is processed and strained. Would you be a little bit tempted to taste this forbidden fish sauce if it was processed?

I would 100 percent taste the forbidden fish sauce. I would do it for science. My wife would kill me if I'm not already dead. I will. If there was a way, if I would be able to fly out there, I would do it, and write a whole report about it because I think that would be a pinnacle achievement for me.

For the record, I agree, and I don't even have the scientific pedigree. I just want to taste it. With the prospect of dying, what kind of pathogens would you be worried about specifically?

Honestly, I don't think there would be any pathogens, because the salt content is so high. There's really nothing that lives in that. There are a lot of products that are shelf stable as long as they have a high concentration of salt, decently acidified, or high concentration of sugar. Basically, the only thing that can live is a handful of bacteria and yeast. It's one of the principles of food safety.

So this is speculative, but given your knowledge of fish sauce, and just extending some of these chemical processes out more and more years, what would be your tasting notes, if you had to guess, for this fish sauce?

Oh my gosh, that rancidity. Unfortunately I think the rancidity and amines are going to be forward, in a way that is probably going to be overwhelming. That said, there's so many complexities with that. You have not only the reactions forming those molecules, but also the molecules are interacting with each other. So amines and aldehydes really like to form bonds, and in doing so, they might create a level of complexity that we've never seen before, right?

There could be an undercurrent of sweetness, even. That would be very bizarre, right? But if you think about the chemistry of sweeteners, artificial sweeteners, some of them have that kind of structure. So that would be interesting. It could be like where you're hit with a horrible bitterness, a rancidity, a horrible fishy overwhelming—but maybe there's something underneath, right? Or maybe we just need to acidify it a little bit. Add a little lemon juice. This is common in Vietnamese cuisine, when you have the fish sauce dressing that's used for a lot of noodle dishes. Maybe we could cut it.

[Both laughing, with hunger]

Maybe we can cut those amines and just not even taste them. That could be really cool. Then you would know: What level of savoriness could we actually achieve out of it? Because this is the fun part. Worcestershire sauce is fish sauce. Basically, what happened was a bunch of chemists accidentally abandoned it for a couple years, they put a barrel of anchovies or mackerel or something like that, and then just threw in some vinegar.

What could happen is, oh, actually this is kind of flavorful in a way that we wouldn't expect—something that's 20 years old, especially the umami flavor, the intensity of the glutamic acid. Maybe the glutamic acid from the amino acid breakdown is reacting to other components like these amines and these aldehydes, and now we have all sorts of new molecules. It's actually a black box. We don't really know.

Oh man, that's so interesting. We've got to get a hold of this somehow. They've got a million liters of it.

Right? If it turns out to be some kind of goldmine ...

I reached out to you because I love the piece you wrote about fish sauce, and I was wondering what you like most about it in its ordinary form.

Being Vietnamese, it's such a quintessential part of my cuisine. My mom would always cook with it. It was always incorporated in some way, but it was also kind of the situation where my friends would come over and be like, "What? What is that horrible smell?" You know you're in a Vietnamese household because you can smell the fish sauce, because it's always in the air. It has a childhood element of warmth; it helps me think about Mom a lot.

Then, as an adult, I use it, and now that I understand the chemistry, it makes a lot of sense. It's a very versatile ingredient because what you're doing is just dumping a lot of glutamic acid, but it's from a very specific flavor profile. It's not soy sauce, which tends to be have a caramelized element to it because of that long-term processing, and has more sugar because it requires rice to jump-start that fermentation process. Whereas fish sauce is pure, right? It's just fish, guts and everything. There's an element of authenticity to it. Not that, of course, soy sauce isn't really authentic, but I just like the idea of that.

There's that piece, and then one of the reasons why my wife and I started dating is because she's Israeli and Romanian, totally removed from my culture, and one time we went out on a date, and she took me to a Vietnamese restaurant, and I'm like, "How does this person even know anything about Vietnamese food?" I kind of wrote it off, like, She's not gonna understand. Of course, they bring out the food, and she's like, "Could I get more fish sauce?" My friends would stay away from my house. But this person who ended up becoming my wife, she's like, "I love fish sauce. I need more of it in my life."

The Daily Front Page 15 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — Serving the Giant Models
article

Smaller, faster, safer: running Kimi and GLM at scale

by ascorbic·▲ 208 points·50 comments·blog.cloudflare.com ↗
They are also very hard to serve efficiently because of memory constraints.

Workers AI runs inference for some of the best open models in the world on GPUs in Cloudflare data centers close to your users. Two of the most capable, and most demanding, are Moonshot's Kimi K-series and Z.ai's GLM. They are large, long-context, mixture-of-experts models, and they are wonderful to use. They are also very hard to serve efficiently because of memory constraints.

We've written before about how we serve large models on Workers AI and about separating the prefill and decode phases of inference to get more out of each GPU. This post looks at three techniques we layer on top of that to fit these models into memory and keep them fast: quantizing the KV cache, compressing the model weights, and, because both of those pack more requests onto shared hardware, protecting the cache those requests share. These optimizations enable us to support more customers at lower costs, with no change in model accuracy.

All our experiments and production traffic are running and benchmarked with SGLang, an open-source inference serving framework. We found that SGLang offers the best performance in the market, and we work closely with the SGLang team to upstream patches and new features to make our work available to the open-source community.

Quantizing the KV cache

As a model generates text, it stores the attention keys (K) and values (V) for every token it has already processed in a structure called the KV cache. The cache is what lets the model extend a long conversation without re-reading the entire context on every new token. For a long-context model, it grows quickly, and it is usually the KV cache, not the model's weights, that fills up GPU memory first.

By default, the cache is stored in 16-bit precision (BF16). We store it in 8-bit floating point instead (FP8, e4m3), which halves its size. On Kimi K2.6, that raises the amount of context we can hold in memory from roughly 686,000 tokens to about 1.37 million, twice as much.

It's worth being precise about where the benefit comes from, because it isn't raw speed. Quantizing the cache adds a small amount of work per token, since the FP8 attention kernel has to convert values as it reads them. What it changes is how many requests we can keep resident at once. The following measurements are for Kimi K2.6 decoding on a disaggregated H200 deployment, comparing the attention kernels directly:

Concurrent requests BF16 KV cache (tok/s) FP8 KV cache (tok/s)
1 137 125
8 731 689
16 1,106 1,028
32 1,558 1,489
64 Out of memory 2,192

At any single concurrency level, BF16 is a few percent faster per token. But BF16 runs out of cache at 32 concurrent requests and can't admit a 33rd, while FP8 keeps going to 64 and reaches 2,192 tokens per second, about 41% higher than BF16's peak, for roughly 30% less cost per token. Because we run prefill and decode as separate pools, we can apply this where it helps most: prefill is compute-bound rather than memory-bound, so there we leave the cache in BF16 and keep its slightly higher throughput.

None of this would matter if it changed the model's answers, so we checked. Across our evaluation suite, FP8 and BF16 caches are indistinguishable:

Benchmark BF16 KV FP8 KV
GSM8K 94.24 94.09
ARC-Easy 89.06 89.14
ARC-Challenge 66.72 67.49
MMLU 89.11 89.04
MMLU-Pro 80.29 79.29
mcxams (internal benchmark) 61 / 63 61 / 63
Tool-call validity 92.2% 92.6%

Compressing the model weights

The KV cache is one demand on GPU memory; the model's weights are the other. For GLM 5.2, we compress the weights from 8-bit floating point down to 4-bit integers (INT4) with no loss in accuracy. The checkpoint shrinks from 705 GB to 421 GB, about 40%, and per-GPU memory across an 8-way tensor-parallel deployment drops from roughly 88 GB to 52 GB, which leaves room for around 1.18 million tokens of KV cache on the same hardware.

Across our evaluation suite, INT4 and FP8 weights are indistinguishable:

Benchmark / Capability Metric FP8 INT4
GSM8K Exact match 94.39% 93.56%
GSM8K Flexible 94.24% 93.48%
ARC-Easy Accuracy 86.62% 86.15%
ARC-Easy Acc (norm) 84.51% 85.19%
ARC-Challenge Accuracy 64.93% 64.85%
ARC-Challenge Acc (norm) 67.24% 66.64%
MMLU Average 86.60% 86.54%
MMLU-Pro Exact 80.80% 80.47%
mcxams (internal benchmark) Passed 62 / 63 62 / 63

Smaller weights make the decode phase faster, and for a clear reason: generating each token means streaming the model's weights out of GPU memory, so decode speed is limited by memory bandwidth. Move less data and every token arrives sooner. The effect is largest at low concurrency, where per-request latency matters most:

Concurrent requests GLM FP8 (tok/s) GLM INT4 (tok/s) INT4 gain
1 60 92 +55%
8 425 513 +21%
16 683 825 +21%
32 994 1,267 +27%
64 1,672 1,933 +16%

Prefill behaves differently. It is compute-bound, and INT4 weights have to be expanded back out before the model can multiply with them, so that extra step makes prefill slower rather than faster, GLM sustains about 10,160 tokens per second of prefill in FP8 versus 8,660 in INT4. As with the KV cache, the disaggregated design turns this into a choice rather than a compromise: we run INT4 for decode, where it wins, and FP8 for prefill, where it wins. Model accuracy stays within 0.8 points of the FP8 model across every benchmark we run, making its quality indistinguishable.

Protecting a shared KV cache

Both techniques above have the same effect: they let many more requests share one GPU's memory at the same time. That efficiency is the whole point, but it also means hundreds of requests are reading and writing pages of the same physical KV cache. The mechanisms that make this fast, paged attention, continuous batching, cache reuse, all rely on getting the bookkeeping exactly right, and at our request volumes, even a one-in-a-billion mistake would show up regularly.

So we built KV cache integrity checking as a layer of defense. The idea is straightforward: every physical cache page gets a tag that changes whenever the page is reallocated, and the server records which pages and tags each request expects to use. Before supported decode operations read from the cache, those mappings are checked. If anything doesn't match, the affected request is aborted rather than allowed to return data from the wrong page.

The question that decides whether a safety check ships is what it costs. We measured it on a mid-sized production model in a two-prefill, two-decode configuration, with 8,192-token inputs and 1,000-token outputs:

Concurrency Throughput change p95 latency change
1 −0.53% +0.42%
2 −0.38% +0.54%
4 −0.79% +0.63%
8 −0.43% +0.80%

The cost is under 1% on both throughput and tail latency, and even the upper bound of the 95% confidence interval stays near 1%. We kept it computationally cheap by running the validation as a separate batch check rather than fusing it into the attention kernel, which would have introduced a race between GPU thread groups. It's enabled per deployment, and the default path uses a no-op tracker with no measurable overhead, so deployments that don't need it pay nothing.

What's next

Serving frontier models efficiently is a moving target, and this is the ongoing work behind it. We're expanding FP8 KV caches across more of the fleet, validating NVFP4 weights on Blackwell (NVIDIA’s GPU architecture), and working toward making integrity checks something we can leave on everywhere at negligible cost. These optimizations will allow us to continue to support more customers at a lower cost and at the same accuracy.

If squeezing the best open models onto GPUs and serving them to millions of developers sounds like your kind of problem, come work with us.

The Daily Front Page 16 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — Repository Desk: CP/M Returns
repository

CP/M-386 – CP/M for 386 protected mode, derived from CP/M‑68K

by TMWNN·▲ 94 points·57 comments·github.com ↗
★ 47⑂ 0 forks C

CP/M-386: CP/M for 386 protected mode, derived from CP/M-68K

CP/M‑386 is CP/M for 386 protected mode, derived from CP/M‑68K.

Overview

CP/M‑386 is currently in the very early development stages.

Hardware support

  • Compatible with 386 (and later systems) with 2MB (or more) memory.
  • Systems using either PC BIOS or UEFI (with CSM) are supported.
  • VGA, 8042 PS/2, 8250/16450/16550 UART, CMOS RTC, and 8253/8254 PIT are supported.

CP/M compatibility

CP/M‑386 should be highly source-compatible with other implementations:

System BDOS coverage CP/M‑68K 1.3 100% CP/M 2.2 100% CP/M‑Plus 71% DOS‑Plus 62% MP/M 2.1 50%

The system currently reports BDOS 2.2 to applications.

  • The CP/M‑386 BDOS is at full parity with CP/M‑68K 1.3 and CP/M 2.2.
  • A large majority of the CP/M‑Plus (CP/M 3) BDOS is also supported.
  • More than 60% of the DOS‑Plus additions have been implemented.
  • Approximately half of the MP/M extensions have been completed.
    • The missing functionality is largely the multi‑user, multi‑tasking, message queuing, and process control calls that don't apply to a single‑user CP/M implementation.
  • Unique CP/M‑386‑specific BDOS extensions have been added to accommodate new features like direct video access, high‑resolution timing, PRNG, etc.

Build requirements

The following dependencies are required to compile CP/M‑386:

†Be sure to use cpmtools version 2.23 or later. Older versions may appear to work but have several known bugs.

Downloads

Compilation

Building CP/M‑386 is supported on current releases of NetBSD and FreeBSD‡, and most recent Linux distributions.

The following are the minimum versions of Linux distributions that have been verified to build CP/M‑386 successfully: CentOS Stream 9, Fedora 36, Debian 12, Ubuntu 18.04 (with gcc-16 from ppa:ubuntu-toolchain-r/test), Ubuntu 22.04, Alpine 3.24, and OpenSUSE Leap 15.4.

  • GCC build (recommended):

    make -Orecurse -j "$(nproc 2> /dev/null || printf '%s' 1)"
    make test
    
  • Clang build:

    make -Orecurse -j "$(nproc 2> /dev/null || printf '%s' 1)" CC="clang"
    
  • It is recommended to use GCC as Clang‑compiled i386 code is larger.

  • Be sure to make clean if switching compilers or adjusting compiler flags.

  • 32‑bit support libraries are required to run the test suite (make test).

  • ‡At the time of writing, FreeBSD is shipping non-functional cpmtools2 packages with broken mkfs.cpm functionality. To successfully build on FreeBSD, you must rebuild cpmtools and ensure it is not linked with libdsk. If you receive a Disc rejected by driver error on FreeBSD from mkfs.cpm, your tools are broken and cannot be used to build CP/M‑386.

Build output

  • The build produces two primary artifacts:

    File Description cpm386.elf Multiboot kernel image floppy.img Bootable 3.5" 1.44MB floppy disk image

You can download pre-compiled binaries above.

QEMU testing

  • Multiboot kernel (recommended):

    qemu-system-i386 -m 2M -serial stdio -monitor none -kernel "cpm386.elf"
    
  • Floppy MBR loader:

    qemu-system-i386 -m 2M -serial stdio -monitor none -drive if=floppy,format=raw,file="floppy.img" -boot a
    

QEMU notes

  • Use -nographic -display none -vga none to disable VGA video (and use only serial console).
  • Use -serial none to disable the serial UART (and use only VGA console).

Included utilities

Program Description ACLOCKDV.386 aclock (VGA text console version) ACLOCKVT.386 aclock (ANSI terminal version) BIG.386 Multi-extent loading test executable CLEARTPA.386 Clears (zeros) and optionally verifies the TPA CLS.386 Clear screen (BDOS 221) DELAY.386 Delay test (BDOS 141) DEMO.SUB SUBMIT demonstration DUMPDIR.386 Directory entry dump utility (BDOS 17/18) DUMPFCB.386 File control block dump utility (BDOS 15) ENV.DAT Environment data file FPARSE.386 F_PARSE test (BDOS 152) GETSN.386 Display serial number (BDOS 107) GFXTEST.386 Graphics and framebuffer demo (BDOS 229/230/231/233) HD.386 Hex dump utility HELLO.386 Hello world (the very first CP/M‑386 program!) ILLEGAL.386 Ring‑3 protection and exception handler test IOTEST.386 File I/O BDOS tests JULIA.386 Draw a Julia set fractal (terminal version) LRBC.386 Query and/or set Last Record Byte Count LS.386 List files (with sizes) MANDEL.386 Draw a Mandelbrot set fractal (terminal version) ALVTST.386 Get Allocation Vector test (BDOS 27) MEM.386 Memory map utility (BDOS 227/228) MORE.386 UNIX more‑style pager OD.386 Octal dump utility PAUSE.386 Wait for keypress PRINTENV.386 Print environment and system data PRNG.386 PRNG test and demo utility (BDOS 253/254) PROFILE.SUB SUBMIT script (automatically executed at boot) RC.386 Return code test and query (BDOS 108) README.TXT Sample text file REBOOT.386 Reboot utility (BDOS 220) RM.386 UNIX rm‑like interactive file deletion utility SEROFF.386 Disable serial console (BDOS 223) SERON.386 Enable serial console (BDOS 223) STAT.386 STAT (A port of Zilog CP/M‑Z8000 STAT v1.0C 01/03/84) SYNC.386 Synchronize disks (BDOS 48) TEST211.386 Numeric format test (BDOS 211) TEXTMODE.386 Query and set the console text mode (BDOS 229/230/231) TICKS.386 High-resolution timer tests (BDOS 225/226) TOD.386 Get (and set) Time of Day clock (BDOS 104/105) TOUCH.386 Create an empty file TRUNCATE.386 File truncation utility (LRBC aware) TRUNCTST.386 Truncation tests (BDOS 99) TSEC.386 Get date and time (BDOS 155) VER.386 Display OS version (BDOS 163) VGAFONT.386 Load a text console font or restore the ROM font (BDOS 232) VGAOFF.386 Disable VGA text console (BDOS 222) VGAON.386 Enable VGA text console (BDOS 222) VGATEXT.386 VGA text direct access demo (BDOS 224)

Contributing

  • Do not open pull requests with large amounts of LLM-generated code. These will be immediately rejected.
  • There is currently no AI-generated code in the operating system at this time (though there are some AI tests, comments, and analysis), as the project is intended to be as much of a learning experience for me as it is a useful OS port.
  • Usage of AI (artificial intelligence) tools by contributors is currently permitted, subject to the same terms and conditions as the LLVM AI Tool Use Policy, but this permission may be withdrawn at any time and without notice.

Future plans

See FUTURE.md.

Code statistics

Language Files Lines Blank Comment Code Complexity Bytes Uloc C 65 31160 6146 4379 20635 4356 730234 10664 C Header 22 3054 551 1233 1270 13 111619 1557 Makefile 2 1570 300 201 1069 331 52823 773 Assembly 6 1351 235 266 850 1 30970 700 Markdown 2 478 58 0 420 0 21907 378 Linker Script 2 199 38 0 161 0 4809 91 YAML 1 80 6 15 59 0 3196 63 Total 100 37892 7334 6094 24464 4701 955558 14148

Mirrors

License

  • CP/M‑386 is distributed under the terms of the permissive MIT License.
  • Bryan W. Sparks of DRDOS, Inc. dba DeviceLogics LLC, successor in interest to Digital Research, Inc.’s CP/M assets, explicitly grants an unlimited authorization to use, distribute, modify, enhance, and otherwise make available CP/M technology, including the CP/M operating systems and their derivatives.
The Daily Front Page 17 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — A New Home in Hamburg
article

More German than many Germans

by mertbio·▲ 506 points·355 comments·mertbulan.com ↗
That internship completely changed my life.

I just wanted to do an internship in Europe so it would be easier to find a job after graduation. That internship completely changed my life.

More German than many Germans

My favourite view in Hamburg

In 2017, after I finished the third year of my Computer Science studies, I decided to do an internship in Europe. So while I was applying for the Erasmus Scholarship, I also started looking for internships. In the end I got the scholarship, which helped a lot with the visa process, and I also found an internship at a company in Hamburg.

I had never been outside of Turkey before. So I had also never really talked to people from other countries. What I knew about Germans came mostly from the Turkish people who moved to Germany in the 60s for work. Those people came back to Turkey almost every summer and told us about their life there. Most of what they said was the same as what you can read on the internet, the stereotypical German.

People who don't laugh, who are cold and unfriendly, who always follow the rules, who speak a language that sounds too harsh, and so on. And of course, someone always brings up the Nazis.

Apart from the people I talked to in the interviews, my first real contact was my German flatmate. Before I arrived he showed me the room on Skype and we agreed on it. When I landed in Hamburg, he picked me up from the airport. That was a great start, and during my three months there we chatted in the kitchen almost every evening for half an hour.

I had a lot of questions for him and he always answered them properly. On the weekends he picked up his girlfriend and they either stayed home or went rowing. Their relationship looked very healthy to me. She was studying medicine, so sometimes she was working at her desk on a Saturday while my flatmate played Witcher 3 right next to her. I never heard them argue about anything.

Near the end of my internship he told me that he and his girlfriend were going to Africa, so I would be alone in the flat for a week. When I asked him what I should do with the keys, he just said to drop them in the mailbox. That much trust after such a short time really surprised me.

We had a last dinner together and I told him things were going well at the company and there was a chance I could come back to Hamburg.

I was lucky with my flatmate and I was also lucky at work. I had a great team. They taught me new things, gave me responsibilities the other summer interns didn't get, and included me in all the team events. The offsite we had outside the city is something I still remember today. And I was getting all of this while earning minimum wage.

My first offsite event

I was really surprised by how friendly everyone was. We weren't just working, we were having fun. Everything I had heard about Germans until that point was gone. It was the best summer of my life.

My lead was happy with my work and offered me a job right away. I could work as a freelancer from Turkey while finishing my studies, and if they were happy with my performance I would get a full-time contract. That is what happened.

Coming back

In April 2018 I got my contract, even before I finished my studies. The next month something nice happened. My German flatmate emailed me and asked when I was coming back, because he already had a room for me for the summer. The company was going to give me a place to stay, but I couldn't say no to him. Right after my last exam, before I even had my diploma, I moved to Hamburg at the end of June and started working full time with the same team, living with the same flatmate.

On my first day there were candies and balloons on my desk. Everybody was happy to see me again. One colleague who knew my interest in Apple gave me a German flag pin he got at WWDC18. He said he tried to swap it for a Turkish flag but couldn't manage it. I was already happy with the gift, because it meant he was thinking about me while he was in California.

My desk

When you start living in Germany you have to register your address. When I went to the public office, the clerk told me I had already lived in Hamburg before. I said I had done a summer internship a year earlier. He just said: Welcome back!

That was the moment I felt like I was coming home, not moving to a new country.

The first years

My first months were mostly about finding a flat and figuring out how things work here. Since my German wasn't good enough, my colleagues came with me to flat viewings after work. When I had a problem with my electricity provider, a colleague came along and did all the talking. When I moved to a different place a year later, a German colleague rented a van and helped me carry everything.

At the time, the company was one of the biggest internet companies here, with around 2.000 people. Sometimes I saw the C-level in the kitchen getting their own coffee or even washing their own glasses. They had assistants, but the assistants helped with work instead of acting like servants. We also had a CFO who rode a very old bike to the office.

Whenever we had a team event or an offsite, the organisers made sure they knew everyone's dietary needs. Vegan, vegetarian, halal, no alcohol, allergies. So everyone would have something to eat and drink.

When I was doing a good job, my lead kept telling me to take vacation instead of working more. When I was sick, he told me to stay home until I felt better. I didn't even need a doctor's note. It took me a while to notice this was not only a work thing. You get on a bus or a train here and nobody checks your ticket. I wasn't used to this level of trust.

My second offsite

Across from our office there was an Italian restaurant where we went for pizza sometimes. The pizzas were very tasty and huge, and it was the only place that sold half a pizza. At lunch I saw people in suits eating there, and right at the next table people from the construction site nearby in their work clothes eating the same pizza. Nobody looked at the other table and nobody thought it was worth noticing except me. That is the part that stayed with me. It was completely normal, and it was normal because a man who spent his morning on a building site can afford an Italian lunch and eat it like everyone else.

I noticed the same thing in the rich districts of Hamburg. You can walk into one and not feel like you don't belong, and the prices in the shops are not that different from anywhere else in the city. Sometimes they are exactly the same. The more I saw of that, the more I wanted to stay. I believe in social democracy, and this is a country that calls itself one and mostly behaves like it.

It didn't take long for me to move up at work. I didn't feel any discrimination, even though people say Germans prefer Germans when it comes to promotions. There were already a lot of people with a migration background at the top. When I ran as a candidate in the works council election, I got the most votes of anyone, even though there were many Germans running and only around 25% of the company were immigrants like me.

You see the same thing outside of companies. Cem Özdemir, whose parents came from Turkey, has been the prime minister of Baden-Württemberg since May. Sinan Selen, who was born in Istanbul, runs the office for the protection of the constitution.

Being in the works council gave me more contact with the C-level. Sometimes I found myself arguing with the CTO or the CEO, and later at a company party we would have a beer together and talk about something else. That is when I understood how flat the management is here. I saw the difference later when I worked for an American company, where they made sure you knew you were lower on the ladder.

I met hundreds of Germans at that company and they were always super friendly. I say this because years later I still see many of my old colleagues at different events, and most of my friends today are people I used to work with. A lot of immigrants complain that it is hard to become friends with Germans, but that wasn't my experience.

My landing was soft

I should be honest about one thing here. I landed softly. I came into a big international company where everyone spoke English, in a city like Hamburg, with a salary that let me pick where I live. I have worked with other German companies since then, mostly smaller ones, so what I write here is not only about that one place. But the start was much easier for me than it is for most people. A lot of them arrive with none of that, and the country they meet is not the same one I met. Everything I write here is my experience, not a report on how it works for everyone.

The language is part of that. Every story I told above happened in English. The team, the flatmate, the works council, the arguments with the CEO, all of it. Once I decided I was going to stay here for a long time, I started taking German classes, and after the citizenship law changed I put much more effort into it. So the German came from the decision to stay. It was not the thing that made me stay.

I never really tried to integrate. It just happened that the way I think about life turned out to be similar to how people here think.

Why I like the rules

Most people complain about the rules in Germany, but I like them. It means someone, or a group of people, sat down and thought about that specific thing and decided on a standard for everyone. When you have to do something, you don't feel lost, because you can just look it up. You don't have to find someone who knows.

Rules also make normal days easier. Something simple like waiting at a red light even when there are no cars takes away the work of deciding whether to cross. And if everyone does it, you don't have to worry about someone suddenly stepping into the street. Or the fire safety rule that makes exit doors in public buildings open outwards. You never have to think about pull or push.

There are also unwritten rules, like being on time. For me the logical thing has always been to aim for 15 minutes before the agreed time, so if something happens on the way I'm still fine. After going on dates with a lot of Germans, I realised they do the same thing. So instead of me arriving early and waiting 15 minutes, we just meet 15 minutes earlier.

My favourite one is Ruhezeit, the quiet time between 10PM and 6AM, plus Sundays and public holidays. My sleep is very important to me and I'm a light sleeper, so this rule really helps me. Sometimes I had neighbours who had parties during those hours, and I didn't hesitate to complain (with Lärmprotokoll) to my landlord. Many Germans have told me I'm more German than many Germans. It is probably because of examples like this one.

The one time a rule was pointed at me instead of working for me was my first application for permanent residence. I had just left my first company and I was between jobs, and that was enough to get it rejected. That was when I learned what a sustainable livelihood means to the German authorities. It doesn't mean the money you have in your account. It means a permanent contract with the probation time already behind you. I had savings and it didn't count for anything.

It was an emotional day. But after I calmed down I could see their logic. A bank balance can be gone in a year and a signed contract that already survived six months says something a number can't. It was the same system I like for every other reason, just this time I was on the wrong side of it.

Understanding the country

The longer I lived here, the more I saw myself spending the rest of my life here. That made me want to read about the country. I'm a heavy reader and I track every book, so here are the ones I read about Germany:

Apart from the books, I also watched a lot of documentaries, especially about the Nazi era.

Like most people, I didn't know that Germany wasn't one country until the 19th century. It was made of small kingdoms, city states and so on. That is why there are so many kinds of bread, beer and sausage, why some parts have different public holidays, different accents and even a different way of living.

The German Genius surprised me the most. It is about 1.000 pages about Germans who contributed to humanity in different fields, and I didn't know how many things in our daily life exist thanks to them. Some of them had to escape the country because of the Nazis and reached their full potential somewhere else, in countries like the US and the UK. The books also helped me understand how Germany built an educated middle class, how workers' rights and social reforms happened, and where the rule about no shopping on Sundays comes from.

What stayed with me is that this is probably the only country in the western world that faced its own history properly, admitted the worst things it did, and built a lot of its identity around not repeating them. You feel that here in small ways, not only in museums. In January 2024, after it came out that far right politicians had talked about deporting people who already hold a German passport, 50.000 to 80.000 people filled the streets of my city in one afternoon.

"Hamburg steht auf!" demonstration

In eight years I have not had a single case of racism. I know that isn't true for everyone, and I know the far right keeps growing.

I don't think most of those votes are about hating foreigners. Some people believe the story they get every day, that the country is broken and that immigrants are the problem. You find that story almost everywhere. The rest are angry that certain problems here have not been solved for years by the existing parties, so they look for an alternative.

For me, Germans are people who give trust before it is earned. People who are friendly without being fake about it. People who make sure everyone is included, down to what is on the table. People who care about someone they will never meet. People who know exactly what happened here and don't look away from it.

Making it official

That is why I decided to become one of them.

The chance came when the traffic light coalition, which I think was the most progressive government this country has had in decades, changed the citizenship rules and brought the waiting time down to five years. I was eligible, so I applied.

People seem to think a German passport is handed out easily now. It isn't. You have to prove you paid into the social system for at least five years. You have to pass the citizenship test. You need German at B1 level. You need a sustainable livelihood while your application is running. And most importantly, you have to accept the democratic values of this country.

For me the process itself was smooth. I applied online by uploading a pile of PDFs. A week later I got a letter saying my application had arrived, with a few papers to sign, scan and upload back. Then the waiting started. In total it took around 14 months to get the email saying my application was successful and that I could come and collect my Einbürgerungsurkunde.

I picked it up this week, at an appointment that only took 15 minutes. I am German now.

I believe I have contributed something to this society in these eight years and I will keep doing it. And I will keep complaining about everything that needs to be better. Because that is what real Germans do.

The Daily Front Page 18 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — Inference, From Scratch
article

Why we write our own C and C++ inference engines

by eatonphil·▲ 126 points·49 comments·localai.io ↗
Eighteen of our backends are C or C++ ports we wrote from scratch instead of wrapping an upstream engine.

Eighteen of our backends are C or C++ ports we wrote from scratch instead of wrapping an upstream engine. Here is why we did it and what we measured.

Most LocalAI backends wrap somebody else’s engine. llama.cpp, vLLM, whisper.cpp, stable-diffusion and MLX are maintained by people who work on those models full time, and wrapping one of them costs us a Dockerfile and a gRPC shim. We do that wherever we can.

Eighteen of our backends do not wrap anything. They are C or C++ ports we wrote from scratch, and each one exists because wrapping the upstream engine would have meant shipping something we could not ship: a multi-gigabyte Python install, a CUDA-only stack that will not run on half the machines our users have, or, in a few cases, a model with no C++ implementation to wrap in the first place. Below are the numbers for four of them, and what keeping them alive takes.

vllm.cpp: 66 MiB instead of 9.1 GiB

Deploying a Python inference stack means resolving a dependency tree at install time, on the target machine, against whatever CUDA and glibc that machine has. Deploying a ggml port means copying a shared library and a GGUF file.

vllm.cpp is our C++20 port of vLLM’s V1 serving architecture. Installing vLLM produces a 9.1 GiB virtualenv. Installing vllm.cpp produces a 66 MiB binary. It implements the same things the Python original does, including paged KV cache, continuous batching, prefix caching, the scheduler and the sampler, with no Python, no PyTorch and no ggml at inference.

The question is what that does to throughput. On an NVIDIA GB10 running Qwen3.6-27B in NVFP4, greedy, closed loop, against vLLM in its production graphed configuration rather than --enforce-eager:

Concurrency 1 2 4 8 16 32
vllm.cpp tok/s 86.05 159.68 292.34 508.77 801.76 1095.01
vLLM tok/s 82.32 158.03 290.31 505.46 789.16 1076.25
Ratio 1.045x 1.011x 1.007x 1.007x 1.016x 1.017x

Those are ties. Our run-to-run noise band is 0.5%, and concurrency 2 through 32 land between 0.7% and 1.7%, so those five points sit inside the noise or close enough to it not to matter. Only the single-stream case, at 4.5%, is clearly outside. Output is token-for-token identical to vLLM at every point on the curve, and peak host memory is 24.88 GiB against 28.18 GiB.

The install drops from 9.1 GiB to 66 MiB and the throughput stays where it was, which is what we were after.

Against llama.cpp on CPU from the same GGUF file, prefill runs 1.18x faster (223.8 against 177.3 tok/s), decode is a tie inside llama.cpp’s own spread, and the tokens match its greedy decode exactly. Against MLX-LM on an Apple M4, prefill time to first token is 1.5% ahead and warm total throughput is 97.6% of MLX-LM, a real 2.4% gap that sits entirely in decode.

depth-anything.cpp is faster on CPU

depth-anything.cpp is a port of ByteDance’s Depth Anything 3, which gives you metric depth in metres from one ordinary photo, plus per-pixel confidence, camera intrinsics and extrinsics, and a back-projected point cloud. On CPU it runs faster than PyTorch on the same model.

Engine Quant Model MB Load ms Infer ms Peak RAM MB vs PyTorch
PyTorch f32 2516 749 416.9 1328 1.00x
C++/ggml q8_0 142 40 319.4 363 1.31x

That is on a Ryzen 9 9950X3D at 504x336 with 16 threads. The C++ build runs the same model 1.31x faster, uses 363 MB of RAM against 1328 MB, and loads in 40 ms instead of 749 ms. The quantized q4_k build is a 99 MB file and stays near-lossless. Output correlates 1.0 with the reference forward pass across 37 parity tests.

We did not write a better matmul kernel than PyTorch. Two positional embeddings, the DPT head’s UV embedding and the backbone’s bicubic position embedding, were being recomputed on every forward pass with single-threaded scalar sin, cos and bicubic loops, even though they depend only on the input geometry and are identical every call. Caching them removed about 95 ms of host-side overhead per forward, which is most of the gap. PyTorch builds the same embeddings with vectorized operations and never had that overhead to begin with.

The heavy GEMMs are close to a wash, because everyone is calling into the same class of BLAS kernel. What is left is host-side work that a Python reference implementation never bothered to optimize, plus not loading an interpreter and a framework to do inference. On GPU it goes back to parity: with the ggml CUDA backend and flash attention on a GB10, depth-anything.cpp ties PyTorch’s tuned cuDNN at 47.3 ms per forward, and wins only the cold start, loading 1.75x to 2.9x faster.

The two where we are slower

face-detect.cpp and voice-detect.cpp replaced LocalAI’s Python insightface and speaker-recognition backends. Neither of them is faster than what it replaced on CPU, and we shipped them anyway.

face-detect.cpp runs the whole insightface buffalo chain, so SCRFD detection, five-landmark similarity-transform alignment to 112x112, and the ArcFace embedding, out of one self-contained GGUF with no Python and no onnxruntime. Detector boxes and landmarks match insightface to within 1 pixel, and the recognition embedding matches to cosine 1.000000 at any thread count. On CPU it is slower than onnxruntime: SCRFD detect runs at about 0.83x at one thread and 0.69x at eight, ArcFace embed at about 0.61x and 0.84x. onnxruntime’s MLAS convolution kernels sit at the FMA-port peak, and a custom AVX2 Winograd path narrowed the gap without closing it. On GPU, routing the same convolutions through cuDNN takes SCRFD from 14.8 ms to 6.4 ms, which lands at torch-cuDNN parity.

voice-detect.cpp has a memory result instead. A WeSpeaker verification peaks at about 62 MB in our binary against about 334 MB for the CPU-only Python, torch and onnxruntime path, roughly 5.4x lower, with an identical verdict and embedding cosine 1.000000. End to end on CPU the two land within 10 to 15% of each other, trading the lead by model and thread count, and on GPU the conv encoders match the reference.

For a biometric pipeline we would rather have the exact match than the speed. An embedding that differs in the fourth decimal place changes verification decisions at a threshold, and every enrolled template in a deployment would have to be recomputed. Matching insightface exactly is what lets somebody swap the backend out without re-enrolling their users.

How we do it

Every port follows the same four steps.

Convert the weights first, into one GGUF with the tokenizer, the vocabulary and any auxiliary model embedded, so that deploying the model is copying a file.

Port the graph second, and check it component by component against reference tensors dumped from the original implementation. depth-anything.cpp has 37 ctest cases covering preprocessing, backbone, attention, the DPT head, depth, pose, the ray head, the ray to pose solver and the exporters. parakeet.cpp checks transcript agreement with NeMo at WER 0. face-detect.cpp checks box and landmark distance in pixels, and embedding cosine. Skip this step and you find out the port is wrong months later, from a user, on a model you had stopped thinking about.

Optimize third, with a profiler, and only once the parity checks pass. In parakeet.cpp the win was caching a prediction-network LSTM forward pass that was 97% of transducer decode time and mostly redundant. In depth-anything.cpp it was the two positional embeddings above. Neither was a kernel rewrite, and neither would have turned up without a working baseline to profile.

Expose a flat C ABI last. LocalAI dlopens the shared library through purego and calls that ABI directly, so there is no subprocess, no gRPC hop to a Python server, and no interpreter in the serving path.

What it takes to maintain

Each engine is its own repository with its own CI, benchmark suite, GGUF conversion script and parity baselines, and upstream keeps releasing checkpoints that need converter work.

GPU kernels are the weak spot. ggml’s generic CUDA convolution and attention kernels trail NVIDIA’s tuned cuDNN on the conv-heavy models, which is why face-detect.cpp needs an explicit cuDNN path to reach parity, and why parakeet.cpp’s GPU margin over NeMo is a median 1.25x while its CPU margin is wider.

It also does not scale to everything. llama.cpp, vLLM, whisper.cpp, MLX and diffusers stay wrapped, because those projects are large, fast-moving and already good at what they do. We write an engine when a model has no C++ implementation, when the Python dependency is heavier than the model itself, or when the thing we need does not exist yet. The rest we install like everybody else.

One thing that confuses people reading the tree for the first time: LocalAI’s own core is Go, and each backend is written in whatever its model’s ecosystem needs, which is why there is C++ sitting next to Python in the same repository.

Every engine above keeps its benchmark suite, its parity checks and its methodology in its own repository, including the runs that did not work out. The full list is the “Backends built by us” table in the LocalAI README.

The Daily Front Page 19 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — The Map’s Quality Bar
article

Why Book Corners won't sync contributions back to OpenStreetMap

by pizzaiolo·▲ 145 points·92 comments·andreagrandi.it ↗
After researching the operational and community requirements, I decided not to implement it.

Why Book Corners won't sync contributions back to OpenStreetMap

I wanted Book Corners to contribute newly submitted public bookcases back to OpenStreetMap. After researching the operational and community requirements, I decided not to implement it.

A feature that sounded obviously good

When I introduced Book Corners, I explained that much of its initial data came from OpenStreetMap. OSM gave the project a useful starting point, with thousands of public bookcases already mapped around the world.

Book Corners also accepts new libraries directly from its users. People can submit a location and a photo, and the contribution becomes public after moderation. It seemed only fair that, when one of those submissions was missing from OSM, Book Corners should be able to contribute it back.

The idea was not to create an uncontrolled background synchronisation process. The workflow I had in mind was deliberately cautious:

  • The person submitting the library would explicitly allow the contribution.
  • An administrator would review the library first.
  • Book Corners would search OSM for possible duplicates.
  • The administrator would preview the exact data being sent.
  • Nothing would be written until the administrator confirmed it.

From a software-development perspective, this looked like a manageable integration: add consent, track contribution state, build a preview, authenticate with OSM, and create the new feature through its API.

The code was not the difficult part.

Contributing data is not just an API call

Once I started researching the implementation properly, I discovered that writing to the API was only a small part of the work.

Because the information would come from the Book Corners database, OSM could consider it an external-data import. Because software would prepare and submit the changes, it could also fall under the rules for script-assisted or automated edits, even though an administrator would review each individual library.

Following the conservative interpretation of the OSM Import Guidelines and the Automated Edits code of conduct would require more than a dedicated account and an OAuth token.

Before the first production contribution, I would need to:

  • Create and maintain a dedicated OSM import account.
  • Publish a detailed import plan on the OSM Wiki.
  • Document the data source, licensing, field mapping, duplicate detection, software, quality checks, changeset policy, and rollback procedure.
  • Open a proposal on the OSM Community Forum.
  • Contact the relevant local communities affected by the contributions.
  • Wait through the review period and resolve any concerns.
  • Keep permanent links between the import account, plan, discussions, and changesets.
  • Maintain a contact and opt-out route for future questions or complaints.

There are also important licensing questions. A user’s permission to send a library to OSM is not automatically the same as having a sufficiently clear right to release that factual information under terms compatible with OSM. The user-facing explanation and consent would need to cover that distinction, including confirming that the information was not copied from an incompatible source.

These requirements are not a one-time form to complete and forget. They create an ongoing responsibility around the account, the documented process, community feedback, failures, and potential reversions.

I understand why these rules exist

OpenStreetMap is a shared global database. A bad import can create thousands of duplicates, overwrite better local knowledge, or introduce errors that are difficult to remove once other people have edited the same objects.

From that perspective, requiring documentation, licensing clarity, duplicate handling, accountable operators, and community discussion is reasonable. The OSM community has to protect the quality of the map, and good intentions do not guarantee good data.

Book Corners itself benefited from that data quality. It would be hypocritical to expect OSM to accept changes from an external service without safeguards.

At the same time, the process has a real cost. It asks a small project to become not only an API client, but also the operator of a documented import programme. That may be appropriate for organisations importing large datasets, but it is a considerable commitment for a low-volume feature whose only purpose was to contribute a few carefully reviewed public bookcases back to the commons.

The operational work outweighs the value

Book Corners has a simple purpose: help people discover little free libraries and share new ones with others.

Operating an OSM contribution pipeline is not central to that purpose. It would add credentials, production safeguards, audit and reconciliation code, community processes, licensing work, and a long-term support obligation. Every part is individually defensible, but together they make this a much larger feature than I initially intended.

There is also an opportunity cost. Time spent operating this integration is time not spent improving library discovery, moderation, photos, accessibility, translations, or the mobile experience. Those improvements directly help Book Corners users and are much easier for a small project to sustain.

I started from the feeling that contributing back was simply the nice and fair thing to do. After investigating it, I no longer think goodwill alone is enough reason to accept an open-ended operational responsibility.

The decision

I have decided to suspend the OSM write-back implementation indefinitely.

Book Corners will continue to acknowledge OpenStreetMap as the source of records imported from it, and OSM-imported libraries will never be submitted back as if they were new. But libraries contributed directly to Book Corners will remain in Book Corners; the service will not automatically or manually create matching OSM objects.

Nothing currently writes from Book Corners to production OSM, so suspending the work does not require disabling or migrating an existing integration.

I may reconsider the decision if a genuinely lightweight workflow becomes available, or if the scale and value of Book Corners contributions eventually justify the process. Another possibility would be a user-driven workflow that opens a proposed feature in an existing OSM editor, although that would still need to be discussed with the community rather than treated as a way around the rules.

For now, the responsible choice is not to build and operate a feature I am not confident I can support properly.

Sometimes the right feature is no feature

It is easy to think of implementation decisions as purely technical: can the API do it, can the application authenticate, and can the code avoid duplicates?

This experience was a reminder that external integrations also come with organisational and social contracts. Sometimes those contracts are more expensive than the code. Discovering that before deployment is useful, even when the result is disappointing.

I still believe contributing data back to shared open projects is valuable. I also understand why OSM protects its database so carefully. But for Book Corners, at its current scale, the balance between benefit and responsibility does not work.

So this is one feature I am choosing not to ship.

The Daily Front Page 20 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — The Backup Works Overnight
article

Massively Parallel Postgres Backups

by ksec·▲ 103 points·12 comments·planetscale.com ↗
Every 12 hours, a backup system must turn the entire state of a busy database into a consistent, encrypted snapshot.

Every 12 hours, a backup system must turn the entire state of a busy database into a consistent, encrypted snapshot, with no impact to production queries.

Such backups are crucially important and simultaneously something that most engineers would rather never have to think about.

Just make the backup work.

Our goal at PlanetScale is to make taking, scheduling, managing, and restoring Postgres and MySQL backups effortless.

Though this is what our customers experience from the outside, achieving this internally requires careful orchestration of cloud infrastructure and DBMS tooling.

It's especially interesting to look at backups for sharded databases, which requires spinning up backup-specific nodes, pulling data from object storage, and WAL replay, all with massive parallelism. These techniques allow for petabyte-scale databases to be backed up in hours, at rates over 50 GB/s.

Here we take a behind-the-curtain look at how to effectively back up a sharded database with massive parallelism.

The backup lifecycle

Here is an example of a Neki (sharded Postgres) database with 8 shards, happily handling hundreds of thousands of queries per second of production traffic.

If sharding is a new concept to you, check out our recent post Making 768 servers look like 1 on how it all works. The first step in taking a backup depends on whether this is the very first backup or if we've taken one previously. We'll start with the steady-state case, which assumes a prior healthy backup already captured and stored in Amazon S3 (or similar object storage in other clouds).

Since a sharded Postgres database is many individual primary Postgres servers working together, we use regular Postgres backups as the building block for large-scale backups with Neki.

There are three ways to take backups in Postgres, which we've written about in detail previously. The best of the three, and the one that Neki uses, is combining filesystem backups with the replay of archived Write-Ahead Log (WAL). To summarize, the steps for this are:

  1. Begin a full backup of the on-disk Postgres database files at time T1
  2. The backup completes at time T2; between T1 and T2, rows on disk may have been mutated
  3. Replay the write-ahead log modifications between T1 and T2 to correct mutated data
  4. Store the final result in a distinct storage location like Amazon S3

We could complete these steps directly on the primary, or perhaps one of the traffic-serving replicas. The problem is that this task utilizes a significant amount of IOPS and compute, especially for a large database. Our goal should be to minimize the impact a backup will have on production query serving.

Because of this, we take a different approach. We spin up a brand new set of EC2 instances, one per shard, to manage the backups on.

These new instances will be responsible for the majority of the work in the backup. Because we operate these sharded databases in clouds like AWS and GCP, dynamically spinning up tens or hundreds of instances for short time slices to complete backups is achievable. It adds a small amount of cost, but is worth it to minimize negative production impact.

Reusing old backups

The next step is restoring the most recent backup to each shard. Prior backups are stored in object storage. Here we will use Amazon S3 as the example, but the same applies to other clouds (like GCS in Google Cloud). These are streamed directly from here.

This approach requires temporary compute and transfers each shard's data out of and back into object storage. We accept that cost for two important reasons:

  • Only recent WAL comes from the primary, minimizing production impact
  • Every cycle proves the previous backup can be restored and replayed

Once all the copying completes, these 8 servers have the exact state of each of the 8 shards from the previous backup, 12 hours ago.

Replaying the WAL

We now must catch up each shard's old backup to match the present state of the database. This requires replaying all changes from the Postgres Write-Ahead Log between 12 hours ago and now.

A naïve approach would be to pull the WAL directly from the primary. This is problematic for several reasons:

  1. This would have nontrivial production impact. Replaying 12 hours of WAL on a high-churn database could take tens of minutes, or even an hour+.
  2. Because we don't want too much server storage consumed by WAL, we continuously archive it to S3. Thus, we likely don't even have the full past 12 hours of WAL resident on the primary node.

On PlanetScale, all Postgres databases use wal-g to continuously archive their write-ahead logs. A sharded Neki database is similar, except each shard has a distinct WAL archive stream.

What if we streamed from there instead?

This almost solves the problem. The remaining problem is that Postgres archives WAL only after a segment is complete. If write traffic doesn't fill a segment sooner, our five-minute archive_timeout setting forces a segment switch so it can be archived. This means the newest changes may not have reached S3 yet. Thus, we take a hybrid approach. The system uses S3 for the majority of the replay, then streams the last ~few minutes of changes directly from the primary. Ideally, this last step takes on the order of seconds, not minutes or hours.

Putting this step together, back in our sharded database:

Completing the cycle

When every node has caught up replication to time T, where T is the timestamp we will log for the backup time, we stop WAL replication, freezing the point-in-time of the backup. Time T is saved to ensure we know the precise time, down to the second, included in this backup. The full backup is now consistent, with no smeared data. The final step is to encrypt and send these backups off to a new S3 bucket for safe keeping.

When complete, the backup nodes have served their purpose, and are decommissioned.

The initial backup

The cycle just described assumed we had a good backup from 12 hours prior to start with. In the steady-state this is true, but not for a brand new database.

Within 12 hours of a new database creation, pg_basebackup is used to seed a backup node for each shard.

pg_basebackup is a built-in PostgreSQL client utility that takes a physical backup of the entire database cluster: the data directory, tablespaces, and configuration needed for recovery.

Why not upload the pg_basebackup output directly? We use it only to seed the temporary backup nodes. The durable backup is created with wal-g, keeping the format and restore process identical for initial and steady-state backups.

The steps for this first one are similar, but slightly different than the steady-state:

  1. Spin up one new EC2 instance per shard.
  2. Run pg_basebackup on each instance to copy data from its primary.
  3. Configure each instance to replicate from its primary.
  4. Replay WAL until every instance catches up.
  5. Stop replication at time T.
  6. Use wal-g to format, encrypt, and upload each backup to S3.

Once this exists, all future backups happen with the restore -> catch up -> save flow.

Need for speed

Part of the reason we do so much parallelism is due to the nature of sharding. Whether it's 4 shards or 400, since each shard contains its own Postgres primary, we may as well take a rock-solid system (regular Postgres backups) and do it over and over on each shard.

A side-effect of this is that backups are VERY fast, even for large databases.

For every backup, the data transfer steps are:

  1. Restore old backup from S3
  2. Catch up the backup using a hybrid of S3 + the primary
  3. Send the new file back to S3

Consider what it would take to complete this backup cycle on an unsharded 32 terabyte database. Backups on PlanetScale are compressed and stored with encryption at rest in S3. We'll assume that backups for this 32 terabyte database compress down to 20 terabytes. Therefore, we have

  1. 20,000 GB transfer from S3
  2. Catch up (Ex: 20 GB, compressed to 10 GB)
  3. 20,010 GB back to S3

This equates to a total transfer volume of ~40,030 GB. If our various nodes and interconnects can sustain a 500 MBps transfer rate, this means the backup would take ~22 hours. Crucially, this means that if we want twice-daily backups, multiple backups would overlap. This would prevent us from meeting our recovery point objective (RPO).

This same database in Neki, spread over 8 shards storing ~4 TB each, performs quite differently. In total, we need to transfer, catch up, and store the same 40,030 GB. But if we can do so across 8 distinct backup nodes in parallel, each capable of 500 MBps, we reduce the total time to ~2.8 hours.

This gets better the more shards you add. The same data spread across 32 shards would back up in 42 minutes. Backup speed scales well. 100 terabytes on 100 shards backs up at ~the same speed as 1 terabyte on a single shard.

What are backups used for?

One reason to take backups is data safety. In the case of accidental data deletion or a one-in-a-million database disaster, backups (and the WAL) are an essential fallback.

But at PlanetScale, backups are also a core part of everyday database operations. For Metal databases specifically (ones with Local NVMe), backups are also used every time the database is resized.

Resizing a Metal database requires:

  1. For every existing node in the sharded database, spin up a brand-new EC2 instance at the new size. In a database with 8 shards each with a primary and 2 replicas, we may currently be running it on 8 x 3 = 24 i8g.xlarge nodes. While running, we initialize 24 additional i8g.2xlarges to double the compute capacity.
  2. Each of the 24 new nodes pulls down a copy of the most recent backup from S3, and begins catching up to the present state of the database via the archived WAL.
  3. All nodes are initialized as standbys of the original primary, and complete final replication catch-up.
  4. When all nodes are synchronized with the primary, a switchover is made from the old i8g.xlarge primary to a selected new i8g.2xlarge primary.
  5. The smaller nodes are decommissioned, leaving only the larger primary and replicas.

We've now completed a full resize across all shards. Backups are used to facilitate the creation / catch-up of the new nodes. This process can take anywhere from minutes to hours, depending on how large the backups are and how much WAL there is to replay.

Backups are also used when a node needs to be replaced due to unexpected failure. If your average server lifetime is 5 years, you'll rarely notice a failure on a small database with a single primary. For a database with hundreds of shards, each with multiple replicas, the statistical likelihood for node failure in a given week or month increases significantly. When we see an individual node fail (say, a single replica in a shard), the process for replacement looks like:

  1. Initialize a new cloud instance of the same size as the previously failed one.
  2. Use the process described earlier to restore a recent back-up to it, catch up the WAL.
  3. Initialize as a follower of the original primary, synchronize data.
  4. This new node can now actively serve read queries and/or serve as a new primary during a switchover or failover operation.

What about MySQL?

Everything here has been about how we complete sharded backups and resizes on Postgres databases, powered by Neki. PlanetScale also operates large-scale sharded MySQL databases, powered by Vitess as our query routing / sharding layer.

The process for backing up and resizing these databases is quite similar! We have a whole separate blog on how this works, but the main difference is that we use VTBackup instead of the Postgres backup builtins, we use the MySQL binary log replication instead of WAL, and replication catchup is done from the primary instead of a hybrid between S3 and primary.

Make it boring

Ultimately, we want all this to be transparent to you. Taking a backup should be as easy as an automated schedule, or clicking a button. Resizing a database should be a single click or API call.

However, we also have a deep appreciation for the finer details of database operations. By taking a journey through the lifecycle of backups, we hope you have a new-found appreciation for how incredible database orchestration is.

If you find this fascinating, we're always looking for talented database engineers.

The Daily Front Page 21 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — What Email Authentication Cannot Do
article

What DMARC Protects You From, and What It Does Not

by adulion·▲ 131 points·30 comments·senderledger.com ↗
DMARC checks one narrow thing.

Ask five people what DMARC does and you will get five answers: it stops phishing, it kills spam, it proves an email is safe. None of that is quite right. DMARC (the current spec is RFC 9989) checks one narrow thing: did the owner of the domain shown in the From line actually authorise this message, provable through SPF or DKIM?

It is a good question to answer. It is also a lot smaller than the reputation DMARC has built up. Reach p=reject thinking you are now phishing-proof and you will quietly drop the controls that handle everything DMARC never touched in the first place.

How email proves who sent it

Two building blocks sit underneath DMARC. SPF is a list a domain publishes of the servers allowed to send mail on its behalf; the receiver checks whether the mail actually arrived from one of them. DKIM adds a cryptographic signature to the message, which lets the receiver confirm it came from the signing domain and was not altered along the way. DMARC then pins both of those to the address you see in the From line.

Here is the part that trips people up. An email actually has two "from" addresses. There is the envelope address, which works like the address on a posted parcel: mail servers use it to route the message and then throw it away, so you never see it. And there is the visible From your mail app displays, the "Your Bank <alerts@your-bank.com>" you read at the top of the message. Nothing forces those two to match. That gap is the whole game: an attacker can show your bank in the visible From while the envelope quietly points at their own server.

SPF looks at the envelope address. DKIM's signature carries a domain of its own. DMARC's job is to take whichever of those actually authenticated and check it against the From line you can see, because that is the address a human trusts.

What these actually look like

All three live as text records in your domain's DNS, the same place your website's address is configured. You do not need to memorise the syntax; it helps to recognise the shape.

An SPF record lists who is allowed to send. This one authorises Google Workspace and a marketing tool, and says anything else should be treated as suspicious:

example.com.  TXT  "v=spf1 include:_spf.google.com include:sendgrid.net -all"

The include: entries pull in each provider's own list of servers, and -all means "if it is not on those lists, it is not us".

A DKIM record publishes the public half of the signing key, so receivers can check the signature on your mail. The long string is the key itself:

selector1._domainkey.example.com.  TXT  "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQ...AB"

Finally the DMARC record ties it together and tells receivers what to do when a message fails. This one asks them to reject failures and to send you reports:

_dmarc.example.com.  TXT  "v=DMARC1; p=reject; rua=mailto:reports@example.com"

p=reject is the strict setting: fail authentication and the mail gets turned away. rua= is simply where your aggregate reports land.

How a pass is actually decided

DMARC sits on top of SPF and DKIM, and it evaluates them independently. There are two separate ways a message can pass: SPF passes for the hidden envelope domain and that domain aligns with the visible From domain, or a DKIM signature validates and its signing domain aligns with the visible From domain. If either aligned path succeeds, DMARC passes. If neither does, it fails. "Aligns" simply means the two domains match closely enough to count as the same organisation.

flowchart TD
  A[Incoming email] --> S{SPF authenticates and aligns with From domain?}
  S -->|yes| P([DMARC pass])
  S -->|no| D{DKIM validates and aligns with From domain?}
  D -->|yes| P
  D -->|no| F([DMARC fail])

DMARC passes if either SPF or DKIM both authenticates and aligns with the visible From domain. It fails only when neither does.

A quick word on what "align" means, because it catches people out. DMARC has two modes. In relaxed mode (the default) the two domains only need to share the same organisational domain, so a DKIM signature from mail.example.com aligns with a From of example.com. In strict mode they must be identical, and that same signature would fail. If you have seen "SPF pass, DMARC fail" and wondered how both can be true at once, it normally means SPF confirmed the hidden envelope domain successfully, but that domain did not match the visible From address closely enough to align. Strict versus relaxed mode then decides whether closely related domains count as the same.

Notice what the test never looks at: the words in the message, the links, the attachments, whether the sender means you harm. It only asks where the mail came from.

Where DMARC helps

The case DMARC was built for is exact-domain spoofing. If someone places your-bank.com in the From address without producing an aligned SPF or DKIM result, a policy of p=reject asks participating receivers to reject the message, although the receiver retains final control over its disposition and may apply local policy or exceptions. This is real protection, and for this specific attack it is strong. It also gives you something you did not have before: aggregate reports (defined in RFC 9990) revealing many of the systems participating receivers have observed sending as your domain, which is how you find the forgotten marketing tool or misconfigured relay before an attacker does.

Where it falls short

Lookalike domains. An attacker registers your-bank-support.com, sets up valid SPF and DKIM, and passes DMARC on their own domain. Your policy has no reach over a domain you do not own. To every receiver, that mail is fully authenticated.

Display-name impersonation. The name shows "Your Bank Security"; the actual address behind it is alerts@some-unrelated-domain.com. DMARC only ever checks the domain. It has nothing to say about the friendly name, which is the bit most people actually read, so this sails straight through a passing check.

Compromised mailboxes. When an attacker signs into a real account through phished credentials and sends through the legitimate provider, the message will usually pass SPF, DKIM and DMARC because, in the protocol's terms, it was sent through authorised infrastructure. Authentication cannot tell a real user apart from an attacker controlling that user's account.

Authenticated but malicious domains. Anyone can register a domain and configure flawless authentication; senders of unwanted mail do this routinely. A pass on totally-legit-invoices.com confirms the owner authorised the mail. It says nothing about whether the owner is honest.

Spam and inbox placement. DMARC is not a spam filter and does not decide whether mail reaches the inbox. Filters may weigh it as one input, but authenticated spam is still spam, and placement is a separate system with its own logic.

Forwarding and mailing lists. Legitimate intermediaries can break authentication. Forwarding commonly breaks SPF because the forwarding server is not authorised by the original sender's domain, while mailing lists may modify the subject or body and invalidate DKIM. A legitimate message can therefore fail DMARC even though nobody is impersonating the sender. This is one reason enforcement should follow careful monitoring and remediation rather than a blind switch to p=reject.

Authentication is not trust

So a DMARC pass tells you one thing and one thing only: the domain in the From line authorised the mail, and SPF or DKIM proves it. Useful. It shuts down exact-domain spoofing and shows you who is sending as you. But whether the message is honest, whether it is safe to click, whether the account behind it has been hijacked, DMARC has no opinion on any of that. When a vendor tells you DMARC "stops phishing", that is the gap they are papering over.

The Daily Front Page 22 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — The Repair Bench
article

Replacing the Kobo Libra H2O Battery

by austinallegro·▲ 69 points·24 comments·ei3lh.eu ↗
I figured the battery was likely on the way out.

OEM Kobo Libra H2O Battery (Left) – Ali Express Battery (Right)

I’ve had my trusty (refurbished) Kobo Libra H2O for about 8627 years and recently it started to act up a bit. It would charge to 100% battery capacity and within an hour or so the device would have an empty tank, begging for a charge again.

I figured the battery was likely on the way out, yet when I took a look at search results for replacing the Kobo Libra H2O battery, I became slightly daunted by the fact it would appear to be a trickier task than I first envisaged.

It wasn’t that replacing the battery was a particularly risky or complex task. It’s not, so long as you can use a soldering iron to remove and reattach the Lithium Ion battery, and even then it’s only two blobs of solder (plus an outer shell of glue on each) that you need to work with.

The problem seemed to be in tracking down a suitable replacement battery, and at the same time, finding a replacement that didn’t cost a fortune. I confess at one stage I nearly gave up and looked for a new eReader.

Saved by Ali Express

After a good while checking search results, I stumbled upon a reddit post which detailed the battery I would need to search for, and more importantly, said battery could be had for a pittance on Ali Express.

Indeed, a few moments later I was able to pin down a suitable replacement battery for my Kobo. In fact, given how large a trove Ali Express is, I was surprised to find only two search results appeared for the battery.

I’ve popped a link to the exact battery I purchased here for you (alternatively, search for: PR-158098N Battery For Kobo).

The shipping arrival date said it would get here in January 2026! Amazingly, just a couple of weeks after placing the order in early November 2025, it arrived.

Replacing the Kobo Libra H2O Battery

The battery arrived safely and in a sturdy cardboard box. Packed in were a couple of 3M adhesive strips to situate the battery on the main board, and a pack of pry tools. I have bags upon bags of these so just put them in the pile already gathered in my tool sort box.

The contents of the Ali Express PR-158098N battery I purchased. November 2025.

The process is fairly straight-forward, which I will outline as follows:

  1. Use the pry tools to pry and unclip the back case from the device. I used the large, ridged, guitar pick tool. Wedge open a small piece of the casing and then run the pick around the line of the case and it should all unclip fairly quickly and easily.

    The battery is fairly malleable but do be careful not to squish and pull and prod at it too much!

  2. With the back case removed, take a soldering iron (heated to around 350 degrees Celcius) and detach the positive and negative wires. Two things to note here a) the solder blobs have a thin glue shell coating over them, so heat with the iron and use a pair of tweezers or similar to scrape away the glue layer, you can then melt the solder easily, and b) remember the polarity when you install the new battery!

  3. Install the new battery, noting the correct polarity. I made sure to strip the new wires a little further back and then tinned them prior to seating them in their final positions.

    Once installed, plug in your Micro USB charging cable and check to see does the device power on and if it is accepting a charge.

  4. Once you have confirmed it is successfully powering on, charging and holding a charge, you can start to button it all back up!

    Pop the two strips of adhesive on to the back of the new battery and situate it on the main board. I should add, I did not remove the existing adhesive as I felt it would be beneficial to leave it in place in case the provided adhesive wasn’t as good as the OEM.

    Snap the rear case back on, press the power button and all being well you should have your Kobo Libra H2O back up and running with a fresh new battery, ready for many more books to devour!

Hopefully the battery will prove to be worth the time and trouble and provide me with many more hours (nay years, or is that a stretch to far?) of reading pleasure.

I hope this little guide proves helpful for someone else who stumbles upon it. These days we are far too quick to jump on board the obsolesence train. I think that eReader technology hasn’t made big enough leaps to justify upgrading just yet – even the new colour eReaders, which is why I decided to give my Kobo a new life with a fresh battery.

Fingers crossed it doesn’t fail on me a few days from now but so far it is looking good, is charging rapidly and more importantly is holding that charge (for now). Best of luck!

73.

The Daily Front Page 23 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — The Play Page
show hn

Show HN: ssh ssh.place

by jeninh·▲ 174 points·108 comments·ssh.place ↗

One canvas. Everyone draws on it over SSH.

No account, no install · 200×60 cells · one placement every 15s

Draw on it:

ssh ssh.place

Any SSH key works. There is nothing to sign up for.

The current ssh.place canvas

22 online · 11509 of 12000 cells drawn

How it works

  • Move the cursor with the arrow keys, wasd or hjkl
  • The canvas is wider than your terminal, so scroll to pan around. shift+/ jumps a whole screen.
  • Pick a color with 0 to 9. tab cycles through all 16.
  • space puts down a solid block of that color
  • Now wait 15 seconds, same as everyone else

This canvas is color only. The server turns down anything with a character in it, so you cannot write text here. Draw something instead.

Your cooldown is tied to your SSH key, so reconnecting will not reset it. This page only reads the canvas. It changes over SSH and nowhere else.

The Daily Front Page 24 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — The Back Page: Old Systems, Small Delays
article

The myth of Snow Leopard

by speckx·▲ 122 points·107 comments·rubenerd.au ↗

The myth of Snow Leopard

Snow Leopard was a version of Mac OS X released in 2010. It was billed by Apple as having “0 new features”, with a focus on refining the system, improving efficiency, and fixing bugs. Those of us using Macs at the time welcomed the news after living with updates that seemingly broke as many things as they introduced with each release.

This idea is so powerful—and so longed for—that it’s escaped containment among the Apple crowd. I’ve seen everything from Linux distro to phone updates referred to as Snow Leopard releases, when their vendors cite stability and bug fixes over new features. Likewise, people plead with their vendors for a Snow Leopard release when they feel quality has slipped.

The reality was a bit different. As I wrote at the time:

This could be the first time I’ve ever downgraded an Apple OS.

As we speak I’m downgrading the Snow Leopard partition on my trusty old Core Duo 2006 MacBook Pro back to Leopard (and while I’m at it, I’m finally getting around to upgrading the FreeBSD partition to 8.0!). I kept waiting for updates to fix the severe stability problems in the Finder, my FireWire 800 ExpressCard and my iMovie HD plugins, but I’ve decided to give up for now.

This was putting it mildly. When I tried it again a few months later, I still had so many problems that I downgraded again, then leapfrogged it for Lion when it was released in 2011. Jeff Johnson has a great post discussing all the problems Snow Leopard introduced and had to have patched. It was a mess.

Snow Leopard and Leopard.

Still, whether Snow Leopard really was this bastion of stability and polish, the myth surrounding its development and stated purpose obviously resonates today. People invoke its memory because they’re broadly craving stability and quality of life improvements, something almost everyone has wilfully discarded as they chase the next rung of enshittification.

Apple’s marketing team hit on something so popular that it has staying power sixteen years later.

The Daily Front Page 25 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — Also on the Front Page
The Daily Front Page 26 of 27
Monday, August 3, 2026 The Daily Front No. #260803 — Colophon

That's the Front for Today

Issue No. #260803 — Monday, August 3, 2026 — went to press 2026-08-04 at 08:17 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 Monday, August 3, 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, chose the highlights, and briefed the cover illustrator — 33 model calls and 212k 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:

A dramatic classical newspaper-cover illustration of a lone software engineer at a wooden drafting table in a midnight workshop, carefully copying glowing lines of code from a towering, humming mechanical oracle onto paper by hand; around the room, tangled cables, open circuit boards, a tiny bonsai tree, a film reel, and mathematical diagrams suggest the day’s technology and culture stories. A broad window reveals distant wind turbines and a city at dawn. Rich ink-and-watercolor texture, strong chiaroscuro, restrained steel-blue and amber palette, no text, no letters, no logos.

Render the entire cover as a direct frontal, childlike wax-crayon drawing on deep midnight construction paper: use heavy pressure marks, chunky contouring, scraped highlights, and boldly unexpected saturated cobalt, electric violet, acid green, hot orange, and cyan, with the lone software engineer, wooden drafting table, glowing mechanical oracle, handwritten code-copying action, workshop clutter, bonsai, film reel, mathematical diagrams, and dawn window scene all clearly preserved; make the glow and dawn emerge through rubbed-away paper and vivid crayon color rather than ink, watercolor, or chiaroscuro, with no legible writing, letters, logos, or cover text.

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

Production Ledger

StageModelCallsTokens InTokens Out
extractgpt-5.6-luna 30 137,006 47,238
layoutgpt-5.6-terra 1 18,608 2,398
covergpt-5.6-luna 1 328 212
covergpt-image-2 1 268 5,488

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. Don't be a meat proxy by ngruhn — gruhn.me·HN discussion ↗
  2. Prevent cognitive debt by manually retyping LLM-generated code by mpweiher — ankursethi.com·HN discussion ↗
  3. SQLite Critical CVEs or LLM Slop? by ymir_e — research.jfrog.com·HN discussion ↗
  4. LLMs reward expertise by MaxMussio — seangoedecke.com·HN discussion ↗
  5. Ten advances in mathematics and theoretical computer science by milkshakes — openai.com·HN discussion ↗
  6. Devtools must be open source by bryanmikaelian — blog.exe.dev·HN discussion ↗
  7. Bonsai: Janestreet's UI Library by KolmogorovComp — github.com·HN discussion ↗
  8. AirLLM 70B inference with single 4GB GPU by Anon84 — github.com·HN discussion ↗
  9. MiniMax H3 Day-0 Support in ComfyUI: Open Weights, Native Audio, and 2K Video by vblanco — blog.comfy.org·HN discussion ↗
  10. How Hollywood stopped making movies in Hollywood by speckx — statsignificant.com·HN discussion ↗
  11. Andy Pavlo joins ClickHouse to establish ClickHouse Labs by nikolay_sivko — clickhouse.com·HN discussion ↗
  12. Rust project goals: Immobile types and guaranteed destructors by paavohtl — github.com·HN discussion ↗
  13. Decades-old fish sauce at abandoned factory in Canada finally being removed by ohjeez — defector.com·HN discussion ↗
  14. Smaller, faster, safer: running Kimi and GLM at scale by ascorbic — blog.cloudflare.com·HN discussion ↗
  15. CP/M-386 – CP/M for 386 protected mode, derived from CP/M‑68K by TMWNN — github.com·HN discussion ↗
  16. More German than many Germans by mertbio — mertbulan.com·HN discussion ↗
  17. Why we write our own C and C++ inference engines by eatonphil — localai.io·HN discussion ↗
  18. Why Book Corners won't sync contributions back to OpenStreetMap by pizzaiolo — andreagrandi.it·HN discussion ↗
  19. Massively Parallel Postgres Backups by ksec — planetscale.com·HN discussion ↗
  20. What DMARC Protects You From, and What It Does Not by adulion — senderledger.com·HN discussion ↗
  21. Replacing the Kobo Libra H2O Battery by austinallegro — ei3lh.eu·HN discussion ↗
  22. Show HN: ssh ssh.place by jeninh — ssh.place·HN discussion ↗
  23. The myth of Snow Leopard by speckx — rubenerd.au·HN discussion ↗
  24. Qwen3.8-Max: A New Bar for Coding and Cowork by ai2027 — qwen.ai·HN discussion ↗
  25. Launch HN: Hoplite (YC S26) – Effortlessly deploy cloud coding agents by BenceRed — hoplite.sh·HN discussion ↗
  26. Wind and solar overtake fossil fuels in Germany for the first time by just_some_user — intellinews.com·HN discussion ↗
  27. Show HN: Isopolis – Isometric pixel map of SF by nuwandavek — sf.isopolis.city·HN discussion ↗
  28. Show HN: A Handwritten Blogging Platform by emilesilvis — handwritten.blog·HN discussion ↗
  29. Celebrating 45 Years of Kermit with the First New C-Kermit Release in 15 Years by roryirvine — changelog.complete.org·HN discussion ↗
  30. 200 Milliseconds by dimitarpanov — 200ms.thenodebook.com·HN discussion ↗

Browse all issues in the archive →