10 interesting stories served every morning and every evening.

Flipper One — we need your help

blog.flipper.net

21 May 2026 • 18 min read

We’re fi­nally ready to talk about Flipper One — a pro­ject we’ve been grind­ing on for years and have re­built from scratch sev­eral times. It’s an in­cred­i­bly hard pro­ject, both fi­nan­cially and tech­ni­cally. So to­day we’re go­ing pub­lic not with a big shiny an­nounce­ment, but to tell the whole story straight. Honestly? We’re gen­uinely ter­ri­fied, and we need your help.

TL;DR With Flipper One, we’re reimag­in­ing what a Linux cy­berdeck can be — it’s a huge pro­ject. We’re open­ing up the de­vel­op­ment process and ask­ing the com­mu­nity for help.

With Flipper One, we’ve set our­selves a list of am­bi­tious goals:

Build the most open and best-doc­u­mented ARM com­puter in the world, with full main­line Linux ker­nel sup­port.

Push ven­dors to open up their ex­ist­ing closed-source code and ditch bi­nary blobs en­tirely.

Build an un­con­ven­tional hard­ware plat­form based on a co-proces­sor ar­chi­tec­ture that pairs a mi­cro­con­troller with a CPU, and port tons of low-level MCU code.

Rethink how peo­ple use Linux and de­velop our own GUI frame­work with wrap­pers around ex­ist­ing CLI util­i­ties.

Many of these goals come with a lot of un­cer­tainty, which is scary. But we be­lieve this is the only way to make a truly mean­ing­ful con­tri­bu­tion to the open-source com­mu­nity and to ed­u­ca­tion.

What is Flipper One?

Flipper One is­n’t an up­grade to Flipper Zero — it’s a com­pletely dif­fer­ent pro­ject with its own goals. Flipper One is an open Linux plat­form you can build al­most any­thing on: from a 5G-enabled IP net­work an­a­lyzer to an SDR-powered ra­dio sig­nal an­a­lyzer with lo­cal AI. We fo­cused a lot on the hard­ware ex­pan­sion sys­tem. You can con­nect high-speed mod­ules to Flipper One over PCI Express, USB 3.0, and SATA in­ter­faces. Add an SDR, a fast SSD, or a cel­lu­lar mo­dem — just plug in the right mod­ule.

Flipper One comes with sev­eral net­work in­ter­faces: 2x Gigabit Ethernet, USB Ethernet (5 Gbps), and Wi-Fi 6E (2.4/5/6 GHz). You can add 5G con­nec­tiv­ity by plug­ging in an M.2 mo­dem. That means you can use Flipper One as a router, a VPN gate­way, or a bridge be­tween wired and wire­less net­works.

Zero vs One

Flipper Zero and Flipper One are com­pletely dif­fer­ent pro­jects built for dif­fer­ent tasks. The eas­i­est way to think about it is in terms of net­work­ing lay­ers:

Layer 0 — Offline point-to-point ac­cess-con­trol pro­to­cols: NFC, low-fre­quency RFID, Sub-1 GHz ra­dio, Infrared, wired pro­to­cols like iBut­ton, UART, SPI, I²C. Based on a low-power mi­cro­con­troller.

Layer 1 — Everything that’s IP-connected: Wi-Fi, Ethernet, 5G, and satel­lite. It’s all about net­work­ing, data trans­fer, and high-per­for­mance com­put­ing. Running on pow­er­ful hard­ware and an open Linux toolkit — enough com­put­ing power to han­dle SDR and lo­cal AI.

So they’re not newer” and older” gen­er­a­tions of the same prod­uct. Flipper One does­n’t re­place Flipper Zero — they’re dif­fer­ent cat­e­gories of de­vices.

Truly Open Linux plat­form

We want to build a truly open Linux hard­ware plat­form — the best-doc­u­mented ARM com­puter, one that works out of the box on any re­cent up­stream ker­nel. It will never go stale be­cause it’ll keep get­ting the lat­est up­dates. Our goals:

Full main­line Linux ker­nel sup­port

No bi­nary blobs, closed dri­vers, or pro­pri­etary firmware

No ven­dor-locked BSP (board sup­port pack­age)

We say truly open” be­cause the cur­rent state of ARM Linux is de­press­ing. Every ven­dor bolts on their own cus­tom mess: closed boot blobs, ven­dor-spe­cific patches, board sup­port pack­ages” that no­body out­side the chip maker can re­ally un­der­stand. You can no longer just read the specs and un­der­stand how com­put­ers work — you can only learn the workarounds for one spe­cific chip with one spe­cific BSP. We’re sick of this our­selves, and we don’t want to be part of the prob­lem by ship­ping yet an­other prod­uct that just adds to the mess.

To pull this off, we’ve part­nered with the Collabora team to push full sup­port for the Rockchip RK3576 SoC into the main­line Linux ker­nel. Practically, this means you can down­load the ker­nel di­rectly from ker­nel.org, with zero ven­dor patches, and run it on your Flipper One.

👩‍👩‍👧‍👦

Flipper + Collabora — Making things open to­gether We’ve part­nered with Collabora to bring the RK3576 SoC into the main­line ker­nel and give Flipper One full up­stream sup­port.Read more: Collabora blog post

Current RK3576 main­line sup­port is in pretty good shape, and all the ma­jor com­po­nents are work­ing. But there’s still one last bi­nary blob in the boot chain — the DDR trainer, which ini­tial­izes RAM dur­ing early boot.

We’re ask­ing the com­mu­nity to help us pol­ish RK3576 sup­port so we can build a truly open plat­form to­gether. We’d be glad for any kind of con­tri­bu­tion, not just code. For ex­am­ple, maybe you can find a way to con­vince Rockchip to open up that last blob.

Right now, we’re fo­cused on power man­age­ment and USB DP Alt-mode sup­port. There are also dri­vers and ac­cel­er­a­tors that aren’t fully up­stream yet — the NPU, hard­ware video de­cod­ing, and other ac­cel­er­a­tors. Collabora main­tains a pub­lic list of what’s al­ready work­ing in main­line and what is­n’t, and we’d love help clos­ing those gaps.

RK3576 open source roadmap — what we plan to do and how you can con­tribute

Open tasks — where you can help us

RK3576 main­line sta­tus from Collabora

Developer Portal — let’s build to­gether

Openness has al­ways been our thing. With Flipper One, we want to go fur­ther — not just open-source code, but an open de­vel­op­ment process. We’re pub­lish­ing our task track­ers, in­ter­nal dis­cus­sions, half-fin­ished docs, and ar­chi­tec­tural de­bates. All the messy stuff com­pa­nies usu­ally keep be­hind closed doors.

Introducing → Flipper One Developer Portal

This is un­com­fort­able. We’ve never been this open be­fore, and there’s a real in­stinct to hide the un­fin­ished work, the wrong turns, and the ar­gu­ments. But we be­lieve the ed­u­ca­tional value of build­ing openly is worth more than the pol­ish of pre­tend­ing it was easy.

What is the Developer Portal?

Flipper One Developer Portal is a pub­lic wiki with all the de­vel­op­ment doc­u­men­ta­tion for Flipper One, and any­one can edit it. The por­tal de­scribes the pro­jec­t’s struc­ture and ways you can par­tic­i­pate in de­vel­op­ment.

Flipper One is a mas­sive pro­ject, and sev­eral teams are work­ing on it, each re­spon­si­ble for its own part. We call these parts sub-pro­jects:

🔌 Hardware — elec­tri­cal hard­ware de­vel­op­ment. This is where the printed cir­cuit boards (PCBs), an­ten­nas, and every­thing re­lated to the elec­tri­cal con­nec­tions of chips, con­nec­tors, and proces­sors are de­signed.

⚙️ Mechanics — me­chan­i­cal en­gi­neer­ing and in­dus­trial de­sign. This is where the en­clo­sure, but­tons, plas­tic and metal parts, and mount­ing com­po­nents are de­signed. Everything the user phys­i­cally in­ter­acts with.

🐧 Linux (CPU Software) — soft­ware de­vel­op­ment for the RK3576 proces­sor. Linux ker­nel, mod­ules, dri­vers, user­space, boot­loader, Rockchip tools, etc. This is the largest and most com­plex sub-pro­ject, span­ning many repos­i­to­ries.

🕹️ MCU Firmware — firmware de­vel­op­ment for the RP2350 mi­cro­con­troller, which con­trols the dis­play, power sub­sys­tem, and CPU boot process, and han­dles but­ton and touch­pad events.

🎨 User Interface — UI/UX de­vel­op­ment. This is where the user in­ter­face, the de­vice’s vi­sual lan­guage, and all graph­ics are de­vel­oped.

📚 Docs — de­vel­oper por­tal wiki, tech­ni­cal docs, guides, and datasheets. All doc­u­men­ta­tion, in­clud­ing the Developer Portal it­self, is de­vel­oped here. It cov­ers the Flipper One prod­uct, de­vel­op­ment processes, and con­tri­bu­tion guides.

🧪 Testing — tools for test­ing de­vice sub­sys­tems and hard­ware val­i­da­tion. Includes scripts and pro­grams for test­ing power, net­work­ing, CPU, au­dio, graph­ics, etc., as well as in­ter­face pro­to­types, demos, and test apps.

Anyone can join

Whether you’re an en­gi­neer, soft­ware de­vel­oper, de­signer, or sim­ply an en­thu­si­as­tic user with ideas to share, you’re wel­come to par­tic­i­pate in de­vel­op­ment and help shape Flipper One.

We’re also hir­ing a Developer Portal Manager — some­one to act as a proxy be­tween our dev team and the com­mu­nity, help shape the Developer Portal, and en­gage with con­trib­u­tors. Apply for the Developer Portal & Community Manager role.

Co-processor ar­chi­tec­ture

Flipper One runs on two proces­sors: a high-per­for­mance CPU and a tiny low-power MCU. They run in par­al­lel, and each man­ages its own part:

High-performance CPU — the 8-core RK3576 SoC that runs Linux. It comes with a Mali-G52 GPU and an NPU for run­ning LLMs and other mod­els lo­cally. There’s also 8 GB of RAM on board. Read more in CPU Software.

Low-power MCU — the 2-core Raspberry Pi RP2350 mi­cro­con­troller that con­trols the dis­play, but­tons, touch­pad, LEDs, and the power sub­sys­tem. It runs its own MCU Firmware.

The de­vice can run on the MCU alone. Even when Linux is off, you can con­trol Flipper One with its but­tons and LCD screen, con­fig­ure the boot process — all with­out the main CPU run­ning. This is what’s miss­ing on most SBCs: when Linux is off, the de­vice is dead.

MCUCPU in­ter­con­nect

The two proces­sors com­mu­ni­cate over a set of in­ter­faces we call the Interconnect: SPI car­ries the frame­buffer to the MCU for dis­play out­put, I²C car­ries com­mands to the MCU and but­ton and touch­pad events back to the CPU, and UART plus a few GPIO lines han­dle CPU boot con­trol. This is a non-triv­ial ar­chi­tec­ture.

We plan to land the dis­play and in­put dri­vers in the Linux ker­nel. We want to do it cleanly, with­out out-of-tree ven­dor hacks. We’d love for the ker­nel com­mu­nity to re­view this de­sign, push back on it, and help us up­stream it the right way.

Flipper OS + FlipCTL

How we’re reimag­in­ing Linux cy­berdecks

I’m a fan of Raspberry Pi and use it in my own pro­jects, in­clud­ing car­ry­ing one around as a travel tac­ti­cal Linux box. A typ­i­cal Raspberry Pi OS (formerly Raspbian OS) work­flow looks like this: to­day it’s a router, to­mor­row it’s a TV box, the day af­ter that it’s a logic an­a­lyzer for a de­bug ses­sion. You in­stall dozens of pack­ages, com­pile some from source, edit sys­tem con­figs, tweak the de­vice tree, patch the ker­nel — and very quickly the sys­tem turns into a mess. There’s no clean way to undo it. Roll back to fac­tory? Doesn’t ex­ist. Every new pro­ject starts with re-flash­ing the SD card.

Even though we’ll be crit­i­ciz­ing Raspberry Pi a lot, we gen­uinely love and re­spect the com­pany. Their prod­ucts in­spired ours in many ways — they make in­cred­i­ble things and have con­tributed mas­sively to the em­bed­ded in­dus­try. And that love is ex­actly why we keep com­par­ing our­selves to them.

What is Flipper OS?

We want to fix this and reimag­ine how peo­ple use Linux on the go. We’re build­ing Flipper OS — a layer on top of a Debian-based sys­tem that in­tro­duces pro­files: full snap­shots of the OS with dif­fer­ent pre­con­fig­ured pack­ages and set­tings. You can boot a pro­file, clone it, break it, in­stall what­ever, and jump back to a clean copy. Or switch to an en­tirely dif­fer­ent pro­file for a dif­fer­ent use case. No more SD card shuf­fling.

Honestly, Flipper OS is an ex­tremely hard pro­ject, and we’re not 100% sure how to ar­chi­tect it yet. We’re pro­to­typ­ing con­cepts, and we want this to be use­ful far be­yond Flipper One — for cy­berdeck builds based on Raspberry Pi, or any portable tac­ti­cal Linux box. If you’ve thought about this prob­lem or built some­thing sim­i­lar, we’d love to hear from you. Read about the Flipper OS con­cept.

FlipCTL — a UI frame­work for tiny screens

As part of Flipper OS, we’re build­ing FlipCTL to solve a prob­lem com­mon to all Linux-based cy­berdecks: no­body de­signs UIs for small screens. So peo­ple end up run­ning full desk­top en­vi­ron­ments (KDE, GNOME, etc.) squeezed onto a tiny 7″ touch­screen. It’s mis­er­able. What made Flipper Zero great was its user in­ter­face, pur­pose-built for a small LCD. That’s largely what made the de­vice pop­u­lar. We want to bring that ap­proach to Linux multi-tools.

FlipCTL is a frame­work for build­ing menu-based in­ter­faces for small LCD screens, con­trolled by a D-pad and a few but­tons. The idea is to wrap ex­ist­ing Linux util­i­ties like ping, nmap, tracer­oute in a clean, nav­i­ga­ble UI that ac­tu­ally makes sense on a tiny screen. Our long-term goal: make adding an HMI (human-machine in­ter­face) to any em­bed­ded Linux de­vice as easy as run­ning one com­mand: apt in­stall flipctl

Routers, NAS boxes, servers, head­less boards — any­thing you can bolt a small screen onto should be able to use FlipCTL. The idea is sim­ple: get FlipCTL, write a con­fig, and ship a us­able in­ter­face with­out drag­ging in Qt, GNOME, or X11. We’re also plan­ning to re­lease the Flipper One dis­play and a but­ton board as a stand­alone FlipCTL Control Board” — a pe­riph­eral you can plug into any Linux-based de­vice and in­stantly get a menu-dri­ven in­ter­face. Right now, FlipCTL is still at the con­cept and ar­chi­tec­ture stage, and we’d love any­one in­ter­ested to join in: Read about the FlipCTL con­cept.

M.2 ex­pan­sion mod­ules

The core idea be­hind Flipper One is an ex­pand­able hard­ware plat­form. Anyone can turn it into their own spe­cial­ized multi-tool. That’s why we added sup­port for high-speed M.2 ex­pan­sion mod­ules that in­stall in­side, un­der the back plate.

M.2 is a com­mon name for an ex­pan­sion mod­ule form fac­tor, but it does­n’t de­fine the ac­tual con­nec­tion in­ter­face. Under the hood, M.2 mod­ules can use dif­fer­ent in­ter­faces and come in dif­fer­ent sizes and con­nec­tor types.

We worked hard to make the M.2 port in Flipper One as uni­ver­sal as pos­si­ble, so you can plug in al­most any type of mod­ule — cel­lu­lar or satel­lite modems, SDR mod­ules, AI ac­cel­er­a­tors, SSDs (NVMe or SATA), and Wi-Fi cards via adapters.

M.2 tech specs

We packed the M.2 port with as many in­ter­faces as pos­si­ble and added sup­port for dif­fer­ent mod­ule sizes:

M.2 type: Key-B

Supported sizes: 2242, 3042, 3052 (up to D3 class thick­ness)

Interfaces: PCI Express 2.1 ×1 / USB 3.1 / USB 2.0 / SATA3 / Serial Audio / UART / I2C / SIM card

For the full M.2 port spec­i­fi­ca­tion and pinout, see the doc­u­men­ta­tion: M.2 Port spec­i­fi­ca­tion. We ex­pect the com­mu­nity and ven­dors to build their own M.2 mod­ules for Flipper One, so any feed­back and sug­ges­tions are wel­come.

GPIO mod­ules

For sim­pler DIY mod­ules, we added a GPIO con­nec­tor with stan­dard 2.54mm pin head­ers. Even here, we made sure the de­vice can be car­ried fully as­sem­bled with the mod­ule at­tached with­out it com­ing loose.

GPIO mod­ules also have their own mount­ing sys­tem:

Threaded in­serts — the back plate and an­tenna rail have threads spaced in a grid with 2.54mm pitch, match­ing stan­dard perf­board hole spac­ing. So you can just cut a piece of perf­board to size, sol­der your mod­ule onto it, and screw it to the Flipper One’s back.

Snap-fit notches — both sides of the body have notches for a snap-fit pro­tec­tive cover that adds rigid­ity to the whole as­sem­bly.

For the tech­ni­cal spec­i­fi­ca­tion, pinout, and schemat­ics, see the GPIO port page. You can also check out ex­am­ples of GPIO mod­ules, in­clud­ing a walkie-talkie and a cam­era mod­ule. Any feed­back and com­ments are wel­come.

Open hard­ware mod­ule sys­tem

0:00

/0:07

[video] You can view and down­load the 3D mod­els

We de­signed a cus­tom mount­ing sys­tem for Flipper One mod­ules. We are fully open­ing up the en­clo­sure parts in­volved in this sys­tem:

Body — the main en­clo­sure of the de­vice. M.2 mod­ules screw into a metal heatsink plate, with two threaded in­serts for 42mm and 52mm mod­ule lengths.

Back plate — the rear cover that pro­vides ac­cess to the M.2 ex­pan­sion port. It at­taches to the body with screws and can be swapped out for dif­fer­ent de­signs de­pend­ing on the in­stalled mod­ule.

Antenna rail — a sep­a­rate part used for mount­ing SMA an­ten­nas. The an­tenna rail is in­ten­tion­ally sep­a­rated from the back plate so that an­ten­nas can be in­stalled and ca­bles routed to the ra­dio mod­ule be­fore the back plate is closed. This elim­i­nates the risk of dam­ag­ing an­tenna ca­bles dur­ing as­sem­bly.

You can down­load the 3D mod­els to­day to de­sign en­clo­sures for your mod­ules or even cre­ate your cus­tom back plate and an­tenna rail. We look for­ward to com­mu­nity feed­back and sug­ges­tions on the me­chan­i­cal de­sign of mod­ules. Read about Mechanics.

Network multi-tool

Flipper One is all about con­nec­tiv­ity — a Swiss Army knife for IP net­works across all OSI lay­ers. We packed in all the es­sen­tial phys­i­cal in­ter­faces, giv­ing you five in­de­pen­dent net­work up­links, which you can bridge to­gether, con­fig­ure cus­tom rout­ing for, or pipe through VPN tun­nels:

Gigabit Ethernet — two in­de­pen­dent WAN/LAN ports, each run­ning at 1 Gbps. Can be used for trans­par­ent bridge, MitM sniff­ing, and more.

Wi-Fi 6E — 802.11ax based on the MT7921AUN chipset with mon­i­tor mode sup­port. Covers 2.4/5/6 GHz bands and can run as both a Wi-Fi client (STA) and a hotspot (AP).

Cellular mo­dem — 5G or LTE mo­dem via the M.2 ex­pan­sion mod­ule, with sup­port for ex­ter­nal an­ten­nas. Accepts a phys­i­cal Nano SIM (4FF) and eSIM.

USB Ethernet — up to 5 Gbps em­u­lated over USB-C. Connect your lap­top or smart­phone via a USB ca­ble to add an ex­tra net­work in­ter­face. Works via USB-CDC NCM, so no dri­vers are re­quired.

Out of the box, Flipper One can work as a gate­way to any net­work, a multi-hotspot bridge, an in­line Ethernet snif­fer, a USB Wi-Fi/Ethernet adapter for a PC or smart­phone — or any com­bi­na­tion, with dy­namic rout­ing, load bal­anc­ing, and failover. We de­scribe these as user-story-dri­ven fea­tures in the Features list.

Hail Mary

valhovey.github.io

AI is just unauthorised plagiarism at a bigger scale

axelk.ee

Axel’s blog

Home Blog Now

20 May, 2026

AI takes in all the in­put, whether the orig­i­nal au­thors have con­sented or not, and do some learning”, and then the AI com­pa­nies sell these learned re­sult to hu­mans, with­out com­pen­sat­ing the orig­i­nal au­thors.

Worse, the cus­tomer of these AI com­pa­nies (AI tools bro) sell the prompted / processed re­sult to other cus­tomers, prof­itting off things AI has copied from all over the in­ter­net.

Is this what the pin­na­cle of hu­man is? Lazy and greedy?

I re­search and write e-com­merce re­lated tu­to­ri­als on my own, and a few other lazy web­site au­thors just ask ChatGPT to copy a few well per­form­ing tu­to­r­ial on­line, and then they pub­lished it as their own.

I found out this be­cause they ranked higher than me in Google search re­sult, and then when I read their ar­ti­cle, their ar­ti­cle con­tains links to my ac­tual web­site, with the ex­act link text (?!) , which means they didnt bother to check and re­move, and thats how I found out.

Fuck Google for rank­ing some copy­cat web­site higher than mine, even though they copied my ar­ti­cle

Google's Antigravity Bait and Switch

www.0xsid.com

The day was to be­gin like any other, with Antigravity open (yes, there are tens of us!), ex­pect­ing to get some work done be­fore my at­ten­tion frag­ments. But Google had other plans. They had rolled out a new ver­sion of Antigravity the day be­fore, at I/O 2026, pre­sent­ing it as a shiny, stand­alone Codex-style ex­pe­ri­ence.

Before I launched it, Antigravity had au­to­mat­i­cally updated” my ex­ist­ing in­stal­la­tion to the new one and, in the process, nuked the IDE, the ac­tual Antigravity I had been us­ing for months. When I clicked my usual short­cut, my en­tire IDE was just gone, and in its place stood a sin­gle con­ver­sa­tional prompt box.

This un­ex­pected shift com­pletely broke my pre­ferred work­flow. Antigravity, as part of the Google AI Ultra plan, is my daily dri­ver, my work­horse. I don’t mind agen­tic work­flows for quick demos or MVPs, but pro­duc­tion soft­ware, in my opin­ion, re­quires pre­dictable out­put. For that, noth­ing beats the plan-re­view-im­ple­ment loop that made me a huge fan of Cursor and ear­lier ver­sions of Antigravity.

Two Versions, Zero Compatibility

Frustrated, I jumped on­line and found that Google ac­tu­ally hosted a sep­a­rate down­load pack­age specif­i­cally for the legacy Antigravity IDE. How to in­ter­pret that it was at the bot­tom of the page, I’m leav­ing as an ex­er­cise to you. I fig­ured I could just down­load this in­staller and run it along­side the new tool to get my day go­ing. I down­loaded and ran the pack­age but the ex­act same 2.0 chat­bot in­ter­face loaded right back up, much to my an­noy­ance.

The 2.0 up­date, it turns out, ag­gres­sively rewrites the de­fault ap­pli­ca­tion paths to the point where it’s im­pos­si­ble, at the time of writ­ing, to have both ver­sions of Antigravity in­stalled and func­tion­ing at the same time. Even re­in­stalling the IDE, hop­ing it might rewrite the rules cor­rectly, does­n’t work as the chat­bot still hi­jacks the launch every sin­gle time.

If In Doubt, Purge

After mess­ing around re­in­stalling both pieces of soft­ware only to get the ex­act same re­sult, I headed over to the Antigravity sub­red­dit. Sure enough, plenty of other peo­ple were post­ing about the same ex­act sce­nario. The only way for­ward was a to­tal purge of every­thing Antigravity re­lated on the ma­chine be­fore try­ing again.

With my sys­tem en­tirely cleared of the 2.0 bi­na­ries, I ran the stand­alone IDE in­staller one more time. Without the chat­bot there to in­ter­fere and hi­jack the ex­e­cu­tion paths, the clean in­stal­la­tion fi­nally worked.

Back to Business (Almost)

Unfortunately, get­ting the in­ter­face back did­n’t mean every­thing was nor­mal. The forced up­date and sub­se­quent purge wiped out my chat his­tory and set­tings. While I could, thank­fully, copy over most of my setup from my old Cursor con­fig, the prompt his­tory from the old Antigravity in­stal­la­tion is gone(-ish). The up­grade fi­asco did leave a folder called anti­grav­ity-backup, which I hope con­tains all my old his­tory and pro­file info.

Right now, I just don’t have the time or the to­kens to fid­dle with it and get my his­tory back. It’s go­ing to stay right there in sta­sis un­til I have some ac­tual time to spare.

Updates Shouldn’t Hijack Your Software

Forcing this kind of tran­si­tion on users via a back­ground up­date is in in­cred­i­bly poor taste. Background up­dates are meant for per­for­mance patches and ver­sion up­grades, not for se­cretly ship­ping an en­tirely dif­fer­ent piece of soft­ware. Hijacking a de­vel­op­ment tool to re­place it with an­other crosses the line, from an in­con­ve­nience into a ma­jor has­sle.

I’m now go­ing to look for ways to stop auto-up­dates al­to­gether, if it’s even pos­si­ble in the first place. We should be able to trust that our tools will re­main the tools we ac­tu­ally signed up to use. I’m fully plugged into the Google ecosys­tem, but sheesh!

Was my $48K GPU server worth it?

rosmine.ai

In 2024 I quit my FAANG job to be­come an in­de­pen­dent re­searcher. To do this I needed GPUs, so I built grumbl”, a 6x 6000 Ada GPU server.

This blog de­scribes the build, some of the is­sues I faced, and an­swers the ques­tion was it worth it to build the server my­self, or should I have rented cloud GPUs?”

(It’s called grumbl” be­cause ap­par­ently I can­not spell GPUs”)

GPUs as an in­vest­ment

This rig cost me $48K. That sounds ex­pen­sive, but it’s way less ex­pen­sive than quit­ting my job. Because of the loss of in­come, if more pow­er­ful GPUs could help me make my work be suc­cess­ful just 2 months ear­lier than I would have with a smaller ma­chine, then buy­ing a more pow­er­ful server would be worth it. So I de­cided to buy the most pow­er­ful server that I could run in my apart­ment.

Choosing the GPUs

I found Tim Dettmers’ guide to choos­ing a GPU help­ful. From that I nar­rowed it down to A100s, H100s or RTX 6000 Ada. A100s don’t sup­port FP8 and have slower in­fer­ence per­for­mance than the newer GPUs, and I’m go­ing to be do­ing a lot of in­fer­ence (RL), so nar­rowed it down to 6000 Ada vs H100. Looking at the price/​through­put ra­tios of 6000 Ada vs H100 vs A100, I went with the 6000 Ada GPUs.

Power Constraints

I live in an apart­ment and don’t have the op­tion to up­grade my elec­tri­cal cir­cuits to sup­port stan­dard dat­a­cen­ter servers. 6 GPUs re­quires too much power for a sin­gle apart­ment cir­cuit to han­dle, so I had to get 2 power sup­plies, and plug the power sup­plies into 2 out­lets in sep­a­rate cir­cuits.

If you google plugging a PC into mul­ti­ple out­lets”, you get lots of warn­ings that if you even con­sider such a setup you will in­stantly burst into flames. So I hired a pro­fes­sional PC builder make sure it was safe. This is more ex­pen­sive than do­ing every­thing my­self, but it’s less ex­pen­sive than do­ing some­thing wrong and burn­ing down my apart­ment.

Ironically, af­ter de­sign­ing the en­tire build around apart­ment power con­straints, I ended up mov­ing grumbl to my par­ents’ base­ment, where I could up­grade the cir­cuits any­way.

Building my own GPU server vs. us­ing a Cloud Provider

Is it bet­ter to buy my own GPUs or should I have rented from a cloud provider? I de­cided to mea­sure this by cal­cu­lat­ing how much I used the GPUs, and com­par­ing that to how much it would’ve cost to rent equiv­a­lent com­pute in the cloud.

In 2024 I cal­cu­lated at the then cur­rent GPU rental rates, it would take me about a year of close to 85%+ uti­liza­tion to match cloud rental rates. That should be easy to do, but for a full analy­sis, I need to also ac­count for elec­tric­ity and the fact that as more pow­er­ful GPUs be­come avail­able, the cost to rent equiv­a­lent com­pute will de­crease.

To be thor­ough, I wrote a script that would log the us­age of each gpu every minute. I also logged the power us­age in watts so I could cal­cu­late how much I spent on elec­tric­ity.

In this analy­sis, I only com­pared against on-de­mand pric­ing. There are also pay­ment plans where you re­serve the in­stance for 6 – 12 months, but those seemed not worth it to me, since they were only a lit­tle cheaper than buy­ing the server it­self, and this way I got to keep the gpus.

GPU us­age over time graph

To mea­sure GPU us­age, for each GPU I counted the num­ber of hours each day where I used that GPU at least once. This seemed a fair com­par­i­son against rental since I would­n’t stop and restart a cloud server if it was only go­ing to be idle for less than an hour.

This com­par­i­son is gen­er­ous to cloud rent­ing, be­cause it as­sumes I could stop and start each GPU in­de­pen­dently. Much of the idle time I had was when I was run­ning mul­ti­ple ex­per­i­ments in par­al­lel, and one fin­ished/​failed but the oth­ers kept go­ing, and I would­n’t have stopped the server if I was rent­ing

Note: This is meant to be a mea­sure of how much I use the gpus, not train­ing ef­fi­ciency, so a GPU with 10% uti­liza­tion would still count as ac­tive for the hour. (My code would be equally in­ef­fi­cient run­ning in the cloud)

Here is the graph of use over time:

You can see 3 sep­a­rate times the server was down for main­te­nance. This is quite stress­ful be­cause you don’t know if the server is­n’t boot­ing be­cause a sin­gle PCIe riser failed, or be­cause some­thing went cat­a­stroph­i­cally wrong and fried all the GPUs.

In June 2025 you can see a clear in­crease in us­age, be­fore that I was do­ing smaller ex­per­i­ments where dev time was com­pa­ra­ble to ex­per­i­ment time, so there was more down time be­tween ex­per­i­ments when im­ple­ment­ing. After June 2025, I had a pro­ject that re­quired more com­pute, so I al­ways had most GPUs con­tin­u­ously run­ning ex­per­i­ments, and only 1 – 2 GPUs for dev.

From the graph, the to­tal av­er­age use was 76%. If you cal­cu­late since 1/1/25, uti­liza­tion is 85%. I have to ad­mit, I’m a lit­tle dis­ap­pointed in that. I’m run­ning ex­per­i­ments 24/7, and al­ways have a queue of more ex­per­i­ments to run once they fin­ish. I thought it would eas­ily be 95+%

Final Calculation

To cal­cu­late money saved, the first step is to use the rental price for each day, and mul­ti­ply that by the num­ber of GPU hours used for that day, and add it all up. I did­n’t have his­tor­i­cal provider API logs, so I es­ti­mated his­tor­i­cal pric­ing from time­stamped ref­er­ences on­line.

Based on the Wattage records that I had logged, I cal­cu­lated the elec­tric­ity cost to be ~$3000, or about $125 per month.

Putting this all to­gether, as of 3/13/26, I cal­cu­lated rental fees for equiv­a­lent com­pute would have cost $68000 so I saved a to­tal of $17000 so far.

Now the GPUs have paid for them­selves, and based on cur­rent mar­ket rate I’m sav­ing $90-$105 every day af­ter this.

The Real Final Calculation

The point of buy­ing the server was­n’t to save money, it was to build some­thing cool. I spent a long time try­ing high risk/​high re­ward ex­per­i­ments and fail­ing. But now I have some­thing good. I’ve solved a ma­jor prob­lem with LLMs. And I’m launch­ing next Monday so we will soon see if it’s ac­tu­ally a break­through or just LLM psy­chosis 🙂 (UPDATE: Launch was a suc­cess! 400K+ views, and mul­ti­ple com­pa­nies reached to use my IP. Read more here)

Advice/Other notes

Be very care­ful about build­ing your own high end server like this, it’s easy to make ex­pen­sive mis­takes. I thought that I could not get a stan­dard dat­a­cen­ter server be­cause my apart­ment would­n’t let me up­grade the cir­cuits, so I needed to have 2 power sup­plies plugged into dif­fer­ent cir­cuits. Because of this I got a moth­er­board with slow GPU in­ter­con­nect. It’s good for run­ning many small ex­per­i­ments in par­al­lel (which is my main use case) but hor­ri­ble for any mod­els split across gpus.

Several of the fail­ures were due to riser is­sues, and Nathan Odle’s riser in­ves­ti­ga­tion was very help­ful for de­bug­ging

I have the spend­ing habits of a broke grad stu­dent and I’ve been sav­ing up for this for years. I’m very lucky to be in a po­si­tion where I can take ques­tion­able fi­nan­cial risks like this, but I would­n’t rec­om­mend buy­ing this rig to every­one. You can still do great work with just a Google Colab sub­scrip­tion or rent­ing some cheaper cloud GPUs, or smaller per­sonal rigs.

The men­tal­ity shift of rent­ing vs. own­ing the gpus is huge. When rent­ing, each ex­per­i­ment costs money and I had to ask my­self is it worth it. When own­ing, it feels like *not* run­ning ex­per­i­ments is cost­ing me money. Also, it’s so nice to not have the an­noy­ance of con­stantly start­ing/​stop­ing cloud in­stances.

This analy­sis does­n’t take into ac­count the cost of my time. Building and main­tain­ing the server took a lot of time.

I tried to in­sure it un­der my renter’s in­sur­ance pol­icy. They did­n’t like that. I had to get busi­ness in­sur­ance to cover it.

If I were to do this again, I would­n’t do a cus­tom build like this. I would buy a stan­dard dat­a­cen­ter server and rent space in a colo­ca­tion cen­ter. But then I would miss say­ing Hi to grumbl once in a while.

Questions? Comments? DM me on X or E-mail me at hello@ros­mine.ai

Thanks to @algomancer for spon­sor­ing this and other work

Amazon, Facebook, ICE, and the FBI have access to a private intelligence-sharing network operated by Seattle police

prismreports.org

Real jour­nal­ists wrote and edited this (not AI)—independent, com­mu­nity-dri­ven jour­nal­ism sur­vives be­cause you back it. Do­nate to sus­tain Prism’s mis­sion and the hu­mans be­hind it.

In Seattle, Facebook, Amazon, real es­tate man­age­ment, and Immigration and Customs Enforcement (ICE) all share one thing in com­mon: mem­ber­ship to Seattle Shield, an ex­clu­sive in­tel­li­gence-shar­ing net­work op­er­ated by the Seattle po­lice.

The sys­tem high­lights how se­cre­tive pub­lic-pri­vate net­works of in­for­ma­tion-shar­ing have per­me­ated law en­force­ment in­tel­li­gence col­lec­tion in Seattle and across the coun­try un­der the ban­ner of sup­pos­edly pre­vent­ing ter­ror­ism. However, ques­tions con­cern­ing the use­ful­ness of the pro­gram, ac­count­abil­ity mea­sures, and how in­for­ma­tion is shared re­main unan­swered.

The Seattle Police Department (SPD) did not re­spond to Prism’s de­tailed re­quests for com­ment. Facebook, Amazon, and each of their an­a­lysts iden­ti­fied in pub­lic records as mem­bers of the Shield net­work did not re­spond to re­quests for com­ment.

The Seattle Shield web­site states that its mis­sion is to pro­vide a col­lab­o­ra­tive and in­for­ma­tion-shar­ing en­vi­ron­ment be­tween the Seattle Police Department and pub­lic/​pri­vate part­ners in the Seattle area. Seattle Shield mem­bers as­sist Seattle Police Department ef­forts to iden­tify, de­ter, de­feat or mit­i­gate po­ten­tial acts of ter­ror­ism by re­port­ing sus­pi­cious ac­tiv­ity in a timely man­ner.”

One SPD email ob­tained by Prism states that the Seattle Shield is an unfunded pro­gram,” which is man­aged by Officer Erin Nicholson.

The Seattle Shield net­work, which in­cludes mem­bers from mul­ti­ple law en­force­ment groups as well as pri­vate in­sti­tu­tions and cor­po­ra­tions, has been es­tab­lished and op­er­at­ing since 2009. However, it ap­pears to be mostly off the radar of some of the most promi­nent civil rights groups in the state, such as the American Civil Liberties Union of Washington, which told Prism in an email that it has­n’t been fol­low­ing or look­ing into the net­work.

Through pub­lic records re­quests, Prism ob­tained the Seattle Shield bul­letins, as well as a full list of Seattle Shield mem­bers who had ac­cess to the pro­gram as of 2020. A Prism re­view of dozens Seattle Shield re­ports sent out be­tween 2020 and 2025 to a list of hun­dreds of mil­i­tary in­tel­li­gence op­er­a­tives, non­prof­its, pri­vate cor­po­rate en­ti­ties, pri­vate se­cu­rity com­pa­nies, and law en­force­ment agen­cies show that in 2025, the re­ports were al­most ex­clu­sively about protests and po­ten­tial traf­fic de­lays caused by protests through­out Seattle.

For in­stance, one email blast” from Oct. 6, 2025, warns about up­com­ing lo­cal events re­lated to the 2nd an­niver­sary of the Hamas and Palestinian mil­i­tants co­or­di­nated as­sault against Israel.” The no­tice lists a few ex­am­ples of at­tacks on Jewish tar­gets in other U.S. cities last year; it does not men­tion wide­spread anti-Mus­lim and anti-Pales­tin­ian at­tacks through­out the coun­try.

Homegrown vi­o­lent ex­trem­ists (HVES), racially or eth­ni­cally mo­ti­vated vi­o­lent ex­trem­ists (REMVES), and griev­ance-dri­ven ma­li­cious ac­tors may use this an­niver­sary to con­duct their own at­tacks at any rel­e­vant tar­get lo­ca­tions, de­pend­ing on their as­pi­ra­tions,” the blast says. There have been sev­eral lo­cal protests last week, in­clud­ing one that re­sulted in graf­fiti and prop­erty dam­age at a lo­cal tech com­pany CEOs res­i­dence.”

The no­tice went on to share in­for­ma­tion about up­com­ing lo­cal events.

Longtime Seattle pri­vacy ac­tivist and or­ga­nizer Phil Mocek has been fol­low­ing the net­work since 2012, around when re­quested sev­eral Seattle Shield doc­u­ments from the SPD. Mocek told Prism that the co­or­di­na­tion among the Seattle Shield net­work is even more con­cern­ing to­day with the im­ple­men­ta­tion of a National Security Presidential Memorandum from President Donald Trump in the fall of 2025 that iden­ti­fies protest speech and pro­tected speech as po­ten­tial indicia” of ter­ror­ist threat.

Information shared over Seattle Shield might be all it takes to get some­one la­beled a far-left do­mes­tic ter­ror­ist,’” Mocek said.

Somebody could show up to protest ICE, and then that in­for­ma­tion gets re­ported out to Seattle Shield and sud­denly they could be on a ter­ror­ist watch list? That is not OK,” Mocek said.

Accountability con­cerns

Seattle Shield re­quests that broad swaths of the city’s pri­vate com­pa­nies cre­ate sus­pi­cious ac­tiv­ity re­ports, which are then pumped into a sys­tem that serves as an ex­ten­sion of a sprawl­ing na­tion­wide law en­force­ment sur­veil­lance ap­pa­ra­tus.

The net­work ef­fec­tively cre­ates its own list of po­ten­tial sus­pects. Photographs of those who end up re­ported by the Seattle Shield net­work or of their cars could end up plas­tered onto a pri­vate blot­ter, hosted on a pri­vate server, for hun­dreds of mil­i­tary in­tel­li­gence, fed­eral, im­mi­gra­tion, and lo­cal law en­force­ment agents, and pri­vate se­cu­rity guards to see.

According to records ob­tained by Prism, mem­bers of the net­work in­clude FBI agents, a Department of Homeland Security (DHS) surface pro­gram an­a­lyst,” and in­tel­li­gence an­a­lysts with the Washington State Fusion Center, a sep­a­rate but par­al­lel in­tel­li­gence-shar­ing net­work that also col­lab­o­rates with ICE.

Law en­force­ment far out­side of Seattle also have ac­cess to the Seattle Shield sys­tem in­clud­ing Nassau County Police in New York, the New York City Police Department, Cleveland Transit, the Hennepin County Sheriff’s Office in Minnesota, and a threat and risk an­a­lyst” for the United Nations.

Virginia State Police Captain Austin White is a mem­ber of Seattle Shield and mul­ti­ple other lo­cal shield net­works across the U.S., all un­der the um­brella of the Global Shield Network (GSN), of which he is the pres­i­dent. Does [the net­work] af­fect me on a daily ba­sis? Not re­ally,” he told Prism. But it can help give a sense of what mem­bers feel is a con­cern, he added.

White said that in 2017, per­sonal con­nec­tions made through shield net­works al­lowed him to ex­pe­dite the search for a mi­nor who made vi­o­lent threats on­line.

He said the GSN does not over­see any of the lo­cal net­works, which op­er­ate in­de­pen­dently.

Mocek said it is un­clear if any over­sight for the Seattle Shield pro­gram ex­ists at all.

This is some­thing that should be tracked, ac­counted for, and prob­a­bly au­dited,” Mocek said. Any shar­ing be­tween any part of Seattle’s mu­nic­i­pal gov­ern­ment and Immigration and Customs Enforcement is con­cern­ing and I think would be con­cern­ing to the ma­jor­ity of the pub­lic.”

Some of the of­fi­cials listed on the 2020 Seattle Shield mem­ber­ship list ob­tained by Prism have since re­tired, left their po­si­tions, or are no longer ac­tive. For in­stance, the Church of Scientology, U.S. Navy, and the Washington State Military Department told Prism that they are no longer work­ing with the net­work.

Creating the panop­ti­con

The Seattle Shield pro­gram is mod­eled di­rectly af­ter NYPD Shield, born in 2005 fol­low­ing 9/11, which aimed to mimic the FBIs InfraGard. The con­cept was ex­ported to var­i­ous po­lice de­part­ments across the world, form­ing lo­cal net­works op­er­at­ing un­der the um­brella of the GSN.

White said the NYPD Shield model was es­sen­tially franchised out” across the coun­try; how­ever, each lo­cal shield net­work is re­spon­si­ble for fund­ing, op­er­at­ing, and man­ag­ing their own sys­tem.

In October 2025, the GSN hosted its sev­enth an­nual global con­fer­ence in part­ner­ship with the Seattle Shield and SPD at Seattle’s Sheraton Grand Hotel. According to a con­fer­ence sched­ule ob­tained by Prism, the keynote ad­dress was de­liv­ered by William Edwards, a re­tired Army colonel and spe­cial­ist in drone sys­tems.

In sev­eral of the pho­tos Prism ob­tained that were taken at the con­fer­ence, some peo­ple’s faces or en­tire bod­ies are redacted. When Prism ap­pealed the redac­tions, SPD said that the in­di­vid­u­als per­form un­der­cover po­lice work, and pub­lish­ing their pho­tos could put them at risk.

The Seattle Shield net­work was formed with the goal of re­duc­ing pre-op­er­a­tional sur­veil­lance by ter­ror­ist or­ga­ni­za­tions,” wrote one SPD of­fi­cer in a 2012 email pre­vi­ously ob­tained by Mocek.

However, since its found­ing in 2009, it’s un­clear what the ul­ti­mate pub­lic ben­e­fit of the sys­tem is  or what its coun­tert­er­ror­ism bona fides might be. A Prism search of the SPDs crime blot­ter shows that the de­part­ment has nei­ther men­tioned the Seattle Shield net­work pub­licly nor touted its use­ful­ness fol­low­ing an ar­rest.

The FBI Seattle did not re­spond to ques­tions from Prism about whether re­ports from the lo­cal Shield net­work had ever led to a ter­ror­ism ar­rest.

FBI Seattle reg­u­larly par­tic­i­pates in meet­ings and work­ing groups with law en­force­ment part­ners, com­mu­nity mem­bers, and mem­bers of the pri­vate sec­tor,” Amy Alexander, a pub­lic af­fairs of­fi­cer at FBI Seattle, told Prism in an email. At var­i­ous times, this has in­cluded Seattle Shield. While we can­not com­ment on spe­cific re­la­tion­ships or com­mu­ni­ca­tions, the FBIs part­ner­ships are crit­i­cal to our mis­sion, and we rou­tinely share in­for­ma­tion with our part­ners at all lev­els, from ex­ec­u­tives to field agents work­ing in­ves­ti­ga­tions to com­mu­nity out­reach events.”

What did Hoover say? I want every­one to be­lieve that there is an FBI agent hid­ing be­hind every mail­box.’ That’s what this list is do­ing. It’s cre­at­ing the panop­ti­con.Terry Albury, for­mer FBI agent

What did Hoover say? I want every­one to be­lieve that there is an FBI agent hid­ing be­hind every mail­box.’ That’s what this list is do­ing. It’s cre­at­ing the panop­ti­con.

What did Hoover say? I want every­one to be­lieve that there is an FBI agent hid­ing be­hind every mail­box,’” for­mer FBI agent Terry Albury told Prism. That’s what this list is do­ing. It’s cre­at­ing the panop­ti­con.”

While serv­ing as an FBI agent, Albury was dis­gusted by how he felt the law was weaponized against vul­ner­a­ble com­mu­ni­ties. In 2018 he was ar­rested and sen­tenced to prison over draconian” charges, ac­cord­ing to the Knight First Amendment Institute, af­ter he be­gan leak­ing FBI doc­u­ments to The Intercept.

Seattle Theatre Group (STG), a non­profit that op­er­ates sev­eral live per­for­mance venues across the city, is part of the Seattle Shield net­work. In a state­ment to Prism, STGs Senior Communications Manager Rachel Liuzzi wrote, Our op­er­a­tions team works with the Seattle Shield net­work to re­ceive in­for­ma­tion that can help keep our venues and au­di­ences safe. We oc­ca­sion­ally call on the net­work for in­for­ma­tion and some­times di­rectly re­ceive in­for­ma­tion from it. The in­for­ma­tion we re­ceive is specif­i­cally re­lated to se­cu­rity con­cerns that may im­pact our venues and the safety and well be­ing of our au­di­ences when at­tend­ing per­for­mances.”

STG de­clined to share any sus­pi­cious ac­tiv­ity re­ports with Prism.

In ad­di­tion to mon­i­tor­ing protests, email no­ti­fi­ca­tions sent to Seattle Shield mem­bers pro­vide up­dates on traf­fic warn­ings, pri­vate ac­cess to SPD com­man­ders, and in­side in­for­ma­tion about SPD staffing.

One sus­pi­cious ac­tiv­ity re­port re­viewed by Prism from March 2025 de­tails a man claim­ing to be an elec­tri­cal sub­con­trac­tor try­ing to ac­cess an elec­tri­cal room at Seattle’s Pike Place Market. The mar­ket dis­trib­uted pho­tos of the man and a de­scrip­tion of the in­ci­dent over the Seattle Shield sys­tem. No po­lice re­port was made, and the man did not gain ac­cess to sen­si­tive ar­eas. The con­trac­tor the man claimed to work with told Prism that by all in­di­ca­tions” the man was not one of their em­ploy­ees or con­trac­tors and that the con­trac­tor did not have record of this pur­ported work or­der and be­lieve that this in­volved a van­dal or at­tempted im­poster.”

Seattle Shield email blasts have also in­cluded no­tice of dig­ni­tary travel and pri­vate meet­ings to re­view the city’s Terrorism Outlook” for 2025. The SPD does not re­lease this in­for­ma­tion pub­licly.

One such email, sent out via the net­work’s mail­ing list on June 12, 2025, stated, Immigration is cur­rently a con­tentious topic around the United States. As you all have prob­a­bly seen, there are many demon­stra­tions tak­ing place around the coun­try to in­clude Seattle. There has been a daily protest at the Federal Building this week where peo­ple are ex­press­ing their un­hap­pi­ness with the fed­eral gov­ern­ment.”

Following the protest, SPD asked Seattle Shield mem­bers to take mea­sures that would aim to pro­tect of­fi­cers from harm dur­ing fu­ture protests, such as look­ing for items around their prop­er­ties that could be used as projectiles.”

During the 2020 Black Lives Matter protests in Seattle, Shield mem­bers re­ceived reg­u­lar up­dates from the SPD, in­clud­ing that the Department is work­ing hard to mit­i­gate the risks of vi­o­lence and prop­erty dam­age.” In ad­di­tion, the SPD asked Seattle Shield mem­bers to review their in­ter­nal se­cu­rity video sys­tems re­ten­tion poli­cies to en­sure valu­able ev­i­dence of crim­i­nal ac­tiv­i­ties are re­tained/​saved. We are re­quest­ing that all sites re­tain any video from May 29th [2020] through a date (TBD).”

Benefiting pri­vate eco­nomic in­ter­ests is ab­solutely one of the lead­ing fac­tors in cre­at­ing these groups and or­ga­ni­za­tions, and the pub­lic is all too happy to carry wa­ter for it,” Albury said.

The Seattle Shield net­work is a larger pool of in­for­mants,” he added, but they’re of­fi­cial in­for­mants be­cause now they have an as­so­ci­a­tion and a con­nec­tion, in the same way that an un­of­fi­cial in­for­mant is used off the books.” In this way, a sur­veil­lance sys­tem of in­for­mants op­er­ates openly, he ex­plained.

The Seattle Shield pro­gram is one com­po­nent within a mo­saic of net­works and con­trac­tual re­la­tion­ships the SPD has built with Seattle’s busi­ness com­mu­nity, where the stream of money, re­sources, spe­cial as­sis­tance, and in­for­ma­tion flows both ways.

Developing partnerships with lo­cal com­pa­nies” is specif­i­cally iden­ti­fied within SPDs Relational Policing Plan.

Another part of that mo­saic in­cludes the SPDs con­trac­tual oblig­a­tions to the city’s 501(c)(6) cor­po­rate busi­ness league named DBIA Services, which re­quires off-duty cops to address ci­vil­ity is­sues and il­le­gal street be­hav­iour that de­tracts from a pos­i­tive ex­pe­ri­ence” down­town, in­clud­ing petty crimes of poverty such as vi­o­la­tions of the city’s sit and lie” or­di­nance, ag­gres­sive pan­han­dling, and pub­lic uri­na­tion.

Contracts be­tween the SPD and DBIA Services ob­tained by Prism show that off-duty SPD of­fi­cers must ap­proach pub­lic safety through the lens of eco­nomic vi­tal­ity.”

Jennifer Casillas, vice pres­i­dent of pub­lic realm and am­bas­sador op­er­a­tions of Downtown Seattle Association, a sub­sidiary of DBIA Services, was a Seattle Shield mem­ber as of 2020, ac­cord­ing to the ros­ter ob­tained by Prism. She did not re­spond to sev­eral re­quests for com­ment.

James Sido, me­dia re­la­tions di­rec­tor for Downtown Seattle Association, wrote to Prism in an email, We have re­ceived emails from Seattle Shield but there’s been no two-way cor­re­spon­dence.”

Seattle Shield mem­bers are also of­fered di­rect ac­cess to train­ing from the Federal Law Enforcement Training Center, housed un­der DHS, show­ing that fed­eral law en­force­ment re­sources are in­vested di­rectly in pri­vate busi­ness in­ter­ests that par­tic­i­pate in in­tel­li­gence col­lec­tion ac­tiv­i­ties.

Technology

Who man­ages the Seattle Shield data streams, web­site, servers, and the in­for­ma­tion pumped into the net­work is an open ques­tion. The SPD did not re­spond to nu­mer­ous ques­tions about how and where Seattle Shield in­tel­li­gence data is stored.

In 2011, ABM Security Services an­nounced that it is aug­ment­ing Seattle Shield’s ca­pa­bil­i­ties by pro­vid­ing a se­cure plat­form that al­lows mem­bers of the as­so­ci­a­tion to share in­for­ma­tion— in­clud­ing pho­tographs and video clips—in real-time about po­ten­tial threats.”

ABM Security Services de­vel­oped and is main­tain­ing the Seattle Shield ap­pli­ca­tion at no charge, though the Company is seek­ing to off­set some of the main­te­nance costs through a Department of Homeland Security grant,” the press re­lease con­tin­ued.

ABM did not re­spond to Prism’s mul­ti­ple re­quests for com­ment. White, the GSN pres­i­dent, told Prism that he’s not fa­mil­iar with ABM and that the GSN does not dic­tate, rec­om­mend, or pro­vide any tem­plates for lo­cal agen­cies to im­ple­ment for their own shield net­works.

According to an archived ver­sion of the Seattle Shield web­site, the net­work uses a se­cure in­ter­net-based web­site to send our alerts.” NetSentinal, the web host­ing ser­vice used by the Seattle Shield, suf­fered a data breach in 2020, later dubbed BlueLeaks, com­pro­mis­ing the en­tire Seattle Shield mem­ber list, in­clud­ing their IP in­for­ma­tion, ad­dresses, and con­tact in­for­ma­tion. Members re­ceived a Seattle Shield bul­letin at the time, ob­tained by Prism, ad­vis­ing mem­bers not to down­load the BlueLeaks data trove.

Editorial Team:Sahar Fatima, Lead EditorLara Witt, Top EditorRashmee Kumar, Copy Editor

Indexing a year of video locally on a 5-year-old M1 Max with Gemma 4 31B

blog.simbastack.com

While I slept, my 5-year-old MacBook ran Gemma 4 lo­cally and in­dexed a year of video

I’m in the Maasai Mara about half the year, in three-month stretches. Animals out the front of the lodge, mo­tor­cy­cles, friends in the Maasai vil­lages, kids who think a drone is the fun­ni­est thing they have ever seen. That’s one half of my year. The other half is six­teen-hour days in front of a ter­mi­nal, Silicon Valley hacker brain on Africa time. Both real, both con­sum­ing at­ten­tion.

The first half is a con­stant flood of footage from the iPhone, the DJI Pocket, the drone, the Nikon Z8, and lately the Ray-Ban Metas too. There’s al­ways some­thing be­ing recorded. Every pho­tog­ra­pher or video­g­ra­pher I know is sit­ting on the same prob­lem: an archive that grows faster than they can edit it. The sec­ond half is why mine never gets touched.

Airport se­cu­rity some­where be­tween Nairobi and Spain. Two trays of cam­eras, head­phones, drone bits, bat­ter­ies, SSDs, more ca­bles than any­one needs. Most of it records some­thing. Almost none of what they record gets touched again any time soon.

Three months ago the lodge’s so­cial chan­nels went dark. Not for lack of con­tent; the lodge has years of raw footage across mul­ti­ple SSDs. The bot­tle­neck was edit­ing time, and my time dis­ap­peared. Claude Code with Opus 4.5 (and then 4.6) hit the point in February where you could leave agents run­ning for hours and come back to merged PRs. KaribuKit was go­ing live with its first pay­ing prop­erty in the same win­dow. I stopped sleep­ing prop­erly, started run­ning three or four agents in par­al­lel in the back­ground, and the months when I would have cut reels turned into months when I shipped soft­ware in­stead.

So one week­end I sat down to fix it. The first thing I tried was wrong.

The wrong layer

The ini­tial pitch (to my­self, af­ter about an hour of re­search) was a SaaS stack: Eddie AI for it­er­a­tive edit­ing, Higgsfield MCP for gen­er­a­tive B-roll, Submagic for cap­tions, Buffer for cross-post­ing. About $140 a month, slick on pa­per.

Two prob­lems showed up be­fore I ran any of it.

First, gen­er­a­tive AI video has no place on a real travel brand. Guests pay $300 a night and up to see the ac­tual place, and mis­la­beled AI shots equals TripAdvisor cru­ci­fix­ion. Higgsfield out.

Second, 3 – 5 posts a week was ag­gres­sive for me, and the re­al­is­tic floor was more like 2 – 3. The pitch was op­ti­mistic in a way that would have me fail­ing by week two.

Then I re­mem­bered I al­ready own DaVinci Resolve Studio, and Resolve 21 ships IntelliSearch (semantic clip search), Smart Bins (auto-organizing fold­ers), and Voice to Subtitle that pro­duces 90 – 95% ac­cu­rate cap­tions on the time­line. That’s roughly 70% of what Eddie sells, so Eddie was out too.

What I was left with was Claude Code dri­ving Resolve via the open-source DaVinci Resolve MCP, with ElevenLabs han­dling voiceover on in­for­ma­tional clips where it earned its place, and the cost had dropped from $140 a month to $22.

But the deeper thing only landed once I tried to ac­tu­ally use any of this. Every AI video ed­i­tor on the mar­ket as­sumes your footage is al­ready la­beled. Mine is IMG_*.mov and DJI_*.mp4 across fold­ers with names like Mara june 2024 backup fi­nal FINAL. Eddie can search by tran­script, but none of these tools can find the ele­phant on the hill at golden hour” against an un­la­beled archive.

The AI ed­i­tor is solv­ing the wrong prob­lem. Or more pre­cisely, it’s solv­ing the sec­ond prob­lem; the first prob­lem is the in­dex.

The ques­tion

I asked it out loud: how does the agent know what’s in each clip?

There’s no an­swer for an un­la­beled archive. You can throw tran­scripts at it, GPS co­or­di­nates, file­names, par­ent fold­ers. None of that gives you the wide shot at sun­rise with the gi­raffe in the frame” un­less some­thing has ac­tu­ally looked at the pix­els.

The lever­age is up­stream. Build the in­dex first, make the archive queryable in English, and the ed­i­tor on top be­comes a thin layer do­ing what it was de­signed to do.

So I built the in­dex, lo­cally.

The build

This is the kind of AI-native build I do for clients at SimbaStack, ex­cept I was both the client and the en­gi­neer this time, which made the de­ci­sion tree a lot shorter.

Four con­straints set the shape:

It had to be lo­cal-first. The Mara Hilltop archive lives on phys­i­cal SSDs and most of the per­sonal stuff is on my lap­top, and up­load­ing thou­sands of multi-gi­ga­byte clips to the cloud made no sense on cost, never mind as a way to hand the en­tire vi­sual record of my life to a third party.

I wanted side­cars rather than a cen­tral data­base: a .description.md per clip, liv­ing right next to it, plain text and grep-able. It sur­vives if my in­dexer breaks to­mor­row, and it trav­els with the data when files move be­tween dri­ves.

One vi­sion call had to cap­ture every­thing, be­cause the vi­sion pass over the ex­tracted frames is the ex­pen­sive op­er­a­tion. Anything I might want to know about a clip later has to come out of that one call, so the schema is ex­haus­tive on day one: rat­ing, tech­ni­cal qual­ity, light­ing, time of day, color palette, au­dio qual­ity, peo­ple count, key­words, faces, lo­ca­tion, tran­script, prose de­scrip­tion. All in one shot.

I wanted three vi­sion back­ends to choose from: Claude via my Max sub­scrip­tion’s CLI as the de­fault (zero mar­ginal cost), the Anthropic API for speed when I need it, and a lo­cal back­end pointed at LM Studio for the bulk pass. The lo­cal one is the one that mat­ters.

The per-clip pipeline:

ff­probe for meta­data.

exiftool for GPS lat/​lon/​al­ti­tude. Works on iPhone, DJI Pocket, drone footage, all the same.

Reverse-geocode via Nominatim. Free, rate-lim­ited, no API key.

ffm­peg ex­tracts five evenly-spaced frames at 1920px.

WhisperX tran­scribes with word-level align­ment and pyan­note speaker di­ariza­tion. Hindi, English, Swahili, 97 lan­guages.

in­sight­face de­tects faces and stores 512-dim ArcFace em­bed­dings in a cen­tral­ized SQLite face DB for cross-archive per­son queries later.

Vision model reads the frames, tran­script snip­pet, and folder con­text, and re­turns YAML front­mat­ter plus a prose de­scrip­tion.

Sidecar writ­ten to disk.

Here’s what that looks like on a real clip from the Mara Hilltop archive.

One frame from IMG_1103.MOV. Ellie on the deck of one of the lux­ury tents at the lodge, mid­day. None of that con­text lives in the file­name.

The side­car Gemma wrote for the same clip. YAML on top (lighting enum, time-of-day enum, color palette, face em­bed­dings, GPS), prose ## Description be­low. It picked up the sa­fari-tent set­ting, the cam­era pan from in­te­rior to sa­vanna, the shot type, and sug­gested two use cases (marketing reels and travel-vlog B-roll). The file­name had IMG_1103.MOV; the side­car has the rest of what I needed to find it again.

A real Mara Hilltop archive folder af­ter the in­dexer has run through it. Every clip has a .description.md side­car next to it; the _INDEX.json and _INDEX.md at the top are folder-level rollups for fast grep and LLM-friendly hand­off.

The whole thing is a Claude Code skill, about 1,400 lines of Python. Claude Code wrote al­most all of it. My work was the ar­chi­tec­ture, the prompts, the schema de­sign, and the bug triage when things went wrong.

The ab­sur­dity

This is the part that ac­tu­ally sur­prised me.

I bought a 16-inch MacBook Pro M1 Max with 64GB of RAM in 2021, and the rea­son had noth­ing to do with LLMs. I’d been hit­ting 32GB lim­its on my pre­vi­ous ma­chine for a while. A messy hacker brain run­ning hun­dreds of Chrome tabs along­side DaVinci Resolve, Slack, Discord, and Drive was too much for pre-uni­fied-mem­ory hard­ware to han­dle with­out pag­ing con­stantly. I maxed out the RAM on the new M1 Max be­cause the old one would­n’t stop killing my work­flow and I had the money to fix it.

Five years later, that same lap­top is run­ning Gemma 4 31B Q4 in LM Studio against a year of video footage.

LM Studio with Gemma 4 31B Q4 loaded. 28.40 GB of model in mem­ory, REST API at 127.0.0.1:1234. The bot­tom panel is the server log dur­ing a real bulk run, en­cod­ing frames one clip at a time.

The bulk run pushed the lap­top past where 64GB of RAM alone would carry it. Activity Monitor re­ported 50.89 GB of swap at the peak.

64 GB of phys­i­cal RAM, 50.89 GB of swap used. Memory pres­sure in the yel­low band, the kind of state you ab­solutely should not run on a nor­mal Tuesday. Apple’s swap is de­signed for it, and the fans were loud.

I Googled whether that would dam­age the SSD, and ap­par­ently for a day or two it’s fine. Don’t make it your nor­mal op­er­at­ing state, but a week­end of push­ing the ma­chine hard is well within tol­er­ance. My lap­top ran hot, the fans spun up, and it kept pro­duc­ing side­cars while I worked on other things.

The M1 Max 16-inch is, hon­estly, leg­endary. People in the Mac com­mu­nity talk about it that way for good rea­son: five years on, it’s run­ning 31B-parameter mod­els at us­able speed with the kind of head­room that should not ex­ist on hard­ware this old. I ex­pect an­other three to five years out of this thing, com­fort­ably, be­cause lo­cal LLMs only get more ef­fi­cient and the hard­ware is the floor, not the ceil­ing.

I bought it for Chrome. It’s run­ning a model that did­n’t ex­ist when I bought it.

Four bugs, four lessons

The build was mostly Claude Code hold­ing the pen. The in­ter­est­ing work was the four times it al­most shipped some­thing wrong.

WhisperX 3.8 broke its di­ariza­tion API be­tween when I last touched it and now. Two break­ing changes had landed: whis­perx.Di­ariza­tion­Pipeline moved to the whis­perx.di­arize sub­mod­ule, and the con­struc­tor kwarg use_auth_­to­ken was re­named to to­ken (inherited from pyan­note 3.x). The fix was sig­na­ture in­tro­spec­tion: the script tries to­ken= first and falls back to use_auth_­to­ken= if the con­struc­tor raises a TypeError, so it sur­vives the next API shuf­fle au­to­mat­i­cally. When you’re shelling out to AI li­braries that move this fast, de­fen­sive con­struc­tor calls are cheap in­sur­ance.

The Claude CLI re­turns per­mis­sion er­rors as suc­cess­ful re­sponses. On the first test of the CLI back­end, all four side­cars came back iden­ti­cal with the text I need per­mis­sion to read the im­age frames…”, and the scrip­t’s suc­cess check passed be­cause exit code was 0 and the out­put was­n’t empty. The cause was that in non-in­ter­ac­tive mode with­out –permission-mode by­passPer­mis­sions, the CLI re­turns the per­mis­sion-de­nial text as the re­sponse body in­stead of prompt­ing, which means the fail­ure mode looks ex­actly like suc­cess un­less you string-match for it. The fix was adding the flag plus a de­fen­sive check that flags any short re­sponse con­tain­ing I need per­mis­sion” as an er­ror rather than a de­scrip­tion. When you script AI tools, the non-in­ter­ac­tive per­mis­sion flow is where the silent fail­ures hide.

Gemma re­turned peo­ple_­count: many” in­stead of an in­te­ger. My vi­sion prompt lit­er­ally said in­te­ger or the string many” if >10. Gemma fol­lowed in­struc­tions cor­rectly; the bug was schema de­sign. The fix was a stricter prompt (integer 0 – 99 with ex­plicit guid­ance to es­ti­mate) plus a co­er­cion in the parser for the legacy many” re­sponses. Don’t union-type schema fields. Pick al­ways-int or al­ways-string, never int or this one spe­cific string,” be­cause every down­stream con­sumer pays for the choice.

Then there was the mo­tor­cy­cle clip that should­n’t have been culled. My ini­tial cull prompt was pho­tog­ra­pher-port­fo­lio-shaped: heavy mo­tion blur, soft fo­cus, and jit­tery sta­bil­ity got rated cull. Technically cor­rect. Then I tested it on a hand­held night­time mo­tor­cy­cle clip from a Spain trip and it culled it. I caught it: that’s a fun mem­ory, the blur is the vibe. I re­framed the cull cri­te­ria to not a real record­ing” only (lens cap, pocket footage, two-sec­ond test clips, fully clipped ex­po­sure), not imperfect cap­ture.” Photo archives cull ag­gres­sively; video mem­o­ries cull per­mis­sively. Same schema, dif­fer­ent cri­te­ria, and you have to be ex­plicit about which mode you’re in.

The ac­tual take

Three things I now be­lieve more strongly than I did a week ago.

Enum con­straints beat in­struc­tions for con­fab­u­la­tion pre­ven­tion. I tested Gemma 4 E4B on a cowork­ing-space photo I’d taken at night, and it de­scribed the scene as brightly lit, abun­dant nat­ural light, floor-to-ceil­ing win­dows,” ex­cept the win­dows were pitch black out­side, be­cause it was night. Then I tested 31B with a struc­tured schema prompt that forces the model to pick from gold­en_hour | bright_­day­light | over­cast | dim_in­te­rior | night­time | mixed | un­clear, and both think­ing-off and think­ing-on re­cov­ered night­time cor­rectly. A model can lie about open-ended prose, but it can only mis-pick from an enum, never in­vent a new value. Use schemas, not in­struc­tions.

Local 31B with struc­tured prompts closes most of the gap to cloud. Gemma 4 31B Q4 think­ing-off against a struc­tured schema pro­duces out­put that’s hard to dis­tin­guish from Sonnet 4.6 on most of my test clips. The cloud pre­mium earns its keep on the hard 10 – 20%. Bulk in­dex­ing at scale (thousands of clips overnight) should run lo­cal; cloud is the re-rate pass on clips lo­cal flagged as re­view. That two-tier setup is the one that scales.

AI video ed­i­tors are pitched one layer too high. The valu­able layer is the in­dex. Once your archive is queryable in plain English (“show me hand­held in­te­rior clips from Mara, golden hour, with peo­ple, longer than 8 sec­onds”), the ed­i­tor on top is straight­for­ward. Most of the AI-editor space is com­pet­ing for the sur­face above an in­dex that does­n’t ex­ist, and the in­dex is the pre­req­ui­site they’re all skip­ping past.

What’s next

Looking back, time was­n’t re­ally what kept this from get­ting fixed sooner. I had every AI su­per­power cur­rently avail­able pointed at the work side of my life: Claude Code refac­tor­ing code­bases overnight, Codex writ­ing most of my pull re­quests, the agen­tic stack I’d just spent three months us­ing to ship KaribuKit. On the edit­ing side, I was us­ing none of it. The not-get­ting-to-it had be­come its own small, low-grade frus­tra­tion that lived in the back of my head all year, the kind of thing you no­tice every time you open a folder on the SSD and close it again with­out do­ing any­thing. What clicked one Saturday was that the edit­ing back­log was a tool­ing prob­lem, and tool­ing is the one kind of prob­lem I hap­pen to be well-equipped to fix right now.

This week­end I’m build­ing the ed­i­tor: Claude Code as the or­ches­tra­tor, DaVinci Resolve MCP for the cuts, ElevenLabs for voiceover on in­for­ma­tional clips. There’s one hard rule baked into the tool­ing: the voice clone is for util­ity con­tent only. Directions, room de­scrip­tions, mul­ti­lin­gual ver­sions, fac­tual stuff I’d say in per­son any­way. Never for tes­ti­mo­ni­als or founder mes­sages. Disclosure laws are real in 2026, and trust in a hos­pi­tal­ity brand is too easy to lose.

The in­dex makes all of that tractable. Without it, I would still be scrub­bing through 47GB of DJI Pocket footage look­ing for the sun­rise wide.

For now: a year of Mara Hilltop footage is queryable in English on a five-year-old lap­top. Cost was a week­end of my time and 50GB of swap. The re­main­ing years across older SSDs are next.

A fair check on all of this: Mara Hilltop’s so­cial chan­nels are still dead to­day. The in­dexer solves only half the prob­lem (finding the right clip); the ed­i­tor that turns those clips into fin­ished reels is the other half, and that’s the part I’m build­ing this week­end. If it works, the chan­nels light back up and I write part two. If it does­n’t, I write about why.

In all hon­esty, the right an­swer here might be to hire some­one. Finding an ed­i­tor with the right sen­si­bil­ity for Mara Hilltop (warm, ob­ser­va­tional, no over-cut MTV-energy reels) is harder than writ­ing an­other skill. If you know some­one who works in that reg­is­ter, send them my way.

Edit: code at github.com/​Sim­bas­tack-hq/​framedex. PRs and is­sues wel­come. Thanks to the HN com­menter who flagged that the orig­i­nal lo­cal-path ref­er­ence was­n’t use­ful.

NJ

Building KaribuKit (AI-native PMS for hos­pi­tal­ity), run­ning Mara Hilltop (eco-lodge in the Maasai Mara), and con­sult­ing through SimbaStack.

#local-llm#claude-code#video-archive#mara-hilltop#simbastack

Python 3.15: features that didn't make the headlines

blog.changs.co.uk

It’s that time of the year again, a new ver­sion of Python is just around the cor­ner. With the Python 3.15.0b1 fea­ture freeze, we know what’s com­ing to Python later this year. There are so many big fea­tures com­ing in­clud­ing lazy im­ports and the tachyon pro­filer which I pre­vi­ously cov­ered.

Last year, I re­ally en­joyed in­ves­ti­gat­ing the smaller fea­tures of Python 3.14. I found that many of those fea­tures were just as in­ter­est­ing as the big PEPs and de­serve a lot more at­ten­tion. This year the sit­u­a­tion is no dif­fer­ent.

Asyncio Taskgroup Cancellation

There are not many Asyncio changes in this re­leases. The main fea­ture to come out here is the abil­ity to can­cel a TaskGroup grace­fully.

TaskGroup is a form of struc­tured con­cur­rency, it en­ables de­vel­op­ers to cre­ate mul­ti­ple con­cur­rent tasks in a clean way.

async with asyn­cio.TaskGroup() as tg: tg.cre­ate_­task(run()) tg.cre­ate_­task(run()) # Waits for all the tasks to com­plete

Suppose we want to wait in the back­ground for a sig­nal of sorts to in­ter­rupt the taskgroup’s ex­e­cu­tion, it’s seems like some­thing sim­ple to do in asyn­cio, but in re­al­ity it’s some­what awk­ward to do this.

class Interrupt(Exception): …

with sup­press(In­ter­rupt): async with asyn­cio.TaskGroup() as tg: tg.cre­ate_­task(run()) tg.cre­ate_­task(run()) if await wait­_­for_sig­nal(): raise Interrupt()

This works be­cause ex­cep­tions raised within a task group cause other tasks to can­cel. The cus­tom Interrupt ex­cep­tion is raised as part of a ExceptionGroup which then gets fil­tered by con­textlib.sup­press, re­sult­ing in a grace­ful exit.

The way sup­press works with ExceptionGroup is yet an­other over­looked fea­ture from 3.12. This is a change I learnt by ac­ci­dent when re­search­ing this ar­ti­cle.

The way sup­press works with ExceptionGroup is yet an­other over­looked fea­ture from 3.12. This is a change I learnt by ac­ci­dent when re­search­ing this ar­ti­cle.

The new TaskGroup.cancel makes this process a lot eas­ier:

async with asyn­cio.TaskGroup() as tg: tg.cre­ate_­task(run()) tg.cre­ate_­task(run()) if await wait­_­for_sig­nal(): tg.can­cel()

Unlike be­fore it’s so sim­ple there’s hardly any point in ex­plain­ing. It sim­ply can­cels the group with­out rais­ing any ex­cep­tions.

Context Manager Improvements

Decorators are sur­pris­ingly hard to write, so much so that it’s be­come a go-to in­ter­view ques­tion. But did you know that con­text man­agers can also dou­ble up as a dec­o­ra­tor?

@contextmanager def du­ra­tion(mes­sage: str) -> Iterator[None]: start = time.per­f_­counter() try: yield fi­nally: print(f”{mes­sage} elapsed {time.perf_counter() - start:.2f} sec­onds”)

Here I have a very com­monly used con­text man­ager to print out the du­ra­tion spent in the block. Ever since Python 3.3 we could di­rectly use it as a dec­o­ra­tor too:

@duration(‘workload’) def work­load(): …

# Or sim­ple as a wrap­per

du­ra­tion(‘stuff’)(oth­er_­work­load)(…)

But whilst it’s con­ve­nient, there are cases where it does­n’t work at all:

@duration(‘async work­load’) async def async_­work­load(): …

@duration(‘generator work­load’) def work­load(): while True: yield …

Iterators, async func­tions and async it­er­a­tors don’t work well here be­cause they have dif­fer­ent se­man­tics to stan­dard func­tions. When you call them they re­turn im­me­di­ately with a gen­er­a­tor ob­ject, corou­tine func­tion and async gen­er­a­tor ob­ject re­spec­tively. So the dec­o­ra­tor com­pletes im­me­di­ately as op­posed to the en­tire life­cy­cle what it’s wrap­ping.

This is an un­for­tu­nate prob­lem I’ve en­coun­tered many times, and it’s of­ten a prob­lem for nor­mal dec­o­ra­tors too. But this has changed in 3.15, now the ContextDecorator will check the type of the func­tion it’s wrap­ping and en­sure that the dec­o­ra­tor cov­ers the en­tire lifes­pan.

In my opin­ion, this now makes con­text man­agers the best way to cre­ate dec­o­ra­tors! It avoids some of the com­mon foot­guns and pro­vides cleaner syn­tax. I rec­om­mend more peo­ple start us­ing it this way.

Thread Safe Iterators

Iterators are one of the foun­da­tions of mod­ern Python. The it­er­a­tor type al­lows us to sep­a­rate data sources from data con­sumers as be­low, re­sult­ing in cleaner ab­strac­tions:

lazy from typ­ing im­port Iterator

def stream_events(…) -> Iterator[str]: while True: yield block­ing_get_event(…)

events = stream_events(…)

for event in events: con­sume(event)

But this ab­strac­tion breaks when us­ing thread­ing or free-thread­ing. An it­er­a­tor by de­fault is not thread­safe, there­fore we may see skipped val­ues or just bro­ken in­ter­nal it­er­a­tor state.

This is solved in 3.15 with thread­ing.se­ri­al­ize_it­er­a­tor, we sim­ply wrap our orig­i­nal it­er­a­tor with this and voila:

im­port thread­ing

events = thread­ing.se­ri­al­ize_it­er­a­tor(stream_events(…))

with ThreadPoolExecutor() as ex­ecu­tor: fut1 = ex­ecu­tor.sub­mit(con­sume, events) fut2 = ex­ecu­tor.sub­mit(con­sume, events)

There is also the thread­ing.syn­chro­nized_it­er­a­tor dec­o­ra­tor which just ap­plies thread­ing.se­ri­al­ize_it­er­a­tor to the re­sult of an gen­er­a­tor func­tion.

Finally we also have thread­ing.con­cur­ren­t_­tee that in­stead of split­ting the val­ues will du­pli­cate the val­ues across mul­ti­ple it­er­a­tors:

source1, source2 = thread­ing.con­cur­ren­t_­tee(squares(10), n=2)

with ThreadPoolExecutor() as ex­ecu­tor: fut1 = ex­ecu­tor.sub­mit(con­sume, source1) fut2 = ex­ecu­tor.sub­mit(con­sume, source2)

Before these util­i­ties ex­isted we pri­mar­ily re­lied on Queues to syn­chro­nise con­sump­tion be­tween threads, with these added in we can avoid chang­ing our ab­strac­tions for multi-threaded code.

Bonus Features

Last year I only high­lighted 3 fea­tures, but this year there are a lot more up­dates that in­trigue me. Here are 2 more changes that are per­haps less im­pact­ful but still very in­ter­est­ing nonethe­less.

Counter xor Operation

col­lec­tions.Counter is a very use­ful class. It let’s us eas­ily count up the fre­quency of dis­crete oc­cur­rences. It be­haves very sim­i­lar to a dict[Key­Type, int] but with a ton of use­ful op­er­a­tions

c = Counter(a=3, b=1) d = Counter(a=1, b=2) print(f”{c + d = }“) # add two coun­ters to­gether: c[x] + d[x] print(f”{c - d = }“) # sub­tract (keeping only pos­i­tive counts)

prints:

Counter(a=4, b=3) Counter(a=1, b=0)

But it has some weirder op­er­a­tions too:

print(f”{c & d = }“) # in­ter­sec­tion: min(c[x], d[x]) print(f”{c | d = }“) # union: max(c[x], d[x])

prints:

Counter(a=1, b=1) Counter(a=3, b=2)

The way to think of it is that a Counter can also rep­re­sents a dis­crete set of ob­jects. so in our ex­am­ple, we’re es­sen­tially do­ing:

{a_0, a_1, a_2, b_0} & {a_0, b_0, b_1} == {a_0, b_0} {a_0, a_1, a_2, b_0} | {a_0, b_0, b_1} == {a_0, a_1, a_2, b_0, b_1}

In 3.15 we can also add xor to the list:

c = Counter(a=3, b=1) d = Counter(a=1, b=2)

c ^ d == c | d - c & d == Counter(a=3, b=2) - Counter(a=1, b=1) == Counter(a=2, b=1)

Once again this is best ex­plained by our no­ta­tion from ear­lier:

{a_0, a_1, a_2, b_0} ^ {a_0, b_0, b_1} == {a_1, a_2, b_1}

I’ve left this one to the bonus sec­tion be­cause I’ve never used set op­er­a­tions on Counters and I’m find­ing it ex­tremely hard to think of a use case for xor specif­i­cally. But I do ap­pre­ci­ate the devs adding it for com­plete­ness.

Immutable JSON Objects

With the ad­di­tion of frozen­dict in 3.15, we now have the abil­ity to rep­re­sent all the json types (array, boolean, float, null, string, ob­ject) in im­mutable (hashable) forms.

A change has been made to json.load and json.loads to add ar­ray_hook pa­ra­me­ter that com­pli­ments the ob­jec­t_hook pa­ra­me­ter. This now al­lows us to parse json ob­jects di­rectly into this form:

json.loads(‘{“a”: [1, 2, 3, 4]}’, ar­ray_hook=tu­ple, ob­jec­t_hook=frozen­dict) == frozen­dict({‘a’: (1, 2, 3, 4)})

The theme is by Smashing Magazine, thanks!

Declining America

www.tbray.org

Recently I got an in­vi­ta­tion from an or­ga­ni­za­tion I re­spect, to a gath­er­ing of se­nior peo­ple, un­con­fer­ence for­mat. Yes, it’s mostly about AI. No, it does­n’t reek of boos­t­er­ism. My guess is that the dis­cus­sions would be rel­a­tively in­tel­li­gent and un­be­liever con­tri­bu­tions would be wel­come. I de­clined, be­cause it’s in the USA.

Here’s the text; maybe some­one in a sim­i­lar sit­u­a­tion might find it use­ful.

Thanks to who­ever thought of me for the kind in­vi­ta­tion, which I must re­gret­fully de­cline.

I’m Canadian and as a mat­ter of prin­ci­ple feel­ing neg­a­tive about vis­it­ing a neigh­bor­ing coun­try whose leader has re­peat­edly threat­ened our sov­er­eignty and shown mas­sive dis­re­spect for our na­tion­hood. Particularly when that leader has fol­lowed up sim­i­lar state­ments about other na­tions with mil­i­tary ac­tion.

I could prob­a­bly work around that. But there’s also the is­sue of en­ter­ing the US; if I roll up at the bor­der and am asked to dis­close my so­cial me­dia out­put, there’s a sig­nif­i­cant risk of an ex­tremely neg­a­tive out­come. I have a fam­ily to sup­port and re­ally can’t af­ford that risk.

I still con­sider my­self a friend of your or­ga­ni­za­tion, and one with strong opin­ions about the sub­jects sched­uled for dis­cus­sion; my re­grets about hav­ing to de­cline are en­tirely sin­cere.

—Regards, Tim

By .

The opin­ions ex­pressed here are my own, and no other party nec­es­sar­ily agrees with them.

A full dis­clo­sure of my pro­fes­sional in­ter­ests is on the au­thor page.

I’m on Mastodon!

Hating AI is good, actually

www.thehandbasket.co

[Ex-Google CEO Eric Schmidt while be­ing booed]

Jonah Peretti is very lucky. Buzzfeed—the vi­ral me­dia com­pany he founded 20 years ago and was once val­ued at $1.6 bil­lion—was run­ning out of cash when bil­lion­aire Byron Allen agreed to buy 52% of its shares. At the same time this new part­ner­ship was re­vealed, Peretti an­nounced he’d be step­ping down as CEO of Buzzfeed to serve in a new role as President of Buzzfeed AI. So Allen will con­tinue to bankroll the for­mer me­dia ti­tan’s ob­ses­sion, as he promises (without ev­i­dence) that AI will right the ship. Lucky, to be sure, but also part of the mass delu­sion that AI is not just worth our money, but owed our re­spect.

Lately I’ve felt my­self rapidly rad­i­cal­iz­ing into what I can only call an anti-AI evan­ge­list. I’ve never been quiet about my feel­ings on the sub­ject—I even wrote a screed about it last month—but as more and more ex­am­ples show how eas­ily it can be used un­eth­i­cally, I’m not just skep­ti­cal. I’m against it.

I would­n’t call this a par­tic­u­larly bold stance, given the front page of to­day’s Wall Street Journal de­clares an AI Rebellion,” not­ing that pub­lic opin­ion on the sub­ject is sour­ing at break­neck speed.” What is novel, I think, is rec­og­niz­ing that peo­ple who loathe AI and the way it’s be­ing foisted upon so­ci­ety are an ac­tual con­stituency to be taken se­ri­ously. I fig­ure that if bil­lion­aires and brands are go­ing to try to beat us into AI sub­mis­sion, it’s only fair we get to take a few swings. We’re told that if we don’t use AI then we’ll get left be­hind, but what if we’d like to leave the AI boost­ers be­hind in­stead? It’s time to give a voice to those who don’t view AI as an in­evitabil­ity but a li­a­bil­ity.

Now is our time.

The sound­track of the past week or so has been the boos of grad­u­at­ing col­lege stu­dents as out-of-touch adults try to tell them that they need to em­brace AI or else. Perhaps most promi­nent were the boos of University of Arizona grad­u­ates as ex-Google CEO Eric Schmidt told them, The ques­tion is not whether AI will shape the world. It will. The ques­tion is whether you will help shape ar­ti­fi­cial in­tel­li­gence.”

These grads, ac­cord­ing to Schmidt, have no agency, which was con­firmed by this com­ment a few min­utes later: When some­one of­fers you a seat on the rocket ship, you do not ask which seat. You just get on, Graduates, the rocket ship is here.” What Schmidt does­n’t get is that these young peo­ple have al­ready been forced onto the ship and there aren’t enough seats.

A few days be­fore Schmidt, record com­pany CEO Scott Borchetta took the stage at Middle Tennessee State University’s com­mence­ment to ex­toll the virtues of AI. When the stu­dents, whose job prospects have shrunken sig­nif­i­cantly be­cause of the AI bub­ble, booed Borchetta, he shot back: Deal with it. Like I said, it’s a tool.”

Sage words from a man re­port­edly worth $450 mil­lion.

It may seem cal­lous for a com­mence­ment speaker to re­spond to grad­u­ates’ ex­is­ten­tial dread with deal with it,” but bil­lion­aires and tech com­pa­nies have been feed­ing us this mes­sage for a while now. You may not like AI, they preach, but be­cause of choices we are mak­ing for you, life will be in­creas­ingly un­liv­able with­out it. Yet while they try to force-feed us this bleakly in­evitable fu­ture, ac­tu­ally ex­ist­ing AI keeps mak­ing the hu­mans who use it look like id­iots.

On Tuesday, the New York Times re­ported on a new book called The Future of Truth: How AI Reshapes Reality,” by me­dia ex­ec­u­tive Steven Rosenbaum. He read­ily copped to hav­ing used AI tools ChatGPT and Claude dur­ing the re­search, writ­ing and edit­ing process.” But he did­n’t dis­close—likely be­cause he did­n’t re­al­ize it!— that his book con­tained mis­at­trib­uted or com­pletely fab­ri­cated quotes cre­ated by those very tools. Only when re­porters be­gan to ques­tion the quotes did Rosenbaum promise to investigate” how they’d been in­cluded.

But Rosenbaum was un­re­pen­tant. He told the Times that if this de­ba­cle serves as a warn­ing about the risks of AI-assisted re­search and ver­i­fi­ca­tion, that is why I wrote the book.” And he went on to say: These AI er­rors do not, in fact, di­min­ish the larger ques­tions that the book raises about truth, trust and AI and its im­pact on so­ci­ety, democ­racy and ed­i­to­r­ial.”

Ronsebaum’s big whoop­sie is cer­tainly a warn­ing, but not in the way he thinks. He him­self is the warn­ing; a cau­tion­ary tale about re­ly­ing so heav­ily on a flawed tech­nol­ogy that it com­pletely un­der­mines your le­git­i­macy. The er­rors may not di­min­ish some of the book’s larger ques­tions, but they di­min­ish the value of the book it­self. If you can’t make the ef­fort to ver­ify the con­tents of your book, then why should any­one make an ef­fort to read it?

Two other lit­er­ary AI-crises un­folded Tuesday. Coincidence? Perhaps. But also po­ten­tially a sign that AI use has reached the crit­i­cal mass bil­lion­aires hoped for. Only, in­stead of mak­ing things bet­ter, it’s just made them stu­pider.

One of the crises in­volved the Commonwealth Short Story Prize, a pres­ti­gious an­nual fic­tion award, and the win­ning sto­ries. When this year’s win­ners were pub­lished on­line by UK-based lit­er­ary mag­a­zine Granta, one im­me­di­ately aroused sus­pi­cion that it was partly AI-generated. Some, per­haps to sar­don­ically prove a point, ran it through AI that claims to de­tect the pres­ence of AI. Later, Granta’s pub­lisher ad­mit­ted to do­ing the same thing. We showed Claude.ai the story and asked whether it was AI-generated,” the state­ment reads. The re­sponse was long, con­clud­ing that it was almost cer­tainly not pro­duced un­aided by a hu­man’.”

But the use of AI on AI only caused more con­fu­sion. It may be that the judges have now awarded a prize to an in­stance of AI pla­gia­rism — we don’t yet know, and per­haps we never will know,” the pub­lisher wrote. For a well-re­spected pub­lisher to sim­ply throw up its hands and say perhaps we never will know,” deeply ran­kled some hu­man writ­ers, to say the least.

The other scan­dal sur­rounded Nobel lau­re­ate Olga Tokarczuk’s ad­mis­sion that she used AI in her writ­ing process, clar­i­fy­ing that she uses artificial in­tel­li­gence on the same prin­ci­ples as most peo­ple in the world — I treat it as a tool that al­lows faster doc­u­ment­ing and check­ing of facts.” The ca­su­al­ness with which she men­tioned it dur­ing an ear­lier in­ter­view in­di­cated she was­n’t par­tic­u­larly tor­tured about us­ing it.

Often I just ask the ma­chine, darling, how could we de­velop this beau­ti­fully?’” Tokarczuk re­port­edly said, per a trans­la­tion from Polish. Even though I know about hal­lu­ci­na­tions and many fac­tual er­rors in the al­go­rithms in terms of eco­nom­ics and hard data, I have to add that in lit­er­ary fic­tion this tech­nol­ogy is an ad­van­tage of un­be­liev­able pro­por­tion.”

This brings up the idea I’ve seen pushed by other writ­ers who openly used AI and say this tech­nol­ogy is merely like a sour­dough starter, cre­at­ing the con­di­tions for some­thing to be made where there was once noth­ing. The prob­lem arises when you don’t know where the starter ends and the cre­ative process be­gins. And can any­thing truly novel be cre­ated by a tech­nol­ogy that feeds on what al­ready ex­ists?

[Image from a 2025 Nature mag­a­zine study that was re­tracted in part be­cause of this AI-generated fig­ure con­tain­ing non­sense to demon­strate the frame­work.”]

To un­der­stand the cru­sade for, and in­creas­ingly against, AI, one must re­gret­tably log into LinkedIn. Originally known as a so­cial me­dia plat­form for job search­ing and pro­fes­sional net­work­ing, it’s mor­phed pri­mar­ily into a place where tech evan­ge­lists as­sert su­premacy by loudly and fre­quently list­ing out the ways they har­ness tech­nol­ogy to achieve peak per­for­mance. None of the posts read like some­thing an ac­tual hu­man would say, and I would guess the peo­ple post­ing this shit don’t talk like that in real life. But it’s not real life. It’s LinkedIn. A haven for syco­phants to gain val­i­da­tion for their orig­i­nal­ity all while say­ing the same things as every­one else. Typically I scroll through for amuse­ment, and some­times post to pro­mote my 100% hu­man-made work.

While LinkedIn may seem like an im­pen­e­tra­ble space for AI skep­tics and out­right haters like me, my pas­sive scrolling has some­what con­firmed what the WSJ la­beled a rebellion.” One trend I no­ticed a month or two back is that mar­ket­ing pro­fes­sion­als, TED talk­ers and com­mu­ni­ca­tions gu­rus alike have started call­ing out what they see as easy tells for AI-generated writ­ing.

At first, I took it as a hope­ful sign that AI use was­n’t go­ing com­pletely unchecked. After all, ac­cord­ing to a Pew study from September, U.S. adults are gen­er­ally pes­simistic about AIs ef­fect on peo­ple’s abil­ity to think cre­atively and form mean­ing­ful re­la­tion­ships,” with 53% say­ing AI will make it worse, and 16% say­ing it will both of those things bet­ter. But af­ter read­ing enough of these posts, I came to re­al­ize peo­ple on LinkedIn weren’t mad oth­ers were us­ing AI; they were mad peo­ple were be­ing so sloppy about it, not even both­er­ing to mas­sage the ma­chine’s lan­guage to con­ceal their process.

And of course with most trends, there’s a back­lash to peo­ple call­ing out AI. One de­fender called the pop­u­lar groundswell against AI slop the new McCarthyism.” Some of these posts about AI polic­ing are im­bued with a sense of out­right be­trayal. How dare you draw at­ten­tion to an un­eth­i­cal short­cut that we all use, even if some of us are bet­ter at us­ing it than oth­ers. How dare you let peo­ple see your writ­ing is ac­tu­ally just two LLMs in a trench coat. Again they’re not mad that peo­ple use it: they’re mad that peo­ple are catch­ing on.

But while I took men­tal notes on what I was ob­serv­ing, I also felt a lack of rep­re­sen­ta­tion for true, pro­found, and gut­tural loathing of AI. The peo­ple like me who have only the vaguest idea of what de­fines AI, but ex­tremely spe­cific ex­am­ples of why it sucks. I’m not a hater based on vibes. I’m a hater based on facts. And those facts de­serve as much re­spect as the bil­lion­aires who con­tinue to dump money into los­ing en­ter­prises.

[My new and im­proved LinkedIn header]

A not-in­signif­i­cant part of my frus­tra­tion with the AI ethos sat­u­rat­ing LinkedIn is that it in­creas­ingly serves only one, nar­row vi­sion of suc­cess. It’s the suc­cess that comes only to the or­ga­nized, the ef­fi­cient and the hy­per-op­ti­mized. And above all, to the deeply cer­tain.

But as some­one who’s built a busi­ness my­self, the one thing I can be cer­tain about is that there is ab­solutely an­other way. You don’t have to be part of the grind­set or be a girl­boss or a so­ciopath or use short­cuts to be suc­cess­ful. You don’t have to out­source think­ing to a ma­chine to demon­strate you un­der­stand the fu­ture. You will only be and do those things if what you’re ac­tu­ally seek­ing is power.

People hate AI,” the CEO of an AI-infrastructure con­sult­ing firm said on a pod­cast, per the Wall Street Journal. AI is less pop­u­lar than ICE. AI is less pop­u­lar than politi­cians.” And much like ICE, AI has sunk its claws into com­mu­ni­ties that don’t want it.

Despite the bray­ing of the tech elite, we still have agency. We still have a choice.  Players with many bil­lions at stake have a vested in­ter­est in re­mov­ing your agency, and re­claim­ing it hurts their bot­tom line. There’s no way to say for cer­tain who will be right about AI in the end, but the cur­rent ev­i­dence points to­wards dis­as­ter. And it’s safe to ac­knowl­edge it.

To add this web app to your iOS home screen tap the share button and select "Add to the Home Screen".

10HN is also available as an iOS App

If you visit 10HN only rarely, check out the the best articles from the past week.

Visit pancik.com for more.