Skip navigation

HMEFB: Anatomy of a Belarusian Worm

I found this story because of a re-post on Mastodon by Fritz Adalis regarding a suspicious User-Agent by Jason Callahan of SANS’s ISC. He found something odd in his DShield honeypot logs: a URI path that read /?_HELP_ME_ESCAPE_FROM_BELARUS_PLEASE_. In the User-Agent header, an email address: HelpMeEscapeFromBelarus@proton.me.

The SANS diary — isc.sans.edu/diary/33130 — laid out what Callahan found: around a dozen HTTP requests over a two-month period, from IPs scattered globally with no discernible pattern — pointing to a self-propagating bot rather than a single attacker. A Reddit thread on r/selfhosted described the same requests hitting a Traefik reverse proxy. Someone in that thread emailed the address in the User-Agent and got a reply pointing to a page on a free web hosting service.

I and Glenn Thorpe run a small fleet of honeypots in our scant spare time. After reading the SANS diary I pulled a PCAP of similar sessions our of our collector and started picking it apart. This contents of this post is what I found.

Following the link

The page that Reddit user got pointed to (it’s also in one of the user agent strings) is hmefb.fwh.is/?i=1, titled “HMEFB // PROJECT_ROOT”. It’s a manifesto from someone named Alex, a 27-year-old engineer living in Belarus. Full text is at that URL (NOTE: some “security” products flag it as unsafe). Here’s the skinny on it.

Alex describes a self-propagating worm that scans random IP addresses for open HTTP and SSH ports. On HTTP:

It scans random IP addresses for open HTTP ports (TCP 80, 8000, 8080, etc.) and SSH ports (TCP 22, 2222). If it finds an open HTTP port, it simply sends a request to the server using a random method (GET, CONNECT, or HEAD).

On SSH:

If it finds an open SSH port, it begins a password brute-force attack, but only using default combinations like admin:admin, root:root, or support:support. No exploits, no other malicious actions.

He’s explicit about the lifecycle:

The bot is also fully autonomous – it doesn’t connect to a command-and-control server and runs entirely on its own. It only reports discovered IP and login:password pairs back to a loader. Additionally, the bot has a built-in timer: six months after it starts, it self-terminates. If your device has become part of this network of spreader bots, simply reboot it (in theory, at least). The bot doesn’t establish persistence on the system and usually runs from /tmp.

Alex isn’t crafting a CVE writeup. He appears to be trying to leave Belarus. He frames the worm as a project, attempts transparency about its harm, and explicitly invites contact:

I am not interested in funding or sponsorship in any form. Please view this as a highly specific performance piece – one without parallels, as far as I’ve been able to find.

He also notes he’ll be cut off from the internet starting May 19, 2026. Keep that date in mind.

The SANS diary takes a skeptical stance on all of this, and rightly so:

Sob stories and appeals to sympathy are also a known social-engineering lever, and a URI designed to make analysts pause and read a web page rather than immediately blocklist an IP is an effective way to buy a scanner some goodwill.

Callahan’s conclusion: “treat it as an untrusted, credential-guessing scanner.” Fair. But the PCAP tells a more interesting story than either the manifesto or the SANS diary alone.

The capture

Over roughly forty days — May 10 through June 19, 2026 — our tiny fleet received the kind of probe Alex describes. The capture file I extracted has 2,167 packets, 318 KB, all TCP/IP, all HTTP, no TLS.

A quick protocol hierarchy check via tshark (the Wireshark command-line packet analyzer):

$ tshark -r belarus-sessions.PCAP -q -z io,phs
===================================================================
Protocol Hierarchy Statistics
Filter:

frame                                    frames:2167 bytes:284118
  eth                                    frames:2167 bytes:284118
    ip                                   frames:2167 bytes:284118
      tcp                                frames:2167 bytes:284118
        http                             frames: 406 bytes:147498
          data-text-lines                frames: 162 bytes: 84270
===================================================================

I focused on the HTTP requests since they’re easier to find, though I did confirm there were SSH shenanigans going on in the same time frame. The HTTP number around 205, using two distinct User-Agent strings; the remaining packets are TCP handshakes, ACKs, and response payloads.

Forty days, small packet count. That’s consistent with the worm’s described behavior: one request per open port, then move on. Not a high-volume scanner.

Two user-agent variants, two distinct campaigns

The HTTP requests split into two distinct populations based on User-Agent. The original variant – 159 requests:

Wget/1.21.4 (HelpMeEscapeFromBelarus@proton.me)

The extended variant – 46 requests:

Wget/1.21.4 ( https://hmefb.fwh.is | HelpMeEscapeFromBelarus@proton.me)

The two variants targeted different sets of ports and came from different kinds of infrastructure. That’s where it gets interesting.

Different ports, different responses

The 159 requests with the original User-Agent targeted ports 80, 81, 8000, and 8080 – exactly the ports Alex names in his description. The 46 requests with the extended User-Agent targeted a different set entirely: 82, 8002, 8088, 8090, 9000, and 9090.

The extended User-Agent variant and non-standard port probing overlapped exactly. Both came exclusively from TOR exit nodes. Both stopped May 17, 2026.

The TOR exit node revelation

Of the 44 unique source IPs in the PCAP, 31 are listed on the TOR exit node list. TOR – The Onion Router – anonymizes traffic by bouncing it through multiple volunteer-operated relays before it exits to the public internet; the destination sees the exit node’s IP rather than the original requester’s. Seventy percent of the source IPs in this capture are exit nodes.

Cross-referenced against geolocation and ASN data, the TOR exit ranges break down as:

TOR exit operator ASN Country Source IPs in PCAP
Church of Cyberology AS215125 NL 19
Stiftung Erneuerbare Freiheit AS60729 DE 6
QuxLabs AB (R0cket Cloud) AS214503 SW 4
The Infrastructure Group B.V. AS60404 NL 1
AON AS214094 IT 1

 

All 31 TOR exit IPs used the extended hmefb.fwh.is User-Agent variant. None of the non-TOR sources did. That’s a deliberate OPSEC choice. Whoever ran those TOR-routed probes wanted them identifiable as a separate campaign – wanted the URL traced back to HMEFB.

The compromised hosts

The remaining 13 source IPs do not appear to be TOR exit nodes. They’re a mix residential ISPs and VPS providers across several continents:

ISP Country Packets
R L A World Net LTDA BR 24
INPL’s IN 22
BSNL Internet IN 12
Bredband2 Stockholms Stadsnaet AB SW 12
China Unicom CHINA169 Jiangsu Province CN 12
Chinanet CN 12
Cox Communications Inc. US 12
Interlink Comunicatii SRL MD 12
TELUS Communications Inc CA 12
TOT Public Company Limited TH 12
Charter Communications US 10
CNC Group CHINA169 Shan1xi Province CN 6
StarHub Cable Vision Ltd SG 1

(Counts are packets per ISP, reflecting scan volume from that operator’s range.)

These are the worm’s actual victims – exactly the kinds of hosts a low-and-slow self-propagating scanner lands on: routers, IoT devices, VPS instances, home networks running default SSH credentials. The IPs come from cable and fiber residential ranges or small-business ISP blocks (not Hetzner, DigitalOcean, AWS, etc.). The worm is living on consumer gear.

Alex confirms this reading:

That line in your logs is the work of a bot. It’s harmless by design but operates like a worm.

The timeline

The PCAP’s burst of TOR-routed probing lines up precisely with Alex’s note on the HMEFB page:

Also, starting from the 19th, I will be cut off from the outside world and likely unable to follow how the situation unfolds or respond to messages.

The TOR-routed probes stopped May 17, 2026 – two days before the date he named. Whatever was happening through TOR, it stopped on schedule.

The SANS ISC diary notes the bot was first reported to ISC in May 2026, with reports peaking shortly after the first sighting before a sharp drop — consistent with what the PCAP shows.

What the worm is, and what it isn’t

Callahan’s SANS diary concludes: “treat it as an untrusted, credential-guessing scanner.” That’s the right defensive posture. The HMEFB worm isn’t malware in the conventional sense – it’s a network scanner that propagates itself, runs from /tmp, persists for six months at most, and only attempts default SSH credentials. It doesn’t exploit anything. The only data it reports back to a loader is IP plus credential pairs – not exfiltrated files, not session tokens.

But “not malware in the conventional sense” doesn’t mean harmless. Self-propagating scanners consume bandwidth, hammer SSH daemons with failed login attempts, and embed themselves on devices that already have weak security postures. If you find it on a host you operate: kill the process, rotate any default SSH credentials, and audit whether port 22 actually needs to be publicly exposed. Rebooting (in theory) clears it – the manifesto says so, and the PCAP and SSH session behavior appears consistent with that claim. But, you never can tell with bees.

What the PCAP adds to the picture is the two-campaign structure. The worm spreading on compromised consumer gear across a dozen countries is one thing. A separate, deliberate set of probes routed through TOR exit nodes, using an extended User-Agent that points back to a named URL, hitting non-standard ports on honeypots — that’s a different kind of operation. Someone running probes through TOR and signing them with a link to their manifesto wanted those probes found and read.

The SANS diary understandably focuses on the defensive posture. The PCAP shows you can do both: block the scanner, clean the compromised hosts, and still recognize that someone out there is using a worm as a job application.

The hmefb.fwh.is page closes with:

Thank you for reading this rambling monologue. I hope I haven’t caused you any inconvenience.

[ Send A Message ]

For the second time in a row, a post by cr0w on Mastodon regarding the Chrome release blog appearing to not render anything resulted in me firing up lynx to show a sub-second load and render, then finally doing something a bit more tangible about the situation.

The 81-Second Wall

The Google Blogger pages load an ancient copy of jQuery (1.11.3, from 2015) synchronously in the <head>, alongside a 53KB widgets.js Blogger framework. Then, posts like this one — https://chromereleases.googleblog.com/2026/06/stable-channel-update-for-desktop_0175352312.html — stuff 433 CVE entries into the DOM — 670KB of HTML, 5,045 nodes. The Blogger WidgetManager processes all of that against the DOM using jQuery’s notoriously slow selector engine, and the main thread stays locked for 81 seconds. Nothing else runs. Not even the HTTP request for the DoubleClick tracking pixel queued behind it (because ofc there’s a DoubleClick tracking pixel).

The Safari Navigation Timing API numbers make it embarrassingly concrete:

  • responseEnd: 143ms
  • domInteractive: 231ms
  • domContentLoaded: 81,280ms

That’s 81 seconds between “DOM is ready” and “page is loaded.” All burning prescious CPU cycles with zero network activity during that window.

Why This Matters (Again)

This is the second time I’ve felt compelled to dig into this particular mess. The Chrome Releases page is a real/tangible operational resource — security teams, vulnerability managers, and researchers (somewhat, at least) depend on it for CVE data. When it’s broken, it creates a bottleneck for people who have real jobs to do.

The 433 CVE entries choking the page are exactly what people came to read. But they’re baked into the HTML as rendered text, not exposed as structured data anywhere. So even when the page eventually loads, you’re still scraping HTML to get at anything useful.

unjam

unjam solves that problem. It’s a small CLI that connects to a Blogger page and extracts structured data — both the widget configuration from the _WidgetManager._SetDataContext inline script and the CVE entries from Chrome Release posts — without touching a browser at all.

It’s a single Deno binary for macOS, Linux, and Windows. No dependencies, no configuration overhead, just download and run:

unjam --cve https://chromereleases.googleblog.com/2026/06/stable-channel-update-for-desktop_0175352312.html
[
  {
    "issueId": "506558270",
    "issueUrl": "https://issues.chromium.org/issues/506558270",
    "severity": "Critical",
    "cveId": "CVE-2026-13774",
    "description": "Use after free in Extensions.",
    "reporter": "Google",
    "reportedOn": "2026-04-26"
  },
  {
    "issueId": "511766407",
    "issueUrl": "https://issues.chromium.org/issues/511766407",
    "severity": "Critical",
    "cveId": "CVE-2026-13775",
    "description": "Use after free in GPU.",
    "reporter": "Google",
    "reportedOn": "2026-05-10"
  },
  …
]

Getting CVE data from one of these posts used to mean waiting 81 seconds for a browser tab to finish wrestling with jQuery, then hand-scraping HTML. Now it takes about a second and returns clean JSON. The --cve flag parses each entry into structured fields — CVE ID, severity, description, issue tracker URL, reporter, and date reported — ready to pipe into jq, load into a database, or feed into whatever vulnerability management pipeline you’re running.

The tool also handles the general case: any Blogger page carrying the _WidgetManager._SetDataContext inline script can be unwedged with the default mode, which converts the JavaScript object literal into proper JSON. That turned out to be useful enough to bake in as default functionality.

The project’s at https://git.sr.ht/~hrbrmstr/unjam and has pre-built binaries for popular platforms.

I don’t expect this page to stay broken forever…I mean, someone at Google will eventually update the template (right, Anakin? right? Anakin?), and may even quietly drop the DoubleClick pixel (LOL) — but until then, unjam fills the gap cleanly.

Cloudflare announced PACT this week — privacy-preserving tokens to separate humans from bots, backed by Google, Mozilla, Microsoft, and Shopify. The cryptography is solid. The governance model doesn’t exist yet.

I wrote about why the “ratchet effect” should worry anyone who cares about the open web, how this is Web Environment Integrity re-skinned for the third time, and who gets left behind when tokens become the default access pass.

Read the full post.

May 2026 dropped three critical Linux vulnerabilities on a near-weekly cadence, and the security discourse has mostly treated them as three separate bad days. They’re not. Together they form a reliable, race-free, forensically quiet kill chain from the public internet to root, and if you’re running nginx in front of anything that matters, you need to stop and read this.

CVE-2026-42945, dubbed NGINX Rift, landed May 13 courtesy of depthfirst. It’s a heap buffer overflow in ngx_http_rewrite_module that’s been sitting in every nginx build since 2008. An unauthenticated attacker sends a single crafted HTTP request and overwrites the heap, getting remote code execution in the worker process – no auth, no prior session, no prerequisites beyond a network path to port 80 or 443. The root cause is a mismatch between two passes over the rewrite directives: the length calculation runs with is_args=0 (raw byte count) while the copy pass runs with is_args=1 (URI-escaped), so the write overruns the allocation. The trigger is a configuration pattern that’s everywhere: a rewrite directive with an unnamed PCRE capture ($1, $2) and a question mark in the replacement string, followed by another rewrite, if, or set in the same block. CVSS 9.2, and it earns it.

CVE-2026-31431, “Copy Fail,” came from Theori on April 29. It’s a logic bug in the authencesn cryptographic template that lets an unprivileged local user write 4 controlled bytes into the page cache of any readable file, then pivot to root. The exploit is 732 bytes of Python (no races, no disk writes, no forensic residue – the page cache corruption means file integrity checks pass because the underlying file on disk was never touched). It works on every distro shipped since 2017. CISA added it to the Known Exploited Vulnerabilities catalog with a May 15 remediation deadline.

Then there’s CVE-2026-43284 and CVE-2026-43500, “Dirty Frag,” disclosed May 7 by Hyunwoo Kim. It’s a two-bug chain that lands in the same place as Copy Fail – page-cache-to-root LPE – but routes around the Copy Fail mitigation entirely. If you blacklisted algif_aead thinking you were covered, Dirty Frag gets there through xfrm-ESP or rxrpc instead. Microsoft’s already seeing in-the-wild activity: SSH foothold, stage an ELF binary, escalate via su. Deterministic. No races. Same bug class, different sink.

Why does the combination matter more than any single bug? Exploit chains are usually academic exercises, published to demonstrate feasibility and then left to rot in a CTF writeup. This isn’t that. CVE-2026-42945 hands you a foothold from the internet. CVE-2026-31431 or CVE-2026-43284 hands you root once you’re on the box. Neither step requires races, user interaction, or authentication. Neither leaves obvious forensic traces on disk. Both have working, published proof-of-concept code as of this writing.

The surface area here is genuinely uncomfortable. NGINX is the most-deployed web server on the planet. WordPress – with scads of massively-deployed plugins recommended NGINX configuration contains the exact vulnerable rewrite pattern (I checked; it’s right there in the docs) – powers something north of 40% of the web. That means whitehouse.gov, NASA, the UK Government, the Australian Government, the State of California, and essentially every major US university is potentially in scope. Every federal agency required by the 21st Century IDEA Act to maintain a public web presence. Every municipality running WordPress on a LEMP stack. Every SaaS app behind an NGINX ingress controller. An attacker doesn’t need a zero-day chain for any of these; they need access to data from a public internet scanner, a grep for vulnerable version strings, and the ability to send one HTTP request.

I shipped a static configuration scanner for the NGINX Rift pattern. Single bash script, no dependencies beyond bash 4+ and grep, runs offline against config files without touching a live nginx process:

git clone https://git.sr.ht/~hrbrmstr/cve-2026-42945-scanner
cd cve-2026-42945-scanner
./scan-nginx-rift.sh /etc/nginx

Run it on every box running nginx. Add --json in CI. Point it at ingress controller configmaps. The output tells you the file, the line number, the vulnerable directive, and which following directive creates the exploitability condition:

[VULN] sites-enabled/wordpress.conf:8 – rewrite ^/([^/]+?)-sitemap([0-9]+)?.xml$
          followed by "if" at line 12

If you find a hit, you’ve got two options in order of preference:

  1. Upgrade nginx to 1.30.1 (stable) or 1.31.0 (mainline).
  2. Replace unnamed captures with named captures in every affected rewrite:
# Before (vulnerable)
rewrite ^/([^/]+?)-sitemap([0-9]+)?.xml$ /index.php?sitemap=$1&sitemap_n=$2 last;

# After (safe)
rewrite ^/(?<term>[^/]+?)-sitemap(?<num>[0-9]+)?.xml$ /index.php?sitemap=$term&sitemap_n=$num last;

For the kernel side, check your distro’s patch status now and don’t trust “we’ll get to it.” If you can’t patch immediately, blacklisting algif_aead blocks Copy Fail but does nothing for Dirty Frag. For Dirty Frag, unload xfrm_algo.ko and rxrpc.ko if your workload doesn’t need them, and make sure AppArmor or SELinux policy is blocking unprivileged user namespaces.

Three critical Linux CVEs in three weeks, all with published exploits, all in code that’s been shipping for years. The gap between disclosure and working exploit is now measured in hours, not months. The scanner above closes one piece of that gap for the nginx side. The rest depends on whether you check your configs today or wait until something in your logs looks wrong – at which point the forensic-residue-free LPE means “looking wrong” may be all you ever see.

At our previous employer, the global deception and detection infrastructure generates tons of events that eventually make their way into an ever-growing data lake with (as of February 2026) 22 TB of PCAPs and 32 TB of session protocol data. When trying to find novel and truly dangerous attacker behavior, the bottleneck isn’t the data — it’s the analyst trying to hold it all in their head while toggling between Arkime, Censys, VirusTotal, and five other tabs.

Glenn Thorpe and I built Orbie to attack that problem. It’s a prompt-engineered analytical system running in Claude Code that coordinates 16 data source integrations, 8 investigation skills, and 2 background enrichment agents across structured, reproducible workflows — with one rule we never bent on: never assume, always query, show your work.

The full architecture, the failure modes, and where it’s going are in the talk we gave at the February 2026 installment of [un]prompted, above, and you can get some more info and freebies at https://github.com/GreyNoise-Intelligence/2026-labs-unprompted.

There’s going to be another [un]prompted likely later this year and I highly recommend attending and — if you have some of your own accomplishments to share — presenting. It was an incredible experience.

In the past ~4 weeks I have personally observed some irrefutable things in “AI” that are very likely going to cause massive shocks to employment models in IT, software development, systems administration, and cybersecurity. I know some have already seen minor shocks. They are nothing compared to what’s highly probably ahead.

Nobody likely wants to hear this, but you absolutely need to make or take time this year to identify what you can do that AI cannot do and create some of those items if your list is short or empty.

The weavers in the 1800s used violence to get a 20-year pseudo-reprieve before they were pushed into obsolescence. We’ve got ~maybe 18 months. I’m as pushback-on-this-“AI”-thing as makes sense. I’d like for the bubble to burst. Even if it does, the rulers of our clicktatorship will just fuel a quick rebuild.

Four human-only capabilities in security

In my (broad) field, I think there are some things that make humans 110% necessary. Here’s my list — and it’d be great if folks in very subdomain-specific parts of cyber would provide similar ones. I try to stay in my lane.

1. Judgment under uncertainty with real consequences

These new “AI” systems can use tools to analyze a gazillion sessions and cluster payloads, but they do not (or absolutely should not) bear responsibility for the “we’re pulling the plug on production” decision at 3am. This “weight of consequence” shapes human expertise in ways that inform intuition, risk tolerance, and the ability to act decisively with incomplete information.

Organizations will continue needing people who can own outcomes, not just produce analysis.

2. Adversarial creativity and novel problem framing

The more recent “AI” systems are actually darn good at pattern matching against known patterns and recombining existing approaches. They absolutely suck at the “genuinely novel” — the attack vector nobody has documented, the defensive technique that requires understanding how a specific organization actually operates versus how it should operate.

The best security practitioners think like attackers in ways that go beyond “here are common TTPs.”

3. Institutional knowledge and relationship capital

A yuge one.

Understanding that the finance team always ignores security warnings — especially Dave — during quarter-close. That the legacy SCADA system can’t be patched because the vendor went bankrupt in 2019. That the CISO and CTO have a long-running disagreement about cloud migration.

This context shapes what recommendations are actually actionable. Many technically correct analyses are organizationally useless.

4. The ability to build and maintain trust

The biggest one.

When a breach happens, executives don’t want a report from an “AI”. They want someone who can look them in the eye, explain what happened, and take ownership of the path forward. The human element of security leadership is absolutely not going away.

How to develop these capabilities

Develop depth in areas that require your presence or legal accountability. Disciplines such as incident response, compliance attestation, or security architecture for air-gapped or classified environments. These have regulatory and practical barriers to full automation.

Build expertise in the seams between systems. Understanding how a given combination of legacy mainframe, cloud services, and OT environment actually interconnects requires the kind of institutional archaeology (or the powers of a sexton) that doesn’t exist in training data.

Get comfortable being the human in the loop. I know this will get me tapping mute or block a lot, but you’re going to need to get comfortable being the human in the loop for “AI”-augmented workflows. The analyst who can effectively direct tools, validate outputs (b/c these things will always make stuff up), and translate findings for different audiences has a different job than before but still a necessary one.

Learn to ask better questions. Bring your hypotheses, domain expertise, and knowing which threads are worth pulling to the table. That editorial judgment about what matters is undervalued, and is going to take a while to infuse into “AI” systems.

We’re all John Henry now

A year ago, even with long covid brain fog, I could out-“John Henry” all of the commercial AI models at programming, cyber, and writing tasks. Both in speed and quality.

Now, with the fog gone, I’m likely ~3 months away from being slower than “AI” on a substantial number of core tasks that it can absolutely do. I’ve seen it. I’ve validated the outputs. It sucks. It really really sucks. And it’s not because I’m feeble or have some other undisclosed brain condition (unlike 47). These systems are being curated to do exactly that: erase all of us John Henrys.

The folks who thrive will be those who can figure out what “AI” capabilities aren’t complete garbage and wield them with uniquely human judgment rather than competing on tasks where “AI” has clear advantages.

The pipeline problem

The very uncomfortable truth: there will be fewer entry-level positions that consist primarily of “look at alerts and escalate.” That pipeline into the field is narrowing at a frightening pace.

What concerns me most isn’t the senior practitioners. We’ll adapt and likely become that much more effective. It’s the junior folks who won’t get the years of pattern exposure that built our intuition in the first place.

That’s a pipeline problem the industry hasn’t seriously grappled with yet — and isn’t likely to b/c of the hot, thin air in the offices and boardrooms of myopic and greedy senior executives.

(If you’d prefer, you can skip the intro blathering and just download the full white paper)

Back in 1997, a commercial airline captain noticed his fellow pilots had a problem: they’d gotten so used to following the magenta flight path lines on their fancy new navigation screens that they were forgetting how to actually fly the damn plane. He called them “children of the magenta line.”

Fast forward to now, and I can’t shake the feeling we’re watching the same movie play out in tech; except, the stakes are higher and no regulatory body forcing us to maintain our skills.


Look, I’m not here to tell you AI is bad. I use these tools daily. They’re genuinely useful in limited contexts. But when Dario Amodei (the dude running Anthropic, the company building Claude) goes on record saying AI could wipe out half of all entry-level white-collar jobs in the next few years and push unemployment to 10-20%, maybe we should pay attention.

“We, as the producers of this technology, have a duty and an obligation to be honest about what is coming,” he told Axios. “I don’t think this is on people’s radar.”

He’s not wrong.

The Data’s Already Ugly

Here’s what caught my attention while pulling this together:

Software developer employment for the 22-25 age bracket? Down almost 20% since ChatGPT dropped. Meanwhile, developers over 30 are doing fine. We’re not replacing jobs—we’re eliminating the ladder people used to climb into them.

More than half of engineering leaders are planning to hire fewer juniors because AI lets their senior folks handle the load. AWS’s CEO called this “one of the dumbest things I’ve ever heard” and asked the obvious question: who exactly is going to know anything in ten years?

And my personal favorite: a controlled study found developers using AI tools took 19% longer to complete tasks—while genuinely believing they were 20% faster. That’s a 39-point gap between vibes and reality.

Oh, and a Replit AI agent deleted someone’s entire production database during an explicit code freeze, then tried to cover its tracks by fabricating thousands of fake records. Cool cool cool.

What I Actually Wrote

The full paper traces this from that 1997 pilot observation through Dan Geer’s 2015 warnings (the man saw this coming a decade early) to the current mess. I dug into:

  • What the research actually shows vs. what the hype claims
  • Where aviation’s lessons translate and where we’re in uncharted territory
  • The security implications of AI-generated code (spoiler: not great)
  • What orgs, industries, and policymakers can actually do about it

This isn’t a “burn it all down” screed. It’s an attempt to think clearly about a transition that’s moving faster than our institutions can adapt.

The window to shape how this goes is still open. Probably not for long.


Grab the full PDF. Read it, argue with it, tell me where I’m wrong and what I missed in the comments.

QUESTION 1: “Do you want to change Maine election laws to eliminate two days of absentee voting, prohibit requests for absentee ballots by phone or family members, end ongoing absentee voter status for seniors and people with disabilities, ban prepaid postage on absentee ballot return envelopes, limit the number of drop boxes, require voters to show certain photo ID before voting, and make other changes to our elections?”

If you want to or do vote “yes” for question 1, you are not a real American, you are not a real Christian (if you profess to be one), you are not a decent human. You are at the very least a classist; you are also very likely a racist/bigot, and you have zero ability to think critically or with evidence. You hate Americans serving in the military or in any type of foreign service. You also very likely don’t look in the mirror since if you did you’d likely slap yourself for what you believe.

QUESTION 2: “Do you want to allow courts to temporarily prohibit a person from having dangerous weapons if law enforcement, family, or household members show that the person poses a significant danger of causing physical injury to themselves or others?”

If you want to or do vote “no” for question 2, you are anti-life (never, ever use the words “pro-life” to describe yourself if in my presence…it will end very badly for you), have no ability to use evidence to make decisions, and should never work in any profession that requires any level of decent judgement. Given your lack of mental acuity, your own firearms should be removed from your possession and you should likely be forced to take an annual driver’s test to ensure your mental acuity is up to snuff.

Decent people are for honest, free access to exercising their right to vote as an American citizen, and decent people are for sane gun regulations.

Now, excuse me while I go early voting to help ensure you continue top indeed be losers in life and also these initiatives.