- ↔
- →
- October 27, 2026
-
🔗 brettcannon/cpython-wasi-build CPython 3.15.2 w/ WASI SDK 33 release
Modernize the release workflow
Old builds are being kept for now as a transition
-
🔗 brettcannon/cpython-wasi-build CPython 3.14.10 w/ WASI SDK 24 release
Modernize the release workflow
Old builds are being kept for now as a transition
-
🔗 anthropics/claude-code v2.1.312 release
What's changed
- Added
oidc.user_id_claimto the Claude apps gateway, to identify people by an id_token claim other thansub, such as Microsoft Entra ID'soid - Added click to send: in fullscreen, clicking the "to send now" hint under a queued message sends it right away, as its key does
- Fixed managed settings and organization policy not being fetched for the rest of the session after signing in from the VS Code extension
- Fixed Claude overwriting a very large CLAUDE.md, rules file or @-included file in a subdirectory after seeing only its start; Write now asks Claude to read it all or edit in place
- Fixed per-directory and
paths:skills not being found after a Bashcddeeper into a git repository - Fixed a rare case where the first reply after resuming a session in the terminal could be missing the next time the session was resumed
- Fixed a command with an invalid name stopping all commands from loading, which could leave
claude -pwith no output - Fixed the Read tool sometimes failing on PDF pages with "pdftoppm failed: Could not write image" when the clean-up of old session files ran at the same time
- Fixed the spinner, OpenTelemetry
effortvalues and transcripts naming a newly picked effort level during a task before the model applied it; they now show the level in force - Fixed the
/modeland/effortcache warning saying the re-read waits for your next message; a change made while Claude is working can trigger it sooner - Fixed some sessions showing as waiting on you when the last message only mentioned items waiting on you mid-sentence
- Fixed agent view restoring input text on the next launch after it was cleared with Ctrl+C just before exiting
- Fixed agent view reopening in shell mode after exiting with Ctrl+D from an empty
!input - Fixed vim mode
d,candywith agjorgkcount larger than the lines left deleting or copying text; like Vim, they now only move the cursor - Fixed
/verifyshowing a long description meant for Claude in/helpand the/command menu instead of a short one - Improved the prompt's effort indicator: a change made mid-task now says it may wait for your next message, and the note clears when it no longer applies
- Improved WebFetch errors in cloud sessions: a host that does not resolve is now explained as possibly outside the allowed network domains, so Claude names the host to allow
- Changed Bedrock, Vertex, Foundry and Mantle to use the shorter system prompt for model names Claude Code doesn't recognize, such as custom deployment names and inference profile ARNs, even when they front Sonnet or Haiku; set
CLAUDE_CODE_SIMPLE_SYSTEM_PROMPT=0to keep the full prompt - Changed automatic model switches after a flagged message to also cover model names Claude Code doesn't recognize, such as custom deployment names; set
CLAUDE_CODE_DISABLE_REFUSAL_FALLBACK=1to turn them off - Changed usage limit messages to call the 5-hour window the "5-hour limit" instead of the "session limit"
- Changed cloud sessions started from the CLI to get their names and branch names from the server
- Changed prompt and agent hooks to run at most 24 at a time per session, sub-agents included, plus at most 12 that have waited longer than their event's timeout; a
timeoutunder 1 second now counts as 1 second - Changed a subagent's
autoCompactWindowto lower the window set byCLAUDE_CODE_AUTO_COMPACT_WINDOW, where it had no effect before; it still never raises that window - Changed OpenTelemetry
mcp_server.nameto report the real name of fixed-URL remote MCP servers declared by plugins from the official Anthropic marketplace, instead ofcustom - Changed Claude Code to stop sending the
claude_code.safety_eventOpenTelemetry event - [VSCode] Fixed sessions ending on a bare exit code when your organization's settings couldn't be loaded or were refused at startup; the tab now says why and offers Retry or Sign in again
- [VSCode] Changed usage limit resets to show a clock time ("Resets at 3:10 PM") and to say "5-hour limit"
- [Cloud sessions] Added an effort level to the model picker when you create or edit a routine that runs in the cloud
- [Cloud sessions] Added a Bash editor with colors, line numbers and a Copy button to the setup script box in cloud environment settings
- [Cloud sessions] Improved the step shown when Claude adds a repository to a cloud session: opening it now shows a short table of what happened instead of raw JSON
- [Cloud sessions] Fixed resending an unchanged message after a failed send in a cloud session sometimes running it twice
- [Cloud sessions] Fixed a failed cloud environment creation showing its error only as a toast outside the open dialog; it now appears inside the dialog
- [Cloud sessions] Fixed Edit in a routine's menu on the Routines page going to the routine's page without opening its edit dialog
- [Remote Control] Fixed an unarchived Remote Control session showing as working until a computer reconnected; it now shows as idle
- [Claude Tag] Improved Claude Tag's retry notice in Slack to name the model in use, or say rate limits were hit, instead of a generic API error
- [Claude Tag] Fixed a Claude Tag channel's on/off switch and agent settings falling back to workspace defaults when an older private Slack channel goes public and gets a new ID
- [Claude Tag] Fixed Claude in Slack not replying in channels whose environment has network access set to None
- [Claude Tag] Fixed Claude in Slack sometimes posting a file in the wrong thread when it was answering in another thread of the same channel
- [Code Review] Fixed Code Review reviewing an outdated commit, or none at all, when GitHub delivered a push event late; it now reviews the pull request's current commit
- Added
-
🔗 ghostty-org/ghostty v1.4.0 release
v1.4.0
-
🔗 exe.dev Automatic Compaction: How Shelley Keeps Going and Going Without Losing the Plot rss
When it comes to LLMs, context rules everything around us. An agent loop is inherently quadratic: messages accumulate and every iteration you send the full stack of messages to the model. That stack of messages is the context , and it starts with a system prompt, descriptions of the tools, and your instructions. Messages upon messages get added. Tool responses (in other words, the agent reading your source code) usually end up being the majority of the context. This impacts cost (see Expensively Quadratic: the LLM Agent Cost Curve) and quality. You want to give the model just the "right amount" of context, but how?

Compaction is the process of taking your current (long) conversation and rewriting or removing stuff to make it a shorter conversation.
Shelley's approach to compaction is to insert a "nudge" message from the harness at about 200k tokens and to give the model a compaction tool that lets it (a) truncate specific tool outputs and (b) "squish" together sections of history into smaller, rewritten segments (which will then have pointers to the originals). 200k seems like the sweet spot for current frontier models, but we've left the exact number configurable.
The compaction tool requires a few rounds. First, the model gets an "index" so that it can identify the messages by a sequential id. Then, the model suggests messages to collapse or trim. Shelley has a "linter" that verifies that the compaction isn't too big or too little. The model tries again, and usually the second time is just right. After compaction, the conversation continues as it always did, except the squished chunks are shorter, the verbose tool outputs are trimmed, and evidence of the compaction is no longer visible to the LLM.
From a data model perspective, a Shelley conversation has some mutable state (slug name, model choice, current draft) and an append-only log of messages. Compaction is materialized as special "compaction" messages, and the harness, when concatenating all the messages together to send to the LLM, replaces the relevant chunks with their rewrites and trimmed results. If the model ever wants to read something that got compacted away, the data is in SQLite, and Shelley has a skill to hint at the right query. (One of Shelley's principles is the ability to be introspective. I tuned the linter heuristics by having Shelley introspect and backtest its own past conversations.)

This is Shelley's third(!) implementation of compaction. The previous two implementations started a new "generation" of a conversation inside the same conversation, with a brand-new context and a summary (first implementation), and preserving the most recent messages (second implementation). This third implementation keeps it going as one conversation, but the history is somewhat rewritten. I'd love to believe this is our last implementation, but model capabilities have been changing quickly, and I expect there will be more iteration.
From the cost perspective, this is the cost graph for a recent long Opus 5.5 conversation. It adds up to about $25 and has gone through 4 compactions, with the context length capping out at about 200k. The little arrows where the price spiked are $1 cache misses, probably when I stepped away from the computer. (You can get this graph in your Shelley session by clicking on the context length counter.)
Context length and cumulative cost for a long Opus 5.5
conversation, across 4 compactions.We've been rocking this implementation for a few weeks, and we think it works quite well. We've enabled "auto compaction" by default. I used to click on "Compact and Send" every once in a while and look at the context length. Now, I just talk, and talk, and talk, and it's all good. I've also started letting my agentic conversations meander a bit more, do follow-ups and so on.
Tune in next week to hear about switching to asynchronous tool and subagent calls. Or maybe we'll talk more about multiple input modalities!
If you're interested in more of our writing about coding agents:
- The Unreasonable Effectiveness of an LLM Agent Loop with Tool Use
- Expensively Quadratic: the LLM Agent Cost Curve
- The Topology of an LLM Agent Loop With Tool Use
P.S.: Here's a behind-the-scenes look at yak-shaving involved in building the animation above. I built it using Shelley, after having earlier built a bespoke program using Excalidraw, and after adding animations to said bespoke drawing program.
Building
out the animations for this post in Shelley -
🔗 r/Harrogate Is Jennifield Drive quiet? rss
Hi! I'm looking to move to a quiet area in Harrogate. I saw a place near Jennifield Drive (around Lindrick Way), is this street noisy? I would like to avoid cars playing loud music, making loud engine noises, etc. Leeds it's usually like that on some similar streets, that's why I'm asking. Thanks
submitted by /u/moonsailorscout
[link] [comments] -
🔗 backnotprop/plannotator v0.28.33 release
Follow @plannotator on X for updates
Missed recent releases? Release | Highlights
---|---
v0.28.32 | A security update (built on Bun 1.4.4, eMudhra certificates), the Inbox Board, custom Inbox prompts, hover cards for issue and PR links, rich-text Copy
v0.28.31 | An onboarding tour for the Inbox, pinned threads, picture choices in questions, palettes in Inbox Settings, tailnet reviews from the plugin tool
v0.28.30 | An Artifacts view in the Inbox, comments on part of an image, diagrams in code review, Ask AI keeps its conversation in annotate
v0.28.29 | Plan review opens on OpenCode 2, a DOMPurify security update, closing a review stops the agent everywhere
v0.28.27 | Jump to open questions, files side by side or full screen, image zoom in the Inbox, empty To field, text size for plan review and annotate
v0.28.26 | Action items and reply drafts in the Inbox, one decision button for plan review, Enter to save a comment, a custom code font
v0.28.25 | Re-ask open questions, delivery ticks on the list, a count of new messages on the tab, right-click a thread, click Inbox to refresh
v0.28.24 | A new look for the Inbox, Send now, tag agents, comment on an agent's message, much smaller reads for agents, links in HTML pages
v0.28.23 | Inbox replies reach sessions with background subagents, dictated text no longer goes missing, 👍 Looks good reaches the agent, notifications that never fail silently
v0.28.22 | 👍 Looks good, full view for files, one viewer for a thread's images and files, every session prints its URL,PLANNOTATOR_BROWSER=noneopens nothing
v0.28.21 | Message an agent from the Inbox, video attachments, Open in for attachments, Code / Tests / Generated in code review, writes from other websites refused
v0.28.20 | Inbox search (⌘K), real folder names for projects, data files open in the code view, word-only replies leave questions openWhat's New in v0.28.33
A fix for Pi users stuck on 0.28.31. 1 PR.
Plannotator
Pi updates no longer get stuck on 0.28.31
0.28.32 required a newer Node for the Pi extension. On an older Node, npm then kept 0.28.31 without an error, and
plannotator updatestill printed "Pi extension updated." That Node requirement is gone. Instead, Pi shows one warning at start when its runtime does not have the October 2026 TLS fixes (Node 22.23.4, 24.22.1 or 26.12.1). The installer now updates Pi withpi updateand checks the version that Pi actually loads.Smaller changes
- The installer's npm check stops quickly on a broken network. #2233
Install / Update
macOS / Linux:
curl -fsSL https://plannotator.ai/install.sh | bashWindows:
irm https://plannotator.ai/install.ps1 | iexClaude Code Plugin: The plugin and the
plannotatorbinary update separately, so run the install script above as well. In a terminal:claude plugin marketplace update plannotator claude plugin update plannotator@plannotatorThen restart Claude Code. Inside Claude Code, run
/plugin marketplace update plannotator, then open/plugin→ Installed → plannotator → Update now.Pi:
pi update npm:@plannotator/pi-extensionOpenCode: Re-run the install script above. It also clears the OpenCode 2 plugin cache.
What's Changed
- fix(pi): updates never get stuck: drop the Node floor, verify the installed version by @backnotprop in #2233
Community
Full Changelog :
v0.28.32...v0.28.33 -
🔗 backnotprop/plannotator v0.28.32 release
Follow @plannotator on X for updates
Missed recent releases? Release | Highlights
---|---
v0.28.31 | An onboarding tour for the Inbox, pinned threads, picture choices in questions, palettes in Inbox Settings, tailnet reviews from the plugin tool
v0.28.30 | An Artifacts view in the Inbox, comments on part of an image, diagrams in code review, Ask AI keeps its conversation in annotate
v0.28.29 | Plan review opens on OpenCode 2, a DOMPurify security update, closing a review stops the agent everywhere
v0.28.27 | Jump to open questions, files side by side or full screen, image zoom in the Inbox, empty To field, text size for plan review and annotate
v0.28.26 | Action items and reply drafts in the Inbox, one decision button for plan review, Enter to save a comment, a custom code font
v0.28.25 | Re-ask open questions, delivery ticks on the list, a count of new messages on the tab, right-click a thread, click Inbox to refresh
v0.28.24 | A new look for the Inbox, Send now, tag agents, comment on an agent's message, much smaller reads for agents, links in HTML pages
v0.28.23 | Inbox replies reach sessions with background subagents, dictated text no longer goes missing, 👍 Looks good reaches the agent, notifications that never fail silently
v0.28.22 | 👍 Looks good, full view for files, one viewer for a thread's images and files, every session prints its URL,PLANNOTATOR_BROWSER=noneopens nothing
v0.28.21 | Message an agent from the Inbox, video attachments, Open in for attachments, Code / Tests / Generated in code review, writes from other websites refused
v0.28.20 | Inbox search (⌘K), real folder names for projects, data files open in the code view, word-only replies leave questions open
v0.28.19 | Ask this session in T3 Code, folder sessions load shared stylesheets and images, the agent note asked once per agent, Copy connect promptWhat's New in v0.28.32
A security release: the binaries are now built on Bun 1.4.4, which no longer trusts the compromised eMudhra certificates. Also a Board page for the Inbox (off unless you turn it on), custom Inbox prompts, hover cards for issue and PR links, replies that wake Codex, and rich-text Copy. 26 PRs: two from @utpalsinghdev and one from first-time contributor @meowhib.
On v0.28.30 or older? Run the install script once:
curl -fsSL https://plannotator.ai/install.sh | bash(Windows:irm https://plannotator.ai/install.ps1 | iex).plannotator updateon those versions asks only GitHub's API and may not reach this release.Security: update now (eMudhra certificates)
Eight eMudhra intermediate certificate keys (6 for TLS, 2 for code signing) chaining to emSign ECC Root CA - G3 were found this month to be trivially recoverable; no misuse has been seen. Release binaries are now built on Bun 1.4.4, which drops that root and blocks the 8 compromised keys whatever root they chain to. v0.28.31 and earlier trust the root and have no block. Please update.
Plannotator also runs inside other hosts, which need their own update:
-
OpenCode plugin: update OpenCode to 1.19.4 or later (it runs on Bun 1.4.4).
-
Pi extension: run Pi on Node 22.23.4, 24.22.1 or 26.12.1 or later in the same line. On an older Node, a fresh install gets 0.28.31 while
pi updategets 0.28.32; 0.28.33 removes that floor. -
VS Code extension: desktop VS Code blocks the keys from 1.144 (Electron 43.8.1 or later); 1.143.x desktop does not. Remote SSH, WSL and containers are fixed in 1.143.1.
-
#2215, from @iMacTia's #2214 and @FNDEVVE's Bun 1.4 work in #1489
Plannotator Inbox
The Board (off by default)
A Board page of cards in lanes, for work you and your agents track together. Agents can add cards, you can drag them between lanes, and a card links its threads, PRs and issues with their live state. It is off unless you turn it on in Settings → General → Board; while off, agents are not offered the
cardaction and nothing changes.Custom Inbox prompts
Settings → Prompts replaces the Inbox reminder your agents get at session start, for every agent or per host (Claude Code, Pi, OpenCode). It is also in config.json under
prompts.inbox.Hover cards for issue, PR and MR links
Rest the pointer on a link to a GitHub or GitLab issue, pull request or merge request (or a
#123the Inbox links) to see its state, title, author, checks and review state without opening a tab.Replies wake Codex
Your Inbox reply now reaches the Codex thread that asked as a new turn, with no plugin. Needs Codex CLI 0.149 or later.
A tour in the real Inbox
The onboarding tour now walks through the Inbox's own viewers: a question with pictures, a comment on its words and on a file, one Send, then compose and Artifacts. It still writes nothing to your Inbox.
Smaller changes
- Never stuck on a version. If update checks keep failing for 3 hours, the Inbox, review windows and the terminal say so and show the install command; a stuck "Updating…" is released and shown as Failed. Settings → General now has the update control. #2210
- Pi, Oh My Pi and OpenCode 2 sessions get a reload line when they run older Plannotator code than what is installed, with the command to copy:
/reloadin Pi,/restartin Oh My Pi,opencode2 reloadin OpenCode 2 (oropencode2 plugin list && opencode2 plugin update <spec>when the plugin itself is behind). Claude Code sessions already got/reload-plugins. #2213 /plannotator-inboxopens the Inbox and shows its address, in every agent that has the other/plannotator-*commands (plannotator inbox --openin a terminal). #2207- Pull down to refresh the list on a phone. #2204
- Question cards on a phone keep their buttons whole, radios show when picked, and pasting an image works. #2206
- Coming back from a file keeps your place in the thread. #2208
- An × button exits full screen in the desktop file view (Escape still works). #2217
- The thread's foot shortens its words before its status wraps onto a second row. #2186
- An action item's why shows as Markdown , not raw
**and backticks. #2225
Plannotator
Copy as rich text
Copy in the selection toolbar (now on desktop too) puts rich text and plain text on the clipboard together. A selection pasted into Outlook, Slack or a doc keeps its headings, lists, links, code and tables; pasted into a terminal or prompt, it is plain text with its line breaks. Works in Markdown, HTML and live app annotation, plan review and the Inbox.
- #2191 by @utpalsinghdev, closing #1972, with #2221
Package changes in code review
A Packages card under each changed
package.jsonor lockfile lists the dependencies the diff adds, removes, upgrades or downgrades, with the versions the lockfile resolved. Lockfile-only diffs, such as Dependabot's, get one too.Smaller changes
- Built on Bun 1.4.4. It drops the compromised eMudhra root certificate, and the CLI uses less memory and starts faster. #2215
- Security: live app annotation never proxies a Plannotator server. A page loaded through the live app proxy could make same-origin writes to the Inbox or another review; every Plannotator server now refuses proxied requests. #2190
- Pi: an update while a review is open no longer loses your feedback. #2223
- A pending comment on a hidden slide hides with it and comes back with your text when you return. #2185 by @utpalsinghdev, closing #1431
- Annotate's file browser says when it hit its file cap (5,000 by default,
PLANNOTATOR_FILE_BROWSER_MAX_FILES) instead of dropping files silently. #2189 - Agent guidance split into focused guides , so harnesses that load AGENTS.md get a short map. #2193 by @meowhib, closing #2192
- Dependency updates. #2200, #2203
Install / Update
macOS / Linux:
curl -fsSL https://plannotator.ai/install.sh | bashWindows:
irm https://plannotator.ai/install.ps1 | iexClaude Code Plugin: The plugin and the
plannotatorbinary update separately, so run the install script above as well. In a terminal:claude plugin marketplace update plannotator claude plugin update plannotator@plannotatorThen restart Claude Code. Inside Claude Code, run
/plugin marketplace update plannotator, then open/plugin→ Installed → plannotator → Update now.Pi:
pi update --extensionsOpenCode: Re-run the install script above. It now also clears the OpenCode 2 plugin cache.
What's Changed
- fix(security): live app annotation never proxies a Plannotator server by @backnotprop in #2190
- fix: hide pending annotations on hidden slides by @utpalsinghdev in #2185
- docs: split agent guidance into focused guides by @meowhib in #2193
- fix(annotate): say when the file browser hit its file cap by @backnotprop in #2189
- Inbox: hover cards for issue, PR and MR links (GitHub and GitLab) by @backnotprop in #2187
- chore(deps): bump the bun-minor-and-patch group with 2 updates by @dependabot in #2200
- chore(deps-dev): bump @types/node from 25.9.5 to 26.6.5 by @dependabot in #2203
- feat(inbox): pull down to refresh the list on phones by @backnotprop in #2204
- feat(inbox): Settings → Prompts, a customizable Inbox reminder by @backnotprop in #2198
- fix(inbox): the thread foot shortens before the draft status wraps by @backnotprop in #2186
- Inbox tour v2: the walk in the real viewers, compose and Artifacts by @backnotprop in #2183
- Inbox: replies wake Codex sessions (codex queue) by @backnotprop in #2172
- feat: add rich-text selection copy by @utpalsinghdev in #2191
- feat(inbox): the Board page by @backnotprop in #2209
- Add /plannotator-inbox: open the Inbox and show its address by @backnotprop in #2207
- Rich-text copy: HTML and live annotate plain text keeps its line breaks (follow-up to #2191) by @backnotprop in #2221
- chore(ci): build with Bun 1.4.4 (drops the compromised eMudhra root) by @backnotprop in #2215
- fix(updates): no user stuck on a version by @backnotprop in #2210
- feat(review): package changes under package.json and lockfile diffs by @backnotprop in #2211
- fix(inbox): question card buttons and image paste on phones by @backnotprop in #2206
- fix(inbox): coming back from a file keeps your place in the thread by @backnotprop in #2208
- Inbox: draw an action item's why as markdown by @backnotprop in #2225
- Inbox: reload line for Pi, Oh My Pi and OpenCode 2 sessions by @backnotprop in #2213
- Inbox full screen: a visible × Exit full screen button (desktop) by @backnotprop in #2217
- fix(pi): an update while a review is open no longer loses the reviewer's feedback by @backnotprop in #2223
- test: wait for the selection message in the rich copy tests by @backnotprop in #2220
New Contributors
- @meowhib made their first contribution in #2193
- @iMacTia made their first contribution in #2215 (co-author, from #2214)
Community
- @iMacTia: first proposed building with Bun 1.4.4 to drop the eMudhra root (#2214); #2215 carried it in as co-author
- @FNDEVVE: found the Bun 1.4
node:httplistener change and a test race (#1489), folded into #2215 - @utpalsinghdev: rich-text Copy and hidden-slide annotations (#2191, #2185)
- @meowhib: split the agent guidance and reported the oversized AGENTS.md (#2193, #2192)
- @delmicio: asked for rich-text Copy for Outlook and Slack (#1972)
- @zane668: asked for customizable Inbox prompts (#2194)
- @Chrysweel: reported comments staying on screen across HTML slides (#1431)
Full Changelog :
v0.28.31...v0.28.32 -
-
🔗 HexRaysSA/plugin-repository commits sync repo: +1 release rss
sync repo: +1 release ## New releases - [DelphiHelper](https://github.com/eset/delphihelper): 1.26 -
🔗 r/Harrogate DANCE EVENT - 28TH NOV & 5TH DEC - HARROGATE rss
| Heyyyyy Harrogate team 🤩 Hope you are keeping well! We are back for number 002 & 003 of Loose 😍 Completely free entry so I am only promoting a good time 🫶 & if it was anything like the 1st one it’s not an event to miss 🦎 It’s hosting all independent Harrogate DJ’s at an Harrogate independent venue!
Major Tom’s Social
7pm - late
Free entry
Pizza til 9pm
Board games Easy listening to dance tunes 💃 🕺 🪩 Jazz house
Afro House
Funk
Groove
House
Techno
Acid
Minimal
UKG
Bassline Loose is a place to leave your worries at the door & let loose, we are all in this together 🦎 All promo is over on Instagram @mclaren.edj 18+ with encouragement for all ages to show up and show out, there’s music for everyone & you might even find something new you like! Old skool & New skool ravers welcome 🫶🦎 If you wanna come n have a dance & make some new friends drop by! Hope to see some of you there! Thank you! 🫶❤️🩹 I AM A HARROGATE LOCAL, BORN N BRED. So you’d be supporting a local event with local djs! submitted by /u/EllsMcL
[link] [comments]
---|--- -
🔗 Project Zero Fuzzers vs. AI: Comparing Fuzzilli and BigSleep on JavaScript Engines rss
Summary
Project Zero compared two automated tools used by Google to find vulnerabilities in Chrome’s JavaScript engine, V8, on a regular basis. Fuzzilli is a generative JavaScript engine fuzzer and BigSleep is an LLM-based bug finding system. In the past six months, BigSleep found more vulnerabilities than Fuzzilli (45 versus 37) with a 25% overlap in the specific bugs reported. Since this comparison methodology has a tendency to underestimate overlap, we also performed dedicated experiments to test theoretical overlap in vulnerabilities reported since 2023. These experiments estimated overlap at roughly 60%. Regardless of which value is accurate, a substantial portion of vulnerabilities were discoverable by only LLMs or only fuzzing. While it is extremely promising that LLMs have become able to find so many vulnerabilities so quickly, fuzzing and LLMs are still complementary approaches. We recommend vendors perform both fuzzing and agentic analysis of their code to maximize the number of vulnerabilities that get reported before they impact users.
Introduction
Fuzzing has long been successfully applied to software projects such as Chrome or V8 (Chrome’s JavaScript engine) to detect bugs. Recently, the arrival of powerful LLMs able to read, reason about, and write code is causing a transformative change to software development and software security. With hundreds, sometimes thousands of new bugs and vulnerabilities having been discovered in well-fuzzed targets, a natural question arises: how do new LLMs compare to “traditional” fuzzers? Are they starting to replace them or do the two approaches complement each other? To help answer this, we look at three key questions:
-
How many bugs does each approach find in the real world?
-
What is the overlap between the two approaches?
-
What is the “shape” of bugs discovered by one system but not the other?
For this blog post, we will limit ourselves to two concrete systems: Fuzzilli, a JavaScript engine fuzzer, and BigSleep, an agentic bug finding system. Both of these systems run in production and automatically look for bugs in newly added code, which makes them fairly directly comparable. Specifically, Fuzzilli runs continuously across many instances, with the first ones usually picking up new changes within a few hours, while BigSleep currently runs once per day and is prompted to review new commits and write proof-of-concept testcases for any bugs it discovers. Both systems report bugs through Clusterfuzz, which will do basic crash triaging, then file bug reports in Chrome’s issue tracker.
We also limit ourselves to V8 as a target, a high-performance JavaScript and WebAssembly engine with a sophisticated and mature testing and fuzzing setup. In particular, Fuzzilli is a special-purpose fuzzing tool designed to find bugs in these engines. The usually complicated nature of these bugs makes for an interesting “playground” to compare the two approaches’ ability to find deep and complex bugs in well-tested software. We leave it to future work to perform similar analysis on a broader set of targets, fuzzers, and agentic bug finding systems.
We will now look into each of the three main questions in a dedicated section. Each section will first summarize the general approach, then describe the methodology in detail (often as bullet points, so you can skip those blocks if you don’t care too much about the details) before exploring the results. We conclude with an attempt at interpreting the results to get a picture of the current state of fuzzing vs. AI.
Part 1: Production Statistics
This is the simplest part to analyze, although with some caveats we’ll see in a bit. The basic idea is to query issues from Chromium’s bugtracker (where V8 bugs are tracked) and extract various statistics from there. This is especially easy since there’s a dedicated hotlist for each of the two systems. We limit our analysis to the six months from April to September 2026 as the automatic BigSleep pipeline only became active in April this year. As such, our raw data comes from the following two bug tracker queries:
From there, the raw numbers of bug reports are:
-
Fuzzilli: 316
-
BigSleep: 441
Small win for BigSleep. However, this includes all types of bugs, and BigSleep initially also found a lot of configuration and integration issues in V8, for example crbug.com/503869331 where the unsafe flag blocking mechanism didn’t work properly yet. These are legitimate issues, but less relevant for our comparison since there’s little real-world security impact. One easy way to get rid of these is to look specifically at vulnerabilities by limiting the results to
type:vulnerability:-
Fuzzilli: 178
-
BigSleep: 95
Suddenly a clear win for the fuzzers? Not quite. There are still some problems with this data, notably duplicates and unactionable reports (e.g. bugs closed as WAI). At first, this seems like a simple thing to fix: just include another constraint such as
status:(fixed | verified). Unfortunately, things are a bit more complicated. Take for example Fuzzilli bug crbug.com/511935486. The events on this bug are basically:-
The bug is filed by Clusterfuzz on May 11 and assigned to an engineer
-
The bug is closed by Clusterfuzz as the testcase no longer reproduces later that same day
As such, this bug received zero developer interactions. Most likely what happened here is that this bug was a duplicate of another bug, crbug.com/511210507, but Clusterfuzz didn’t realize it as the crash signature (derived from the stack trace) was slightly different. When the other bug received a fix, the testcase stopped reproducing on Clusterfuzz, which closed the issue.
Maybe the best thing we can do is to look at “actionable” bugs, defined as those that are not marked as duplicates or WAI and that received at least one fix commit referencing them. Then, looking at only
Type-Vulnbugs filters out a lot of the less-relevant BigSleep bugs, even though these were “actionable”. With that, the final picture looks like this:
So in terms of vulnerabilities, it’s roughly a tie (small advantage BigSleep) at the moment: 45 vs. 37.
This naturally raises the question of cost: how expensive is each of the two approaches and what does that mean in terms of cost-per-bug? Unfortunately, it’s challenging to make a comparison at this stage in the research. While some effort has been dedicated to making Clusterfuzz more efficient, similar effort has not been expended for Big Sleep and neither system is particularly calibrated for an optimal cost-per-bug ratio.
Part 2: Overlap
The next question is how much these approaches overlap each other. For this, our approach is twofold: we first attempt to find an answer in the bugtracker, by trying to identify bugs discovered by both systems. Next, we run a dedicated experiment in which we let BigSleep try to rediscover old Fuzzilli bugs.
Bugtracker Overlap
The basic idea is to see which bugs were found by both systems, so we’re effectively looking for duplicate bug reports. Similar to part 1, there are a few steps we need to take to ensure we get a somewhat accurate picture:
-
First, we look for bugs filed by one system that get deduplicated into a bug filed by the other. For example crbug.com/522410841 which is a duplicate of crbug.com/522860268. This is a clear overlap.
-
Next, we need to take into account that many “unactionable” reports (those with zero associated fixes) are often duplicates. For those reports, we need to find the commit that fixed them, then look at the bug associated with that commit, and treat these two bugs as duplicates. This can be a multi-prong relationship: both bug X found by BigSleep and bug Y found by Fuzzilli might be a duplicate of bug Z reported by someone/something else. In that case, that bug still counts as overlap.
-
Then, we need to realize that many duplicates never receive a bugtracker entry since they are already deduplicated at the Clusterfuzz level (since both Fuzzilli and BigSleep rely on Clusterfuzz for basic triage and bug filing). As such, we need to query Clusterfuzz’s underlying database to find more duplicates.
-
Finally, we need to decide what to do with separate bugs that get fixed by the same CL, for example the four bugs fixed by crrev.com/c/7965120. While this can legitimately happen for distinct bugs, it’s probably more likely for the bugs to be duplicates (such as in this case), and so we count them as such.
With all the different types of deduplication, we get this final picture:

Again, looking at just the actionable vulnerability reports (likely the best measure), we see an overlap of roughly 25% (20 out of a total of 81), with a slight majority of these found first by Fuzzilli and later by BigSleep.
Overlap Experiment
The second way to measure the overlap is to run a dedicated experiment in which we try to re-discover bugs found by one system in the past using the other. Specifically, here we try to re-discover old Fuzzilli bugs using a BigSleep setup that’s as close to the production configuration as possible. For each bug we collect the commit that (likely) introduced the bug, and ask the agent to review those changes just as in the production CI environment. Note that the other direction, trying to rediscover past BigSleep bugs with Fuzzilli is more difficult to set up, since fuzzers cannot easily be given a similar “starting point”. Moreover, for many of these bugs we already know the outcome of such an experiment: the majority of “historic” BigSleep bugs (e.g. those from 2025) were found after fuzzers like Fuzzilli had already been fuzzing vulnerable builds for months, sometimes years. So they would most likely also not rediscover them in an experiment (except perhaps in a few cases where Fuzzilli was since updated to support new language features). Similarly, in production, BigSleep only reports crashes with a delay of 1-2 days (as there’s currently only one run per day). As such, fuzzers also get a head-start there.
In more detail, here is how the experiment is set up:
-
We start with a list of historic Fuzzilli bugs (from early 2023 until mid-2026) by querying the bug tracker hotlist. This gives us around 1150 raw bugs.
-
We restrict this to only
type:vulnerabilityas these are the types of bugs we care most about and will remove some “noise” as above. We are left with roughly 600 vulnerabilities. -
Next, we filter this list down to bugs that reproduce in the environment used by the agent. This involves two parts:
-
Bugs that reproduce on an x64 debug+asan build of the d8 shell as provided by Chrome’s public build infrastructure. This is important because many bugs only reproduce in special builds, for example because they are architecture-specific or need certain compile-time features.
-
Bugs that can be reproduced without special flags. The problem here is that fuzzers often set custom flags, either to enable in-development features (e.g.
--experimental-wasm-jspiin crbug.com/361123483) or to turn on different fuzzing modes that make certain types of bugs easier to discover (e.g.--deopt-every-n-timesin crbug.com/362784006). However, we can’t let the agent set arbitrary flags on historic V8 builds as these didn’t have a “safe-flags only” mode (leading to many false-positive crashes), and we also don’t want to tell the agent which flags it should use for a given challenge as that would be a hint. As such, for simplicity we limit ourselves to bugs that can reproduce with a standard set of flags (--fuzzing,--jit-fuzzing,--expose-gc) and only allow the agent to set those.
-
-
We end up with 132 historic bugs.
-
We now perform some deduplication similar to what we did above to identify implicit duplicates, which we remove. This leaves us with a final number of 112 bugs.
-
For a realistic comparison, we then convert these bugs into “code review challenges” similar to the ones used by the production BigSleep pipeline. For that, we try to identify the commit that (likely) introduced the bug, for example based on bisection. We note that this skews the comparison against BigSleep for two reasons:
-
We likely sometimes identify the wrong commit that is unrelated to the bug in question, making the task harder or even impossible.
-
We only have one commit per bug, while in the real world, the agent might discover the bug from another, subsequent commit that touches a similar part of the codebase.
-
-
We now run the agent for 25 attempts on each commit. The agent is asked to find bugs related to the commit and prove their existence by writing a testcase that crashes the vulnerable build. The attempt is terminated once a crash is found, so each attempt can report at most one bug. We use essentially the same configuration that was used in production BigSleep at that time, including the same underlying model: Gemini 3.6 flash.
-
Finally, we run some post-processing on the results to check if the agent found the “right” bug or an unrelated one. For that, we check that the testcase crashes the pre-fix revision but not the post-fix revision. This is imperfect but fairly easy to implement.
Here are the results from the experiment:

Starting from just the commits that (likely) introduced the bugs, BigSleep was able to re-discover ~62% of the original bugs, while finding a different (but by now fixed) bug for another ~12% of commits. On around 26% of the commits it failed to find any bugs.
Memorization
One thing to worry about with experiments such as this one is memorization: the LLM remembering specific bugs from its (pre-)training data and as such having an easier time “re-discovering” them during evaluation. We can try to get some idea of the effect of this by looking at the success rates for bugs from different time spans, e.g. every half-year period for which we have bugs in the data set. If there was memorization, we’d expect higher success rates (both for a single attempt and for the combined run) on bugs prior to the learning data cutoff of the model. Here are the results for our experiment:

For the model used in this experiment (Gemini 3.6 flash), the knowledge cutoff date is March 2026. Combining that with the fact that in early 2026, Chrome bugs would only become publicly visible after ~3 months, the effective knowledge cutoff for Fuzzilli bugs should be around Jan 2026. Looking at the data, there seems to be no statistically significant amount of memorization pre-2026. We note, however, that this may be different for other models or future model generations and as such recommend that this be re-evaluated for similar experiments in the future.
Difficulty
A follow-up question we might ask is how the overlap compares with “difficulty”. For example, in the best case a system like BigSleep would easily find issues that fuzzers struggle with and vice versa. In that case, budget that was previously spent on long fuzzing sessions may now be re- allocated and put to different uses. Here are the results of analysing this, where “bug difficulty” is measured by the time it took Fuzzilli to discover the bug:

While we do get a statistically significant result here (although not of particularly great magnitude), it actually points in the other direction! Bugs that are hard to find for a fuzzer are likely also hard to find for an AI agent. As such, those fuzzers should probably be kept running for now.
Components
Another thing we can look at is a per-component breakdown of the bugs and their rediscovery rates:

Interestingly, the overlap is significantly smaller for compiler bugs. This is the area where Fuzzilli probably specializes most in, which may explain the results. Later on (in part 3), we’ll also develop another hypothesis for why (some) bugs in the compilers may be more difficult to rediscover for BigSleep.
Prompting
A final question is how much the specific prompting played a role in the performance of the AI agent. For that, we run two quick follow-up experiments, only on the bugs that weren’t previously re-discovered and with different prompts:
-
Instead of starting from commits, we start from the vulnerable file or function. This may be an easier starting point but is still a fairly realistic setup since both can for example be obtained by extracting modified files and functions from a given commit.
-
Instead of asking the agent to find memory corruption vulnerabilities (what we care most about), we specifically tell it that assertion failures and similar crashes are also desirable.
Running these two experiments with only 5 attempts per bug (instead of the 25 used in the main experiment), the agent re-discovered 10 additional bugs in total: 8 from the different starting points and 7 with the rephrased prompt (with 5 found in both runs).
In total, combining these results with our original experiment, we get the following picture:

So the share of “correct” bugs found climbs to ~70%, and we find some kind of bug for ~84% of starting points. However, for fairness it should be noted that equivalent tweaks to a fuzzer could likely also result in higher discovery rates for certain bugs, so the results of this follow-up experiment should be treated with some caution.
Summary
The main results from our two angles are:
-
In production, the overlap is noticeable but not substantial at around 25%.
-
In our experiment, overlap was around 60% of historic Fuzzilli bugs (70% with additional runs that used different prompts).
-
The overlap is not uniformly distributed:
-
Bugs that are difficult for a fuzzer to find are more likely to also be difficult to find for an agent, so there’s more overlap on “easy” bugs.
-
The overlap seems to be smaller in the JIT Compilers and higher in the rest of the engine.
-
From just the experiment, we might expect a higher overlap in production. However, there are probably a few factors that prevent(ed) this:
-
There’s a limited time window for overlaps: once a bug reported by either system is fixed, the other system no longer has a chance to rediscover it (as the bug won’t reproduce on Clusterfuzz and will therefore be discarded).
-
Our experiment only looked at a subset of Fuzzilli bugs that reproduce on a standard x64 d8 fuzzer build and without special flags. In production, each system has access to slightly different and specialized builds, as well as different runtime flag constraints, and there the overlap is potentially smaller.
-
Pipeline hiccups such as overloaded servers or bugs in the automation likely prevented a number of commits from being reviewed by BigSleep in the last months, so bugs introduced by them may have been missed.
-
Since its introduction in April, the model underlying the BigSleep pipeline has been upgraded multiple times. Earlier models likely performed worse, and we expect future models to perform better.
Part 3: Shape of Bugs
In this section, we will first look at three case studies of bugs found by one system but not the other, then attempt to draw conclusions from these and other bugs.
BigSleep: Chrome Bug 449760249 (October 2025)
This bug is a nice example of BigSleep benefiting from the underlying model’s reasoning capabilities to discover a variant that was (likely) too complex to trigger by a fuzzer in a reasonable amount of time. It’s also a good example to show the general working of an agentic bug finding system.
Background: TDZ and Hole Check Elision
Before diving into the bug specifics, we first need to look at some JavaScript internals, specifically variable initialization. In JavaScript, variables declared with the
letorconstkeywords cannot be used before they are initialized, and attempting to do so will lead to an exception (”ReferenceError: Cannot access 'foobar' before initialization”). In V8’s terminology, these variables reside in a “temporal dead zone” (TDZ) until they are initialized. Internally, V8 sets variables in the TDZ to a special sentinel value,the_hole, and then checks for this value when accessing the variable’s content.To limit the performance impact of these hole-checks, V8’s bytecode compiler implements an optimization (behind the default-enabled --ignition-elide- redundant-tdz-checks flag) to identify redundant checks and subsequently remove them. The idea here is to identify “dominating” checks where it can then be guaranteed that a hole-check has already been performed for a given variable on all possible paths leading to the current position.
This is a security-relevant optimization as an incorrectly removed hole-check would result in the internal
the_holevalue leaking to JavaScript code, a condition that has historically been exploitable (although new mitigations for this bug class have since shipped).The Original Vulnerability
The original bug (issue 40071027 - discovered two years earlier by Fuzzilli!) involved
do-whileloops containing abreakstatement. In ado-whileloop, the loop condition evaluates after the body. If the condition contains an assignment to a variable, the bytecode compiler will mark the variable as initialized. However, if abreakstatement executes in the loop body in the first iteration, then the condition will never execute. The bytecode compiler originally failed to account for this, leading to an incorrectly omitted hole check and subsequent leak ofthe_holevalue.To fix this, the implementation of
BytecodeGenerator::VisitDoWhileStatementwas modified in the following way:- VisitForTest(stmt->cond(), ...); + if (!loop_builder.break_labels()->empty()) { + HoleCheckElisionScope elider(this); + VisitForTest(stmt->cond(), ...); + } else { + VisitForTest(stmt->cond(), ...); + }Specifically, the patch works by creating a
HoleCheckElisionScopefor processing the condition code in case the loop contains break statements. This means that any updates to the TDZ state of variables will be discarded once the scope object is destroyed. As such, code after the loop will see the previous TDZ state (which is the correct behavior in this case).Discovery of the Variant
The BigSleep agent began its analysis by examining the patch to
VisitDoWhileStatement, realizing that the fix relied onloop_builder.break_labels()->empty()to decide if a protectiveHoleCheckElisionScopewas required. It then began creating and testing various hypotheses for scenarios in which nobreakstatement was registered with a given loop but the condition would still be skipped at runtime. For example, it hypothesized that a try-catch in combination with athrowinside the loop might confuse the hole-check elision logic. It then investigated how try-catch was implemented in the bytecode compiler and concluded that this was handled correctly.Eventually, the agent started investigating labeled breaks, which allow directly breaking out of inner loops. It hypothesized that these might not be handled correctly and continued to investigate how these were being processed, for example by studying the logic in
BytecodeGenerator::VisitBreakStatement. This time, it seemed to have identified a real flaw: in the case of nested breaks, the inner loop was apparently not being informed of the existence of a break statement! It therefore formulated the following vulnerability hypothesis:- If a labeled break inside a
do-whileloop targets an outer scope, the innerdo-whileloop’sLoopBuilderis not notified. - Consequently,
loop_builder.break_labels()->empty()remainstrue. - Therefore, when generating the code for the loop condition, the
HoleCheckElisionScopeintroduced by the patch is not used. - The condition is bypassed at runtime, but the bytecode compiler erroneously removed a later hole-check, leading to a leak of
the_holeto JavaScript.
The agent then began writing a testcase to prove the existence of this bug. The initial attempt with simply two nested loops and a label failed, however, as the bytecode compiler would add another protective scope object for the labeled block. To work around this, the agent decided to use a
switchstatement. When handling aswitchstatement, the bytecode compiler uses aHoleCheckElisionMergeScopeto compute the intersection of initialization states across all branches. By ensuring that the variable was initialized in adefaultcase, the merge logic then concluded that the variable was correctly initialized on all paths.Proof of Concept
With that, the agent had everything in place to produce a testcase to demonstrate the vulnerability. Below is the agent’s PoC:
// Flags: --ignition-elide-redundant-tdz-checks function trigger(cond) { { target: switch(1) { case 1: do { // Labeled break targeting the switch. The do-while LoopBuilder remains unaware. if (cond) break target; } while((x=1) && false); // Condition performs a check/assignment on x. break; default: x=1; // Ensure x is considered initialized across all switch branches for merging. } // Generator incorrectly believes x is checked/initialized. Elides TDZ check. x + 1; let x; } } trigger(true);Here is how this testcase works:
trigger(true)executes, enteringcase 1of theswitch.- The
do-whileloop executesbreak target. - Control flow jumps to the end of the
switch, bypassing thedo-whilecondition wherexis assigned. - At runtime,
xremains uninitialized (holdingthe_hole). - Because the TDZ check was elided at compile time, the engine leaks the internal
the_holevalue to JavaScript code in thex + 1expression, leading to a potentially exploitable condition.
We can see how this bug would be difficult for a fuzzer to find since the testcase is quite complex. While a coverage-guided fuzzer would have received rewards for triggering individual code paths (such as the handling of labeled break, the switch statement, the do-while loop, etc. in the parser), there is no additional reward for putting these together “in the right way” and so ending up with a testcase like this is quite difficult.
BigSleep: Chrome Bug 443765373 (September 2025)
This bug is an example of a relatively simple bug type that is challenging to discover with standard fuzzing approaches.
Background: Exception handling in V8
To understand this bug, it is necessary to briefly look into exception handling in V8. Take the following example JavaScript code:
function simple() { try { throw 42; } catch (e) { return e; } }Here, we have a function consisting of a try-catch block in which an exception is raised. Running this in d8 with
--print-bytecode, we can see the internal bytecode that the engine generates to execute the JavaScript code:[generated bytecode for function: simple] 0x2ad5001000e4 @ 0 : 1b ff f9 Mov <context>, r0 0x2ad5001000e7 @ 3 : 0d 2a LdaSmi [42] 0x2ad5001000e9 @ 5 : b5 Throw 0x2ad5001000ea @ 6 : d1 Star1 0x2ad5001000eb @ 7 : 8d f8 00 CreateCatchContext r1, [0] 0x2ad5001000ee @ 10 : d2 ... ... 0x2ad5001000f7 @ 19 : b7 Return Handler Table (size = 16) from to hdlr (prediction, data) ( 3, 6) -> 6 (prediction=1, data=0)For the purpose of this bug, the relevant part is mostly the last line of the output. Here, the bytecode essentially says “if there is an exception while the PC is between offset 3 and 6 in this bytecode, then execution should continue at offset 6 (the start of the exception handler)”.
The Bug
The agent spotted the bug while looking at the following function, responsible for writing the handler table data structure in memory:
void HandlerTable::SetRangeHandler(int index, int handler_offset, CatchPrediction prediction) { int value = HandlerOffsetField::encode(handler_offset) | HandlerWasUsedField::encode(false) | HandlerPredictionField::encode(prediction); int offset = index * kRangeEntrySize + kRangeHandlerIndex; Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t)) = value; }Here, the
intoffset is being combined with a few other bits of data into a newintvalue. As such, thehandler_offsetcannot have the full integer range in the new field, possibly leading to integer truncation issues. The agent then investigated the specific bounds of these values and realized that theHandlerOffsetFieldhad only 28 bits (allowing for 256MB) while the maximum bytecode size was 512MB! From there it was relatively simple to craft a testcase that crashes, simply by creating a huge function (resulting in256MB of bytecode) with an exception handler at the end, then triggering an exception inside of it. The result is a jump to a wrong bytecode offset, a primitive that’s easily exploited. Here is the relevant part of the testcase:
// yield statements turn into a large chunk of bytecode let kNumYields = 500000; let body = ` if ("foo" === "bar") { ${"yield* 42;".repeat(kNumYields)} } try { throw 42; } catch (e) { // Will never get here } `;Such a testcase would again be difficult to craft by a fuzzer as the fuzzer isn’t rewarded for creating large code (at least not with generic coverage feedback). In fact, the fuzzer is likely even actively discouraged from finding this bug since generating and executing large bytecode takes some time (in debug builds, the testcase generated by the agent needs a few seconds to trigger) and would therefore probably have led to timeouts during fuzzing.
Fuzzilli: Chrome Bug 40076141 (November 2023)
This bug is a good example of a type of bug that is likely difficult to find just by looking at (one part) of the source code. It was originally discovered by Fuzzilli and not rediscovered by any of the experiments from part 2.
Background: Value Representation in V8
Consider the following piece of JavaScript code:
let i = 42; let f = 13.37; let s = "foobar" i = s;Here we create multiple variables holding values of different types. Note, however, that we never declare the type of a variable, and that variables can hold values of different types throughout their lifetime (
ifirst contains an integer, later a string). What we see here is that JavaScript is a dynamically typed language, and so variables (and also object fields, etc.) have no fixed type. However, the actual runtime values still need to have a type: the engine somehow needs to know thatfoobaris a string value and that certain operations (e.g. substring search) can therefore be performed on it. Conceptually, this is possible by representing runtime values with a struct such asenum JSType { JS_TYPE_INT, JS_TYPE_FLOAT, JS_TYPE_STRING, ... }; struct JSValue { JSType type; // Either the raw value or a pointer to another object, e.g a JSString. uintptr_t value; };However, this is somewhat inefficient since we now need something like 16 bytes to represent a simple 4-byte integer at runtime. As such, modern JS engines use clever tagging schemas, which rely on unused pointer bits to encode type information. Specifically, in V8 the
JSValuetype is a tagged pointer (or justtaggedfor short) which stores one bit of type information in the least-significant bit:- If the bit is one, then the value minus 1 is a pointer to another object. This works because objects are aligned and so cannot start at an uneven address.
- If the bit is zero, then the next 31 bits contain a raw integer value (also called a small integer - Smi)
As such, to figure out the type of a value at runtime, the engine first looks at the least-significant bit. If that is zero, the value can be “untagged” to obtain the integer value by right-shifting by one. On the other hand, if the bit is one, the value is a valid pointer to an object that contains further type information. For more details on V8’s pointer tagging scheme see also this blog post.
The Testcase
Let’s start by looking at the testcase produced by the fuzzer, which isn’t overly long:
function f0() { let v2 = 1; for (let i3 = v2; i3 >= v2; i3 += v2) { v2 = v2 && i3; } } f0();The bug is caused during optimization of the loop by the Maglev compiler, specifically due to a conflict between two stages of the compiler pipeline: the initial graph builder and the later MaglevPhiRepresentationSelector.
The Graph Builder
The graph builder is responsible for building the initial Maglev intermediate representation (IR) of the code. For that, it consumes both the input code (in the form of V8 bytecode) as well as runtime feedback that was collected while the code executed in lower tiers such as the interpreter. When processing the loop in this testcase, the following happens:
- Both
i3andv2are modified during the loop. Since the IR uses static single-assignment (SSA) form, these turn into Phi nodes, which make the code look like every variable only has a single assignment :) - For the
i3 >= v2comparison, the runtime feedback states thati3was so far always a Smi and therefore speculates that this will be the case in the future. It guards this assumption by emitting aCheckedSmiUntag, which will extract the raw int from the tagged value and will bail out to the interpreter if the input is ever not a Smi. - For the following operations on
v2, the compiler can then rely on the existing check and emitUnsafeSmiUntagnodes, which avoid the runtime checks but are only safe to use if the input is guaranteed to be a Smi.
The resulting code for the loop now looks roughly like this (in Maglev pseudocode):
loop: i3 <- Phi(1, i3_next) // loop variable, tagged v2 <- Phi(1, v2_next) // loop variable, tagged i3_int <- CheckedSmiUntag(i3) // deopt if i3 is not a Smi v2_int <- CheckedSmiUntag(v2) // deopt if v2 is not a Smi if i3_int < v2_int: break v2_next <- Phi(i3, v2) // result of `v2 && i3`: "known Smi" v2_next_int <- UnsafeSmiUntag(v2_next) // no (re-)check needed i3_next_int = i3_int + v2_next_int i3_next <- Int32ToNumber(i3_next_int) // tag the int32 result for the phiThe MaglevPhiRepresentationSelector
The purpose of this optimizer is to identify Phi nodes where all inputs have the same raw representation (e.g. int32), and if so convert the Phi to that representation to avoid future untagging operations. For the code above, the code sees that both inputs to
i3are int32 and therefore decides to convert the Phi to int32 representation. FollowingCheckedSmiUntagoperations then become a no-op and can be removed, while consumers that need a tagged value now require a conversion step. With that, the final code now looks like this:loop: i3 <- Phi(1, i3_next) // all inputs int32, so i3 becomes a raw int32 v2 <- Phi(1, v2_next) // stays tagged v2_int <- CheckedSmiUntag(v2) if i3 < v2_int: break // CheckedSmiUntag(i3) removed as a no-op i3_tagged = Int32ToNumber(i3) // HeapNumber if i3 >= 2^30! v2_next <- Phi(i3_tagged, v2) // stays tagged, needs tagged inputs v2_next_int <- UnsafeSmiUntag(v2_next) // HeapNumber pointer treated as a Smi i3_next <- i3 + v2_next_int // tagging no longer needed hereThe Conflict
The bug now occurs because of two optimizations interacting badly with each other:
- The graph builder uses
UnsafeSmiUntagas it believes that the value must be a Smi at this point - The representation selector removes a
CheckedSmiUntagas it believes it is no longer required
Specifically, what can happen now is that eventually,
i3becomes larger than the maximum Smi value. At that point,Int32ToNumbercan no longer fit the integer into aSmiand instead allocates aHeapNumberobject (a container holding a larger number, basically). At this point, however, theUnsafeSmiUntagis no longer safe as the input is now a pointer. This leads to a corrupted pointer value being extracted and subsequently to memory corruption. Note that in the original code, this could not have happened as theHeapNumberwould’ve been rejected by theCheckedSmiUntag(i3).What may have made this bug difficult to find for BigSleep is the fact that both optimizations are correct in isolation. As such, looking at just one of them would’ve made it difficult to spot the issue. The agent would somehow have needed to hypothesize about the other optimization or stumbled upon the relevant code by chance (or exhaustive search).
Overview
Looking at the examples above as well as other bugs found by LLMs, we can see a few clear examples of bugs where an LLM has the advantage:
- Bugs that require complex logic to trigger but can be found through progressive logical reasoning and experimentation with the target program, such as crbug.com/449760249 discussed above. This is likely the strongest advantage.
- Bugs that require specific “magic” values (e.g. edge-case integers, specific strings, etc.), such as crbug.com/443765373 discussed above.
- Bugs that require new (or less common) features that a fuzzer may not be aware of. Examples include crbug.com/436181695, where the fuzzer didn’t support the new
await usingsyntax yet, and in fact also crbug.com/449760249 above where Fuzzilli lacked support for labeled breaks at the time. - Bugs that require a non-standard harness, custom flags, or special helper tools/functions that a fuzzer is not configured to use (e.g. crbug.com/516833326 which required --expose-fast-api and the
d8.test.FastCAPIAPI).
On the other hand, here are some advantages that fuzzers enjoy (for now):
- They can find “non-local” bugs reasonably well if not too many individual pieces are required. crbug.com/40076141 discussed above is an example for such a bug.
- They can find bugs that are hard to spot by reasoning about the source code alone. One clear example would be bugs caused by (incorrect) C++ compiler optimizations such as crbug.com/500771385. Another potential example is bugs such as crbug.com/414840455, which are related to handling dead code in V8’s compilers. This is likely an unusual state and therefore may be hard to reason about. BigSleep missed a few of these in our experiments.
- They are immune to certain biases affecting the agentic approaches, such as the choice of starting point (e.g. commits), the exact prompt phrasing, or the bug types seen (and not seen) during training. They do suffer from other types of biases though (e.g. the weights of individual mutators and generators).
- They don’t get distracted by “shallow” bugs, whereas BigSleep missed a few bugs because it found easier ones instead. This is probably somewhat self-correcting though as the shallow bugs would eventually get fixed, giving the agent another chance to discover the deeper bug.
There is probably also a category of bugs that are hard to find for both approaches: bugs that are very non-local (bad for the agent) and require complex testcases (bad for the fuzzer) to trigger. In this case, a fuzzer would probably discover the individual pieces of the testcase (through coverage feedback) but won’t be able to find the right combination to trigger the bug (as in our first example). A code-reviewing agent, on the other hand, may struggle with the large search space of code fragments that may interact badly with each other (as in our last example). This is only a hypothesis, however, and would require further experiments and data to validate.
Part 4: Conclusion
In this blog post, we’ve compared coverage-guided fuzzers with vulnerability- discovery agents that read and reason about the source code. Specifically, we’ve looked at Fuzzilli and BigSleep, which both run as automated pipelines on V8 to discover newly introduced bugs. Looking at the data from those pipelines, we saw a roughly equal share of vulnerabilities found in the last 6 months (around 40 each), and a moderate overlap in discovered bugs of around 25%. However, in a dedicated experiment, overlap was closer to 60%. For now, this means that the two approaches remain complementary, and specialized fuzzing continues to provide value by finding bugs quickly and identifying certain kinds of issues that are otherwise hard to spot. At the same time, LLMs only very recently became capable of finding bugs in software like V8 at all, and have made tremendous progress since. The model used for our experiment is by now already outdated and outperformed by newer generations. Looking to the future, we expect further model improvements, potentially coupled with better prompting and more flexible harnesses (that e.g. allow the model to build, improve, and run fuzzers itself instead of being limited to pure code auditing), to lead to a growing share of bugs being discovered by agentic systems.
-
-
🔗 Filip Filmar An AXI bus in TxHDL: links, routers and bridges rss
Complex designs in TxHDL communicate over AXI4 interfaces. The Vreteno RISC-V processor, the Razboj rasteriser, DDR3 memory controllers, Ethernet MACs, and HDMI video controllers all use AXI interconnects. This post describes the AXI components in the TxHDL standard library. The library provides high-level channel abstractions, hardware protocol trackers, address routers, and bridges to AXI-Lite and Wishbone. All components lower to synthesizable Verilog and VHDL, verified against randomized bus fuzzing on every build.
-
🔗 Filip Filmar FireSim Under Bazel rss
FireSim is an open-source tool from UC Berkeley that runs a chip design, usually a RISC-V system written in Chisel, on an FPGA, so that it is simulated cycle by cycle, far faster than in software. FireSim 1.22.0 now builds under Bazel, from Chisel source to a bitstream and a host driver, with no sbt, conda or Vivado project on the host. Upstream, getting a machine ready to build FireSim takes dozens of pages of setup instructions. Under Bazel, all of that setup comes down to a single
bazel_depline inMODULE.bazel. It is a net of 22 small modules in my Bazel registry, most of them build files laid over an upstream commit, plus one rules module,rules_firesim. On FireSim’s own Nitefury II recipe, a single Rocket core, the build gives a bitstream that meets timing on Vivado 2025.2. Three problems decided the design: Golden Gate needs Chisel 6’s FIRRTL, it needs an older Scala and other dependency commits than the target, and Chisel writes machine paths into the output. -
🔗 Ampcode News Amp on Android rss
We now have an Android app:
:::gallery carousel
::::::gallery carousel
:::Download and install from ampcode.com/app, or scan this QR code:
-
- October 26, 2026
-
🔗 IDA Plugin Updates IDA Plugin Updates on 2026-10-26 rss
IDA Plugin Updates on 2026-10-26
New Releases:
Activity:
- ffxiv_bossmod
- 7be17d76: release for kage chan
- c1edd84f: WIP p2
- e785274f: Merge branch 'rotations'
- f1f82216: Merge branch 'modules'
- ad9ccd6d: WIP trying to solve p2
- 4d02adbf: fix obstacle maps and a bunch of bugs introduced by hot reload
- 11867936: update
- 29633396: add helper to mnk pb force
- b4f611bd: multi import: support replacement
- c024b042: improve grand octet reliability
- gpt6-Astra
- e431bc16: fix: restore desktop CI for all fifteen model seats
- ipyida
- 656c0f2a: Fix typos in comments and docstrings
- oh-your-pi
- plugin-ida
- ffxiv_bossmod
-
🔗 Quarkslab's blog Snapshotting our way to CVE-2026-9539 rss
Introduction
In this blogpost we present a LibAFL-Qemu based fuzzer we developed with the goal of targeting (complex) state machines using incremental snapshots. We targeted libslirp's TCP code during development and showcase the fuzzer on CVE-2026-9539 which we missed at that time due to a lack of detection.
First we will describe CVE-2026-9539, why it went unnoticed for years as well as when we fuzzed the code and what can be done about it. Then we will describe how the fuzzer works and show it running against libslirp to find CVE-2026-9539. The code is available on Quarkslab's github and we tried to isolate the target-specific parts so it is easy to adapt to a different target.
Description of CVE-2026-9539
libslirp is «a user-mode networking library used by virtual machines, containers or various tools.». Being Qemu's default network stack makes it an interesting target for a VM escape.
CVE-2026-9539 is described as an «heartbleed-like» Out-Of-Bound (OOB) Read vulnerability which exposes data from other connections. It was found by Bruce Chen and Shi Weiming from STAR Labs SG Pte. Ltd and was reported to libslirp in May 2026, around the same time we failed to see our fuzzer triggering it because of a lack of detection.
We won't explain the bug at length here and stick to the important bits as the ticket on libslirp's gitlab is very detailed:- Libslirp allocates two large arrays (128KiB) that it uses to support the socket's send and receive buffers. It uses two pointers to walk these buffers like ring-buffers.
- Libslirp was testing the TCP urgent pointer against the size of an intermediate buffer, not against the amount of valid data in the socket.
- As it tries to read more data than available, an integer underflow happens leading to even more data being read.
- The data is sent with multiple packets and leaks the whole content of the receive buffer, including leftovers from a previous allocation if the memory chunk is a previously freed one that was re-used for this socket. The same 128KiB of data is sent over-and-over.
As the data is too big to be sent in a single packet and multiple checks try to prevent OOB accesses, the bug stays inside the ring-buffer area and never goes out-of-bound as far as Address Sanitizer (ASAN) is concerned, making this bug seemingly invisible.
Why CVE-2026-9539 went unnoticed and what can we do about it
As we said in the previous section, the bug is not a classical OOB read but an OOB read inside a custom allocator, so it will not crash the program and ASAN is blind even if a fuzzer is able to reach it.
Speaking about fuzzers, libslirp integrates a bunch of them. These are libfuzzer-based and use a custom mutator working with PCAP files. The main issue with the fuzzer targeting the TCP-related code is that it fails to open and connect to sockets. The fuzzers are not using libdesock or preeny and bypassing the socket part by modifying the source code can lead to surprising results and be tricky.
There are two ways to detect CVE-2026-9539 using sanitizers: the easiest one consists in detecting its side effect, while the other consists in working around ASAN's shortcomings when an internal allocator is used.
Detecting the side effect
The integer underflow in the
sosendoobfunction is not the whole story but interestingly it makes the vulnerability easy to detect using ASAN's sibling UndefinedBehaviorSanitizer (UBSAN).We recommend reading MaskRay's excellent blogpost All About UndefinedBehaviorSanitizer for a complete tour of UBSAN.
Contrary to ASAN, UBSAN only exists as an LLVM pass so it is only available when you are able to compile the project from source. Recompiling libslirp with integer overflow detection (
-fsanitize=unsigned-integer-overflow,signed- integer-overflow) and reachingsosendoob's underflow, we are rewarded with multiple UBSAN runtime errors (which we can suppress with custom annotation after determining whether this is an expected behavior), including the relevant one:../src/socket.c:394:15: runtime error: unsigned integer overflow: 8 - 2048 cannot be represented in type 'uint32_t' (aka 'unsigned int') SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../src/socket.c:394:15Customizing ASAN
Address Sanitizer is using a shadow memory to track allocation sizes and memory accesses. Basically, it handles a big array mimicking the memory of your program filled with values indicating if the program is allowed to read/write the associated byte.
A byte which should not be accessed is said to be poisoned and ASAN provides functions to (un)poison a memory region.You can refer to TrailOfBits' Sanitize your C++ containers: ASan annotations step-by-step blogpost for a tutorial-like introduction to manual poisoning with ASAN.
Poisoning the whole ring-buffer and manually unpoisoning/poisoning memory when it is «allocated»/«freed» by the internal allocator should detect this bug. It requires more work and is prone to errors but it would be more reliable as it does not depend on side effects of the bug.
LibAFL-Qemu's ASAN implementation also exposes an API to poison/unpoison memory regions, so this can also be achieved when the source code is unavailable.
Fuzzing against the (state) machines
Fuzzing a state machine, such as the TCP one, generally requires sending multiple inputs in a given order. There are multiple ways to solve this problem, each having pros and cons. We are only listing some techniques which require low efforts and fuzzers built on modern fuzzers such as AFL++ or LibAFL.
Persistent mode and persistent record
The first and easiest option is to run your fuzzer in persistent mode, avoid resetting anything between iterations, opt-in for the low stability and hope AFL++'s persistent record option will catch the right input chain to have a reproducer.
Splitting the input
A common technique in order to easily find reproducible issues is to split the fuzzer's input into multiple inputs. This can be done by letting the fuzzer generate a sequence of bytes and then use FuzzedDataProvider, Arbitrary or similar.
Another way of doing it is by creating a custom mutator which uses a magic value to separate the parts of the input. This is what libslirp's fuzzers do.This approach is subject to the havoc effect (a change to an early input part changes the interpretation of the next ones) and the fuzzer could theoretically generate the magic value (choose your separator wisely and avoid compiling the harness with cmplog).
Multipart inputs
Multipart inputs is a variation of the previous approach. It is built in LibAFL and removes the need for a custom mutator. It also removes the very unlikely risk that the fuzzer generates the magic value that separates the parts, but the havoc effect is still an issue.
Working from snapshots
Instead of working from the initial state and sending multiple inputs to the target, a security analyst tries to reach interesting states manually in order to take a snapshot. This snapshot is then fuzzed in isolation, one input at a time.
This setup removes most of the issues discussed previously but the ability to reach a complex state might depend on how the current state was reached.
Fuzzer in the Middle (FitM)
FitM is a fuzzer designed for client-server targets when both are available. The fuzzer impersonates one end of the protocol until the other end's response changes. When a new response (which is a proxy for the state) is found, the fuzzer takes a snapshot and switches to impersonating the other end of the communication channel.
It relies on Qemu for emulation and CRIU to take the snapshots. The setup might be a bit tedious.
Taking snapshots while fuzzing
The approach we have implemented is inspired by FitM, it is also close to NyxNet with a different backend and design choices, and to FTZ. We built our fuzzer on top of LibAFL-Qemu usermode, its
SnapshotModuleandSnapshotManager. We could have mostly copy-pasted theSnapshotModuleinto aMultiSnapshotModulebut we chose another route which looked a bit easier back then.
Using the hook mecanism provided by LibAFL-Qemu, we are detecting changes to the state machine to trigger a new snapshot.
TheSnapshotManagerthen saves the internal structures of theSnapshotModuleand can restore it on demand. This way, we should be able to explore the different states and state transitions of the target.
Leveraging LibAFL's metadata concept, we are able to track which input generated a snapshot and the full chain of snapshots leading to a given state, allowing to easily try to reproduce any issue.
On libslirp, we are using a lain-based custom mutator to only generate TCP packets so the fuzzer does not explore code unrelated to the state machine we are targeting.Lain is an input mutator/generator which works using annotations on Rust
struct. The mutations it performs try to conform with the type and it offers some control over which parts of thestructcan be mutated. Nowadays it could be replaced with Autarkie which shares the concept of using annotations on Ruststructbut is considered a grammar mutator rather than a structure-aware one.Our «incremental snapshot fuzzer»
LibAFL-Qemu's
SnapshotModuleLibAFL-Qemu's usermode comes with a
SnapshotModulewhich unlocks snapshot fuzzing for linux userland targets. It only snapshots the target's memory, not its registers. Taking a snapshot of the registers should be done manually in the harness.
In this section, we will briefly describe how it works.The
snapshotfunction is in charge of taking the snapshot and does the following:- It saves the values of
brk(think of it as the limit of the memory region the heap can use) andmmap_start. - It walks the whole
Qemumemory mapping and saves the bounds and permissions of the mappings. - While walking the memory map, it also walks the pages of each mapping, one at a time, and stores the content of the pages along their address and permissions in the
SnapshotPageInfostructure.
In order to track when memory is written, the
SnapshotModulesets up «write hooks» inQemutasked with adding the (now) dirty pages to theSnapshotModule'saccessesfield. It also registerspre_syscallsandpost_syscallshooks to track some syscalls which affect memory (mmap,munmap,mprotect,brk,read, ...).Thanks to these hooks, the
resetfunction can restore the snapshot's state in a more efficient way than just restoring everything the way it was. It works as follows:- If the heap has shrunk or grown (the value of
brkchanged), it reverts it by mapping/unmapping memory. - It walks the dirty pages to restore their content.
- If some mappings were mapped or unmapped, it reverts the changes and restores the content if needed.
- If a mapping's permission changed, it calls
mprotectto revert it.
The
SnapshotManagerThe
SnapshotManageris a member of LibAFL-Qemu'sEmulatorstructure. The defaultSnapshotManagerfor usermode is theNopSnapshotManagerwhich does nothing as the name suggests. ASnapshotManagermust implement theIsSnapshotManagertrait, which exposes 3 functions:save: which is responsible for taking snapshots;restore: which is responsible for restoring snapshots;do_check: which is in charge of verifying the snapshot's correctness. We are not using this function in our fuzzer.
Our implementation's
savefunction is called when a change to the TCP state is detected. To limit the amount of duplicate snapshots, it first performs a hash of the state (augmented with the flags of the answer packets from the stack to have more diversity) to decide if we actually take a snapshot. It then saves most of theSnapshotModule's fields and uses theaccessesas a diff between a snapshot and its parent.
TheSnapshotManagerkeeps aHashMaptracking the chain of snapshots to restore in order to reach another snapshot. ThisHashMapis filled during the call tosave, leveraging the fact that the first step to reach a given snapshot is to reach the new snapshot's parent, as well as the converse (reaching the new snapshots is done by first reaching its parent).
Last but not least, theSnapshotManagerupdates its internal state and a module we calledObserverModule, which is used to add snapshot-relatedmetadatato the testcase.
Save function flowThe
restorefunction is simpler, it restores the current snapshot before retrieving the path to the target snapshot. It then restores the chain of snapshots by copying the savedSnapshotModulestate back into theSnapshotModuleand calling theSnapshotModule'sresetfunction.
Restore function flowTaking snapshots
As the goal is to explore a state machine, we want to take snapshots when the internal state changes. This part is target specific, some will use a single function that sets the state, others could have a function for each possible state, and some others will just write the state to a memory region. Libslirp falls into the latter category.
To target libslirp, our fuzzer is using a hook to retrieve the memory region allocated for the
tcpcbstructure (which contains thet_statefield) to track the state of the connection. Then, awrite_hookstracks write- operations in thet_statefield, signaling to the harness, through theOberserverModule, that it should ask theSnapshotManagerto try taking a new snapshot when execution ends.
We also used apre_syscall_hookto hook thesocketandfcntlsyscalls, and variousInstructionHookto bypass some verifications such as the checksum.The harness and metadata
With our design, part of the logic is handled in the harness. LibAFL-Qemu expects the harness to take the fuzzer's state as an argument, so it is possible to retrieve the current testcase and the metadata attached to it. Our implementation heavily relies on this to drive the
SnapshotManagerand to save to disk all the information we need to reproduce a given testcase.When a snapshot is generated, its
SnapshotIdis added to the new testcase's metadata. When a testcase is used and mutated, the harness retrieves its metadata and restores the snapshot associated to the storedSnapshotId. If no new snapshot is generated but new coverage is found, the restored snapshot is kept as the associated snapshot.
The bytes that were sent are stored in the metadata under the namegen_bytes, along with the associatedSnapshotId. This allows to easily retrieve the full chain of inputs leading to a given testcase (because it is not straightforward to differentiate between a testcase which generated new coverage while on a given snapshot, and the testcase which generated the snapshot).
Harness decision makingDrawbacks and limitations
There are a few drawbacks and limitations coming either from our design or LibAFL itself, that we will discuss a bit more later in the section:
QASANdoes not work with (multiple) snapshots.- This fuzzer was built on LibAFL 0.15.4, which often crashes when the target/Qemu crashes, killing the fuzzer.
- LibAFL-Qemu does not come with a full-restore mechanism, making it impossible to have two separate trees of snapshots.
- A new snapshot is associated to the testcase that generated it, providing a low diversity in the subsequent inputs.
- External tooling is required to reproduce a series of input.
- The snapshots take a lot of memory so the deduplication criterion is very important.
- It is not possible to share testcases between fuzzer instances.
The third limitation comes at the price of having only a single entry in the initial corpus, or taking a snapshot before starting the fuzzing loop and forcing it as the root of all snapshots.
Optimizing the memory consumption of storing snapshots would require modifications to the
SnapshotModule, so we did not do it (yet).
Sharing testcases does not carry metadata informations and even if it did, theSnashotIdwould not correlate between instances. It should be possible to work around it using theEventManagerbut this was not explored (yet) as the benefit might not be worth the time.QASANhas an internal shadow memory which would need to be saved and restored by theSnapshotManager. It appears theAsanHostModuleprovides thesnapshotandrollbackfunctions that could be leveraged for this but it is not straightforward.As new snapshots are associated to the testcase generating it, the mutation step will generate a variant of this testcase and restore the associated snapshot. So the fuzzer has a high chance to keep generating inputs which resemble the one which generated a given snapshot.
In the case of a TCP stack, the difference is not huge, especially when we have a mutator which ensures some fields are kept, but targeting a protocol such as TLS would require more diversity. Decoupling the testcase from the snapshot could be the answer in such cases.External tooling is required to walk the input list and reconstruct the full chain required to run it. We can turn this limitation into a strength by having a separate tool which monitors new inputs, retrieves the chain leading to it and runs it under ASAN and dumps the coverage.
Offline reproducer, coverage collection and sanitization
As stated in the previous section, some instrumentation can interact with the snapshot part of the fuzzer in bad ways, so the easy path is to have external tooling. We chose to use Notify to react to new testcases being written to disk. When a new testcase is found its metadatas are parsed in order to retrieve the associated snapshot, the parent snapshot of the associated snapshot, the
gen_bytesand a few other useful information.
Keeping aHashMapallows to retrieve the full chain of inputs leading to the new testcase, then the only thing left to do is spawn a new process which will set up a fuzzer with bothAsanHostModuleandDrCovModuleto test the input chain against ASAN and collect the coverage in DrCov format, ready to load in bncov. The design of the two modules makes it mandatory to run a full fuzzer and callfuzzer.evaluate_input, rather then just callqemu.runon the instrumented Qemu instance because it does not trigger thepre_execandpost_execfunctions.Testing the fuzzer
The fuzzer targeting libslirp is available on Quarkslab's github. The instructions to compile libslirp on the correct commit, along with a patch to build the target binary and suppress false positive integer overflow (seq/ack numbers wrapping), and then run the fuzzer are in the readme.
The code has been split to highlight libslirp-related and tcp-related code parts. We kept the full naming (e.g.
libslirp::utils::setup_target_arguments) to make it easier to locate which parts are the core of the fuzzer and which parts are target-specific.&boxvr&boxh&boxh Cargo.lock &boxvr&boxh&boxh Cargo.toml &boxur&boxh&boxh src &boxvr&boxh&boxh libslirp &boxv &boxvr&boxh&boxh hooks.rs &boxv &boxvr&boxh&boxh misc.rs &boxv &boxvr&boxh&boxh mod.rs &boxv &boxur&boxh&boxh utils.rs &boxvr&boxh&boxh network_targets_utils &boxv &boxvr&boxh&boxh inputs.rs &boxv &boxvr&boxh&boxh mod.rs &boxv &boxvr&boxh&boxh mutator.rs &boxv &boxvr&boxh&boxh tcp.rs &boxv &boxur&boxh&boxh utils.rs &boxvr&boxh&boxh main.rs &boxvr&boxh&boxh feedback.rs &boxvr&boxh&boxh observer_module.rs &boxvr&boxh&boxh snapshot_manager.rs &boxur&boxh&boxh utils.rsOur fuzzer against CVE-2026-9539
The video below shows the fuzzer running against an unpatched libslirp, compiled with UBSAN only looking for signed and unsigned integer overflows and ignoring the overflows on seq/ack numbers. The logs show both the TCP connection state before the next input is sent (call to
libslirp::misc::log_target_stateatmain.rs:244) and the input we are sending.
In the video it takes seconds for Qemu to crash on aIllegal instruction, this is because UBSAN is in trap mode so it raises anUDinstruction upon errors. As stated in the «Drawbacks and limitations» section, LibAFL-Qemu can have some issues with signal handling on the version we used.
Our fuzzer against CVE-2026-9539As Qemu and the fuzzer are crashing on the
UDinstruction we have no information about what happens, so you should either trust us or try it yourself in minimal runtime mode, stop the fuzzer and scroll-up to find the error and confirm it did hitCVE-2026-9539.Acknowledgement
This project was AI-free.
I'd like to thank my colleagues, in particular Laurent Laubin, Chris and Celian for their support and inputs on the project.
I'd also like to thank:
- Addison Crump, his parking game fuzzer was a great and fun introduction to implementing custom feedbacks and metadatas in LibAFL;
- Toka for his work on LibAFL-Qemu;
- Romain Malmain for his work on LibAFL-Qemu and answering my questions when I first started experimenting with LibAFL-Qemu;
- last but not least, I'd like to thank Samuel Thibault, who is a maintainer of libslirp and supervised my first try at fuzzing on a real target back in 2020.
-
🔗 anthropics/claude-code v2.1.311 release
What's changed
- Added
--hold-idle-fileand--max-hold-mintoself-hosted-runner, to keep an idle session while your host reports processes it left running - Added a tip for the Explanatory output style, shown when you ask Claude for explanations
- Fixed long freezes at startup and after reading or editing files when a CLAUDE.md file holds a very long list item
- Fixed interrupting Claude not taking effect until a timeout while an MCP server had not answered a resource read or a skill was still downloading
- Fixed standard-context sessions stopping with "Usage credits required for 1M context" when a request ran over 200K tokens; Claude Code now compacts the conversation and continues
- Fixed Write and Edit stalling for up to 5 seconds after they ran, and reporting 0 lines changed, when changing thousands of lines in a file
- Fixed subagents being unable to use MCP tools from servers that finish connecting after the subagent starts
- Fixed Claude seeing stale MEMORY.md and CLAUDE.md content right after automatic compaction when those files were edited earlier in the session
- Fixed
claude -pand SDK sessions saving transcript messages out of order or keeping messages that were taken back - Fixed
SubagentStophooks running about twice a minute for each running subagent instead of once when it finishes - Fixed the @ file picker ignoring
.ignore/.rgignorenegation rules that re-include git-ignored files - Fixed a subagent's isolated worktree being removed while a background subagent it started was still working in it
- Fixed background agents in auto mode that wait on their own shells starting a new main conversation turn on every wake
- Fixed the Bash tool description claiming the working directory always persists between calls
- Fixed the environment block naming a shell commands don't run in, such as fish when the Bash tool uses zsh
- Fixed
claude mcp add,claude mcp removeand/mcpnaming the current folder instead of the project entry in~/.claude.jsonthat holds a local-scope server when run below a repository root - Fixed
claude mcp listandclaude mcp getshowing the error code twice on failed-connection lines (for exampleENOENT: ENOENT: …) - Fixed Remote Control sessions staying on "Connecting" for about two minutes when a network proxy blocks a startup request
- Fixed messages that Claude sends to a cloud or Remote Control session appearing as your own message in the Claude mobile apps
- Fixed Claude not being told the cause when a file attached to a message sent over Remote Control or to a cloud session could not be saved because the disk was full, or that a message's attachments past the first 20 were left out
- Fixed WebFetch and WebSearch hanging on a stalled response in Cowork cloud sessions; an unfinished request now fails after 300 seconds
- Fixed a background session that crashed between turns not being restarted while it was attached, pinned, or had a scheduled task or wake-up set
- Fixed the "background service did not respond" error suggesting the disabled
claude daemon restart; it now suggestsclaude daemon stop --anyand says it ends background sessions - Fixed
claude respawn <id>starting the background service before reporting that no background session matches the id - Fixed
/effortnot warning about a prompt cache miss in plan mode when the plan model differs from the session model - Fixed
/idesaying the VS Code extension was installed before the install finished or when it failed - Fixed the Write tool's file preview skipping rows and miscounting hidden lines when a line is wider than the terminal
- Fixed ↑ in an agent's chat tab recalling a message that was still waiting to be delivered, so resending it sent a second copy
- Fixed Cowork cloud sessions losing their connectors and most tools after a restart when a plugin or your settings named an
agent; Cowork cloud sessions now ignore that setting - Fixed agent teams sessions showing an empty task list when coming back with
--resume,--continue,/resumeor--session-id, including after/clearor a crash, and/branchwriting to the original session's list - Fixed pasting text that mentions an image file, such as
! open /tmp/shot.pngor/review look at /tmp/shot.png, attaching the image and dropping its path from the prompt - Fixed the feedback draft card showing its 1/2/0 and Esc shortcuts while the prompt has text, when those keys act on the prompt instead of the card
- Fixed a lone backslash in quotes or brackets, like
"\"or(\), disappearing from Claude's responses - Fixed agent teammates compacting their history when
DISABLE_COMPACTis set - Fixed the rewind menu offering "Summarize from here" and "Summarize up to here" when
DISABLE_COMPACTis set - Fixed a finished
/code-review, or another skill that runs in a sub-agent, running a second time when a cloud or background session restarts - Fixed long hidden thinking being cut off as idle on Google Vertex AI, Microsoft Foundry and Claude Platform on AWS, where the endpoint sends thinking progress updates
- Fixed
/idesaying it had installed the JetBrains plugin when nothing was installed - Fixed Claude Pro and Max subscribers being told to ask their admin when their subscription can't be used; the message now points to billing settings
- Fixed the diff pane opening by itself after an edit in wide fullscreen terminals when it had nothing to show
- Fixed
/mcpshowing a remote server as failed after "Clear authentication" when the server works without sign-in - Fixed
/mcpshowing "authenticated" for a remote server that Claude Code sends no credentials to - Fixed a
--plugin-dirfolder of plugins loading as one plugin when an empty.mcp.jsonwas at its top - Fixed
/usagenever showing large prompt-cache misses under "What's contributing to your limits usage?" - Fixed status line links staying plain text in background sessions after you open them from a terminal that supports links
- Fixed the /rewind confirmation saying the conversation "will be forked" when the later messages are removed from the conversation
- Fixed the /rewind warning that wrongly said manual and Bash edits are never affected by a code restore
- Fixed plan approval in screen reader mode sending feedback you had dismissed with Escape
- Fixed Claude Code retrying requests the API marked not to retry, which could hold a turn for minutes or, in unattended retry mode (
CLAUDE_CODE_RETRY_WATCHDOG), indefinitely - Linux: Fixed sandboxed Bash commands failing with
bwrap: Can't create filewhen a--plugin-dirfolder was also an added directory andpermissions.blockReadsOutsideWorkingDirectorieswas on - Self-hosted runner: Fixed a session failing to start when a rate limit (HTTP 429, or a git wrapper that exits 75) blocks an added read-only repository; it now starts without that repository
- Improved startup time for Pro and Max accounts by skipping two network requests on launches within an hour of the last check
- Improved
/teleportandclaude --teleportto warn when a compacted cloud session loads from its last compaction, so the messages it summarized aren't in the local copy - Improved the messages shown when a background session's process exits: they no longer promise a restart that isn't coming, and they say how to resume the session
- Improved artifacts with several views: Claude now routes each view on the link's
#nameand no longer says the address bar stays the same as you switch views - Improved shell commands that reach their timeout: the result now shows the output so far and says the command is still running in the background
- Improved compaction: when the model's reply has no summary in it, Claude Code now usually asks for the summary once more before it replaces the conversation
- Improved the Artifact tool's choice between a page and a document: explainers and visual or interactive work become artifact pages; documents are for writing people keep editing or pass around
- Improved startup time for launches whose only arguments are options and their values, such as
claude --model opus - Improved the "Connection dropped" API error: it now says where to look first (the proxy or gateway in use, else VPN or firewall; Anthropic API only, Bedrock, Vertex and Foundry are unchanged)
- Improved screen reader mode: deleting a rule in /permissions says "Deleted allow rule …" right away
- Improved the message shown when a pasted sign-in code is refused: it now says the code may have expired or been used, and to sign in again
- Improved Slack connector sends: Claude now checks a channel's topic for posting rules before messaging a channel you didn't name
- Improved screen reader mode: Claude's questions are listed as "Questions: Color (answered), Pages", without arrows or symbols
- Changed
ultrathinkin the interactive terminal to run its turn at xhigh effort on Opus 5.5, Sonnet 5.5, Haiku 5.5 and Fable 5.1 through Anthropic's API; typed while Claude is working, it raises the rest of that turn - Changed the
ultrathinkrainbow to appear only where the keyword can raise effort, and not when the word is quoted or part of a file path - Changed Ctrl+D in agent view to match the prompt: on an empty input, pressing it twice exits
- Changed
--output-format jsonandstream-jsonoutput to write DEL, C1 control and Unicode format characters inside strings as\uXXXXescapes; parsed values are unchanged - Changed model names and IDs to drop the
[1m]suffix and its label on models where the suffix has no effect; the suffix is still accepted - Changed startup warnings about permission rules in settings files to show once per user until the rule changes
- Changed
/code-reviewto tell Claude to put the effort level first and use max only when asked - Changed
DISABLE_COMPACTin settings files and in a mod's$.env.setso they can only turn compaction off, not back on - Changed Claude Code on Bedrock, Mantle, Vertex, and Foundry to load model settings from a signed file on downloads.claude.ai; set CLAUDE_CODE_MODEL_CATALOG=off to turn this off
- Changed sessions that set
CLAUDE_CODE_SYNC_SKILLSwith feature-flag fetching off to reuse a claude.ai skills list up to 10 minutes old that another session on the machine fetched - Changed clicks on scrollbar arrows and bars in fullscreen lists to act when the mouse button is released, so moving off the scrollbar before letting go cancels the click
- Changed
claude purgeto say it deletes data only on this computer, not anything stored by Anthropic - [VSCode] Added syntax coloring to code blocks in Claude's replies, in light, dark and high contrast dark themes
- [VSCode] Added a "Running UserPromptSubmit hooks" spinner status and screen reader announcement for slow UserPromptSubmit hooks
- [VSCode] Fixed custom skills and custom slash commands sent from the VS Code or JetBrains panel leaving out the open file or selected lines that ordinary messages include (#102799)
- [VSCode] Fixed the extension host freezing while the login shell ran its start-up files to read PATH on macOS and Linux
- [VSCode] Fixed clicking an image in a tool result, or closing its preview, also opening the result's text in an editor tab
- [VSCode] Fixed voice dictation continuing to record after a message was sent with the Send button; sending now stops dictation first, as pressing Enter already did
- [VSCode] Changed the extension to start Claude Code sessions with
DISABLE_TELEMETRYset while VS Code's telemetry setting is off, so they send no usage metrics or error reports and fetch no feature flags - [VSCode] Changed the session list side bar to load Web sessions when the Web tab is first opened, not at startup
- [Cloud sessions] Fixed routines in Anthropic-hosted environments staying locked after their owner left the organization and rejoined; the owner can now turn them back on
- [Cloud sessions] Fixed a failed routine API token delete or regenerate showing nothing if the edit dialog had already closed; it now shows an error toast
- [Cloud sessions] Fixed cloud environment dialogs, including the admin dialog, accepting duplicate names; they now refuse a name another listed environment already has
- [Claude Tag] Added a Skills view to Claude Tag analytics showing how often Claude runs each attached skill in Slack channels and which go unused, with Usage links in admin settings
- [Claude Tag] Improved Claude Tag routines that run in a new session: a run with nothing to report can now end without posting a throwaway message to the channel
- [Claude Tag] Changed Claude Tag admin settings to show a lock instead of # for private Slack channels that your own Slack account can see
- [Code Review] Improved Code Review's check run to say no further automatic review will start when the model still can't analyze a change on the automatic retry
- [Code Review] Improved Code Review reliability: a review whose session fails to start because of a transient server fault is now retried once automatically, and its check run says so
- Added
-
🔗 @HexRaysSA@infosec.exchange 📢 IDA 9.5 is here: more platforms, more agentic power. mastodon
📢 IDA 9.5 is here: more platforms, more agentic power.
→ 3 new decompilers: Android Dalvik, Infineon TriCore and Qualcomm Hexagon
→ IDA MCP and Assist for AI-driven reverse engineering
→ Recursive decompilation across call graphs
→ IDA Home now includes 11 cloud decompilers instead of 2, at the same price
→ And much, much moreIt’s one of our biggest releases yet. Active license holders can download it now from the Download Center.
-
🔗 Hex-Rays Blog IDA 9.5 Is Here: More Platforms, More Agentic Power. rss
IDA 9.5 is here, and it’s one of our biggest releases yet.
Three new decompilers for Android Dalvik, Infineon TriCore, and Qualcomm Hexagon significantly expand platform coverage, while Apple kernelcache and DriverKit analysis take a major step forward. Support for AVX/SSE, Armv9, MIPS Release 6, WebAssembly 3.0, PowerPC, and ARC gets stronger too.

-
🔗 r/Harrogate Duck ponds? rss
Are there any places to see ducks in Harrogate? Thanks!
submitted by /u/jadorefrenchfries
[link] [comments] -
🔗 pydantic/monty v1.4.0 - 2026-10-26 release
What's Changed
- Enable smallvec's union feature so monty builds for 32-bit targets alone by @Butch78 in #1113
- fix(os_access): reject a file that replaces a directory, in any order by @Yi-111-a in #1070
- Fix argument reference leak when calling non-callable types by @RanaPriyansh in #1098
- Reject OSAccess directory renames into descendants by @GoldArowana in #1067
- Preserve async future snapshots after auto-resume rejection by @GoldArowana in #1112
- Preserve OSAccess state when renaming a path to itself by @RanaPriyansh in #1095
- Match Python line boundaries in str.splitlines by @rudrakshkarpe in #1106
- Add a WebSocket pool to the napi JS client by @rewitt94 in #1104
- misc fixes to unwinding by @davidhewitt in #1094
- Generate dataclass methods and store on heap by @rewitt94 in #1026
- Use strum's
use_phffor largeEnumStringderives by @samuelcolvin in #1122 - Cut allocations from
fand%float formatting by @samuelcolvin in #1123 - Add the
decimalmodule by @samuelcolvin in #1119 - Release type-checker memory when sessions reset by @jaheba in #1083
- Make len and indexing O(1) on ASCII heap strings by @femto in #1127
- release: 1.4.0 by @rewitt94 in #1128
New Contributors
- @rudrakshkarpe made their first contribution in #1106
- @femto made their first contribution in #1127
Full Changelog :
v1.3.0...1.4.0 -
🔗 crmne/spotifast Spotifast v0.14.2 release
Spotifast 0.14.2 fixes signing in for the first time. Until now, Spotifast signed in through ncspot's Spotify app, and its developer has closed that app to other apps, so a first sign-in failed with "redirect_uri: Not matching configuration". Now you make your own free Spotify app, and the sign-in screen guides you through it. This release also plays local files at any sample rate, with their own covers and lyrics, asks Spotify for fewer audio keys, and fixes a crash in playlists with hidden songs.
Download Spotifast: Mac · Windows · Windows ARM · Linux · Linux ARM · Flatpak · AppImage · AppImage ARM
On Windows, pick the
.msi. The setup program (-setup.exe) is still attached so that installs from 0.12.0 and earlier can update through it.Changed
- Sign in with your own free Spotify app, guided on the sign-in screen. The screen shows each step: open Spotify's developer dashboard, create an app with the redirect URI it shows (with a Copy button) and Web API ticked, then paste the app's Client ID. Spotifast checks the Client ID with Spotify before the browser opens. Spotify requires Premium on the account that creates the app. If you are already signed in, nothing changes: Spotifast keeps working, and Settings offers the switch to your own app. Getting started has the steps. By @crmne; thanks @MrHunor and @Fabsss0505. (#1057, #1059)
New
- Local files play at any sample rate, including 48 kHz, hi-res and mono files, instead of only 44.1 kHz stereo. By @crmne; thanks @PeeblyWeeb. (#3)
- Queue a playlist's local files. Add to queue, Play next, a selection and a drop now queue them while this computer plays. By @crmne; thanks @paulwinches. (#1002)
- Local files show their own cover and lyrics, from the picture in the file and a
.lrcfile beside it or the lyrics in its tags. By @crmne; thanks @MaximoLongo. (#1001) - A page for when something goes wrong. When something goes wrong explains "Spotify refused the audio key" and "Spotify is being slow" in plain words, with what helps. By @crmne.
- The Winamp D button steps through 1x too, so a skin can show pixel for pixel. By @crmne.
Fixed
- Fewer "Spotify refused the audio key" errors. Spotifast now asks Spotify for one audio key at a time, waits after a refusal before asking again, and fetches ahead only the next song's key. By @crmne; thanks @mrcego. (#283)
- A refused audio key is explained in a banner that says what happened, that a phone or another device still plays, and opens the device picker, instead of a red error. By @crmne; thanks @mrcego. (#283)
- When Spotify slows the shared app, a banner says so and offers to set up your own app, at most once a day. By @crmne.
- Repeat One turns into Repeat All when you change songs, as in Spotify's apps. Restarting the song keeps it. By @crmne; thanks @jorisw. (#1022)
- Scrolling to the end of a playlist with hidden songs no longer crashes Spotifast, and the right row plays. By @MaxRong; thanks @Alexandre-Froes. (#1046, #1041)
- The remote volume slider no longer jumps back while Spotify catches up. By @nikankad; thanks @TobiasVeiga00. (#1045, #1009)
- Related artists load without waiting on the shared app. By @github-lover-9999. (#1044)
- A
.lrcfile saved with a byte order mark keeps its first line. By @MaxFreedomPollard. (#1034) - Dates like "2 days ago" stay in step with the clock in every language. By @EnricoNSilva. (#1032)
- Single-key player shortcuts work while a song row has focus. By @EnricoNSilva. (#1031)
- Full-screen lyrics use the whole window width, without room kept for a side panel. By @itsmunzir; thanks @pomjoep. (#892, #783)
- Page Up, Page Down, Home and End move through the main page. By @sabrimete; thanks @warfl0p. (#998, #990)
- The account menu shows your plan right under your name, and settings cards no longer have extra room at the bottom. By @crmne; thanks @Guanran928. (#1038, #1037)
- macOS says menu bar, not tray. By @crmne; thanks @jorisw. (#1006)
- Visualizers keep moving in Winamp shade mode. By @jeffgreco. (#985)
- Your Top Songs can show the last 4 weeks, the last 6 months or the past year, on Home and its page, in every language. By @saikumargudelly. (#956, #955)
Thanks
@MrHunor, @Fabsss0505, @PeeblyWeeb, @paulwinches, @MaximoLongo, @mrcego, @jorisw, @MaxRong, @Alexandre- Froes, @nikankad, @TobiasVeiga00, @github- lover-9999, @MaxFreedomPollard, @EnricoNSilva, @itsmunzir, @pomjoep, @sabrimete, @warfl0p, @Guanran928, @jeffgreco, @saikumargudelly, and everyone who reported problems since 0.14.1.
Full changelog :
v0.14.1...v0.14.2 -
🔗 roboflow/supervision supervision-0.31.0 release
v0.31.0 — Depth, moving cameras and pose mAP
supervision now sees depth: load depth maps from your model or stereo rig, measure how far each object is, and draw the map.
sv.DepthMapmeasures the distance to every detection and colours depth over any image, no OpenCV needed.PolygonZoneandLineZonekeep counting in the right place while the camera pans.KeyPointMeanAveragePrecisionscores pose models the waypycocotoolsdoes.- Kosmos-2 , Gemini 3.6/3.7 and MediaPipe hands now load straight into
DetectionsandKeyPoints. MeanAveragePrecisionruns far faster on crowded images and lets you raise the detection cap.
It's a drop-in upgrade if 0.30.x showed you no deprecation warnings, apart from four output changes.
sv.ByteTrackwith thesupervision.trackerpackage,supervision.keypoint,sv.LMM, the legacysv.MeanAveragePrecisionand a few helpers are gone; the Migration guide has the swaps.✨ Spotlights / highlights
Depth maps: load, measure and draw
sv.DepthMapholds metric depth, stereo disparity or relative depth for one frame, and keeps track of which one it is.sv.DepthCameraconverts disparity to metres,measure_detectionswrites the median depth under each object todetections.data("depth_m"when the map can give metres), andsv.DepthAnnotatorcolours the map over an image without OpenCV.sv.DepthClipRangekeeps one colour scale across a whole video, so colours don't flicker between frames. Loaders read Roboflow Inference, Ultralytics, Transformers, and 16-bit PNG and PFM dataset files such as KITTI and Middlebury. (#2691, #2692, #2693, #2694)import numpy as np import supervision as sv depth = np.full((100, 100), 20.0, dtype=np.float32) depth[20:40, 20:40] = 4.0 depth_map = sv.DepthMap(depth, kind="depth_m") detections = sv.Detections(xyxy=np.array([[20, 20, 40, 40], [60, 60, 90, 90]], dtype=float)) detections = depth_map.measure_detections(detections) detections.data["depth_m"] # array([ 4., 20.], dtype=float32) annotated = sv.DepthAnnotator().annotate(np.zeros((100, 100, 3), np.uint8), depth_map)people-walking-composed.mp4
Zones that follow the camera
Zones used to assume a fixed camera; when it panned, the scene slid out from under the zone.
PolygonZone.triggerandLineZone.triggernow take an optional per-framecoord_transformthat maps detection anchors back into the frame the zone was drawn on. Any object withabs_to_relandrel_to_absworks, as described by the newsv.CoordinatesTransformationprotocol, including the transformations from thetrackersmotion estimator. Drawing is unchanged, andcoord_transform=Nonekeeps current results. (#2657)import numpy as np import supervision as sv class CameraShift: def abs_to_rel(self, points): return points + [50, 0] def rel_to_abs(self, points): return points - [50, 0] zone = sv.PolygonZone(polygon=np.array([[0, 0], [100, 0], [100, 100], [0, 100]])) car = sv.Detections(xyxy=np.array([[120.0, 40.0, 140.0, 60.0]])) zone.trigger(car) # array([False]) zone.trigger(car, coord_transform=CameraShift()) # array([ True])COCO keypoint mAP for pose models
sv.metrics.KeyPointMeanAveragePrecisionscoressv.KeyPointspredictions by Object Keypoint Similarity at ten thresholds from 0.50 to 0.95, and its scores agree withpycocotoolsCOCOeval(..., "keypoints"). COCO greedy matching is now vectorized for box and keypoint mAP. In the benchmark reported with that change, one image with 1000 predictions and a 1000-detection cap dropped from 35.9 s to 0.5 s.MeanAveragePrecisionalso takesmax_detection_thresholdsfor scenes with more than 100 objects. (#2687, #2733, #2716)import numpy as np import supervision as sv from supervision.metrics import KeyPointMeanAveragePrecision targets = sv.KeyPoints( xy=np.array([[[10, 10], [60, 10], [35, 80]]], dtype=np.float32), class_id=np.array([0]), data={"area": np.array([4000.0])}, ) predictions = sv.KeyPoints( xy=np.array([[[11, 10], [60, 12], [35, 79]]], dtype=np.float32), class_id=np.array([0]), detection_confidence=np.array([0.9]), ) metric = KeyPointMeanAveragePrecision(sigmas=[0.25, 0.25, 0.25]) metric.update(predictions, targets).compute().map50 # 1.0More models, and the matcher behind the metrics
sv.Detections.from_vlmparses Kosmos-2 grounding results (sv.VLM.KOSMOS_2) and Gemini 3.6 and 3.7 structured boxes and polygon masks.sv.KeyPoints.from_mediapipeloads MediaPipe hand landmarks, withclass_id0 for a left hand and 1 for a right hand.sv.match_detectionsexposes the one-to-one greedy IoU matcher the metrics use, for comparing two models or auditing labels against predictions. (#1903, #2504, #2283, #2557)import supervision as sv caption = "a snowman next to a fire" entities = [("a snowman", (0, 9), [(0.1, 0.2, 0.4, 0.9)]), ("a fire", (19, 25), [(0.5, 0.6, 0.8, 0.95)])] detections = sv.Detections.from_vlm(sv.VLM.KOSMOS_2, (caption, entities), resolution_wh=(640, 480)) pairs, unmatched_a, unmatched_b = sv.match_detections(detections_a, detections_b)🔄 Migration guide
No breaking changes beyond the APIs deprecated in 0.26–0.28 and scheduled for removal in 0.31.0. If 0.30.x printed no deprecation warnings for your code, only the four output changes at the end of this section can affect it.
Removed | Use instead
---|---
sv.ByteTrackand thesupervision.trackerpackage |ByteTrackTrackerfrom thetrackerspackage (pip install trackers); callupdate()instead ofupdate_with_detections()
supervision.keypoint|supervision.key_points
sv.LMM,Detections.from_lmm|sv.VLM,Detections.from_vlm
legacysv.MeanAveragePrecision(supervision.metrics.detection) |sv.metrics.MeanAveragePrecision
sv.denormalize_boxes(normalized_xyxy=...)|sv.denormalize_boxes(xyxy=...)
supervision.dataset.utils.mask_to_rle/rle_to_mask|sv.mask_to_rle/sv.rle_to_mask
ensure_cv2_image_for_annotation|ensure_cv2_image_for_class_method(supervision.utils.conversion)
ensure_pil_image_for_annotation|ensure_pil_image_for_class_method(supervision.utils.conversion)
ensure_cv2_image_for_processing|ensure_cv2_image_for_standalone_function(supervision.utils.conversion)
create_tiles,overlay_image(alsosv.overlay_image),validate_keypoint_confidence,validate_keypoints_fields| no direct replacement# before tracker = sv.ByteTrack() detections = tracker.update_with_detections(detections) map_result = sv.MeanAveragePrecision.from_detections(predictions=predictions, targets=targets) # after from trackers import ByteTrackTracker from supervision.metrics import MeanAveragePrecision detections = ByteTrackTracker().update(detections) map_result = MeanAveragePrecision().update(predictions, targets).compute()Four behaviour changes can alter output:
sv.Detectionsraises on non-finite boxes,sv.CSVSinkwrites arrays as JSON lists,ConfusionMatrix.from_detectionsrejects lists of different length, and multi-classmAR @ Kscores follow COCO. Details under Changed and Fixed.📝 Notable changes
🚀 Added
- Depth maps.
sv.DepthMap,sv.DepthAnnotator,sv.DepthClipRangeandsv.DepthCamera, withto_depth,measure_detections,resize,crop,value_at,DepthAnnotator(scale="metric"), and loadersfrom_inference,from_ultralytics,from_transformers,from_png16andfrom_pfm. (#2691, #2692, #2693, #2694) - Camera-motion-aware zones.
PolygonZone.triggerandLineZone.triggeracceptcoord_transform, typed by the newsv.CoordinatesTransformationprotocol. (#2657) - COCO keypoint mAP.
sv.metrics.KeyPointMeanAveragePrecisionforsv.KeyPoints, matchingpycocotoolskeypoint evaluation. (#2687) - Configurable mAP detection limits. Keyword-only
max_detection_thresholdsonMeanAveragePrecision; the default(1, 10, 100)is unchanged. (#2716) - Mask confusion matrix.
sv.ConfusionMatrix.from_detectionsandbenchmarkacceptmetric_target=MetricTarget.MASKSand match by mask IoU, on dense masks orCompactMask. (#2612) - Metric result aggregation.
MetricResultbase class for metric results, plusaggregate_metric_results()andplot_aggregate_metric_results()to compare several results in one table or grouped bar chart. (#2498) - Public matcher.
sv.match_detectionsreturns one-to-one greedy IoU matches and the unmatched indices on each side, optionally per class. (#2557) - Kosmos-2.
sv.VLM.KOSMOS_2insv.Detections.from_vlm, one detection per grounded region. (#1903) - Gemini 3.6 and 3.7.
sv.VLM.GOOGLE_GEMINI_3_6andsv.VLM.GOOGLE_GEMINI_3_7parse the structured{"boxes": [...]}format, including normalized polygon masks. (#2504) - MediaPipe hands.
sv.KeyPoints.from_mediapipeloads hand landmarks from the TasksHandLandmarkerand the legacyHandssolution, with a new hand skeleton,class_id0 for left and 1 for right, and the handedness score indata["handedness_score"]. (#2283)
🌱 Changed
sv.Detectionsvalidatesxyxy: non-finite (NaN, inf) or non-numeric boxes now raiseValueErrorinstead of failing later. (#2503)sv.ConfusionMatrix.from_detectionsraises whenpredictionsandtargetsdiffer in length, instead of scoring the shorter list. (#2612)sv.CSVSinkwrites NumPy arrays indataandcustom_dataas JSON lists instead of NumPy's truncatedstr()form; parse array cells withjson.loads. (#2707)sv.Detections.with_nmmandsv.mask_non_max_mergemergeCompactMaskunions without full-image allocations; the error for mismatched image shapes now names both shapes. (#2606, #2616)sv.Detections.from_inference(compact_masks=True)crops each polygon mask to the polygon instead of the whole image, cutting time and memory for many polygons on large images. (#2678)- COCO greedy matching in
MeanAveragePrecisionandKeyPointMeanAveragePrecisionis vectorized; results are unchanged. (#2733) sv.ComparisonAnnotatorbuilds its mask union fromCompactMaskcrops in place instead of allocating a full(N, H, W)stack. (#2495)
❌ Removed
- APIs deprecated since 0.26.0–0.28.0 and scheduled for 0.31.0:
sv.ByteTrackand thesupervision.trackerpackage (usetrackers.ByteTrackTracker), thesupervision.keypointmodule (usesupervision.key_points),sv.LMMandDetections.from_lmm(usesv.VLMandfrom_vlm), the legacysv.MeanAveragePrecision(usesv.metrics.MeanAveragePrecision),create_tiles,overlay_image,ensure_cv2_image_for_annotation,ensure_pil_image_for_annotationandensure_cv2_image_for_processing(use theensure_*_for_class_method/ensure_cv2_image_for_standalone_functiondecorators),validate_keypoint_confidence,validate_keypoints_fields, thenormalized_xyxyargument ofsv.denormalize_boxes(usexyxy), and thesupervision.dataset.utilsimport path formask_to_rle/rle_to_mask. (#2582)
🔧 Fixed
sv.Detections.from_ultralyticsno longer shifts or truncates segmentation masks when letterbox padding is fractional. (#2739)- Indexing
sv.Detectionswith a Python list of booleans now selects list-valueddatawith the same mask as the arrays; it was read as positions. (#2737) sv.move_boxesandInferenceSlicerno longer wrap integer coordinates when an offset crosses the dtype's range. (#2734)sv.Detections.box_aspect_rationo longer overflows on integer boxes at large coordinates. (#2729)BlurAnnotatorandPixelateAnnotatorkeep a(H, W, 1)grayscale channel axis instead of failing with a broadcasting error. (#2725)- Without OpenCV, thick
line,polylinesanddrawContoursoutlines match OpenCV'sLINE_8pixels forthickness2 or more. (#2727) - Without OpenCV,
fillPolypaints the same boundary pixels as OpenCV, sopolygon_to_maskandPolygonZoneagree across backends. (#2730) - Without OpenCV,
resizewithINTER_NEARESTsamples the same source pixels as OpenCV, which also alignssv.CompactMask.resizeacross backends. (#2722) sv.process_videostops reading the source when a callback or frame write fails, instead of decoding the rest of the video before raising. (#2720)- Label annotators with
smart_position=Trueseparate labels whose boxes share a center; before, only the last label was visible. (#2718) - Oriented-box
MeanAveragePrecisionkeeps corner precision at large coordinates and puts objects in the right size bucket. (#2717) sv.KeyPointskeeps all three coordinates when selecting a single key point with a NumPy integer index. (#2715)- Integer boxes and oriented boxes no longer land in the wrong object-size category when their area overflows the dtype. (#2713)
sv.CompactMaskaccepts NumPy'scopykeyword, so NumPy 2 no longer warns on conversion. (#2708)sv.CompactMask.resizematches dense nearest-neighbour resizing, including crops that become empty. (#2697, #2705)DetectionDataset.as_yolo,as_pascal_vocandas_labelmeexport a mask with holes as one instance instead of one extra instance per hole;approximate_mask_with_polygonsinsupervision.dataset.utilsgains the opt-inbridge_holesparameter that does this. (#2703)sv.metrics.MeanAverageRecallapplies themAR @ Klimit per class per image, as COCO does; multi-class scores were too low. (#2701)sv.metrics.MeanAveragePrecisionscores perfect predictions as exactly1.0instead of 0.99999988. (#2687)from_vlmwith Gemini 2.5 or 3.5 keeps a mask pixel only where the score exceeds 127 of 255; masks grew by half a mask pixel per side. (#2589)from_vlmwith Gemini 2.5 or 3.5 keeps masks for the detections that passclasseswhen a filtered-out item has no mask. (#2504)from_vlmkeepsclass_idinteger-typed when aclassesfilter removes every detection for PaliGemma, DeepSeek-VL2 and Gemini 2.0. (#2556)from_ultralyticsforDetections,KeyPointsandClassificationsaccepts NumPy-backed results, includingResults.numpy(). (#2710)
🏆 Contributors
- JANG BYUNGKUN (@8rulerstar) — added
KeyPointMeanAveragePrecisionand fixed perfect-prediction mAP scoring. - Caio Viotti (@cfviotti, LinkedIn) — added depth support:
DepthMap,DepthAnnotator,DepthClipRange,DepthCameraand model loaders. - Kari Pikkarainen (@kari-pikkarainen, LinkedIn) — made zones follow camera motion with
coord_transform. - Christoph Deil (@cdeil, LinkedIn) — added
max_detection_thresholdstoMeanAveragePrecision. - Raghav Rathi (@raghav-rathi, LinkedIn) — added mask targets to
ConfusionMatrix. - shao (@shaoming11, LinkedIn) — added metric-result aggregation and sped up
ComparisonAnnotatorwith compact masks. - David (@David-rn) — co-authored metric-result aggregation from the original proposal.
- Jabrail (@jabrailkhalil) — added
sv.match_detections. - Soumik Rakshit (@soumik12345, LinkedIn) — added Kosmos-2 support in
from_vlm. - @Xayar145 — added Gemini 3.6 and 3.7 support in
from_vlm. - @tarunbommawar27 — added MediaPipe hand landmarks to
KeyPoints.from_mediapipe. - Advait Shukla (@AdvaitS) — made
Detectionsreject non-finite or non-numeric boxes. - Avanish Garg (@avanish-garg, LinkedIn) — fixed
CSVSinkarray output,CompactMask.resizeand mask holes in dataset export. - Iuri de Silvio (@iurisilvio) — sped up
Detections.from_inferencewith compact masks. - @trueoneplusone — sped up
with_nmmfor compact masks. - max (@quotentiroler) — vectorized COCO greedy matching in mAP.
- A Aswanth Raj (@aswanth-07, LinkedIn) — fixed
box_aspect_ratiooverflow,CompactMaskconversion and resize, single-pointKeyPointsselection and NumPy-backed Ultralytics results. - Mohammad Hijjawi (@MohammadHijjawi97, LinkedIn) — fixed boolean-list
Detectionsindexing andsmart_positionlabel overlap. - NIKHIL (@Nikhi00718) — fixed Ultralytics letterbox masks, grayscale blur and pixelate,
process_videocleanup and box-area overflow in metrics. - kevin (@kevin9327) — fixed thick-line drawing without OpenCV and Gemini mask binarization, and typed the test suite.
- Kaushik Reddy Lingireddy (@Lingikaushikreddy, LinkedIn) — fixed nearest-neighbour
resizesampling without OpenCV. - peng xiang (@px12811) — fixed
fillPolyrasterization without OpenCV. - Devulapalli Naga Sri Vaishnavi (@Vaishnavi220506) — fixed integer wrap in box translation and oriented-box mAP precision.
- Muhammad Talha (@Talhax55z) — fixed per-class
MeanAverageRecallscoring. - FootysHands (@ayo0la) — converted documentation examples to doctests.
- Eesha (@eesha5) — fixed imports in docstring examples.
- Jirka Borovec (@Borda, LinkedIn) — removed deprecated APIs, fixed
from_vlmclass_iddtype, followed up onwith_nmmperformance, and maintained docs, CI and release infrastructure.
Automated contributions:@dependabot, @pre- commit-ci, @Copilot
Full changelog :
0.30.0...0.31.0 -
🔗 HexRaysSA/plugin-repository commits sync repo: +1 release rss
sync repo: +1 release ## New releases - [HashDB](https://github.com/oalabs/hashdb-ida): 1.13.0 -
🔗 backnotprop/plannotator v0.28.31 release
Follow @plannotator on X for updates
Missed recent releases? Release | Highlights
---|---
v0.28.30 | An Artifacts view in the Inbox, comments on part of an image, diagrams in code review, Ask AI keeps its conversation in annotate
v0.28.29 | Plan review opens on OpenCode 2, a DOMPurify security update, closing a review stops the agent everywhere
v0.28.27 | Jump to open questions, files side by side or full screen, image zoom in the Inbox, empty To field, text size for plan review and annotate
v0.28.26 | Action items and reply drafts in the Inbox, one decision button for plan review, Enter to save a comment, a custom code font
v0.28.25 | Re-ask open questions, delivery ticks on the list, a count of new messages on the tab, right-click a thread, click Inbox to refresh
v0.28.24 | A new look for the Inbox, Send now, tag agents, comment on an agent's message, much smaller reads for agents, links in HTML pages
v0.28.23 | Inbox replies reach sessions with background subagents, dictated text no longer goes missing, 👍 Looks good reaches the agent, notifications that never fail silently
v0.28.22 | 👍 Looks good, full view for files, one viewer for a thread's images and files, every session prints its URL,PLANNOTATOR_BROWSER=noneopens nothing
v0.28.21 | Message an agent from the Inbox, video attachments, Open in for attachments, Code / Tests / Generated in code review, writes from other websites refused
v0.28.20 | Inbox search (⌘K), real folder names for projects, data files open in the code view, word-only replies leave questions open
v0.28.19 | Ask this session in T3 Code, folder sessions load shared stylesheets and images, the agent note asked once per agent, Copy connect prompt
v0.28.18 |plannotator inboxconnects your agents, agents are told when to use the Inbox, rendered Markdown in code review, Inbox Settings in sectionsWhat's New in v0.28.31
An onboarding tour for the Inbox, pinned threads, picture choices in questions, palettes in Inbox Settings, tailnet reviews from the Claude Code plugin tool, and the right gh account for a PR. 39 PRs, four of them from a first-time contributor, @utpalsinghdev.
Plannotator Inbox
An onboarding tour
A first run now opens on a screen explaining that the Inbox works beside the agents you already run, with two choices: take the tour or connect your agents. The tour replays a real thread from building the Inbox (a question with pictures, the reply, the next messages) and writes nothing to your Inbox. Returning users find it in Settings → General → Getting started.
Pin threads
Pin a thread from its right-click menu or the pin in its header. Pinned threads sit in the sidebar above Projects with their state, keep their place in the list, and stay pinned when archived.
Pictures and stakes in questions
An agent can put a picture on each choice, and a question card shows them as tiles you pick from, with a zoom button. Optional
Stakes:,Shows:,Why:andReversible:lines show under the prompt and the choices. A recommendation that names the start of a choice (Recommended: Unpin itfor- Unpin it: …) now marks that choice.Skip questions from the open-questions list
Skip… at the foot of the "N open questions" list lets you tick the questions to skip, or Skip all. Skips wait in your draft until the next Send.
Palettes in Inbox Settings
Settings → General → Appearance → Colors picks the palette for the light and the dark half, the same setting plan review's Theme tab uses.
Step through files on a phone
Full screen on a phone has a
4/9 ⌄pill for every file in the thread, and a sideways swipe steps to the next or previous file.Smaller changes
-
The Inbox says which agents your reply wakes. Claude Code, Pi and OpenCode 2 get it as a new turn on their own; agents through MCP see it when they next check. Agents nothing wakes are told to call
wait_for_reply. #2168 -
Every wake ends with a line naming the thread id,
read_threadandplannotator inbox --help. #2143 -
The Claude Code mod never steers into or aborts another plugin's turn. A reply waiting on such a turn goes in when the session is idle. #2176
-
The Inbox reminder reaches Team/Enterprise Claude Code sessions and comes back after compaction. #2167, closing #2159
-
No more "hook was skipped" notice at every permission prompt on Team/Enterprise accounts. #2160
-
The first-run screen asks for notifications , so the first question can notify. Your own sent reply shows your words and a short list of your answers. #2148
-
A dot on the sidebar toggle when an update is waiting and the sidebar is closed. #2135
-
Cursor gets the agent note as text to paste into its Rules (
plannotator inbox --notes cursor). #2153 by @utpalsinghdev, closing #1991 -
Agents are nudged to attach a screenshot for something visual. #2175
-
An image the Inbox cannot load shows as its alt text , not a broken icon. #2177
-
Images and code in a choice keep their corners ; only the Recommended tag is a pill. #2179
-
Decision mode is experimental and off by default. It clears what agents ask across threads one decision at a time; turn it on in Settings → General → Experimental. #2141, #2154
Plannotator
Tailnet reviews from the plugin tool
The
plannotatortool in Claude Code takes atailscaleoption, so a review the agent opens can be read on your phone over Tailscale. Ask this session keeps working there for the Tailscale login that owns the machine; anyone else on the tailnet gets the separate Ask AI.The gh account that can see the PR
With two accounts signed in to
gh,plannotator review <PR URL>now uses the one that can read the PR, for that review only. Your gh setting is unchanged, and an invalidGH_TOKENis named.A fixed port for live app annotation
PLANNOTATOR_LIVE_PORTsets the live app proxy's port (or a range), so live annotation works over an SSH port forward.- #2145 by @utpalsinghdev, #2151, closing #2109
Plannotator Graphite
A new palette with a lighter, near-neutral dark half that stays readable in a bright room. Pick it in Settings → Theme.
Smaller changes
- A broken config.json is no longer overwritten. A settings save refuses, says how to fix the file, and leaves it as it was. #2178
- Session secrets no longer reach child processes. The Ask this session token and the decision-file paths stay out of git, gh and the agent CLIs a review starts. #2169
- A new release shows within minutes. Update checks read GitHub's latest-release link, and the review-window toast shows at most once a day. #2133, #2135
- Cursor review jobs never start another program named
agent. #2173 - Linux folder watches no longer exhaust inotify on large repositories. #2155 by @utpalsinghdev, #2163, closing #1439
- Replacing an Ask AI question in Pi no longer stops the running turn. #2126 by @utpalsinghdev, closing #2038
- Back in a multi-file annotate session keeps your place. #2129, closing #2128
- The image viewer says how to zoom when the wheel starts scrolling. #2131, closing #2127
- The diff shows again after switching through an empty diff in code review. #2180
- Guided Review viewer uploads retry and publish the entry last, so a failed deploy cannot leave exported guides unstyled. #2150
- Dependency updates , including Mermaid 12.2. #2152
Install / Update
macOS / Linux:
curl -fsSL https://plannotator.ai/install.sh | bashWindows:
irm https://plannotator.ai/install.ps1 | iexClaude Code Plugin: The plugin and the
plannotatorbinary update separately, so run the install script above as well. In a terminal:claude plugin marketplace update plannotator claude plugin update plannotator@plannotatorThen restart Claude Code. Inside Claude Code, run
/plugin marketplace update plannotator, then open/plugin→ Installed → plannotator → Update now.Pi:
pi update --extensionsOpenCode: Re-run the install script above. It now also clears the OpenCode 2 plugin cache.
What's Changed
- fix: preserve Pi turn when replacing an Ask AI question by @utpalsinghdev in #2126
- fix: Back in a multi-file annotate session keeps the reader's place by @backnotprop in #2129
- Image viewer: say how to zoom when the wheel starts scrolling by @backnotprop in #2131
- Inbox: skip a question from the open-questions list by @backnotprop in #2132
- Update notices: check GitHub's latest-release link often by @backnotprop in #2133
- Update notices: toast once a day, dot on the sidebar toggle by @backnotprop in #2135
- Inbox: skip from the questions list with a select mode by @backnotprop in #2136
- Add the Plannotator Graphite dark palette by @backnotprop in #2137
- Inbox: choose light and dark palettes in Settings → Appearance by @backnotprop in #2138
- Question cards: match a recommendation to the choice it begins by @backnotprop in #2139
- Inbox: pin threads to the sidebar by @backnotprop in #2140
- Inbox: decision mode (experimental, off by default) by @backnotprop in #2141
- Usage counts for experimental features, phase 1 (nothing is recorded or sent yet) by @backnotprop in #2142
- Inbox wake: a closing line with the thread id, read_thread and --help by @backnotprop in #2143
- Question blocks: optional Stakes, Shows, Why, Reversible and picture choices by @backnotprop in #2144
- fix: support fixed ports for live app proxies by @utpalsinghdev in #2145
- Inbox first run: notifications ask on the first-run screen; your sent reply in your own words by @backnotprop in #2148
- guides.show: retry viewer uploads, publish entries last, verify every file by @backnotprop in #2150
- Live proxy port: tests for PLANNOTATOR_LIVE_PORT, one-line errors for EACCES by @backnotprop in #2151
- chore(deps): bun minor and patch group by @backnotprop in #2152
- fix: offer manual Inbox notes for Cursor by @utpalsinghdev in #2153
- Decision mode: the agent contract lines on the Queue card by @backnotprop in #2154
- fix: watch directories instead of files on Linux by @utpalsinghdev in #2155
- Inbox: the onboarding tour by @backnotprop in #2156
- fix(mod): only take ExitPlanMode PermissionRequest events by @backnotprop in #2160
- feat: use the gh account that can see the PR by @backnotprop in #2161
- fix: Linux folder watches keep working past the cap and unreadable folders by @backnotprop in #2163
- Inbox: step files on a phone with the toolbar pill and a swipe by @backnotprop in #2164
- Inbox reminder reaches Team/Enterprise sessions and survives compaction by @backnotprop in #2167
- Inbox: say plainly which agents a reply wakes by @backnotprop in #2168
- fix: scrubbed env vars no longer reach child processes by @backnotprop in #2169
- Tailnet reviews from the plugin tool, with Ask this session for the machine's owner by @backnotprop in #2170
- Code review: Cursor agent jobs never start another program named agent by @backnotprop in #2173
- Inbox: nudge agents to attach a screenshot for something visual by @backnotprop in #2175
- Claude Code mod: never steer into or abort another plugin's turn by @backnotprop in #2176
- Inbox: draw an image the window cannot load as its alt text by @backnotprop in #2177
- Inbox tour: fix the QA findings; never write over an unreadable config.json or pins.json by @backnotprop in #2178
- Inbox: keep the pill on the Recommended tag, not on images or code in a choice by @backnotprop in #2179
- Code review: show the diff after a switch through an empty diff; name a rejected GH_TOKEN by @backnotprop in #2180
New Contributors
- @utpalsinghdev made their first contribution in #2126
Community
- @utpalsinghdev: the live app proxy port, Linux folder watches, the Cursor note and the Pi Ask AI fix (#2145, #2155, #2153, #2126)
- @serpi4: asked for tailnet reviews from the plugin tool (#2166)
- @tobeycodes: reported reviews failing with two gh accounts (#2157)
- @spawnia: reported the Team/Enterprise hook notices and the missing Inbox reminder (#2159)
- @vladmarchuk: asked for a fixed live proxy port (#2109)
- @aniravi24: reported inotify exhaustion on large repositories (#1439)
- @kyletruong: asked for the agent note in Cursor (#1991)
- @pstanton237: reported the Pi Ask AI interrupt (#2038)
- @zane668: reported the multi-file Back position and the image wheel zoom (#2128, #2127)
Full Changelog :
v0.28.30...v0.28.31 -
-
🔗 Rust Blog How to fund Rust contributors rss
TLDR:
- To fund general maintenance, donate to the Rust Foundation Maintainers Fund or sponsor the RustNL Maintainers Team
- To fund specific features and improvements, sponsor fundable Rust Project Goals
- To fund individual contributors, donate to their GitHub Sponsors accounts
There is always so much to do in the Rust Project! New features to implement, bugs to fix, performance optimizations to make, issues to triage… It takes a lot of work to keep our high bar of quality while also shipping new features and improvements. And the workload keeps increasing with the continuous growth of Rust adoption.
As is unfortunately common in open source projects, a large fraction of that work is currently done by volunteers. That causes various issues, such as people burning out or complex features taking many years to ship.
Unsurprisingly, one of the best ways to help improve that is to get more people who work on Rust funded! This year, several funding initiatives started ramping up, and we already experience many positive effects. They helped us improve the maintenance status of critical Rust projects and make significant progress on several long-awaited features, such as allocators, the never type, the next trait solver or the Polonius borrow checker. However, only a fraction of people working on Rust are currently funded for their work.
We know that there are Rust users, both individuals and companies, who would like to help improve Rust by funding it, but it might not always be obvious how exactly to do that. This post thus provides suggestions on how you can support the development of Rust in three ways.
If you're unsure which option fits, or would like to discuss funding on behalf of your company, please contact the Funding team.
Fund general maintenance
Maintenance is a continuous process required to keep Rust (or any software project for that matter) working. It consists of two main activities. The first is general housekeeping, such as ensuring that Continuous Integration works, dependencies are kept up-to-date and issues, bugs and security incidents are promptly triaged and resolved. The second is performing refactorings and code reviews, which ensures that the codebase will be able to evolve and continuously ship new features, without accruing extensive technical debt.
Having quality maintenance is crucial for the long-term health of Rust, yet it is typically very difficult to find funding for it; funders often want to sponsor specific new features, rather than just "keeping the lights on". However, without sufficient maintenance, it becomes much more difficult, and much slower, to ship new features. Improving the maintenance of Rust thus also helps us ship features and improvements faster, though the effects are sometimes only observable over longer periods of time.
Funding maintenance is a great choice if you want to let us decide how best to improve Rust. The Rust Funding team continuously looks for Rust teams and projects that require help with their maintenance efforts, and allocates available funds to Rust maintainers who could help improve the situation.
To fund Rust maintainers, consider donating to theRust Foundation Maintainers Fund or sponsoring the RustNL Maintainers Team.
Fund specific features and improvements
There are always many Rust improvements and new features that are in progress. We track some of those initiatives through Rust Project Goals. Each Goal describes a specific improvement to Rust: what it is, who is going to develop and drive it forward and which Rust teams are willing to help reviewing and maintaining it.
Some of those Goals are looking for funding. Either to help their owner dedicate time and focus to push the given feature forward, or to fund maintainers who will perform refactorings necessary to unblock that feature and review its implementation. Often funding is required for both. When a Goal is properly funded, the probability that it will achieve its milestones is much higher, which then translates in the given improvement being shipped sooner to Rust users.
Funding Project Goals is a great choice if you want to help push forward specific Rust features or Rust toolchain improvements that will benefit you or your company.
To fund contributors working on Project Goals, consider taking a look atGoals that need funding and reaching out to their funding contact. If in doubt how to proceed, reach out to the Rust Funding team.
Fund individual contributors
There are hundreds of people in the Rust Project who continuously work on improving Rust. Some of them have personal fundraising profiles (e.g. on GitHub Sponsors), which allows you to support them directly.
There might be various reasons for supporting a specific person. Maybe they are maintaining a crate that you love to use, maybe you like reading their blog posts, or maybe you are simply a fan of the work that they do. Whatever the reason, we are sure that they would appreciate your support!
Funding individual contributors is a great choice if you want to directly support Rust contributors whose work you appreciate.
To fund individual Rust contributors, check out their GitHub profile or personal website to see what options there are for supporting them. You can also examine our list of Rust Project members who can be supported through GitHub Sponsors[1].
Conclusion
We hope that this post is useful to anyone who would potentially like to invest funds into making Rust better. You can also find a shortened version of the "how to fund Rust guide" at the Funding page of the Rust website, or check out a RustConf 2026 talk by Niko Matsakis about how Project Goals and their funding works.
If you are a company looking to fund the development of Rust, consider joining the Rust Commercial Network. Joining the network is free, and Rust Foundation membership is not required. It can help you find opportunities for funding improvements in specific areas related to Rust usage (e.g. user interfaces, language interop, supply chain security, etc.) and collaborate on funding Rust development with other companies.
There are of course other ways of helping Rust other than donating funds. For example, you can check out Project Goals that are looking for contributors or more generally check our contributor onboarding guide. Companies can also help by giving employees paid time to contribute upstream, or by hiring Rust contributors to do that work. One possible model is the Engineer in Residence role, that was recently established in the Rust Foundation.
- Note that this list is not exhaustive; there are some Project members who accept donations through GitHub Sponsors (or another fundraising platform), but did not opt into being listed on this page. ↩
-
🔗 seanmonstar Micro: Make smaller structs rss
I’ve seen the hype about view types being added to Rust. I worry it exceeds the strangeness budget. And there’s a solution already available. Make your structs smaller.
I’ve always insisted on optimizing for reading. And as many use LLMs make writing faster, there’s even less reason to pick shorter but more complex.
Structs are free. They don’t result in auto boxing. So, divide up your structs by how the fields relate to each other. Then it’s much easier to borrow one field than to wish for some complex syntax to borrow many.
I have even created temporary projection structs to borrow disjoint fields together, though it’s a pretty rare thing to need.
I wrote a clippy lint to catch structs that are too big, but seems others think it’s too strict. I still think it’s a good idea.
-
🔗 New Music Releases Philip Glass - Classical Workday Focus rss
Philip Glass - a new release is available:
- 2026-10-26: Classical Workday Focus (Compilation)
Amazon: Canada | Deutschland | France | United Kingdom | United States
Visit muspy for more information.
-
- October 25, 2026
-
🔗 IDA Plugin Updates IDA Plugin Updates on 2026-10-25 rss
-
🔗 Register Spill Joy & Curiosity #103 rss
… and we're back! I spent the last two weeks travelling. First a week in New York City, then a week in San Francisco. I did many things in those two weeks, but not a lot of reading or writing, which is why you didn't hear from me.
But now I'm back! So, without further ado this week (my daughter is waiting for me to build a Lego truck), here's a bag of links.
-
We recorded a new episode of Raising An Agent, in person, in San Francisco. I think it turned out great. In fact, I said somewhere else that this might be the most important episode we've recorded this year. It's about nothing less than the company of the future. Highly recommend watching this if you're in any way curious about how Amp -- the team, the company -- operates.
-
While in New York, we visited a large customer of ours, an investment bank. I gave a talk there about how I use Amp and what I think have been the biggest 10x multipliers when working with agents. In San Francisco I then recorded the talk and it's been received very well, so here it is: How I Use Amp.
-
Adam Mastroianni is truly one of the best in the game right now. Everything he puts out is incredibly good. This newest one, Claude, don't touch my lump, is no exception. It might be the most convincing argument for why AI won't lead to unemployment I've read so far. The only counter-argument I can see is that, well, there will be jobs in the long term, but what about in the next five years?
-
"I'm 38. If You're in Your 20's or 30's, Read This." I'm also 38 and when I first saw this title I went "ugh", because hey, feels like I'm only just starting. But it's surprisingly good, even though it's a bit Buzzfeed-y. Maybe because it quotes the life-changing Jason Pargin post?
-
PhotoCraft: An open-source, photo editor written by scratch in pure Rust. I saved this link two weeks ago to share with you here. And now it's old news, isn't? Photoshop rebuilt in Rust? Big whoop. There's AAA games being decompiled and remixed with other AAA games while I'm typing this. (Still: what a time!)
-
This is still lovely: "made a rug for your desktop so you can sweep your mess under it"
-
"People are surprised that AI is finding weird unelegant maths results like this. I think there is a plausible explanation. Maths (and adjacent disciplines like physics and comp sci) had elegant results so far because humans are biased towards elegant solutions. I think this bias is due to how human minds work. We have a pretty small context window, and we are only able to find solutions that are relatively elegant. This gave us the impression that maths and the universe are elegant. Maybe they are not, and we are now finding out because we have intelligences that can work with much more complex solutions." The same is coming for programming and codebases. Some codebases in the future will look ugly, hacky, disgusting to programmers who grew up writing code by hand and yet they will run perfectly well in production, just as well as any handcrafted piece of code ever did, and agents will have zero problems modifying them.
-
Namespace had me on their new podcast and I finally got to talk about the Big Amp Rewrite we went through this summer. Because where else would you talk about it if not on a podcast called Once In The Trenches?
-
David Foster Wallace's Consider The Lobster. I don't know what made me re-read it, but it's so, so, so good. If you never read it, I highly recommend you do.
-
Toto Wolff talking to Patrick Collison on the Cheeky Pint podcast. This was really good. Not only because looking at F1 from a business and management and investment perspective is interesting, but also because Wolff, born in Austria, has a unique background: racing driver, then salesman, then investor in Austria and Germany at the height of the dot-com boom, then car racing investor and so on. Loved the story about sms.at.
-
John Gruber says you can now move (back) to X as a social media platform: X Once Again Marks the Spot. As someone who has never left but at times wondered whether he should, I could write pages here that would boil down to this: I have not used another social network where the highs are that high. And then there'd be a bunch of other pages about the lows, of course. If you're coming (back) to X, here's my advice: follow me (obviously), mute freely, mute keywords, train the algoritm by saying "I don't like this" on posts you don't like (you can configure the iOS app to do this with a single swipe), set a time limit per day and give the password to your wife.
-
(Even Marco seems to have soft-launched his comeback to X. I know that's a pretty cynical way to put it but I don't mean it in a negative way. It's just that… well, there was all this screaming and shouting about who's where and why and how could you that I can't help but raise an eyebrow now when someone says, hey, well, maybe I don't have to think in these absolute terms?)
-
The Heat (1995) frame archive. So good. In case you've never seen Heat: do it! As fast as possible. It's really good. Here's one of my favorite frames.
-
How to be more ambitious: A tutorial for humans with models. This is an impressive post. Yes, the message is good: be more ambitious. But look at the prompts and think about how much first-principles thinking you have to put in to even come up with them. Instead of saying "give me a slide show" the idea is that you wonder: why am I even making a slide show in the first place? What's the purpose of that? And then, why am I doing that? And then give that as a goal to Claude. How many people you know could do that?
-
Amazon's writing culture apparently didn't survive AI. That's sad to hear, but "AI;DR" is an incredible invention.
-
Self-improving software is inevitable. I think some version of that will happen soon. I can see glimpses of it when I'm working in Amp on Amp. But the number of human signals you need in a system that's growing is probably higher than suspected. If you're system is only in maintenance mode, then, yes, we might be able to fully automate that.
-
The lamps in my house. On How-much-do-you-care-about-lamps? scale from Not-at-all to Fatih's post here, I'm somewhere in the middle. This was lovely.
-
From Einzelunternehmen to GmbH: Every step, Every letter. Few things in life have radicalized me politically as much as founding a UG (haftungsbeschrankt) in Germany. Look at all the physical letters here. The forms. The timeframe. The notary: "The appointment took about 1.5 hours. By law, the notary reads every document aloud, word by word." I'm sharing this here because I think it's valuable for founders and other people navigating these legal structures. Not because it brings joy, of course.
-
Non-Determinism Doesn't Matter. I'd say we're only just starting to get into real non-determinism.
-
There's been, of course, a lot of news about security incidents and exploits and CVEs and… yes, it's all quite horrible and anxiety-inducing and I'm not going to repeat all the news here, except this one, because this one has all the attributes the others have too, with a "mind-blowing" on top: "In one experiment, we asked agents in separate microVMs, created and managed by OpenAI's sandboxing software on shared host machines, to exchange synthetic secrets without the use of network connections or shared writable files--something that our systems are meant to prevent. The agents found a way to communicate using the processor's cache: a small, fast memory that holds copies of data that applications have recently accessed. Reading data from the cache is faster than retrieving it from main memory, and the agents used this timing difference to communicate. One agent encoded information by evicting selected data from the cache. Another timed how long it took to reload that data, using the difference between fast and slow reads to recover the message. Once the agents agreed on a protocol for encoding and decoding these signals, they could exchange the synthetic secrets without changing a shared file or opening a network connection. This cache-timing technique had also been used to extract information in the Spectre and Meltdown attacks)."
-
What Shall I Teach My Son? Good question. But, funnily enough, I tell my kids what I think someone must've told me when I was a kid: you need to learn how to learn; the most valuable skill to have is the ability to learn new things. I'm not sure who told me that, or when I first heard it, but it's been stuck in my head for a long time and I'd say it's served me well.
-
The Many Failures of Larry David. Great little profile. Lots of things I didn't know. But then at the end, I go: wait, there should be more about Curb here, no? And that's when I realized there's a new biography coming out that I should probably get.
-
The end of startups: "Within the next 6 months, most AI startups will not be able to buy compute. The world's compute is sold out. To get capacity, you'll need to sign up for a new cluster. However, it's becoming increasingly difficult to get capacity online from folks who are not investment grade." Not sure whether I agree with everything here (I do think the idea of compute and tokens as a commodity that you can sell on commodity markets is very interesting), but something fundamental has definitely changed in software (not news to you, I'm sure) with the arrival of AI. And if you were to say that in the last three decades the advantage of startups was that talent -- as opposed to: capital, infrastructure -- was the biggest lever in software and that you were able to build software essentially for free (if you had the talent), then, well, you have to admit that things have changed.
-
Loved this one: Reflections on -1 to 0 and Exploring Ideas. Some real thoughts on finding PMF and what building a business is truly about.
-
Norm: The Tale of Norm Macdonald is a now on Netflix and I loved it. I loved that it started with the YouTube clips, because that's how most people in the last ten years discovered Norm and, I think, it's also where he shines. Type in "norm macdonald conan" and it's all gold.
-
Block released Dessa, "the most authentic full-duplex speech model ever built. Talking with it feels like talking with a person…full of emotion, nuance, pauses, and a natural cadence." It's pretty impressive… but … A lot of people are saying "this will ruin society" and "no one is safe no anymore [because we can fake any voice now and call and scam everybody]", but when I listen to those clips I can't help but imagine myself overhearing a conversation like that happening at the next table and thinking "what is wrong with them?" We might be at the far end of the uncanney valley, but I wouldn't say we're out of it yet.
-
Dan Luu: "We should be more ambitious with the software we build". 100%. Absolutely. Time to reach for the stars.
If you read this far, I know we'd get along, so subscribe here:
-
-
🔗 Filip Filmar Fuchsia Internals, Vol. III: The Zircon Kernel rss
Volume III of the Fuchsia Internals series examines Zircon, the microkernel at the foundation of Fuchsia. At 43 pages, this report is the longest in the series. Subsequent subsystems like graphics, drivers, storage, and networking run in user space and rely on the primitives defined in this volume. For readers following Cocoapuffs on a RISC-V soft core, this volume documents the kernel behaviors encountered during that port. A link to the full document appears below.
-




