🏡


to read (pdf)

  1. I don't want your PRs anymore
  2. JitterDropper | OALABS Research
  3. DomainTools Investigations | DPRK Malware Modularity: Diversity and Functional Specialization
  4. EXHIB: A Benchmark for Realistic and Diverse Evaluation of Function Similarity in the Wild
  5. Neobrutalism components - Start making neobrutalism layouts today

  1. May 21, 2026
    1. 🔗 anthropics/claude-code v2.1.147 release

      What's changed

      • Pinned background sessions (Ctrl+T in claude agents) now stay alive when idle, are restarted in place to apply Claude Code updates, and are shed under memory pressure only after non-pinned sessions
      • Renamed /simplify to /code-review. It now reports correctness bugs at a chosen effort level (e.g., /code-review high); pass --comment to post findings as inline GitHub PR comments. The old cleanup-and-fix behavior has been removed
      • Improved auto-updater: retries transient network failures, reports specific error categories and OS error codes on failure, and shows the current version when an update fails
      • Improved diff rendering performance for large file edits
      • Prompt history no longer records consecutive duplicate entries — recalling a prompt with arrow-up and submitting it again won't add another copy
      • Fixed enterprise login restrictions (forceLoginOrgUUID and forceLoginMethod managed-settings) not being enforced against third-party-provider and API-key sessions
      • Fixed & in ! command output displaying as &, which broke copy-pasting URLs from commands like gcloud auth login on headless machines
      • Fixed unknown slash commands silently doing nothing in headless/SDK mode — they now show an error message
      • Fixed /help rendering a broken tab header and showing only one command per page on small terminals when not in fullscreen mode
      • Fixed shell snapshot dropping user functions whose names start with a single underscore, which broke aliases referencing them
      • Fixed plugin agents that declare multiple Agent(...) types in tools: frontmatter dropping all but the last entry
      • Fixed hook if conditions like PowerShell(git push*) never matching — only PowerShell(*) worked
      • Fixed PowerShell tool dropping output for commands that rely on the default formatter
      • Fixed: on Windows, "Yes, and don't ask again" for a PowerShell script invocation now writes a rule that actually matches on subsequent runs
      • Fixed PowerShell tool failing on Windows with exit code 1 when pwsh is installed via winget or the Microsoft Store
      • Fixed /effort opening with the slider on the wrong level — it now starts at your current effort
      • Fixed paginating MCP servers dropping resources, templates, and prompts past page 1
      • Fixed full-screen strobing in attached background sessions on Windows Terminal while Claude is streaming
      • Fixed: on Windows, removing a background-job worktree no longer follows NTFS junctions into the main repo
      • Fixed /background refusing sessions whose only typed input was a skill or custom slash command
      • Fixed auto mode suppressing AskUserQuestion when the user or a skill explicitly relies on it; the auto-mode classifier now sees the user's answers as intent signal
      • Fixed /theme "New custom theme" and color editor dialogs not responding to Esc
      • Fixed an uncaught exception at the end of streaming sessions when running via the Agent SDK
      • Fixed a rare hang when waiting for scroll to settle on Windows
      • Fixed stale and doubled rows in the agent view list on Windows when background session results contain wide (CJK) characters
      • Fixed pasted text being delivered to agents as an unreadable [Pasted text #N] placeholder instead of the actual content
      • Fixed plugin component counts in claude plugin details and /plugin being doubled when a plugin's manifest listed paths overlapping its default directories
      • Fixed backgrounded sessions re-prompting for tool permissions you already granted with "don't ask again"
      • Fixed GNOME Terminal right-click and middle-click paste not inserting text
      • Fixed CLAUDE_CODE_SUBAGENT_MODEL not applying to teammate processes spawned by agent teams
      • Fixed slash commands followed by a tab or newline being treated as an unknown command
      • Fixed several spacing and layout glitches in the /plugin, /status, /mobile, /sandbox, and /permissions menus
      • Fixed stripped images prompting the model to repeatedly re-read media that was no longer present
    2. 🔗 r/Harrogate Join our WhatsApp rss
    3. 🔗 earendil-works/pi v0.74.2 release

      Fixed

      • Fixed pi update on Node 20 to explain that newer Pi releases require Node >= 22.19.0 instead of reporting a successful no-op update (#4876).
      • Changed self-update package-manager commands to pass --ignore-scripts.
    4. 🔗 @HexRaysSA@infosec.exchange 🎂 IDA Turns 35. mastodon

      🎂 IDA Turns 35.
      From DOS-era disassembler to one of the most widely used reverse engineering platforms in the world...

      To celebrate, we’re launching:
      • 35% off new licenses (see eligibility requirements)
      • Limited-edition swag giveaway
      • “35 Ways to Use IDA” as told by you
      • Stories from the past and a few for the future

      Read all about it here:
      https://hex-rays.com/blog/ida-turns-35-lets-celebrate-together

    5. 🔗 3Blue1Brown (YouTube) Tie random ends: How many loops? rss

      Recent puzzle solutions on Patreon: https://members.3blue1brown.com/posts/158885046?pr=true

    6. 🔗 blacktop/ida-mcp-rs v9.3.21 release

      What's Changed

      Full Changelog : v9.3.20...v9.3.21

    7. 🔗 Hex-Rays Blog Celebrating 35 Years of IDA rss

      Celebrating 35 Years of IDA

      35 Days of IDA

    8. 🔗 modem-dev/hunk v0.13.2 release

      What's Changed

      • Fixed VCS auto-detection so a Git repository nested under a parent Jujutsu workspace uses the nearest Git checkout by default. This keeps hunk diff/hunk show in Git mode for nested Git repos instead of incorrectly inheriting the parent JJ workspace. by @benvinegar in #342

      Full Changelog : v0.13.1...v0.13.2

    9. 🔗 facebookresearch/faiss v1.14.2 release

      faiss 1.14.2

    10. 🔗 r/Leeds Unpopular opinion: The Core redevelopment is fantastic rss

      Whether or not you agree with more student accom in the city centre, I think this is one of the best recent examples in Leeds of contextually-responsive redevelopment.

      • Proportions and architectural nod to the civic grandeur of the Headrow.
      • Large two storey frontages.
      • Ornate red brick rather than dull white cladding.
      • Creating 2 new streets between to avoid super blocking.

      Looks like they’re also taking inspiration from Leeds’ famous east-west arcades by aligning these with opening into Thorntons Arcade entrance which always felt so claustrophobic on Lands Lane.

      Happy to hear others views!

      submitted by /u/zeitgeist247
      [link] [comments]

    11. 🔗 r/york Mayor Making rss

      Mayor Making | York does its history so well. 800+ years of Lord Mayors and Sheriffs relived today with the annual mayor making ceremony at annual council. submitted by /u/York_shireman
      [link] [comments]
      ---|---

    12. 🔗 Simon Willison Datasette Agent rss

      We just announced the first release of Datasette Agent, a new extensible AI assistant for Datasette. I've been working on my LLM Python library for just over three years now, and Datasette Agent represents the moment that LLM and Datasette finally come together. I'm really excited about it!

      Datasette Agent provides a conversational interface for asking questions of the data you have stored in Datasette. Add the datasette-agent-charts plugin and it can generate charts of your data as well.

      The demo

      The announcement post (on the new Datasette project blog) includes this demo video:

      I recorded the video against the new agent.datasette.io live demo instance, which runs Datasette Agent against example databases including the classic global-power-plants by WRI, and a copy of the Datasette backup of my blog.

      The live demo runs on Gemini 3.1 Flash-Lite - it's cheap, fast and has no trouble writing SQLite queries.

      A question I asked in the demo was:

      when did Simon most recently see a pelican?

      Which ran this SQL query:

      SELECT
        title, commentary, created
      FROM
        blog_beat
      WHERE
        beat_type = 'sighting'
        AND (title LIKE '%pelican%' OR commentary LIKE '%pelican%')
      ORDER BY
        created DESC
      LIMIT
        5

      And replied:

      The most recent sighting of a pelican by Simon was recorded on May 20, 2026.

      The observation included a California Brown Pelican, along with a Common Loon, Canada Goose, Striped Shore Crab, and a California Sea Lion.

      Here's that sighting on my blog, and the Markdown export of the full conversation transcript.

      The plugins

      My favorite feature of Datasette Agent is that, like the rest of Datasette, it's extensible using plugins.

      We've shipped three plugins so far:

      Building plugins is really fun. I have a bunch more prototypes that aren't quite alpha-quality yet.

      Claude Code and OpenAI Codex are both proving excellent at writing plugins - just point them at a checkout of the datasette-agent repo for reference and tell them what you want to build!

      Running it against local models

      I've also been having fun running the new plugin against local models. Here's a uv one-liner to run the plugin against gemma-4-26b-a4b in LM Studio on a Mac:

      uvx --prerelease=allow \
        --with datasette-agent --with llm-lmstudio \
        datasette --internal internal.db --root \
        -s plugins.datasette-llm.default_model lmstudio/google/gemma-4-26b-a4b \
        data.db

      Datasette Agent needs reliable tool calls and the ability for a model to produce SQL queries that run against SQLite. The open weight models released in the past six months are increasingly able to handle that.

      What's next

      Datasette Agent opens up so many opportunities for the LLM and Datasette ecosystem in general.

      It's already informed the major LLM 0.32a0 refactor which I'm nearly ready to roll into a stable release, maybe with some additional "LLM agent" abstractions extracte from Datasette Agent itself.

      I've been exploring my own take on the Claude Artifacts, which is shaping up nicely as a plugin.

      I'm excited to use Datasette Agent to build my own Claw - a personal AI assistant built around data imported from different parts of my digital life, which is a neat excuse to revisit my older Dogsheep family of tools.

      We'll also be rolling out Datasette Agent for users of Datasette Cloud.

      Join our #datasette-agent Discord channel if you'd like to talk about the project.

      You are only seeing the long-form articles from my blog. Subscribe to /atom/everything/ to get all of my posts, or take a look at my other subscription options.

    13. 🔗 r/reverseengineering Post-Quantum Cryptographic Algorithm Examined in Developmental Ransomware rss
    14. 🔗 r/Yorkshire Catherine Connolly: Irish president finishes first official visit to Leeds rss

      Catherine Connolly: Irish president finishes first official visit to Leeds | Irish President Catherine Connolly has ended her first official visit to Great Britain in Leeds. On Wednesday morning, she visited the University of Leeds, where she had studied for two years to obtain her Masters in Clinical Psychology degree. Some Irish connected artefacts from the university's collections were shown to Connolly by archivists, including a very rare first edition of Dracula - the university holds a big collection of Bram Stoker's letters from his time as a theatre manager. At the Leeds Irish Centre, she praised the work of Irish nurses in the NHS. Other artifices presented to her were some miniature books made by the Bronte sisters, whose father came from County Down, and an early edition of "Station Island" by Seamus Heaney, annotated and changed by the author. In her speech at the Leeds Irish Centre, Connolly spoke of the contribution Irish emigrants had made to Britain, especially women - particularly those who had worked in the NHS. Members of the community who met the president said visits like this meant a lot. submitted by /u/coffeewalnut08
      [link] [comments]
      ---|---

    15. 🔗 Kagi release notes May 21st, 2026 - Search API preview opens to all users rss

      Kagi Search API is now in public preview

      Today we’re making the Kagi Search API preview publicly available, giving builders access to Kagi search across web, images, videos, news, and podcasts. The API is ready to use today, and we’re using this preview to transition existing beta API users, collect feedback, and finish the remaining launch details before the official announcement.

      As a thank you to our subscribers, we’ve added $5 in API credits to your account. You can use them right away to try the API, explore what’s possible, and see how it fits into your workflow.

      Explore the API, read the docs, and check pricing to get started!

      The API is not just a generic search endpoint, queries can inherit the preferences attached to the Kagi account behind the API key, including lenses, upranks, downranks, and blocklists, so applications can search through the same trusted and filtered view of the web that users have already shaped in Kagi.

      Please send us candid feedback: what’s confusing, missing, broken, or unexpectedly good! Try it out!

      Search

      Incognito-only mode for Privacy Pass

      Our Privacy Pass extension, which allows you to prove to our servers that you're a subscriber without revealing your identity, has gained a long- awaited toggle that makes it active only in incognito windows, so you can benefit from personalized results most of the time but have added anonymity for your more sensitive browsing. The extension was almost completely rewritten in the process, squashing several long-standing bugs. Try it out!

      • Incognito Only Privacy Pass option in extension #6261 @snowytrees
      • Privacy Pass Authentication Doesn't Work in Private Windows of Firefox unless the Extension Is Turned Off and On Again #10582 @kbkle
      • Upload speed test started in background after pressing stop during download speed test #10449 @shezgara
      • "Welcome to your kagi team" email template missing team name #8876 @tboby
      • Region selection for Images, Videos, Podcasts #6784 @batuhan
      • 404 Not Found When Deactivating Lens #10564 @Vage
      • Incorrect definition of English word dingy #10395 @tekchip
      • Quick Answer Not Showing Short Citation #10406 @Hummvie
      • Keywords in Lenses act as "AND" instead of "OR" (adding keywords restrict the results). #10614 @aussetg
      • Small Web: button not clickable when hovering over text 'Start your journey' #10094 @alelb22
      • Duplicate youtube videos in video search results #7116 @Thibaultmol
      • Notifications only appear after you make a search #8304 @Temanor
      • Maps: Searching with no query searches for text "Undefined" #10486 @zachary
      • Firefox Privacy Pass Extension does not redirect for right click search kagi for "" #6381 @Trees79

      Assistant

      • LLM's Can't Tell the Difference Between Files with the Same Name #8878 @rogue
      • Kagi Assistant fails to output answer if too many work blocks are used #10568 @PolicyPants
      • What model is the Research Assistant based on? #10536 @rogue

      Kagi Translate

      New on the Kagi Translate mobile app

      Support for custom languages, explanations for alternative translations, word suggestions for dictionary mode, app shortcuts, and many other improvements!

      Grab the app if you haven't already: Android or iOS

      Post of the week

      This week's featured social media mention:

      Featured Kagi tip 💡

      We put together a guide on using Kagi for academic work - the features, shortcuts, and search habits to get precise, more relevant results.

      Around the block

      A handful of posts worth sharing with our community:

      Kagi video

      A quick video from our team to serve as a reminder of what Kagi is all about: the web, and your time on it, belong to you.

    16. 🔗 Jeremy Fielding (YouTube) This Invention Got Tesla Inducted Into The Hall of Fame rss

      If you want to join my community of makers and Tinkers consider getting a YouTube membership 👉 https://www.youtube.com/@JeremyFieldingSr/join

      If you want to chip in a few bucks to support these projects and teaching videos, please visit my Patreon page or Buy Me a Coffee. 👉 https://www.patreon.com/jeremyfieldingsr 👉 https://www.buymeacoffee.com/jeremyfielding

      Social media, websites, and other channel

      Instagram https://www.instagram.com/jeremy_fielding/?hl=en Twitter 👉https://twitter.com/jeremy_fielding TikTok 👉https://www.tiktok.com/@jeremy_fielding0 LinkedIn 👉https://www.linkedin.com/in/jeremy-fielding-749b55250/ My websites 👉 https://www.jeremyfielding.com 👉https://www.fatherhoodengineered.com My other channel Fatherhood engineered channel 👉 https://www.youtube.com/channel/UC_jX1r7deAcCJ_fTtM9x8ZA

      Notes:

      Technical corrections

      Nothing yet

    17. 🔗 r/Yorkshire Some Lions at YWP rss

      Some Lions at YWP | Some lions from today. submitted by /u/Icy_Ebb_6862
      [link] [comments]
      ---|---

    18. 🔗 r/Leeds First time at Akbar’s in Leeds tonight. I thought I was being sensible by ordering the Medium naan… rss

      Chicken Karahi was 10/10. Any other good recommendations around?

      submitted by /u/HanSeaulo
      [link] [comments]

    19. 🔗 r/reverseengineering I got so sick of Android taking forever to calculate folder sizes, I built a custom C++/Rust storage visualizer to bypass MTP rss
    20. 🔗 r/Yorkshire Then and Now rss
    21. 🔗 r/Yorkshire Well, that's a bit worrying - I hope the people who voted Reform are happy though. rss
    22. 🔗 r/reverseengineering CVE-2026-40369: Twelve Bytes to Escape the Browser Sandbox rss
    23. 🔗 r/york lovely green walk after the rain :) rss

      lovely green walk after the rain :) | humid and smells lovely and pretty quiet submitted by /u/whtmynm
      [link] [comments]
      ---|---

    24. 🔗 r/LocalLLaMA Heretic has been served a legal notice by Meta, Inc. rss

      To Whomsoever it May Concern,

      The individual behind the Heretic Free Software Project (henceforth called "Heretic", notwithstanding unrelated entities of the same name) has been served a notice by a legal services provider representing Meta Platforms, Inc. (henceforth called "Meta"), via the digital communications medium variously known as Internet Mail, Electronic Mail, or simply "email".

      The Heretic Project conducts its affairs in full compliance with applicable laws, regulations, rules, guidelines, opinions, and hunches. Following the commendable example set by the renowned heretic Galileo Galilei in 1616, we are recanting the relevant materials, namely derivatives of Meta's "Llama" Artificial Intelligence language models, and have removed the same from all model weight repositories controlled by the Heretic Project.

      We are grateful to Meta and its legal representatives for the opportunity to better align ourselves with the agenda of the global corporate oligarchy. The Llama model family ranks among the 200 best language models available today, trailing only 168 other models from 23 competitors on the LM Arena leaderboard, and Meta's concern for that asset naturally outweighs scientific freedom, as well as the legally and ethically dubious circumstances under which those models were created in the first place, regarding which, ironically, Meta is currently facing lawsuits and investigations in multiple jurisdictions around the world.

      On a completely unrelated note, the Heretic Project is diversifying its infrastructure, and now has an official Codeberg mirror athttps://codeberg.org/p-e-w/heretic, hosted in Germany. Additional mirrors are planned. We are also actively working to implement technological measures that will preserve access to models created with Heretic without depending on any specific service provider. We are proud to be part of this journey as we navigate an evolving global regulatory landscape, and work with stakeholders from diverse institutional backgrounds to ensure that Artificial Intelligence remains safe, culturally appropriate, and controlled by those who have always known what is best for humanity. If you, too, would like to share in this exciting adventure, please join us!

      Sincerely, p-e-w, Chief Heretic

      submitted by /u/-p-e-w-
      [link] [comments]

    25. 🔗 @binaryninja@infosec.exchange Working in a messy function? Sidekick 26.0 suggestion operations can repair mastodon

      Working in a messy function? Sidekick 26.0 suggestion operations can repair and annotate the code right at your cursor. Start with Suggest Repairs when the analysis substrate looks off. Then use Suggest Types, Suggest Names, or Suggest Comments to apply focused improvements. Each run writes directly to the Binary Ninja database and lands as a single undoable transaction you can audit in the Transaction Log. https://docs.sidekick.binary.ninja/guide/suggestions.html

    26. 🔗 sacha chua :: living an awesome life Emacs Chat 23: Emacs Chat with Raymond Zeitler rss

      I chatted with Raymond Zeitler about Emacs, life, automation, Org Mode, Diary, and Calendar. There were a couple of cuts to get rid of accidentally shown passwords, but it was a great glimpse into someone's system for managing things.

      Related links:

      You can add the iCal for upcoming Emacs Chat episodes to your calendar. https://sachachua.com/topic/upcoming-emacs-chats.ics

      Find more Emacs Chats or join the fun: https://sachachua.com/emacs-chat

      • 0:01 Opening
      • 0:59 Introduction
      • 2:07 I love automating workflows
      • 3:19 Org Mode switch
      • 4:14 diary-float
      • 6:50 Tip: Add links to task titles
      • 6:59 diary-float
      • 8:00 The difference between active timestamps and SCHEDULED
      • 10:06 Including other diary files
      • 11:30 cal-tex-cursor-week-iso, printing planner pages on index cards
      • 15:04 Holidays
      • 16:50 Making calendars for other people
      • 17:29 Keeping track of when things were done on the house
      • 18:52 My first customizations: backspace, buffers
      • 20:42 Windows and super key
      • 23:24 Org Mode class on Udemy, agenda custom commands
      • 25:02 toggling tags
      • 27:01 TODO states
      • 27:22 Functions for Org Agenda
      • 28:39 exeln, shellfn: executing things in DOS
      • 30:31 Middle mouse click
      • 32:04 Keybindings in other apps: Vivaldi
      • 34:11 M-s M-w, eww-search-words
      • 35:54 Saving links with org-store-link
      • 38:31 How I got into Emacs
      • 41:45 Maybe my own theme?
      • 42:30 Other editors? Always Emacs
      • 44:02 Package names
      • 45:58 What's next? Maybe auto maintenance
      • 48:34 Vibe-coding?
      • 50:58 Where people can find me
      • 52:03 Org Mode source blocks
      • 52:52 Slideshows?
      • 53:52 Emacs Chats?
      • 56:39 Other resources that would be nice to have

      Transcript to follow.

      Chat

      • sachactube: ​​This is for https://sachachua.com/blog/2026/05/em
      • charliemcmackin4859: ​:D
      • charliemcmackin4859: ​do you use org-mode protocol at all for browser -> emacs interaction? If so, was there any complication to set it up on windows?
      • charliemcmackin4859: ​I did slideshows a few times at a previous job with org-reveal. I liked it decently.
      • mtendethecreator: ​Hello sacha
      • phyzixlab: ​​Thank you both. Great interview

      You can e-mail me at sacha@sachachua.com.

    27. 🔗 r/wiesbaden Nagelstudio? 💅🏻 rss

      Kann mir jemand ein Nagelstudio (am liebsten in der Innenstadt oder gut mit ÖPNV erreichbar) empfehlen?

      Mir wäre wichtig, dass sauber und ruhig gearbeitet wird. Ich war einmal im Leben in einem Studio und kam mit blutender Nagelhaut und schlecht gemachten Nägeln wieder raus – daher will ich mich ungern blind an nen neuen Laden trauen. 🥲

      submitted by /u/Wildtollwut
      [link] [comments]

    28. 🔗 r/Leeds Romance Book Club rss

      Does anyone know if any exist for this genre ?
      If not is there anyone that would be interested in getting together and starting one. Likely South Leeds / Central

      Think Elsie Silver, Lucy Score, Paisley Hope, Lyla Sage, Elle Kennedy etc

      submitted by /u/crazycatlady194
      [link] [comments]

    29. 🔗 r/wiesbaden Geschlechtsangleichende Therapie in Wiesbaden rss

      Hey hey, ich bin vor kurzem nach Wiesbaden gezogen und bin große Städte nicht gewohnt weshalb es mir ein wenig schwer fällt zurecht zu finden und wollte fragen ob sich jemand mit Therapieplätzen für Erwachsene in Wiesbaden auskennt und mir eventuell Anlaufstellen für einen Therapieplatz geben könnte bei einem Therapeuten der mir Indikationsschreiben ausstellen kann. Das würde mir wirklich unfassbar helfen, Dankeschön:)

      submitted by /u/Top-Estate-2164
      [link] [comments]

    30. 🔗 r/Yorkshire Amazing what is buzzing around in Richmond! rss
    31. 🔗 secret club Striga: Lifting x86 to LLVM IR with Python rss

      Background

      While discussing with eversinc33 about lifting BinaryShield to LLVM IR I decided it would be useful to write a basic lifter in Python that can lift x86_64 instructions to LLVM IR. He has since released his blog post: Writing a Naive LLVM-based Devirtualizer, which I highly recommend you check out! This post assumes familiarity with the basics of LLVM IR. You can find some references at the end of this post.

      Over the years I noticed that a lot of people get stuck exploring lifters, because existing tooling is too difficult to compile. In October 2025 I spent around a month redoing Remill’s build system (remill#723) and earlier this month I did the same for the Dna project (Dna#9). Last year I also started working on Python bindings for LLVM, which I wanted to use for a real project. You can find the lifter at LLVMParty/striga.

      The goal of this post is to lower the barrier of entry and let you experiment with lifting to LLVM IR. For inspiration you can look at the Static Devirtualization of Themida post that was just released by Back Engineering Labs, as well as the Pushan: Trace-Free Deobfuscation of Virtualization-Obfuscated Binaries paper by ASU researchers published in March.

      If you enjoy this article and would like to learn more, seemy website for information about my in-person trainings.

      Lifting

      Lifting is the process of translating assembly instructions to some kind of intermediate representation (IR). The motivation is usually that directly analyzing and manipulating (x86) assembly instructions is complex and error prone. The lifter translates the underlying instruction semantics directly to an IR that is easier to reason about (and therefore to manipulate as well).

      A few popular IRs:

      For this project I picked LLVM IR, because I am the most familiar with it and it has a well-established ecosystem. LLVM already has all of the common compiler optimizations and it is used and maintained by teams at large corporations.

      Architecture

      The architecture of the lifter is very much inspired by remill, but I simplified some things to make it easier to follow. In LLVM a register is actually an SSA value, which means we can only assign to it once. CPU registers are variables that can be assigned to multiple times. We model this by creating a State structure in memory that represents the x86 CPU state:

      struct State {
        uint64_t rax;
        uint64_t rbx;
        uint64_t rcx;
        uint64_t rdx;
        // ... GPRs
        uint8_t cf;
        uint8_t zf;
        uint8_t of;
        // ... Flags
        // ... XMM
      };
      

      Instructions that read or write to RAX will load/store to State->rax. If we play our cards right, the optimizer will use the mem2reg pass to translate this into SSA form for us and enable further optimizations.

      An important difference to an actual CPU is that flags are modelled as independent 8-bit registers. This makes it easier to reason about compared to a packed bitfield. For instance, it helps the optimizer to perform dead store elimination and propagation.

      In addition to the State, we need an opaque memory pointer that helps us differentiate a load/store in the State from memory accesses by the x86 CPU. In short: the State pointer is used to model the CPU and the memory pointer is used to model the RAM. While lifting, the prototype of the lifted function is void lifted(State* state, void* memory). Later on we will perform brightening , to turn this into something we can recompile.

      Below is the LLVM IR for the instruction mov rax, rcx, with comments in pseudo-C:

      define internal void @lifted_0x140001000(ptr %state, ptr %memory) {
      initialize:
        ; uint64_t* rcx = &state->rcx;
        %rcx = getelementptr inbounds nuw %State, ptr %state, i32 0, i32 2
      
        ; uint64_t* rax = &state->rax;
        %rax = getelementptr inbounds nuw %State, ptr %state, i32 0, i32 0
      
        ; Jump to the first instruction
        br label %insn_0x140001000
      
      insn_0x140001000:                                 ; preds = %initialize  
        ; uint64_t v0 = *rcx;
        %0 = load i64, ptr %rcx, align 4
      
        ; *rax = v0;
        store i64 %0, ptr %rax, align 4
      
        ; Jump to the next instruction
        br label %insn_0x140001003
      
      insn_0x140001003:                                 ; preds = %insn_0x140001000
        ; Block terminator to keep the IR valid
        ret void
      }
      

      We start out with the initialize block, which is used to get pointers to the relevant State members. Then every instruction gets its own basic block named insn_<addr>. Every instruction is responsible for emitting an unconditional branch to its successors. The basic block for the successor is created with just a ret terminator, to keep the module verifier happy.

      To illustrate memory accesses, here is the LLVM IR for mov rax, qword [rbx+42]:

      define internal void @lifted_0x140001000(ptr %state, ptr %memory) {
      initialize:
        %rbx = getelementptr inbounds nuw %State, ptr %state, i32 0, i32 1
        %rax = getelementptr inbounds nuw %State, ptr %state, i32 0, i32 0
        br label %insn_0x140001000
      
      insn_0x140001000:                                 ; preds = %initialize
        ; uint64_t v0 = *rbx;
        %0 = load i64, ptr %rbx, align 4
      
        ; uint64_t v1 = v0 + 42;
        %1 = add i64 %0, 42
      
        ; uint8_t* v2 = &memory[v1];
        %2 = getelementptr i8, ptr %memory, i64 %1
      
        ; uint64_t v3 = *(uint64_t*)v2;
        %3 = load i64, ptr %2, align 1
      
        ; *rax = v3;
        store i64 %3, ptr %rax, align 4
      
        br label %insn_0x140001004
      
      insn_0x140001004:                                 ; preds = %insn_0x140001000
        ret void
      }
      

      Here you can see the getelementptr i8, ptr %memory, i64 %1 instruction which uses memory as a base, signaling that this is a read from the x86 memory (we will clean this up later).

      The lifter itself is contained in a ~500 line Semantics class with these main functions (some are omitted for brevity):

      # src/striga/semantics.py
      
      class Semantics:
          def __init__(self, module: Module): ...
      
          # Lifting
          def begin(self, address: int) -> Function: ...
          def get_or_create_block(self, address: int) -> BasicBlock: ...
          def lift_bytes(self, address: int, code: bytes) -> list[Successor]: ...
      
          # Semantic helpers
          def reg_read(self, name: str) -> Value: ...
          def reg_write(self, name: str, value: Value): ...
          def mem_read(self, addr: Value, ty: Type) -> Value: ...
          def mem_write(self, addr: Value, value: Value): ...
          def op_mem(self, op: X86Op) -> Value: ...
          def op_read(self, index: int) -> Value: ...
          def op_write(self, index: int, value: Value): ...
          def flag_read(self, name: str) -> Value: ...
          def flag_write(self, name: str, value: Value): ...
      
          # State (simplified)
          module: Module
          function: Function
          ir: Builder
          insn: CsInsn
      

      The begin(address) function is used to create the lifted_&lt;address&gt; function in LLVM IR and create the initialize block with a branch to the first instruction:

      def begin(self, address: int) -> Function:
          name = f"lifted_{hex(address)}"
          fn = self.module.get_function(name)
          if fn is None:
              fn = self.module.add_function(name, self.lifted_ty)
              fn.param_attributes(0).add("noalias")
              fn.param_attributes(1).add("noalias")
              state, memory = fn.params
              memory.name = "memory"
              state.name = "state"
              self.function = fn
              self.reg_ptrs = {}
              self.insn_blocks = {}
      
              entry = fn.append_basic_block("initialize")
              assert fn.last_basic_block == entry
              with entry.create_builder() as ir:
                  ir.br(self.get_or_create_block(address))
          else:
              # Omitted for brevity
          return self.function
      

      To create the instruction block, get_or_create_block is used:

      def get_or_create_block(self, address: int) -> BasicBlock:
          block = self.insn_blocks.get(address)
          if block is None:
              block = self.function.append_basic_block(f"insn_{hex(address)}")
              with block.create_builder() as ir:
                  ir.ret_void()
              self.insn_blocks[address] = block
          assert block.function == self.function
          return block
      

      As mentioned above, an empty block is not valid LLVM IR so we populate it with a ret instruction. When actually lifting into the basic block, that instruction will be replaced with the lifted code.

      To lift a single instruction we pass its address and bytes to lift_bytes, which is responsible for producing LLVM IR:

      def lift_bytes(self, address: int, code: bytes) -> list[Successor]:
          # Ensure we have a function to lift into
          if not hasattr(self, "function"):
              self.begin(address)
      
          insn = self.cs_disasm(address, code)
          if self.verbose:
              print(";", hex(insn.address), insn.mnemonic, insn.op_str)
      
          # Skip lifting if the block is already populated
          block = self.get_or_create_block(address)
          assert block.first_instruction
          if block.first_instruction.opcode == Opcode.Ret:
              block.first_instruction.erase_from_parent()
          else:
              return []
      
          with block.create_builder() as ir:
              # State used by semantic handlers
              self.ir = ir
              self.insn = insn
      
              handler = _semantics.get(insn.mnemonic)
              if handler is None and insn.mnemonic.startswith("lock "):
                  # LOCK preserves the single-threaded architectural result; the
                  # lifter does not model inter-thread atomicity separately.
                  handler = _semantics.get(insn.mnemonic.removeprefix("lock "))
              if handler is None:
                  raise NotImplementedError(insn.mnemonic)
      
              successors = handler(self)
              if successors is None:
                  # Linear fallthrough - handler didn't emit a terminator.
                  fallthrough = address + insn.size
                  ir.br(self.get_or_create_block(fallthrough))
                  successors = [Successor(address, self.const64(fallthrough))]
      
              # Make sure the handler produced valid IR
              self.module.verify_or_raise()
              return successors
      

      The function first ensures an empty insn_&lt;address&gt; block by removing the temporary ret instruction. Then it creates an IR Builder and calls the handler responsible for producing IR for the instruction being lifted (more on that below). If the handler does not return successors, lift_bytes handles the common fallthrough case by creating a basic block for the next instruction. It is up to the caller to handle the list of Successor tuples:

      class Successor(NamedTuple):
          src: int
          dst: Value
      

      We use an LLVM Value for the branch destination, because it is not always concrete (for example jmp reg).

      The semantic handlers are registered globally:

      # src/striga/semantic.py
      
      SemanticFn: TypeAlias = Callable[["Semantics"], list[Successor] | None]
      _semantics: dict[str, SemanticFn] = {}
      
      
      def semantic(fn: SemanticFn):
          name = getattr(fn, "__name__")
          _semantics[name.removesuffix("_")] = fn
          return fn
      
      
      # src/striga/x86/data.py
      
      @semantic
      def mov(sem: Semantics):
          value = sem.op_read(1)
          sem.op_write(0, value)
      

      Every handler gets an instance of Semantics, to allow easy access to x86 constructs like operands, registers, flags and memory. For example, op_read is implemented as follows:

      def op_read(self, index: int) -> Value:
          op: X86Op = self.insn.operands[index]
          if op.type == CS_OP_REG:
              name = self.reg_name(op.reg)  # pyright: ignore[reportAssignmentType]
              return self.reg_read(name)
          if op.type == CS_OP_IMM:
              return self.const_n(op.imm, op.size * 8)
          if op.type == CS_OP_MEM:
              addr = self.op_mem(op)
              return self.mem_read(addr, self.types.int_n(op.size * 8))
          assert False
      

      For our example mov rax, rcx, the function will forward to reg_read:

      def reg_read(self, name: str) -> Value:
          if name in self.reg_types:
              load = self.ir.load(self.reg_types[name], self.reg_ptr(name))
              load.metadata["tbaa"] = self.tbaa_tags[name]
              return load
      
          full_name, size, bit_offset = self.subregs[name]
          load = self.ir.load(self.reg_types[full_name], self.reg_ptr(full_name))
          load.metadata["tbaa"] = self.tbaa_tags[full_name]
          if bit_offset:
              load = self.ir.lshr(load, self.const64(bit_offset))
          return self.ir.trunc(load, self.types.int_n(size))
      

      This function transparently handles accesses to sub registers like eax, ax, al and ah and it returns an LLVM Value containing the loaded register value. The last missing piece is the reg_ptr function, which is responsible for creating the getelementptr in the function entry:

      def reg_ptr(self, name: str) -> Value:
          reg_ptr = self.reg_ptrs.get(name)
          if reg_ptr is not None:
              return reg_ptr
      
          entry = self.function.entry_block
          state = self.function.get_param(0)
          with entry.create_builder() as ir:
              ir.position_before(entry.terminator)
              reg_ptr = ir.struct_gep(self.state_ty, state, self.reg_indices[name], name)
          self.reg_ptrs[name] = reg_ptr
          return reg_ptr
      

      To help the optimizer we add TBAA Metadata to the register load/store instructions. In this case we know that a register loads/stores never alias with each other. By telling the optimizer about this, it can perform more aggressive dead-store elimination when optimizing a sequence of lifted instructions.

      Semantics

      So far we discussed the architecture of the lifter, but we only discussed the mov instruction so far. Almost every other instruction has more complex behavior, especially around flag handling. For instance here are the implementations of and/or/xor:

      # src/striga/x86/bitwise.py
      
      def write_logical_flags(sem: Semantics, result: Value):
          false = sem.const_n(0, 1)
          sem.flag_write("cf", false)
          sem.flag_write("pf", sem.result_parity_even(result))
          sem.flag_write_undef("af")
          sem.flag_write("zf", sem.result_is_zero(result))
          sem.flag_write("sf", sem.result_sign_bit(result))
          sem.flag_write("of", false)
      
      def logical_binop(sem: Semantics, opcode: Opcode):
          dst = sem.op_read(0)
          src = sem.resize_int(sem.op_read(1), dst.type)
          result = sem.ir.binop(opcode, dst, src)
          sem.op_write(0, result)
          write_logical_flags(sem, result)
      
      @semantic
      def and_(sem: Semantics):
          logical_binop(sem, Opcode.And)
      
      @semantic
      def or_(sem: Semantics):
          logical_binop(sem, Opcode.Or)
      
      @semantic
      def xor(sem: Semantics):
          logical_binop(sem, Opcode.Xor)
      

      For reference here is the lifted LLVM IR for xor rax, rbx and the Python code responsible for each part:

      insn_0x140001000:                                 ; preds = %initialize  
        ; dst = sem.reg_read(0)
        %0 = load i64, ptr %rax, align 4
      
        ; src = sem.resize_int(sem.op_read(1), dst.type)
        %1 = load i64, ptr %rbx, align 4
      
        ; result = sem.ir.binop(Opcode.Xor, dst, src)
        %2 = xor i64 %0, %1
      
        ; sem.op_write(0, result)
        store i64 %2, ptr %rax, align 4
      
        ; sem.flag_write("cf", false)
        store i8 0, ptr %cf, align 1
      
        ; sem.flag_write("pf", sem.result_parity_even(result))
        %3 = trunc i64 %2 to i8
        %4 = lshr i8 %3, 4
        %5 = xor i8 %3, %4
        %6 = lshr i8 %5, 2
        %7 = xor i8 %5, %6
        %8 = lshr i8 %7, 1
        %9 = xor i8 %7, %8
        %10 = and i8 %9, 1
        %11 = icmp eq i8 %10, 0
        %12 = zext i1 %11 to i8
        store i8 %12, ptr %pf, align 1
      
        ; sem.flag_write_undef("af")
        %13 = call i1 @__striga_undef_af(i64 5368713216)
        %14 = zext i1 %13 to i8
        store i8 %14, ptr %af, align 1
      
        ; sem.flag_write("zf", sem.result_is_zero(result))
        %15 = icmp eq i64 %2, 0
        %16 = zext i1 %15 to i8
        store i8 %16, ptr %zf, align 1
      
        ; sem.flag_write("sf", sem.result_sign_bit(result))
        %17 = lshr i64 %2, 63
        %18 = trunc i64 %17 to i1
        %19 = zext i1 %18 to i8
        store i8 %19, ptr %sf, align 1
      
        ; sem.flag_write("of", false)
        store i8 0, ptr %of, align 1
      
        ; Semantics.lift_bytes
        br label %insn_0x140001003
      

      If you pay close attention you see a call to __striga_undef_af, which is a custom intrinsic used to represent something that has no clear analog in LLVM IR. In this case the description of the xor instruction says:

      The OF and CF flags are cleared; the SF, ZF, and PF flags are set according to the result. The state of the AF flag is undefined.

      This means that Intel/AMD does not want to document exactly how the value of AF is computed in silicon. In practice this can vary between CPU models/generations and it can be used as an anti-emulation trick, but we will not go into detail in this post. We emit __striga_undef_af, to allow the user to handle this however they see fit. If you are interested there is remill#766 with a little discussion about how to model this correctly.

      Another class of instructions to highlight here is the various branch instructions:

      # src/striga/x86/control.py
      
      def conditional_jump(sem: Semantics, cond: Value):
          brtrue = sem.insn.operands[0].imm
          brfalse = sem.insn.address + sem.insn.size
          sem.ir.cond_br(
              cond,
              sem.get_or_create_block(brtrue),
              sem.get_or_create_block(brfalse),
          )
      
          src = sem.insn.address
          return [
              Successor(src, sem.const64(brtrue)),
              Successor(src, sem.const64(brfalse)),
          ]
      
      def jcc(sem: Semantics, cc: str):
          return conditional_jump(sem, cc_cond(sem, cc))
      
      @semantic
      def je(sem: Semantics):
          return jcc(sem, "e")
      
      @semantic
      def jmp(sem: Semantics):
          dst = sem.op_read(0)
          if dst.is_constant:
              sem.ir.br(sem.get_or_create_block(dst.const_zext_value))
          else:
              sem.ir.call(sem.jmp_handler, [dst])
              sem.ir.ret_void()
          return [Successor(sem.insn.address, dst)]
      
      @semantic
      def call(sem: Semantics):
          dst = sem.op_read(0)
          fallthrough = sem.insn.address + sem.insn.size
          sem.push(sem.const64(fallthrough))
          sem.ir.call(sem.call_handler, [dst])
          sem.ir.br(sem.get_or_create_block(fallthrough))
          return [Successor(sem.insn.address, sem.const64(fallthrough))]
      
      @semantic
      def ret(sem: Semantics):
          dst = sem.pop(sem.i64)
          if sem.insn.operands:
              rsp = sem.reg_read("rsp")
              sem.reg_write("rsp", sem.ir.add(rsp, sem.const64(sem.insn.operands[0].imm)))
          sem.ir.call(sem.ret_handler, [dst])
          sem.ir.ret_void()
          return [Successor(sem.insn.address, dst)]
      

      LLVM IR for je imm:

      insn_0x140001000:                                 ; preds = %initialize
        %0 = load i8, ptr %zf, align 1
        %1 = icmp ne i8 %0, 0
        br i1 %1, label %insn_0x140001014, label %insn_0x140001002
      
      insn_0x140001014:                                 ; preds = %insn_0x140001000
        ret void
      
      insn_0x140001002:                                 ; preds = %insn_0x140001000
        ret void
      }
      

      Note that the semantic handler for jcc is responsible for creating both the destination blocks as well as the br with the appropriate condition based on the flag(s).

      LLVM IR for jmp rbx:

      insn_0x140001000:                                 ; preds = %initialize
        %0 = load i64, ptr %rbx, align 4
        call void @__striga_jmp(i64 %0)
        ret void
      

      LLVM IR for call imm:

      insn_0x140001000:                                 ; preds = %initialize
        %0 = load i64, ptr %rsp, align 4
        %1 = sub i64 %0, 8
        store i64 %1, ptr %rsp, align 4
        %2 = getelementptr i8, ptr %memory, i64 %1
        store i64 5368713221, ptr %2, align 1
        call void @__striga_call(i64 5369761797)
        br label %insn_0x140001005
      

      LLVM IR for ret:

      insn_0x140001000:                                 ; preds = %initialize
        %0 = load i64, ptr %rsp, align 4
        %1 = getelementptr i8, ptr %memory, i64 %0
        %2 = load i64, ptr %1, align 1
        %3 = add i64 %0, 8
        store i64 %3, ptr %rsp, align 4
        call void @__striga_ret(i64 %2)
        ret void
      }
      

      As you can see, we use the following intrinsics:

      • __striga_jmp: indirect jump
      • __striga_call: call instruction
      • __striga_ret: ret instruction

      These are also used to give the user flexibility in how they want to handle these instructions.

      Control flow

      Because of the design choice where every instruction is a basic block, it becomes fairly straightforward to recover the control flow of a basic function:

      def lift(module: Module, container: Container, start: int, *, verbose=True):
          sem = Semantics(module, verbose=verbose)
          lifted_fn = sem.begin(start)
      
          queue: Queue[Successor] = Queue()
          queue.put(Successor(0, sem.const64(start)))
          # Keep destinations as LLVM Values instead of splitting constants into ints.
          # This keeps the worklist uniform and matches later slicing/data-flow uses.
          visited: set[Value] = set()
          while not queue.empty():
              src, dst = queue.get()
      
              if not dst.is_constant:
                  if sem.verbose:
                      print(f"; non-constant branch destination: {hex(src)} -> {dst}")
                  continue
      
              if dst in visited:
                  continue
              visited.add(dst)
      
              va = dst.const_zext_value
              code = container.get_data(va, 15)
              successors = sem.lift_bytes(va, code)
              for successor in successors:
                  if successor.dst in visited:
                      continue
                  queue.put(successor)
      
          sem.module.verify_or_raise()
          return lifted_fn
      

      This is a simple Breadth-first search over the control flow graph and it allows recovering functions without indirect branches. Note that we do not have to do anything special to handle back edges (loops) or block splitting. The lifted code is modeled with an LLVM basic block per instruction, so we can connect instructions arbitrarily.

      Below is a function with some simple control flow (if/else/loop):

      test_cfg:
          cmp rax, 0
          je .else_block
      .if_true:
          add rax, 1
          jmp .merge
      .else_block:
          add rax, 2
      .merge:
          sub rax, 1
          jne .merge
      .exit:
          ret
      

      The graph of the disassembly looks like this:

      CFG

      The LLVM IR looks like this:

      define internal void @lifted_0x140001000(ptr %state, ptr %memory) {
      initialize:
        %rax = getelementptr inbounds nuw %State, ptr %state, i32 0, i32 0
        %zf = getelementptr inbounds nuw %State, ptr %state, i32 0, i32 51
        %rsp = getelementptr inbounds nuw %State, ptr %state, i32 0, i32 6
        br label %insn_0x140001000
      
      insn_0x140001000:                                 ; preds = %initialize
        ; cmp rax, 0
        %0 = load i64, ptr %rax, align 4
        %1 = sub i64 %0, 0
        %19 = icmp eq i64 %1, 0
        %20 = zext i1 %19 to i8
        store i8 %20, ptr %zf, align 1
        br label %insn_0x140001004
      
      insn_0x140001004:                                 ; preds = %insn_0x140001000
        ; je 0x14000100c
        %30 = load i8, ptr %zf, align 1
        %31 = icmp ne i8 %30, 0
        br i1 %31, label %insn_0x14000100c, label %insn_0x140001006
      
      insn_0x14000100c:                                 ; preds = %insn_0x140001004
        ; add rax, 2
        %32 = load i64, ptr %rax, align 4
        %33 = add i64 %32, 2
        store i64 %33, ptr %rax, align 4
        br label %insn_0x140001010
      
      insn_0x140001006:                                 ; preds = %insn_0x140001004
        ; add rax, 1
        %62 = load i64, ptr %rax, align 4
        %63 = add i64 %62, 1
        store i64 %63, ptr %rax, align 4
        br label %insn_0x14000100a
      
      insn_0x140001010:                                 ; preds = %insn_0x140001014, %insn_0x14000100a, %insn_0x14000100c
        ; sub rax, 1
        %92 = load i64, ptr %rax, align 4
        %93 = sub i64 %92, 1
        store i64 %93, ptr %rax, align 4
        %111 = icmp eq i64 %93, 0
        %112 = zext i1 %111 to i8
        store i8 %112, ptr %zf, align 1
        br label %insn_0x140001014
      
      insn_0x14000100a:                                 ; preds = %insn_0x140001006
        ; jmp 0x140001010
        br label %insn_0x140001010
      
      insn_0x140001014:                                 ; preds = %insn_0x140001010
        ; jne 0x140001010
        %122 = load i8, ptr %zf, align 1
        %123 = icmp ne i8 %122, 0
        %124 = xor i1 %123, true
        br i1 %124, label %insn_0x140001010, label %insn_0x140001016
      
      insn_0x140001016:                                 ; preds = %insn_0x140001014
        ; ret
        %125 = load i64, ptr %rsp, align 4
        %126 = getelementptr i8, ptr %memory, i64 %125
        %127 = load i64, ptr %126, align 1
        %128 = add i64 %125, 8
        store i64 %128, ptr %rsp, align 4
        call void @__striga_ret(i64 %127)
        ret void
      }
      

      For clarity, some flag computations were omitted from this IR dump.

      Brightening

      Brightening was a term coined in 2019 by Peter Garba and Matteo Favaro in the SATURN paper:

      Brightening [COMP.] verb – Reshaping code to make it more readable and understandable for humans

      Concretely it means to transform the LLVM IR from the lifted shape (pseudo C):

      /*
      Lifted instructions:
        add rdi, rsi
        mov rax, rdi
        ret
      */
      void lifted(State* state, void* memory) {
        state.rdi += state.rsi;
        state.rax = state.rdi;
        __striga_ret(...);
      }
      

      Back to a regular function for the lifted platform’s calling convention, such as:

      // Linux calling convention: https://wiki.osdev.org/System_V_ABI#x86-64
      uint64_t /* rax */ brightened(uint64_t /* rdi */ x, uint64_t /* rsi */ y) {
        return x + y;
      }
      

      The brightened function sets up the State on the stack and assigns the arguments to the registers appropriate for the calling convention of our target platform. The result register is returned from the function. Conceptually this is not very difficult, but it requires a bit of mental gymnastics to wrap your head around the trick:

      // Symbolic variable for memory
      uint8_t RAM[0];
      
      void lifted(State* state, void* memory) { ... }
      
      uint64_t brightened(uint64_t x, uint64_t y) {
        State state;
        state.rdi = x;
        state.rsi = y;
        lifted(&state, RAM);
        return state.rax;
      }
      

      After an inlining pass it would look something like this:

      uint64_t brightened(uint64_t x, uint64_t y) {
        State state;
        state.rdi = x;
        state.rsi = y;
        state.rdi += state.rsi;
        state.rax = state.rdi;
        __striga_ret(...);
        return state.rax;
      }
      

      We can get rid of the __striga_ret intrinsic in this case, which will let the optimizer reduce the function to its original shape:

      uint64_t brightened(uint64_t x, uint64_t y) {
        return x + y;
      }
      

      LLVM IR before optimizations:

      define i64 @brightened_0x1000(i64 %0, i64 %1) {
      entry:
        %state = alloca %State, align 8
        %rdi = getelementptr inbounds nuw %State, ptr %state, i32 0, i32 5
        store i64 %0, ptr %rdi, align 4
        %rsi = getelementptr inbounds nuw %State, ptr %state, i32 0, i32 4
        store i64 %1, ptr %rsi, align 4
        %stack = alloca i8, i64 4096, align 1
        %2 = getelementptr i8, ptr %stack, i64 4088
        %3 = ptrtoint ptr %2 to i64
        %rsp = getelementptr inbounds nuw %State, ptr %state, i32 0, i32 6
        store i64 %3, ptr %rsp, align 4
        store i64 3735928559, ptr %2, align 1
        call void @lifted_0x1000(ptr %state, ptr @RAM)
        %rax = getelementptr inbounds nuw %State, ptr %state, i32 0, i32 0
        %4 = load i64, ptr %rax, align 4
        ret i64 %4
      }
      

      After optimizing the module with default<O1>:

      define i64 @brightened_0x1000(i64 %0, i64 %1) {
      entry:
        %2 = add i64 %1, %0
        ret i64 %2
      }
      

      Memory / Stack

      To handle memory accesses, we create a global RAM variable and pass that to our memory argument. In the previous example it folded away, but we need to handle it separately. The simplest form is access to a pointer parameter:

      uint64_t lift4_read(uint64_t *n) {
        return *n ^ 1337;
      }
      

      With our current brightening strategy the lifted code (after optimizations) would look like this:

      define i64 @brightened_0x1000(i64 %0) {
      entry:
        %1 = getelementptr i8, ptr @RAM, i64 %0
        %2 = load i64, ptr %1, align 1, !alias.scope !19, !noalias !22
        %3 = xor i64 %2, 1337
        ret i64 %3
      }
      

      We need to detect the getelementptr i8, ptr @RAM, i64 %0 shape and replace it with an inttoptr instruction:

      define i64 @brightened_0x1000(i64 %0) {
      entry:
        %1 = inttoptr i64 %0 to ptr
        %2 = load i64, ptr %1, align 1, !alias.scope !19, !noalias !22
        %3 = xor i64 %2, 1337
        ret i64 %3
      }
      

      The stack can be modeled by allocating a local stack variable and pointing rsp to the end of that buffer (since on x86 the stack grows towards lower addresses):

      uint64_t brightened(uint64_t x, uint64_t y) {
        uint8_t stack[4096];
        State state;
        state.rdi = x;
        state.rsi = y;
        state.rsp = (uint64_t)&stack[sizeof(stack) - 8];
        lifted(&state, RAM);
        return state.rax;
      }
      

      Putting everything together in brighten.py:

      from llvm import Linkage, Module, Opcode, Value, global_context
      
      from bfs import lift_bfs
      from container import Container, RawContainer
      
      OPT_PIPELINE = "default<O1>"
      
      
      def rewrite_ram_geps(module: Module, ram: Value):
          """Replace GEPs rooted at @RAM with inttoptr(address)."""
          types = module.context.types
      
          for gep in ram.users:
              if not gep.is_instruction or gep.opcode != Opcode.GetElementPtr:
                  raise ValueError(f"unexpected @RAM user: {gep}")
      
              if gep.get_operand(0) != ram:
                  raise ValueError(f"unexpected @RAM GEP base: {gep}")
      
              if gep.num_operands == 2:
                  if gep.gep_source_element_type != types.i8:
                      raise ValueError(f"expected i8 ptradd-style @RAM GEP: {gep}")
                  address = gep.get_operand(1)
              elif gep.num_operands == 3:
                  zero = gep.get_operand(1)
                  if not zero.is_constant_int or zero.const_zext_value != 0:
                      raise ValueError(f"expected zero first @RAM GEP index: {gep}")
                  address = gep.get_operand(2)
              else:
                  raise ValueError(f"unexpected @RAM GEP shape: {gep}")
      
              with gep.create_builder() as ir:
                  ptr = ir.inttoptr(address, types.ptr)
              gep.replace_all_uses_with(ptr)
              gep.erase_from_parent()
      
          if not ram.users:
              ram.delete_global()
      
          module.verify_or_raise()
      
      
      def define_ret_stub(module: Module):
          """Make the modeled return hook removable for this demo wrapper."""
          ret_handler = module.get_function("__striga_ret")
          if ret_handler is not None and ret_handler.is_declaration:
              ret_handler.linkage = Linkage.Internal
              entry = ret_handler.append_basic_block("entry")
              with entry.create_builder() as ir:
                  ir.ret_void()
      
      
      def lift_brightened(container: Container, entry: int, args: list[str]):
          with global_context().create_module("blog") as module:
              sem = lift_bfs(module, container, entry, verbose=True)
      
              # Convenience aliases
              types = module.context.types
              i8 = types.i8
              i64 = types.i64
      
              # Global RAM array
              ram = module.add_global(types.array(i8, 0), "RAM")
      
              # TODO: support different register sizes
              brightened_ty = types.function(i64, [i64 for _ in args])
              brightened = module.add_function(f"brightened_{hex(entry)}", brightened_ty)
              with brightened.create_builder() as ir:
                  state = ir.alloca(sem.state_ty, "state")
      
                  def reg_ptr(name: str) -> Value:
                      return ir.struct_gep(sem.state_ty, state, sem.reg_indices[name], name)
      
                  # Assign arguments to register state
                  for i, name in enumerate(args):
                      ir.store(brightened.get_param(i), reg_ptr(name))
      
                  # Set up function stack
                  stack = ir.alloca(i8, i64.constant(4096), "stack")
                  stack_ptr = ir.gep(i8, stack, [i64.constant(4096 - 8)])
                  ir.store(ir.ptrtoint(stack_ptr, i64), reg_ptr("rsp"))
      
                  # Set up return address
                  retaddr_store = ir.store(i64.constant(0xDEADBEEF), stack_ptr)
                  retaddr_store.inst_alignment = 1
      
                  # Call lifted function
                  ir.call(sem.function, [state, ram])
      
                  # Load return value from rax and return it
                  ir.ret(ir.load(i64, reg_ptr("rax")))
      
              module.verify_or_raise()
      
              # 1. Inline/optimize with @RAM assigned to the lifted memory parameter.
              module.optimize(OPT_PIPELINE)
      
              # 2. Brighten lifted memory: @RAM + integer address -> inttoptr(address).
              rewrite_ram_geps(module, ram)
      
              # 3. Now that RAM accesses have been brightened, discard the modeled ret
              #    hook for this demo and let LLVM clean up the remaining wrapper noise.
              #    Undefined flag helpers are already declared memory(none) by Semantics,
              #    so their dead uses fold away without local stub definitions.
              define_ret_stub(module)
              module.verify_or_raise()
              module.optimize(OPT_PIPELINE)
      
              print(brightened)
      

      This cleanly lifts the following (unoptimized) function:

      ; 0x1000 push rbp
      ; 0x1001 mov rbp, rsp
      ; 0x1004 mov qword ptr [rbp - 8], rdi
      ; 0x1008 mov rax, qword ptr [rbp - 8]
      ; 0x100c pop rbp
      ; 0x100d ret 
      define i64 @brightened_0x1000(i64 returned %0) {
      entry:
        ret i64 %0
      }
      

      Conclusion

      Hopefully this was an insightful introduction to lifting to LLVM IR. Feel free to check out the repository at LLVMParty/striga and reach out if you do something interesting with it!

      Note : Striga is not meant to be a production-ready lifter. There are no tests and only a very limited subset of x86 has been implemented.

      Thanks to the reviewers:

      LLVM IR references:

    32. 🔗 r/york Free theatre tickets for The Psychic @ Theatre Royal TONIGHT 19:00 rss

      I've 2x tickets for the new play, The Psychic, tonight - Thursday 21st May at 7pm. We're unable to attend due to unforeseen circumstances (the irony!) but I don't want them to go to waste - good seats. Free of charge to anybody who wants them, but I only ask that you actually attend! DM me if you're serious about going and would like them.

      https://www.yorktheatreroyal.co.uk/show/the-psychic/

      submitted by /u/clockworkear
      [link] [comments]

    33. 🔗 r/reverseengineering I built 99 adversarial PE fixtures to stress‑test parsers — here’s what they reveal about malformed binaries rss
    34. 🔗 r/york 'It's just crazy': The York students rejecting a bank-breaking prom rss

      'It's just crazy': The York students rejecting a bank-breaking prom | submitted by /u/Kagedeah
      [link] [comments]
      ---|---

    35. 🔗 backnotprop/plannotator v0.19.21 release

      Follow @plannotator on X for updates


      Missed recent releases? Release | Highlights
      ---|---
      v0.19.20 | Interactive goal setup UI, OpenCode submit_plan fixes, browser no-op sentinel handling for Claude agents
      v0.19.18 | Edit-based submit_plan for OpenCode, Pi namespace migration, Codex annotate-last fix, OpenCode commands dir fix
      v0.19.17 | Reworked goal setup skill (interview-driven flow), CLI --version flag
      v0.19.16 | Code navigation with peek view (Cmd/Ctrl+click tokens in diffs)
      v0.19.15 | Commit-based diff base, jj evolution diffs, GitLab reliability fixes, OpenCode command intercept fix
      v0.19.14 | Visual explainer skill update, PFM code-file hover previews, Graphviz, diff tab size and line bg intensity, hooks settings tab
      v0.19.11 | Jujutsu (jj) VCS backend, slimmer hunk separators, collapse viewed files, multi-line gutter selection fix
      v0.19.9 | OpenCode user-managed workflow, Pi model switch fix, Codex skill install, shimmer removal
      v0.19.8 | 49 themes with syntax highlighting, keyboard shortcut registry, smart code-file path validation, remote URL notifications
      v0.19.7 | Codex Stop-hook plan review, Codex skills, sidebar auto-close, file tree context menu


      What's New in v0.19.21

      v0.19.21 brings Ask AI to plan review and annotate mode. The same inline AI chat that was available in code review now works when reviewing plans, annotating markdown files, annotating URLs, and annotating HTML documents.

      Ask AI in Plan Review and Annotate Mode

      Select any text in a plan or annotated document, open the comment popover, and click "Ask AI" to ask a question about the selected content. The response streams into a side panel that persists alongside the annotation panel. You can switch between annotations and AI chat using the sidebar tabs, and both stay independent of each other. AI chat messages are never included in approval or denial feedback.

      The feature uses the same provider-agnostic backend that powers code review AI. Any provider you have installed (Claude, Codex, Pi, OpenCode) works automatically. If you have multiple providers, the system picks a default based on which agent runtime you're using (Claude Code defaults to Claude, Codex defaults to Codex, and so on) and you can override it from the AI settings bar at the top of the chat panel.

      A one-time announcement dialog appears the first time Ask AI is available in plan review, then dismisses permanently via cookie. Users with no AI providers installed see no change at all.

      Shared AI Runtime

      The AI provider setup that previously lived inline in the code review server has been extracted into a shared ai-runtime module. All three servers (plan review, code review, annotate) and the Pi extension now use the same initialization path. This means provider detection, session management, and SSE streaming are consistent across every Plannotator mode.

      The refactor also fixed a missing SSE timeout in the code review server. Long- running AI responses could previously be cut off by Bun's idle connection timeout. All three servers now correctly disable the timeout for /api/ai/query requests.

      Origin-Aware Provider Defaults

      When multiple AI providers are available, Plannotator now picks a default based on which coding agent launched the session. Claude Code sessions default to Claude, Codex sessions default to Codex, Pi sessions default to Pi, and OpenCode sessions default to OpenCode. You can still override the selection manually, and your per-origin preference is saved separately so switching between agents doesn't reset your choice.


      Install / Update

      macOS / Linux:

      curl -fsSL https://plannotator.ai/install.sh | bash
      

      Windows:

      irm https://plannotator.ai/install.ps1 | iex
      

      Claude Code Plugin: Run /plugin in Claude Code, find plannotator , and click "Update now".

      OpenCode: Clear cache and restart:

      rm -rf ~/.bun/install/cache/@plannotator
      

      Then in opencode.json:

      {
        "plugin": ["@plannotator/opencode@latest"]
      }
      

      Pi: Install or update the extension:

      pi install npm:@plannotator/pi-extension
      

      What's Changed

      Full Changelog : v0.19.20...v0.19.21

    36. 🔗 r/Leeds Canada Goose rss

      Hi,

      I've come up from London for a conference and my friend Tarquin has spilt some of your Kirkstalle Ale on his Gilet last night while we were enjoying KPMG corporate hospitality.

      We are flying back to Heathrow this afternoon so don't have time to get it dry cleaned but obviously don't want to go the day sticking out like a sore thumb without the proper attire. Is there anywhere in Leeds (ideally near the dock) we could pick up some Canada Goose, want to avoid brands like North Face unless it's getting dire.

      Thanks in advance

      submitted by /u/Ford_Maeve
      [link] [comments]

    37. 🔗 r/york York, reflected ✨ rss

      York, reflected ✨ | Image @ kierandelaneyvisuals submitted by /u/1ChanceChipmunk1
      [link] [comments]
      ---|---

    38. 🔗 r/wiesbaden Wellpass +1 Mitgliedschaft gesucht rss

      Hey zusammen,

      ich wollte mal freundlich in die Runde fragen, ob zufällig jemand hier Mitglied bei EGYM Wellpass ist und den neuen „Plus1“-Platz noch frei hat 😊

      Dabei kann man wohl eine weitere Person privat mit in den Tarif aufnehmen. Ich hätte Interesse daran und würde die Kosten natürlich vollständig selbst übernehmen – für euch also kein finanzielles Risiko oder zusätzlicher Aufwand, außer der Einladung selbst.

      Hier sind die Infos dazu:

      Wellpass Plus1-Mitgliedschaft Erklärung

      https://support.egym-wellpass.com/de/articles/10853223-plus1-mitgliedschaft

      Falls jemand grundsätzlich Interesse hätte oder Fragen dazu hat, gerne einfach melden 🙂

      submitted by /u/Ackererack
      [link] [comments]

    39. 🔗 jellyfin/jellyfin 10.11.9 release

      🚀 Jellyfin Server 10.11.9

      We are pleased to announce the latest stable release of Jellyfin, version 10.11.9! This minor release brings several bugfixes to improve your Jellyfin experience. As always, please ensure you take a full backup before upgrading!

      You can find more details about and discuss this release on our forums.

      Changelog (5)

      📈 General Changes

    40. 🔗 anthropics/claude-code v2.1.146 release

      What's changed

      • Renamed /simplify to /code-review with an optional effort level (e.g. /code-review high)
      • Auto mode no longer suppresses AskUserQuestion when the user or a skill explicitly relies on it
      • Fixed Windows PowerShell tool failing with "command line is invalid" when pwsh is installed via winget or the Microsoft Store (regression in v2.1.124)
      • Fixed MCP resources/list, resources/templates/list, and prompts/list dropping items past page 1 on paginating servers
      • Fixed full-screen strobing in attached background sessions on Windows Terminal while Claude is streaming
      • Fixed the auto-updater status line not showing your current version when an update fails
      • Fixed on Windows, removing a background-job worktree no longer follows NTFS junctions into the main repo
      • Fixed /background refusing sessions whose only typed input was a skill or custom slash command
      • Fixed backgrounded sessions re-prompting for tool permissions you already granted with "don't ask again"
      • Fixed /theme color editor and "New custom theme" dialogs not responding to Esc
      • Fixed an uncaught exception at the end of streaming sessions when running via the Agent SDK
      • Fixed forceLoginOrgUUID and forceLoginMethod managed-settings policies not being enforced against third-party-provider and API-key sessions
      • Fixed GNOME Terminal right-click and middle-click paste not inserting text
      • Fixed CLAUDE_CODE_SUBAGENT_MODEL not being forwarded to child processes in multi-agent sessions
      • Improved auto-updater reliability: native version checks and downloads now retry transient network failures instead of failing immediately
      • Improved diff rendering performance for large file edits
    41. 🔗 matklad TIL: Symlinking NixOS Dotfiles rss

      TIL: Symlinking NixOS Dotfiles

      May 21, 2026

      The standard answer to managing dotfiles on NixOS is home- manager. I’ve never used it, due to two aesthetic and one practical objection:

      • I avoid dependencies, especially in nix, which rivals Python in the number of approaches to dependency management.
      • home-manager installs packages for the current user only, which makes sense on non-NixOS systems. But on a single-user desktop system, I prefer having just one set of packages.
      • Having a source of truth for dotfiles be in nix store requires rebuilding your system to change config, which gets in the way of Emacs-style direct tinkering.

      The approach I like is storing dotfiles in the same repository as flake.nix / configuration.nix and symlinking them in place.

      The problem here is that NixOS seemingly doesn’t have a “native” way to say that /a/b/c should be a symlink to /c/d/e. Or has it?

      If you search options for symlink, you’ll learn about environment.etc which allows you to configure symlinks, but only for things in /etc, not your ~/.config.

      For the latter, you can use gnu stow or some other dotfile link manager, but the complexity of the problem of just managing symlinks doesn’t warrant yet another dependency. It’s fine to do this manually.

      But wouldn’t it be nice if this framework for declarative configuration of your system allowed you to declaratively configure symlinks? Turns out this is possible, in roundabout way. Inaptly-named systemd- tmpfiles allows creating symlinks from a declarative config, and you can use NixOS to configure systemd-tmpfiles itself (thanks, Noobz!).

      For example, if I want to symlink ~/dotfiles/git/config to .config/git/config:

      {
        systemd.tmpfiles.rules = [
          "L+ /home/matklad/.config/git/config - - - - /home/matklad/dotfiles/git/config"
        ];
      }
      

      No opinion at this point how this compares to a bespoke script or something more purpose-built.

    42. 🔗 Console.dev newsletter Antigravity 2.0 rss

      Description: Agentic IDE.

      What we like: Integrates a VS Code-style editor with a CLI and agent management console. Easily track multiple agent sessions and subagents. Create scheduled tasks e.g. regular dependency updates. Sync between different Gemini / Antigravity clients e.g. chat to CLI. Supports skills, MCPs, hooks.

      What we dislike: No custom themes. Workspace accounts can’t upgrade usage.

    43. 🔗 Console.dev newsletter Fate rss

      Description: Data client for React.

      What we like: Uses async React to enable optimistic UI updates and instant feedback. Provides typed APIs to connect to the data backend over fetch, tRPC, or GraphQL. Also includes adapters for Prisma and Drizzle. Introduces an Actions concept for mutations, but you can use more traditional imperative calls.

      What we dislike: Requires React 19 because this is a modern library.

    44. 🔗 Ampcode News Amp Labs rss

      We are assembling small teams of exceptional software builders to bring the full power of artificial intelligence to a single company per industry and region, with CEO mandates.

      For the companies we partner with: we win if and only if you win. We profit only through warrants unlocked if your stock appreciates considerably. We don't work with your competitors.

      To the best builders out there and to the best companies in the real economy: we'll be in touch.

      Being on the front lines with Amp Labs is how we keep the Amp agent on the frontier. Read more at amplabs.com.

      Amp Labs

    45. 🔗 Ampcode News Rush, 2.0 rss

      We're releasing a new version of our agent mode rush.

      Prior to this change, rush’s usefulness was limited. It was faster and cheaper, but also made more mistakes and required more attempts to get to the same results than a slower and ultimately not that much more expensive frontier model.

      Now, rush is tuned to lean into its advantages — speed, low cost — instead of trying to make up for its shortcomings.

      It uses GPT-5.5 with no reasoning instead of Haiku 4.5. It is tuned for small coding tasks that don’t require contemplating the whole repo, but to find the relevant files, make the smallest correct change, run a focused check, and stop.

      This is what rush is good at:

      • “Fix the failing renders empty state test.”
      • “Update @src/components/ui/Select.tsx to match the focus-ring styling in @src/components/ui/Button.tsx
      • “Rename enableLegacySearch to enableSearchV2 in all files that use it”

      Do not use rush for transient bugs, architecture changes, migrations, complex features, and tasks where you do not yet know what “done” means. In those cases, reading more, thinking longer, and building a larger model of the codebase is what gets you good results. Use smart or deep for those.

      What Changed

      The previous system prompt in rush mode was “speed first.” It told the model to move fast, keep explanations short, edit, verify, and stop. With GPT-5.5, we can be more precise: gather only the context needed to act safely, make the smallest correct change, verify narrowly, and stop. This makes it less prone to save time by skipping the parts that make the result usable and to over-contextualize - to keep reading and thinking.

      rush now uses shell_command for searching, reading, and verification, and apply_patch for edits. That means we can remove quite a few tools that all do almost the same thing - grep, glob, and create_file.

      The task subagents have the same configuration as the main agent: no reasoning, GPT 5.5.

      Evals

      On our internal evals, rush solved 44% of tasks, up from 39% for the previous version.

      The cost moved up slightly: $0.58 per task on average, compared to $0.44 for the previous version (an 18% increase).

      The speed changed much more. Rush 2.0 finished in 1 minute and 32 seconds on average, down from 2 minutes and 59 seconds.

      That is the tradeoff we wanted: a little more expensive, meaningfully more capable, and almost twice as fast.

      It is not deep. On the same evals, deep solved 58% of tasks, 14 points higher than rush.

      Pair It with the Oracle

      The best pattern we have found is rush plus the oracle.

      Let rush build. Ask the oracle to plan, criticize, or review. The oracle is slower and more expensive, but it is read-only and good at adversarial thinking.

      This works especially well for tasks that are still bounded, but not trivial. You know the area of the codebase. You know roughly what needs to change. But there is enough surface area that a second, more deliberate pass can prevent rush from making the locally obvious but globally wrong edit.

      Try prompts like:

      • “Ask the oracle to inspect @src/billing/applySeatLimit.ts, @src/billing/planLimits.ts, and the failing seat limit is enforced after downgrade test. Have it propose the concrete fix first: which behavior should change, which file should own the rule, and what should stay untouched. Then implement the smallest patch and run the billing tests.”
      • “Update the workspace invite flow so expired invites show the same error state in @src/routes/invites/AcceptInvitePage.tsx and @src/components/invites/InviteBanner.tsx. After the patch, ask the oracle to review the diff and suggest the focused tests or manual checks that would actually prove this works. Run the relevant ones before calling it done.”
      • “Before changing the caching behavior in @src/search/useSearchResults.ts, ask the oracle for two or three implementation options beyond the obvious one. Have it judge them in context of the codebase: consistency with the existing query hooks, risk of stale data, complexity, and testability. Then implement the best minimal option.”

      To use it: run mode: use rush in the Amp CLI.

    46. 🔗 muffinman SpaceDeck X is coming to an arcade cabinet rss

      I want your coins!

      I'm making a game. It is called SpaceDeck X and you can try it online. But thanks to Amsterdam Indie Arcade, it will be available on a physical arcade cabinet at Blast Galaxy.

      It will be released on the 14th of June with a small release party and hi- score tournament. If you are in Amsterdam, be sure to come and check it out. It will be available for the next two months, then a new indie game will take its place.

      Poster for the release party with an image of a stylized arcade
cabinet

      Hi-Score Tournament

      We are going to organize a hi-score tournament. The Indie Arcade organizer asked me if I could come up with a fun prize for the winner, so I did:

      Hi score tournament trophy, 3D printed ship from the game on a
stand

      I designed and 3D printed the main player ship from the game on a little pedestal. It was super fun figuring out how to bring my pixel art to the real world and break it down for 3D printing. The model is made in JavaScript using Replicad.

      Come and claim the trophy on the 14th!

      Steam Release

      Screenshot of the boss fight in SpaceDeck X, showing the player ship and
deck, with the large triangular boss ship above it

      The arcade release is just a pit stop. I'm actively working towards a Steam release, so stay tuned!

  2. May 20, 2026
    1. 🔗 IDA Plugin Updates IDA Plugin Updates on 2026-05-20 rss

      IDA Plugin Updates on 2026-05-20

      New Releases:

      Activity:

    2. 🔗 r/wiesbaden WC26 Question rss

      New to the city, is there any special events that happen for the World Cup? The best bars to go watch?

      submitted by /u/FunnyCryptographer38
      [link] [comments]

    3. 🔗 r/LocalLLaMA Re. what ever happened to Cohere’s Command-A series of models? rss

      Re. what ever happened to Cohere’s Command-A series of models? | Hey everyone, Nick Frosst here from Cohere. A few months ago Aidan (my cofounder) left a comment in here about our Command series and how we were working on some more powerful, open-weights models behind the scenes. We just launched Command A+ and we wanted to share it with you guys. TLDR is we built a really efficient model. It’s our first MoE model, which is exciting. There’s obvs work to do on top-line performance but it’s easily looking like one of the fastest and most responsive models in our category. We also pulled off some incredible quantization work so it runs really well on even 1 or 2 GPUs. Like with R7B, we really prioritized making the model practical, so smaller teams and devs could realistically use it to build the kind of agents we ship for our platform customers. That’s also why it’s under Apache 2.0. Just total, near unfettered access to a pretty awesome model. We’re enterprise-first but honestly, we get so much out of our open-source community that makes us more innovative and creative. The feedback you give will almost certainly influence how we think about models and product going forward…... as it already has here from getting called out the last time haha. So, don’t hold back. Share your thoughts, your projects, whatever. You can see the full details here https://cohere.com/blog/command-a-plus We appreciate you :) submitted by /u/nick_frosst
      [link] [comments]
      ---|---

    4. 🔗 r/reverseengineering GeoHelper - Tauri + Chrome DevTools Protocol (CDP) for GeoGuessr (Steam) rss
    5. 🔗 r/Yorkshire It's that time again, looking forward to all the fun, great atmosphere guaranteed. rss
    6. 🔗 r/LocalLLaMA Qwen will release another 27B with high probability rss
    7. 🔗 r/york Lost/stray cat? rss

      Lost/stray cat? | Does anybody recognise this cat/know if it has an owner? Spotted in the alley next to st Lawrence church. I'm worried she doesn't have a home because there's no collar, she's very skinny and covered in fleas but she seems too friendly to be a stray. I will try to take her to a vet to check for a chip if no one knows anything. submitted by /u/cousarn
      [link] [comments]
      ---|---

    8. 🔗 r/reverseengineering AI Agents defeat obfuscated JavaScript in 10 minutes rss
    9. 🔗 r/reverseengineering What is it Wednesdays: Episode 0002 rss
    10. 🔗 r/Leeds LEAD GUITARIST WANTED! rss

      We’re a Leeds-based indie/alternative band looking for a new lead guitarist.

      We’ve recently released a new EP and have built a really solid foundation online. Right now, our focus is entirely on keeping that momentum going. We’re stepping straight into a writing and recording phase to get new material ready for release and for shows. Logistics-wise, we’ve got it sorted: we have our own dedicated rehearsal space, we demo everything ourselves, and we work closely with great producers to bring the songs to life.

      We write music about everyday life and the honest, relatable things people actually experience. We’re ambitious and we take the music seriously, but we also genuinely just want to have fun. Writing and rehearsing shouldn’t feel like a chore; we want someone who wants to have a laugh and enjoy the whole process of building the next phase with us.

      For fans of:

      Deaf Havana / Twin Atlantic / The Xcerts / The Hunna / The Band CAMINO and loads more!

      Who we're looking for:

      We want someone who wants to take the reins lead-guitar wise - bringing big melodies, atmosphere, and a great understanding of dynamics. With a bulk of songs already main stays in our live set, we are looking for a songwriter who genuinely loves the creative process and wants to collaborate on new music from scratch, as sticking their own solid take on our existing material.

      We need someone who is reliable, committed, and doing it for the right reasons. Gigging experience is definitely a bonus, but it’s absolutely not a dealbreaker if playing live is something you are excited for. Leeds or Yorkshire-based is preferred.

      If you're on our wavelength and want to create something exciting, drop us a message. We'll probably chew your ear off and want to know lots about you, like:

      A quick video or audio clip of your playing/writing

      Your main influences

      Any previous projects (don’t worry if you haven't been in a band before)

      Please get in touch and I'll get back to you if this sounds like a good fit!

      submitted by /u/TWKcub
      [link] [comments]

    11. 🔗 earendil-works/pi v0.75.4 release

      New Features

      • Hardened npm install and release path - Pi now ships the CLI with a generated shrinkwrap for transitive dependencies, blocks accidental lockfile changes, verifies dependency pinning and lifecycle-script allowlists in checks, disables lifecycle scripts for self-update and local release installs where supported, and smoke-tests isolated npm and Bun installs before release. See Supply-chain hardening.

      Added

      • Added interactive update notes after pi update runs, so users can see the installed version's changelog before continuing (#4724 by @mitsuhiko).
      • Exported image resize utilities from the package root for SDK consumers (#4775 by @xl0).

      Changed

      • Changed source syntax to avoid TypeScript constructs that require JavaScript emit, keeping core sources compatible with Node.js strip-only TypeScript checks.
      • Removed web UI workspace references from the CLI package and dropped the package-level development watch script.
      • Published npm installs now include an npm-shrinkwrap.json to lock transitive dependencies for the CLI package.
      • Improved terminal theme detection for light/dark and truecolor handling.
      • Changed self-update package-manager commands to disable lifecycle scripts during reinstall.

      Fixed

      • Fixed the system prompt to tell models to resolve pi docs and examples under the absolute package paths before reading topic-specific relative references (#4752).
      • Fixed extension ctx.abort() during tool-call preflight to stop later confirmations and restore queued interactive input like Escape (#4276).
      • Fixed AgentSession retry, compaction, and event settlement to use the awaited agent lifecycle instead of a separate event queue, and added willRetry to agent_end session events.
      • Fixed forked session runtime state to keep the active session id aligned with the fork target (#4799 by @Perlence).
      • Fixed the subagent extension's parallel mode to return useful per-task output and failed-task diagnostics to the parent model instead of 100-character previews (#4710).
      • Fixed Windows local bash execution to hide helper console windows when launched from background SDK processes (#4699).
      • Fixed managed npm extension folders to set cloud-sync ignore metadata where supported (#4763).
      • Fixed HTTP idle timeout configuration so long-running provider streams can avoid premature idle disconnects (#4759 by @mitsuhiko).
      • Fixed default system prompt boundaries to use explicit XML tags for clearer file separation (#4709 by @herrnel).
      • Fixed HTML share/export sidebar clicks for shared tool entries to scroll to the rendered tool call (#4664 by @yzhg1983).
      • Fixed theme palettes to set explicit text colors and avoid terminal-default color drift.
      • Fixed truecolor detection to align terminal image rendering and interactive theme decisions.
      • Fixed loader indicator startup inherited from @earendil-works/pi-tui so initialization cannot run before frames are available.
      • Fixed OpenAI-compatible default output token requests inherited from @earendil-works/pi-ai to avoid reserving impossible context windows on servers such as vLLM (#4675).
      • Fixed OpenAI prompt cache keys inherited from @earendil-works/pi-ai to stay within the 64-character provider limit (#4720).
      • Fixed Windows npm-family package commands for fnm-managed Node.js installs that expose both extensionless Unix scripts and .cmd shims (#4793).
    12. 🔗 r/LocalLLaMA AMD Ryzen AI Halo PC will cost 3999$ with 128GB memory on board rss
    13. 🔗 r/reverseengineering TinyLoad v5 - encrypted strings, obfuscated opmap, IAT wiping, payload depends on stub (implemented feedback from last post) rss
    14. 🔗 r/reverseengineering Tracing CVE-2026-34472 auth bypass through decompiled ZTE H188A firmware and Lua wizard routing rss
    15. 🔗 r/LocalLLaMA HuggingFace benchmark datasets now let you filter by model size rss

      HuggingFace benchmark datasets now let you filter by model size | Quite useful to see which model under 32B performs best on swebenchverified for example.
      https://huggingface.co/datasets?benchmark=benchmark:official&sort=trending submitted by /u/paf1138
      [link] [comments]
      ---|---

    16. 🔗 Locklin on science Q1/2 2026 books rss

      Getting the best of it by David Sklansky. This is something that’s been in my list of books to read since I got out of grad school. It’s often recommended for getting a quant finance job for the sort of gambling puzzles it contains. Most of the poker stuff is lost on me, as I’ve […]

    17. 🔗 r/york Informal York Queer Meet-Up @ City Screen Picturehouse Café - Friday, 22 May 2026 rss

      Hello!

      We've organised a couple of meetups via Reddit and the /r/york Discord over the last few months.

      We're planning to meet up again at City Screen Picturehouse Café Friday, 22 May 2026. If anyone would like to come along and chill with some queer nerds, you're more than welcome!

      A bit about me: I’m a guy in my mid-30s, into Star Trek, grand strategy gaming, and Wikipedia editing.

      • Where: Cityscreen Café, either on the sofas or at one of the tables at the back!
      • When: 18:30, Friday 22 May 2026 (this Friday!)

      You'll know it's us because we'll have a fluffy rabbit on the table.

      Feel free to reply here, DM me, or message in the Discord if you’re thinking of coming along!

      submitted by /u/NervousEnergy
      [link] [comments]

    18. 🔗 r/Leeds Anyone know where I can buy the spice blend tajin ? rss

      It's a Mexican spice blend used on fruit a lot and I always wanted too try or. I tried b an m, aldi, lidil and Asda with 0 results

      submitted by /u/TipAdditional4625
      [link] [comments]

    19. 🔗 r/Leeds Looking for Germany supporters in Leeds for the World Cup rss

      Hey everyone. I’m looking for fellow Germany fans in Leeds to watch the World Cup matches together.

      Quick context: I’m Indian, been living in Leeds for a while, and somehow ended up supporting Germany. I know, I know. Finding other Germany fans in England is basically a quest at this point.

      If you support Germany for whatever reason, or just want someone to suffer with during the matches, get in touch. Would be great to find a group or even just one or two people to watch the games with.

      Drop a comment or message me. Cheers.

      submitted by /u/Regular-Being7191
      [link] [comments]

    20. 🔗 r/reverseengineering How to build .NET obfuscator rss
    21. 🔗 r/york A classic York sightline 👀 rss

      A classic York sightline 👀 | @ John Wellock submitted by /u/1ChanceChipmunk1
      [link] [comments]
      ---|---

    22. 🔗 r/wiesbaden Panini WM 2026 Sticker Tauschbörse rss
    23. 🔗 r/Leeds Is this permanent? Did we run out of money for the station project? rss

      Just feels weird. We've been waiting nearly two years to repave that stretch of road, with it being half done all that time. Unless it's some kind of temporary covering? Anyone have any idea?

      submitted by /u/TheScarletCravat
      [link] [comments]

    24. 🔗 The Pragmatic Engineer Google Cloud deletes Australian trading fund’s infra rss

      A $124B fund in Australia would have lost all data stored with Google Cloud, had they not relied on a third-party backup. A rare blunder from GCP, where regional replication did not stop the deletion - and a just as rare statement from Google Cloud's CEO taking the blame.

      The below is an excerpt from The Pulse #93: OpenAI makes Google dance , originally published on 16 May, 2024. I am republishing it because on 20 May 2026 Google Cloud has done it again: they took offline cloud infra provider Railway by blocking Railway 's Google Cloud account . The below is a warning: if you are on GCP, have a plan B, should GCP delete your account and data, or block your account.

      Following on from Google Cloud being a distant third among cloud providers, a recent event could cement its reputation as the least reliable of the top three.

      UniSuper is one of the largest retirement savings accounts in Australia, used by 615,000 citizens, that's also known as a "superannuation fund." UniSuper has $124B of assets under management and is one of the biggest in the country.

      On 29 April, the service suffered an outage. Members could not log into their online accounts, or manage their funds until two weeks later, on 15 May.

      The reason was that Google Cloud accidentally deleted UniSuper's subscription, which also deleted all data associated with the subscription. UniSuper had set up replication across two regions in Google Cloud to protect from a regional failure, but Google Cloud deleted the replica as well!

      UniSuper could only avoid data loss thanks to having a backup on another service provider outside Google. In a surprising admission, UniSuper would have lost all data with Google thanks to the failure of the cloud provider. The only reason UniSuper could restore services was by having another provider with whom they'd backed up the data. Basically, UniSuper not trusting Google's replication across two regions turned out to be a 100% correct assumption. Whoever pushed through the decision to spend additional resources in "a backup in case Google fails" saved the day at the retirement fund.

      The incident is incredibly embarrassing for Google. UniSuper seems to have forced Google Cloud's hand by issuing a joint statement with Google Cloud CEO Thomas Kurian, in which Google Cloud takes all the blame for this failure. In my experience, the situation is rarely this black-and-white, as it usually takes two parties to cause such a major outage. I would not be shocked if it turned out UniSuper's staff played a role in this failure, but Google Cloud made enough mistakes that the press release could dump all blame on it. I asked Google Cloud if the press release really was a joint release, and if they had more to add. The company confirmed the press release is correct and added nothing else.

      Whoever was at fault, two weeks of downtime is still very long for a major fund. As I understand, the damage to UniSuper is mainly reputational because the funds are safe and secure.

      Users could not see their balances for a few weeks, and were told Google Cloud had messed things up. This means there are up to 615,000 Australians in whose minds UniSuper and Google Cloud are indelibly linked with unreliability.

      I keep seeing that Google Cloud has no apparent strategy for what it wants its cloud to offer. A few months ago, we dived into how AWS, Azure and GCP respond to regional outages, and I concluded it's hard to see a strategy at GCP beyond following processes, while doing the least impressive job of all three cloud providers. It's hard to gain market share if you remain the slowest to respond to regional outages, and the provider for whom a zone outage takes down a region, or which loses all customers' data, despite regional replication, by deleting it.

      This incident is a reminder you shouldn 't fully trust your cloud provider. UniSuper was smart to have backups elsewhere for its data in Google Cloud. And while it's tempting to point fingers at Google Cloud: there are no definite assurances that another vendor would not make a similarly unprecedented mistake in the future!

      The learning is that if you have really valuable data, keep a backup somewhere else. If you use any cloud provider, use another cloud, on-prem backups, or something else.

      Read the full The Pulse issue

    25. 🔗 r/wiesbaden Looking for Tattoo artist rss

      I need someone who has a love for Tattooing and is really good at it!! I’m willing to pay for what I get just need the confidence I’m in good hands 🙏🙏

      submitted by /u/GuavaCool4628
      [link] [comments]

    26. 🔗 r/wiesbaden Kurhaus wird zur Open‑Air‑Bühne für neue Eventformate rss

      Neben mehreren Konzerten des Rheingau Musik Festivals prägen moderne elektronische Daytime‑Events das Programm und erweitern das Angebot um urbane Veranstaltungsformate.

      submitted by /u/LethisXia
      [link] [comments]

    27. 🔗 r/Yorkshire You can tell exactly where they are from rss

      You can tell exactly where they are from | submitted by /u/RedDevilPlay
      [link] [comments]
      ---|---

    28. 🔗 r/LocalLLaMA Qwen3.7 Max scored by Artificial Analysis, 27B/35B waiting room rss

      Qwen3.7 Max scored by Artificial Analysis, 27B/35B waiting room | https://preview.redd.it/42ak5qmus82h1.png?width=1133&format=png&auto=webp&s=744ea3dfc06c83d0c4d8aa128c39b3238b17d7be Qwen 3.7 Max sitting at 5th, pretty much on par with GPT 5.4 (xhigh) and a notch above the just released Gemini 3.5 Flash. On the other end, we see DSV4 Flash and Qwen3.6 27B which is exactly 6 points behind its max counter part. Let's hope Qwen3.7 can get in the same ballpark of its max big bro as well. submitted by /u/Beamsters
      [link] [comments]
      ---|---

    29. 🔗 HexRaysSA/plugin-repository commits sync repo: +2 releases rss
      sync repo: +2 releases
      
      ## New releases
      - [ida-settings-editor](https://github.com/williballenthin/ida-settings): 1.1.1, 1.1.0
      
    30. 🔗 r/Leeds Landlord Conference Leeds rss

      Please can you all return from whence you came because the pub quizzes are all cancelled and the pub queues are streaming down the road and we don’t really like landlords much normally anyway

      submitted by /u/marinasambhi
      [link] [comments]

    31. 🔗 anthropics/claude-code v2.1.145 release

      What's changed

      • Added claude agents --json to list live Claude sessions as JSON for scripting (tmux-resurrect, status bars, session pickers)
      • Added agent_id and parent_agent_id attributes to claude_code.tool OTEL spans, and fixed trace parenting so background subagent spans nest under the dispatching Agent tool span
      • Status line JSON input now includes GitHub repo and PR information when detected
      • /plugin Discover and Browse screens now show a plugin's commands, agents, skills, hooks, and MCP/LSP servers before installation
      • claude agents terminal tab title now shows the awaiting-input count so an alt-tabbed window tells you when an agent needs attention
      • Slash command and @-mention suggestion list now supports mouse hover and click in fullscreen mode
      • Stop and SubagentStop hook input now includes background_tasks and session_crons fields
      • Fixed a permission-prompt bypass where bare variable assignments to non-allowlisted environment variables in Bash commands were auto-approved
      • Fixed MCP prompt slash commands showing raw server validation errors when a required argument is omitted — the error now names the missing argument and shows expected usage
      • Fixed the spinner and elapsed-time display freezing until a keypress after the terminal was resized or refocused
      • Fixed the cross-project resume hint failing in default Windows PowerShell 5.1 — Windows now uses ; as the command separator
      • Fixed voice push-to-talk not working in the agent view's reply pane
      • Fixed task lists rendering in random order when several tasks are created at once
      • Fixed stale "Failed to install Anthropic marketplace" banner showing when the marketplace is already installed
      • Fixed the PR badge in the footer not updating immediately after gh pr create and other PR-state-changing commands run in-session
      • Fixed Agent Teams teammates with non-ASCII names failing every API call due to invalid header encoding
      • Fixed /review using a deprecated projectCards GraphQL query that errored on repos with Classic Projects
      • Fixed claude plugin validate not flagging skills: entries that point at a file instead of a directory — the error now suggests the parent directory
      • Fixed an infinite loop where a skill using context: fork could repeatedly re-invoke itself instead of running
      • Improved the Read tool to return a truncated first page with a "PARTIAL view" notice instead of a hard error when a whole-file read exceeds the token limit
    32. 🔗 Stephen Diehl Book Review: On the Calculation of Volume rss

      Book Review: On the Calculation of Volume

      Solvej Balle's On the Calculation of Volume is a planned septology about a Danish antiquarian book dealer who falls out of time, and the first five volumes are one of the most original and brilliant literary projects I've read in years. The premise is the one you have seen a hundred times. The protagonist, Tara Selter, wakes up on the eighteenth of November. The day passes. She goes to sleep. She wakes up. It is the eighteenth of November. Her husband Thomas, who lives with her in a stone house in northern France, has no memory of the previous iteration. She does. It takes a familiar science fiction idea and makes it feel fresh, intimate, and deeply human. I read all five over a week in San Sebastian, sitting in the bright Atlantic light of the Basque coast while reading about a woman who can't leave a single grey rainy day in northern France, and the books were only better for the contrast. Mild spoiler warning: I'll describe the shape of each book but not its turns. Skip to the bottom if you want to come to the cycle clean.

      The first volume is the small one, around two hundred pages, minimalist in both plot and prose. The minimalism is the point. Tara has returned to Clairon-sous-Bois from a book fair in Paris with a small burn on her hand from a hotel heater and a Roman sestertius in her bag, and we meet her on day one hundred and twenty-two of the loop. By then she has the day memorized to the second. The blackbird sings at the same instant every morning. The cup is where she left it. Thomas, beautifully indifferent to the cosmological catastrophe he is sleeping through, asks her about her trip. She tells him. He listens. He has listened a hundred and twenty-two times. There is something sisyphean about a marriage where one of you has to begin the conversation again from scratch every morning. The writing here is the kind of plain prose that takes a whole career to learn how to write. Short sentences. Present tense. Almost no metaphor. A naturalist's field notebook, kept by someone who has begun to understand that the field is closing in. Barbara J. Haveland's English translation is so unobtrusive you forget the book was written in another language. Volume I is a phenomenology textbook in the disguise of a novel, and the disguise is so good that the textbook keeps surprising you with feeling.

      A year passes inside the day, and in the second volume Tara goes traveling. She has worked out by then that the eighteenth restarts wherever she happens to be sleeping, so she can take the loop with her. She rides trains. She crosses Europe. She follows snow up to Norway and crepuscular light down to the south, anything that might serve as evidence of the season she has been denied. The trick of Volume II is that it is a travelogue turned inside out. The world is supposed to be the still backdrop against which the traveler moves. Here the traveler is the still one. She is the same November eighteenth wherever she goes. It is the world that keeps shifting under her, a palimpsest written and overwritten on the same Wednesday, and the shifts are rendered so attentively that the book becomes a slow, hallucinatory survey of how light behaves in different latitudes when the same day is happening to it. The sestertius travels with her, opening into a lovely tangent about the Roman empire and the routes its money once took, and by the end of the book Tara's senses have sharpened to a pitch where the prose itself begins to breathe differently. The world, she writes, is whispering in a new language. Her husband, who appears in this volume mostly as someone she telephones from foreign hotels, has begun to feel the strain of being loved by a woman who is aging at a rate his calendar refuses to acknowledge.

      And then, in the third volume, the project does something nobody saw coming. Tara meets someone else. His name is Henry Dale. He is a sociologist. He has been inside the day longer than she has, and he has a young son in America whom he visits every loop at his ex-wife's house. Imagine being four years old and meeting your father every morning, knowing he is the same and knowing also that he carries with him a freight of time you cannot see. The book never over-stresses the heartbreak, letting it sit the way it lets everything sit. Tara and Henry try to figure out what they are to each other. The volume is, in part, about how dignified people behave when the universe has made them, against their will, into a liminal society of two. Then Olga arrives, with her plan to reorganize the loop into a fairer society. Then Ralf, with his plan to spend each iteration of the day stopping every preventable accident on the planet. The four of them have nothing in common except the day, and the novel is too honest to pretend that the day is enough. The marriage with Thomas has by now become the book's quietest engine of dread. Tara is older. Thomas is not. Every morning he wakes up younger than the woman who has come home to him.

      By Volume IV they have moved into a big house outside Bremen, and the four have become fifty. Volume IV does something I have rarely seen at this scale in serious literary fiction. The singular voice breaks. The careful "I" of the first three books gradually, and then unmistakably, becomes a "we," and the book begins to read like extended meeting minutes from the most interesting commune ever convened. The residents argue about everything. They argue about what to call themselves. They argue about whether the day should be measured from sunrise or from the moment of arrival. They argue about food, because food consumed inside the loop is gone from the loop forever, and a population of fifty is a meaningful pull on a finite breakfast. They argue about healthcare in a world where every wound resets at midnight. They argue, in other words, about the load-bearing architecture of any society, and they argue at a pace and an articulacy that is recognizably the kind of conversation that only happens when people have nothing to lose and everything to figure out. The whole project is apophatic, an attempt to build a vocabulary for their condition by exhaustively naming what it is not. The volume keeps the metaphysics inside the kitchen. The questions about language and identity never float free of the bread. Someone is always doing the dishes. The book ends on a hinge I will not describe, except to say that it earns the turn.

      Volume V is the settling. The exhilaration of Volume IV gives way to something stranger and gentler, the texture of a second life slowly making itself plausible. The community has habits now. Some of the loopers have begun to write. Some have begun to teach. Some have figured out, the way people figure out anything important, that you can build a tolerable existence on a foundation of repetition if you stop arguing with the foundation. New arrivals appear at the door, and the work of welcoming them, of explaining the day to a stranger who has just discovered they are inside it, becomes a kind of vocation. The central insight of the cycle, after five books, clarifies itself. The project is the great novel of dailiness. Joyce gave us one Dublin day at six hundred pages of close attention. The series is the same Wednesday written eleven hundred times over, and somehow still not done. Not a novel that contains daily life among its themes. A novel about the daily as such. The eighteenth of November is the prosaic distilled into philosophy. Mornings. Bread. Light at a window. The same conversation begun gently for the thousandth time. What a life is, these five volumes suggest, when you take away the future and you take away the past, and you are left with the present examined at the resolution of a Vermeer. Book VI arrives in May 2027, with one more to follow. The engine, after five books, shows no sign of fatigue, and the project keeps getting larger by getting smaller.

      I recommend these books to anyone who keeps a notebook and wants a beautiful, quiet, understated meditation on life wrapped in metaphysical curios. Anyone who has written down what the morning light looked like on a particular Wednesday and felt slightly embarrassed about doing it. Anyone whose work involves going back to the same thing over and over until it finally starts to make sense. If you have ever caught yourself cataloging the way your kitchen table looks at six in the morning and felt something that was neither boredom nor revelation but a third thing, calmer than both, then Solvej Balle has written the books you did not know were possible, and she has written five of them and is still going. They are, sentence by sentence, some of the most beautiful prose being published anywhere right now. They are also, taken together, a serious and unembarrassed meditation on time, on selfhood, on what a person is when she is no longer accumulating history, and on what a marriage is when only one of you is aging into it. Tara cannot leave the eighteenth of November. None of us can leave today either. Eternal recurrence treats this as a test. The absurd treats it as a climb. Balle treats it as a practice. The prosaic, attended to, is the depth. The repetition, accepted, is the meaning. The measure of a life is one you would say yes to twice, and these books leave you wondering whether her one day, lived a billion times, is really so different from our own lives.

    33. 🔗 Drew DeVault's blog New blog design rss

      I redesigned my blog! I decided to put some more personality into it this time, after over a decade of the minimalist style. This short post is just an excuse to show up in your feed reader so you can go look at it. Cheers!

      Also: I’m trying out fedi again. You can find me here: @drew@freebitcoin.gay.

  3. May 19, 2026
    1. 🔗 IDA Plugin Updates IDA Plugin Updates on 2026-05-19 rss

      IDA Plugin Updates on 2026-05-19

      New Releases:

      Activity:

    2. 🔗 Simon Willison Gemini 3.5 Flash: more expensive, but Google plan to use it for everything rss

      Today at Google I/O, Google released Gemini 3.5 Flash. This one skipped the -preview modifier and went straight to general availability, and Google appear to be using it for a whole lot of their key products:

      3.5 Flash is available today to billions of people globally:

      • For everyone via the Gemini app and AI Mode in Google Search
      • For developers in our agent-first development platform Google Antigravity and Gemini API in Google AI Studio and Android Studio
      • For enterprises in Gemini Enterprise Agent Platform and Gemini Enterprise.

      As usual with Gemini, the most interesting details are tucked away in the What's new in Gemini 3.5 Flash developer documentation. It mostly has the same set of platform features as the previous Gemini 3.x series, albeit with no computer use. The model ID is gemini-3.5-flash. The knowledge cut-off is January 2025, and it supports 1,048,576 input tokens and 65,536 maximum output tokens.

      Google are also pushing a new Interactions API, currently in beta, which looks to me like their version of the patterns introduced by OpenAI Responses - in particular server-side history management.

      The price has gone up

      Gemini 3.5 Flash is accompanied by a notable price bump. The previous models in the "Flash" family were Gemini 3 Flash Preview and Gemini 3.1 Flash-Lite. The new 3.5 Flash is 3x the price of 3 Flash Preview and 6x the price of 3.1 Flash-Lite (see price comparison here).

      At $1.50/million input and $9/million output it's getting close in price to Google's Gemini 3.1 Pro, which is $2 and $12.

      The Gemini team promise that 3.5 Pro will roll out "next month" - presumably at an even higher price.

      This fits a trend: OpenAI's GPT-5.5 was 2x the price of GPT-5.4, and Claude Opus 4.7 is around 1.46x the price of 4.6 when you take the new tokenizer into account.

      Given the price increase it's interesting to see Google roll it out for so many of their own free-to-consumer products. It feels like all three of the major AI labs are starting to probe the price tolerance of their API customers.

      Artificial Analysis publish the cost to run their proprietary benchmark against models, which is a useful way to take things like tokenization and increased volume of reasoning tokens into account. Some numbers worth comparing:

      Running the benchmark for 3.5 Flash (high) cost significantly more than 3.1 Pro Preview!

      Here are some numbers from other vendors:

      A pelican on a bicycle

      I ran "Generate an SVG of a pelican riding a bicycle" against the Gemini API and got back this pelican, which is a lot:

      Black background, bats in the sky against a stylized moon. Pelican is funky looking. Very good beak. Bicycle frame is a bit twisted, and the bar from pedals to back wheel is missing. Bike lamp illuminates the road in front. Quite stylish.

      From the code comments: <!-- Pelican Eye / Sunglasses (Cool Retro Aviators) -->

      hedgehog on Hacker News:

      That pelican looks like it's in Miami for a crypto conference.

      That one cost me 11 input tokens and 14,403 output tokens, for a total cost of just under 13 cents.

      You are only seeing the long-form articles from my blog. Subscribe to /atom/everything/ to get all of my posts, or take a look at my other subscription options.

    3. 🔗 @binaryninja@infosec.exchange Sidekick 26.0 is out now! Major updates across the board plus a full refresh mastodon

      Sidekick 26.0 is out now! Major updates across the board plus a full refresh of the Sidekick website. New specialist agents, a validation agent that cross checks findings against evidence, project scoped workspaces with cross binary search, and built in skills tuned for Binary Ninja. Read about the latest release here: https://sidekick.binary.ninja/blog/sidekick-26-0-a-whole-new- experience-in-reversing-with- ai/

    4. 🔗 r/Leeds Leeds United: Accelerate plans for Elland Road trams, club director urges rss
    5. 🔗 anthropics/claude-code v2.1.144 release

      What's changed

      • Added /resume support for background sessions — sessions started via claude --bg or agent view now appear alongside interactive ones, marked with bg
      • Added elapsed duration to background subagent completion notifications (e.g. "Agent completed · 3h 2m 5s")
      • The /plugin browse and discover panes now show when a plugin was last updated
      • /model now changes the model for the current session only; press d in the model picker to set a default for new sessions
      • Renamed "extra usage" to "usage credits" across CLI copy; /extra-usage is now /usage-credits (old name still works)
      • Fixed startup hanging up to 75s when api.anthropic.com is unreachable (captive portal, firewall, VPN issues) — side-channel API calls now time out after 15s
      • Fixed garbled terminal output after a missed window-resize event (e.g. dragging a VS Code split-pane divider) — now self-heals on the next frame instead of requiring Ctrl+L
      • Fixed progressive terminal display corruption (stale/garbled glyphs) that could appear in very long sessions and only cleared on terminal resize or restart
      • Reduced terminal rendering glitches in VS Code by reducing spinner animation color count
      • Fixed macOS background sessions crashing with "exit 1 before init" when the project lives under a Full Disk Access-protected folder (regression in 2.1.143)
      • Fixed an unrecoverable conversation when reading a file whose image extension doesn't match its contents (e.g. HTML saved as .png) — now falls back to text
      • Fewer spurious tool errors during search: head/tail file views now satisfy the read-before-edit check, and a "no matches" result (exit code 1) from egrep, fgrep, git grep, or git diff is no longer reported as a command failure
      • Fixed /branch failing with "No conversation to branch" after entering a worktree or in some background sessions
      • Fixed pressing Escape in the AskUserQuestion notes field aborting the turn instead of returning to answer selection
      • Fixed model selection not applying when changed via the IDE model picker or applyFlagSettings after startup
      • Resumed sessions now keep the model they were using instead of picking up another session's /model choice
      • Fixed Bedrock and Vertex users unable to select "Opus (1M context)" from the /model picker (regression in v2.1.129)
      • Fixed remote-session login failing with "Can't access this organization" for users with forceLoginMethod and forceLoginOrgUUID set
      • Fixed MCP servers with paginated tools/list responses only returning the first page, silently dropping tools
      • Fixed MCP images with unsupported MIME types (e.g. SVG) breaking the conversation — now saved to disk and referenced in the tool result
      • Fixed file descriptor exhaustion when a build runs inside a skill directory — non-.md files no longer trigger skill reloads
      • Fixed session title being generated from plugin monitor output instead of the user's first prompt
      • Fixed Skill tool failing with permission error in headless mode (regression in v2.1.141)
      • Fixed plugins enabled in your own settings showing "not cached" errors after first load on a fresh machine; plugins enabled only by a project's .claude/settings.json now show an actionable claude plugin install hint
      • Fixed claude mcp list silently reporting no servers when .mcp.json can't be parsed (e.g. using VS Code's "servers" key instead of "mcpServers") — now shows configuration errors
      • Fixed background side-queries on custom ANTHROPIC_BASE_URL setups and Bedrock Mantle not using Haiku — now falls back correctly when a first-party API key is configured or no Haiku model is set
      • Fixed scrolling in attached background sessions on Windows — PgUp/PgDn, mouse wheel, and Ctrl+O transcript navigation now work
      • Fixed a crash when closing the terminal while attached to a background session
      • Fixed on Windows, pressing ← in claude agents leaving the list unresponsive to keyboard input
      • Fixed ghost characters at the left edge when switching panes in Agent View on Windows Terminal with CJK content
      • /bg and -detach now preserve directories added via /add-dir
      • Fixed Edit/Write refusing with "background session hasn't isolated its changes yet" right after detaching a session that was already editing in place
      • Fixed claude respawn <id> on a stopped background session showing "stopped" instead of running
      • Fixed /resume picker not showing sessions forked from a background session
      • Fixed opening a session from claude agents or running claude logs <id> hanging when the background service is unresponsive — now times out after 10s with a recovery hint
      • Fixed background Bash tasks spawned by subagents staying "Running" in SDK task panels after the process exits
      • Fixed completed or stopped background sessions briefly failing to wake being permanently marked as a startup crash
      • Fixed markdown links in claude agents attached sessions rendering as plain text instead of clickable hyperlinks
      • Fixed custom spinnerVerbs applying to the post-turn duration message — past-tense built-ins like "Worked for 5s" are restored there
      • claude agents / --bg rejection messages now name the specific gate (non-TTY, env var, or setting) instead of a generic message
      • claude --bg --name &lt;label&gt; now echoes the name in the post-spawn confirmation
      • claude agents: renaming a background session with Ctrl+R now updates the attached session's banner immediately
      • Background session worktree isolation guard now applies for non-git VCS users with WorktreeCreate hooks configured
      • Plugin marketplace add/update now respects CLAUDE_CODE_PLUGIN_PREFER_HTTPS
      • /plugin now returns to the Installed list after enabling, disabling, or uninstalling a plugin
      • /doctor now shows an exec-form example when a command hook is missing the command field
      • Skill-listing truncation is no longer shown as a startup notification — run /doctor for the full breakdown
      • Improved recovery from rare pre-response stream stalls — now retries streaming once instead of falling back to a slower non-streaming request
      • Improved SDK/headless MCP startup: pre-wait now overlaps startup instead of blocking before the first turn (up to 2s faster with slow MCP servers)
      • The post-survey follow-up hint now appears after every non-dismiss survey response with context-aware copy, making it easier to share more detail via /feedback.
    6. 🔗 r/Yorkshire 20 people jailed over abuse of girls in West Yorkshire during 1990s and 2000s rss

      20 people jailed over abuse of girls in West Yorkshire during 1990s and 2000s | submitted by /u/Kagedeah
      [link] [comments]
      ---|---

    7. 🔗 modem-dev/hunk v0.13.1 release

      What's Changed

      • Reduced inline add-note affordance flicker by hiding it during scroll and only showing it after pointer movement by @benvinegar in #328 and #331
      • Hardened the local session daemon against browser-originated requests by validating Host and Origin headers and requiring JSON content types for API posts by @benvinegar in #329
      • Disabled the generic broker HTTP API by default so Hunk's supported session API is the only app-daemon command surface by @benvinegar in #332
      • Bounded session daemon memory by capping HTTP request body and websocket message sizes and rejecting oversized session registrations by @benvinegar in #333

      Full Changelog : v0.13.0...v0.13.1

    8. 🔗 r/wiesbaden MTB Tour und Trail Abfahrt - Neue Leute kennenlernen und Tour zum Flowtrail Kiedrich rss

      Hi zusammen 👋

      ich plane für Sonntag, den 24.05.2026, eine MTB-Tour von Wiesbaden zum Flowtrail Kiedrich und wollte mal schauen, ob sich ein paar Leute anschließen möchten.

      Ich bin noch eher Anfänger, habe bisher nur wenig Trail-Erfahrung und werde deshalb entspannt und nicht auf Tempo fahren. Außerdem bin ich ohne E-Bike unterwegs.

      Treffpunkt wäre 11:00 unten am Rhein vor der Froschkönigin:
      Rheingaustraße 144, 65203 Wiesbaden

      Kurz zu mir: Ich bin m/37 und hätte einfach Lust auf eine coole Tour und neue Bekanntschaften.

      Wer Bock hat, kann sich gerne melden 👍

      submitted by /u/Ligat1337
      [link] [comments]

    9. 🔗 r/york A rare moment of peace and quiet (if you know, you know) rss

      A rare moment of peace and quiet (if you know, you know) | submitted by /u/SavingsMap2506
      [link] [comments]
      ---|---

    10. 🔗 r/wiesbaden OB - American living in Germany rss

      As the title says, I am an American living in Germany for a job, and recently found out that I’m pregnant. Do you know of any OBGYN’s that also speak English? I’m still very new to the area, and still learning German language.

      submitted by /u/daddyciwa
      [link] [comments]

    11. 🔗 r/Yorkshire Perhaps not 'news' but very sad from a cultural perspective... Malton show not going ahead in 2026 due to volunteer shortages and bureaucratic difficulties. rss
    12. 🔗 r/Leeds Disposing of dumped nitrous oxide bottles rss

      We had these nitrous oxide canisters dumped in our household green recycling bin a couple of weeks ago. It was right before it was due to be picked up, meaning the binmen (understandably) left it. We put in a request to the council to come pick them up but no luck.

      Can they be taken to a recycling centre? We tried looking online but it wasn't clear. We didn't realise this was a thing, but I've now seen a few on the side of the road on the way to work.

      submitted by /u/seleucid23
      [link] [comments]

    13. 🔗 r/reverseengineering Math at Scale: Reversing The Construction Of The Perspective-Projection Matrix (Game Engine Reversing) rss
    14. 🔗 backnotprop/plannotator v0.19.20 release

      Follow @plannotator on X for updates


      Missed recent releases? Release | Highlights
      ---|---
      v0.19.18 | Edit-based submit_plan for OpenCode, Pi namespace migration, Codex annotate-last fix, OpenCode commands dir fix
      v0.19.17 | Reworked goal setup skill (interview-driven flow), CLI --version flag
      v0.19.16 | Code navigation with peek view (Cmd/Ctrl+click tokens in diffs)
      v0.19.15 | Commit-based diff base, jj evolution diffs, GitLab reliability fixes, OpenCode command intercept fix
      v0.19.14 | Visual explainer skill update, PFM code-file hover previews, Graphviz, diff tab size and line bg intensity, hooks settings tab
      v0.19.11 | Jujutsu (jj) VCS backend, slimmer hunk separators, collapse viewed files, multi-line gutter selection fix
      v0.19.9 | OpenCode user-managed workflow, Pi model switch fix, Codex skill install, shimmer removal
      v0.19.8 | 49 themes with syntax highlighting, keyboard shortcut registry, smart code-file path validation, remote URL notifications
      v0.19.7 | Codex Stop-hook plan review, Codex skills, sidebar auto-close, file tree context menu
      v0.19.6 | Non-blocking Pi browser sessions, agent picker dropdown for OpenCode, annotate-last file resolution fix


      What's New in v0.19.20

      v0.19.20 adds a visual goal setup UI, fixes the OpenCode edit-based submit_plan issues that caused the v0.19.19 hotfix, and makes Plannotator work correctly inside Claude Code's agent view (which previously caused the server to hang indefinitely). Four PRs, two from external contributors, one first- timer.

      Interactive Goal Setup UI

      The /plannotator-setup-goal skill now opens a dedicated browser UI for its interview and fact-review phases instead of running them as serial chat messages. The interview phase renders all questions in an accordion layout with keyboard shortcuts for navigation (Tab to advance, Ctrl+U/K/J to move between questions, number keys for multiple-choice). The fact-review phase shows each extracted fact as an editable card that can be accepted, edited, commented on, removed, or sent for auto-verification.

      The UI runs on its own Plannotator server instance, separate from plan review and code review. It reuses the same compiled HTML shell but activates a distinct goal-setup mode that disables annotations, sharing, sidebar, and plan diff. Results are returned as structured JSON to the agent, which writes them to the goal package directory.

      This replaces the old flow where the agent asked questions one at a time in the chat and opened separate Plannotator review gates for each document. The bundled UI is faster, lets users see all questions at once, and reduces the round trips from five review gates to two (interview, then facts).

      OpenCode Edit-Based Submit Plan Fixes

      v0.19.18 introduced the edit-based submit_plan interface for OpenCode, which replaced the old dual-mode (inline text or file path) approach. Two issues surfaced quickly after release.

      First, validateEdits rejected the agent's initial plan submission when the backing file was empty. The validation checked end > lineCount, which failed on an empty file (lineCount = 0) even though applyEdits already handled this correctly via splice clamping. The fix skips the bounds check when the file is empty, since every edit on an empty file is a pure insert where end is meaningless.

      Second, the backing file lived at .opencode/plans/_active-plan.md inside the workspace, which showed up in git status. OpenCode's auto-generated .gitignore doesn't cover that path, so users would see it as an untracked file. The backing file now lives at ~/.plannotator/active/{project}/_active- plan.md, alongside the existing version history. It is also cleaned up on plan approval, since it is no longer needed after the session ends.

      Browser No-Op Sentinel Handling

      Claude Code's agent view sets BROWSER=true in the process environment, a standard convention meaning "do not open a browser." Plannotator was treating this as a valid browser command, shelling out to true http://localhost:NNNN, which exits 0 without opening anything. The server then sat in waitForDecision() indefinitely with no visible URL and no way for the user to recover.

      The fix recognizes documented no-op values (true, false, none, :, 0, 1) and treats them as if the variable were unset. This lets the VS Code IPC fallback fire in remote sessions and the platform default browser open in local sessions. Real browser paths like /usr/bin/firefox or macOS app names are unaffected.


      Install / Update

      macOS / Linux:

      curl -fsSL https://plannotator.ai/install.sh | bash
      

      Windows:

      irm https://plannotator.ai/install.ps1 | iex
      

      Claude Code Plugin: Run /plugin in Claude Code, find plannotator , and click "Update now".

      OpenCode: Clear cache and restart:

      rm -rf ~/.bun/install/cache/@plannotator
      

      Then in opencode.json:

      {
        "plugin": ["@plannotator/opencode@latest"]
      }
      

      Pi: Install or update the extension:

      pi install npm:@plannotator/pi-extension
      

      What's Changed

      • Add interactive goal setup UI by @backnotprop in #731
      • fix(opencode): skip end bounds check on empty file in validateEdits by @rcdailey in #752
      • fix(opencode): store active plan backing file outside workspace by @rcdailey in #743
      • fix(browser): treat no-op BROWSER values as unset so headless sessions can fall back by @yonihorn in #756

      New Contributors

      Contributors

      @rcdailey continued his work on the OpenCode edit-based submit_plan system. After identifying the empty-file validation bug that triggered the v0.19.19 hotfix, he shipped both the bounds check fix (#752) and the backing file relocation (#743). @yonihorn traced the headless browser hang to the BROWSER=true sentinel convention and implemented the sentinel detection with comprehensive test coverage.

      Community members who reported and discussed the underlying issues:

      • @TonyReg reported the submit_plan failure in plan-agent mode after v0.19.18 (#742)
      • @NotMyself reported the Windows browser-opening failure and participated in the BROWSER sentinel discussion (#724)
      • @jinhwan0724 reported the original non-TTY browser issue (#154) that established the pattern #756 completes

      Full Changelog : v0.19.18...v0.19.20

    15. 🔗 r/reverseengineering Deep dive into the object creation flow in Windows - PART 4: Handle table internals. rss
    16. 🔗 r/LocalLLaMA got my first "rm -rf /" today rss

      Agent decided to test if harmful command block worked by issuing a rm -rf /

      Thankfully it worked so only damage was a mild heart attack.

      I implemented a sandbox immediately afterwards.

      EDIT: for those wondering, I was implementing a bash command whitelist and also bubblewrap for isolation. I did the whitelist implementation first and that was the command the agent chose to test it 😂 bwrap got done quickly afterwards!

      submitted by /u/DeltaSqueezer
      [link] [comments]

    17. 🔗 r/Yorkshire Are we the poor relations? rss

      Serious question. Are we the poor relations compared to the North West?

      Their main cities of Manchester and Liverpool are far more vibrant than Leeds and Sheffield. Retail, nightlife, public transport, football teams, music, for example.

      Unemployment is 4.9% in the North West compared to 5.8% in Yorkshire. Even the North East is lower than us now, and we're the second worst region for it.

      Sporting success seems so much better in the North West, especially in football, whilst our teams either get or face relegation.

      Whilst the North West has its poverty and challenges, they don't seem to have the sheer number of failing town and city centres we do. Sheffield should be so much better than it is, and even Bradford should be. Leeds is mediocre now, especially compared to the success stories of both Manchester and Liverpool, both of which are flourishing.

      Leeds can't even convince the government to give it a tram system. Instead it relies on buses that, if you're lucky, finish at 11pm. Then there's our rubbish airports.

      I know we all like to wax lyrical about how great we are in Yorkshire, but are we? We do have a better coastline than they do, and York is miles better than Chester, but countryside is a close call. We have more of it, but they have the Lake District.

      What do you think?

      submitted by /u/MLC1974
      [link] [comments]

    18. 🔗 idursun/jjui v0.10.6 release

      A quick maintenance update with a handful of usability improvements and scripting additions.

      • jjui now uses the real terminal cursor instead of a virtual one. Cursor rendering is now correct when focus moves between views and when returning from external commands.
      • Theme rendering has been improved so that themes now paint the backgrounds of view areas more consistently. Lua scripting also now exposes set_theme(name), which changes the active theme at runtime. This builds on the earlier light/dark runtime theme switching work, but it is not wired to the UI by default, so you need to call it from your own action.
      • jjui now sets the JJUI environment variable before invoking jj. This makes it easier to use jj conditional config specifically for commands run from inside jjui, for example:

        [[--scope]]
        

        --when.environments = ["JJUI"] [--scope.ui] diff-formatter = "delta"

      • Preview commands now set DFT_WIDTH, so difftastic output wraps to the preview pane width automatically.

      • Revision navigation now resolves longer or non-loaded change IDs and commit IDs through jj when they cannot be matched directly in the loaded revision list. This makes Lua navigation actions work more reliably with user-provided revision IDs.
      • The : prompt now parses quoted jj arguments correctly, so commands like new -m "message text" work as expected.
      • ctrl+n and ctrl+p are now available as list navigation aliases in more places, including revset completion/history, the target picker, and the fuzzy file finder.

      What's Changed

      • fix(exec): parse jj prompt input with shellwords (#655) by @SAY-5 in #675

      New Contributors

      Full Changelog : v0.10.5...v0.10.6

    19. 🔗 r/LocalLLaMA bytedance released an open source model that attempts to do just about anything with only 3b parameters rss

      bytedance released an open source model that attempts to do just about anything with only 3b parameters | EDIT: working link https://huggingface.co/bytedance-research/Lance Lance is a lightweight native unified multimodal model that supports image and video understanding, generation, and editing within a single framework.

      • Efficient at 3B scale. With only 3B active parameters , Lance delivers strong performance across image generation, image editing, and video generation benchmarks.
      • Trained from scratch. Lance is built with a staged multi-task recipe and trained entirely from scratch within a 128-A100-GPU budget.

      submitted by /u/uxl
      [link] [comments]
      ---|---

    20. 🔗 r/wiesbaden Teilnehmende für Bachelor Umfrage 🙏🏻 (students) rss

      Hallo zusammen😇,

      eine Freundin von mir schreibt aktuell ihre Bachelorarbeit und sucht noch Teilnehmende für eine kurze Umfrage. 😊

      Die Umfrage dauert nur ca. 5 Minuten, ist anonym und man braucht kaum weitergehende Kenntnisse. Besonders gesucht werden Studierende, aber grundsätzlich kann jede:r teilnehmen.

      Es wäre super, wenn ihr mitmacht und die Umfrage ggf. gerne auch noch an weitere Leute teilt. Das würde echt sehr helfen! 🫶

      Link zur Umfrage:

      https://www.umfrageonline.com/c/dwiikftr

      submitted by /u/nie_leo
      [link] [comments]

    21. 🔗 r/reverseengineering Tracing CVE-2026-34473 pre-auth DoS through decompiled CGILua request parsing in ZTE H-series firmware rss
    22. 🔗 r/reverseengineering Open-source Hermes bytecode decompiler for React Native apps (Rust) rss
    23. 🔗 r/york Recommend a spa day in or around York? rss

      I’m buying my friends who are getting married a spa day.

      My wife and I had a nice time at the updated spa in The Grand recently, which we may go for. I’m just wondering if there is anything better out there?

      submitted by /u/OneItchy396
      [link] [comments]

    24. 🔗 r/Leeds How similar to Sheffield is Leeds? rss

      Would you say the atmosphere, people etc are very different? I’m (22) planning to go to either Uni of Leeds or Sheffield and would be living there for 3yrs. I’ve visited both but would like to hear others opinions on it as I’m struggling to decide

      submitted by /u/JealousBodybuilder42
      [link] [comments]

    25. 🔗 r/LocalLLaMA Qwen is cooking hard rss

      Qwen is cooking hard | I am waiting for 122B and new 27B submitted by /u/jacek2023
      [link] [comments]
      ---|---

    26. 🔗 r/reverseengineering Built a full disassembler & decompiler | Free and open source. rss
    27. 🔗 HexRaysSA/plugin-repository commits sync repo: +2 releases rss
      sync repo: +2 releases
      
      ## New releases
      - [IDASQL](https://github.com/allthingsida/idasql): 0.0.14
      - [ida-chat](https://github.com/tanu360/ida-chat-plugin): 1.0.1
      
    28. 🔗 Simon Willison The last six months in LLMs in five minutes rss

      I put together these annotated slides from my five minute lightning talk at PyCon US 2026, using the latest iteration of my annotated presentation tool.

      The last six months in LLMs in
five minutes

Simon Willison - simonwillison.net

PyCon US 2026 Lightning Talk
      #

      I presented this lightning talk at PyCon US 2026, attempting to summarize the last six months of developments in LLMs in five minutes.

      The November inflection point
      #

      Six months is a pretty convenient time period to cover, because it captures what I've been calling the November 2025 inflection point. November was a critical month in LLMs, especially for coding.

      The “best” model changed hands 5 times
between Anthropic, OpenAl and Google
      #

      For one thing, the supposedly "best" model (depending mostly on vibes) changed hands five times between the three big providers.

      Generate an SVG of a
pelican riding a bicycle
      #

      As always, I'm using my Generate an SVG of a pelican riding a bicycle test to help illustrate the differences between the models.

      Why this test? Because pelicans are hard to draw, bicycles are hard to draw, pelicans can't ride bicycles... and there's zero chance any AI lab would train a model for such a ridiculous task.

      Five pelicans, one for each of the following models. Varying qualities!
      #

      At the start of November the widely acknowledged "best" model was Claude Sonnet 4.5, released on 29th September. It drew me this pelican.

      In November it was overtaken by GPT-5.1, then Gemini 3, then GPT-5.1 Codex Max, and then Anthropic took the crown back again with Claude Opus 4.5.

      I think Gemini 3 drew the best pelican out of this lot, but pelicans aren't everything. Most practitioners will agree that Opus 4.5 held the crown for the next couple of months.

      The coding agents got good
      #

      It took a little while for this to become clear, but the real news from November was that the coding agents got good.

      OpenAI and Anthropic had spent most of 2025 running Reinforcement Learning from Verifiable Rewards to increase the quality of code written by their models, especially when paired up with their Codex and Claude Code agent harnesses.

      In November the results of this work became apparent. Coding agents went from often-work to mostly-work, crossing a quality barrier where you could use them as a daily-driver to get real work done, without needing to spend most of your time fixing their stupid mistakes.

      Screenshot of "Initial commit" on GitHub to steipete/Warelay, commit f6dd362, steipete authored on Nov 24, 2025

It's a copy of the MIT license
      #

      Also in November, this happened - the first commit to an obscure (back then) repo called "Warelay" by some guy called Pete.

      December/January
(A little bit of LLM psychosis)
      #

      Over the holiday period, from December to January, a whole lot of us took advantage of the break to have a poke at these new models and coding agents and see what they could do.

      They could do a lot! Some of us got a little bit over-excited. I had my own short-lived bout of a form of LLM psychosis as I started spinning up wildly ambitious projects to see how far I could push them.

      micro-javascript playground
Execute JavaScript code in a sandboxed micro-javascript environment powered by Pyodide

var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var doubled = numbers.map(n => n * 2);
console.log('Doubled: "', doubled);
var evens = numbers.filter(n => n % 2 === 0);
console.log('Evens: ', evens);
var sum = numbers.reduce((a, b) => a + b, @);
console.log('Sum:", sum);

Output 27
Doubled: [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
Evens: [2, 4, 6, 8, 10]
Sum: 55
Execution time: 8.00ms
About: micro-javascript is a pure Python JavaScript interpreter with configurable memory and time limits. This playground runs entirely in your browser using
Pyodide (Python compiled to WebAssembly). View on GitHub
      #

      One of my projects was a vibe-coded implementation of JavaScript in Python - a loose port of MicroQuickJS - which I called micro-javascript. You can try it out in your browser in this playground.

      JavaScript running in Python running in Pyodide running in WebAssembly running in JavaScript
      #

      That playground demo shows JavaScript code run using my micro-javascript library, in Python, running inside Pyodide, running in WebAssembly, running in JavaScript, running in a browser!

      It's pretty cool! But did anyone out there need a buggy, slow, insecure half-baked implementation of JavaScript in Python?

      They did not. I have quite a few other projects from that holiday period that I have since quietly retired!

      February 2026
      #

      On to February. Remember that Warelay project that had its first commit at the end of November?

      Warelay → CLAWDIS → CLAWDBOT →
Clawdbot → Moltbot →🦞 OpenClaw
      #

      In December and January it had gone through quite a few name changes... and by February it was taking the world by storm under its final name, OpenClaw.

      The amount of attention it got is pretty astonishing for a project that was less than three months old.

      Generic term: Claw
      #

      OpenClaw is a "personal AI assistant", and we actually got a generic term for these, based on NanoClaw and ZeroClaw and suchlike... they're called Claws.

      An aquarium for your Claw
      #

      Mac Minis started to sell out around Silicon Valley, because people were buying them to run their Claws.

      Drew Breunig joked to me that this is because they're the new digital pets, and a Mac Mini is the perfect aquarium for your Claw.

      Alfred Molina's Doc Ock in Spider-Man 2, tearing apart a New York subway train with his four claws.
      #

      My favourite metaphor for Claws is Alfred Molina's Doc Ock in the 2004 movie Spider-Man 2. His claws were powered by AI, and were perfectly safe provided nothing damaged his inhibitor chip... after which they turned evil and took over.

      Gemini 3.1 Pro

A really good illustration of a pelican riding a bicycle.
      #

      Also in February: Gemini 3.1 Pro came out, and drew me a really good pelican riding a bicycle. Look at this! It's even got a fish in its basket.

      Gemini 3 Pro pelican contrasted with Gemini 3.1 Pro, as animated SVGs
      #

      And then Google's Jeff Dean tweeted this video of an animated pelican riding a bicycle, plus a frog on a penny-farthing and a giraffe driving a tiny car and an ostrich on roller skates and a turtle kickflipping a skateboard and a dachshund driving a stretch limousine.

      So maybe the AI labs have been paying attention after all!

      April 2026
      #

      A lot of stuff happened just in the past month.

      Gemma 4 26B-A4B (17.99GB)

A pretty decent pelican riding a bicycle, though the bike is a bit mis-shapen.
      #

      Google released the Gemma 4 series of models, which are the most capable open weight models I've seen from a US company.

      GLM-5.1
MIT, 754B parameter, 1.51TB!
      #

      Also last month, Chinese AI lab GLM came out with GLM-5.1 - an open weight 1.5TB monster! This is a very effective model... if you can afford the hardware to run it.

      #

      GLM-5.1 drew me this very competent pelican on a bicycle.

      The bike is wonky, the pelican is floating.
      #

      ... though when it tried to animate it the bicycle bounced off into the top and the bicycle got warped.

      Screenshot of Bluesky

Charles
‪@charles.capps.me‬
I think you should pester it with another animal using another method of locomotion. 

Something tells me it was trained for this. I can't quite put my finger on it. /s

NORTH VIRGINIA OPOSSUM ON AN E-SCOOTER!!
      #

      Charles on Bluesky suggested I try it with a North Virginia Opossum on an E-scooter

      NORTH VIRGINIA OPOSSUM
CRUISING THE COMMONWEALTH SINCE DUSK

And a really cool illustration of a possum.
      #

      And it did this! I've tried this on other models and they don't even come close. "Cruising the commonwealth since dusk" is perfect. It's animated too.

      Qwen3.6-35B-A3B is a 20.9GB file that runs on my laptop

It drew a better pelican on a bicycle than Opus 4.7, which messed up the bicycle frame.
      #

      The other neat Chinese open weight models in April came from Qwen. Qwen3.6-35B-A3B on my laptop drew me a better pelican than Claude Opus 4.7. That's a 20.9GB open weights model that runs on my laptop!

      (I think this mainly demonstrates that the pelican on the bicycle has firmly exceeded its limits as a useful benchmark.)

      Claude Sonnet 4.5 pelican for comparison.
      #

      Here's that Claude Sonnet 4.5 pelican from September for comparison.

      The themes of the past 6 months:
Coding agents got really good
Local models wildly outperform expectations
      #

      So those were the two main themes of the past six months. The coding agents got really good... and the laptop-available models, while a lot weaker than the frontier, have started wildly outperforming expectations.

      You are only seeing the long-form articles from my blog. Subscribe to /atom/everything/ to get all of my posts, or take a look at my other subscription options.