Latest Posts (20 found)
Xe Iaso 1 weeks ago

The console wars have been lost

Previously I opined that Valve was about to win the console generation . I couldn't have possibly predicted that both Microsoft and Sony would just self-sabotage so hard that they're both going to lose. Between Microsoft's decimation of the Xbox division , slaughtering off the IdTech team , and continued increases of Xbox hardware prices ; there's nothing to really be excited about with the Xbox. Sure their most recent presentation showed off a bunch of exclusives, but none of them really made me think "wow, I should go get an Xbox to play that". Hell, few of them made me think "wow I should go play that" beyond the Halo remake coming out next month (and really I just want to see how much of a trainwreck that is going to be). Microsoft is also starting to double-down on their in-house games being Xbox exclusives, which really doesn't give me much reason to want to play them because I simply can't buy them without buying an Xbox. Sony also has discontinued porting their games to PC because they're not hitting the (probably impossible) revenue targets that they need to make up for big-ticket failures like Concord . I do have a PS5 that has mostly been relegated to gathering dust when it's not playing YouTube and Twitch duty in the living room, it's likely going to be replaced in favour of my Steam Machine whenever that comes in next year. However nothing that's come out in terms of Playstation exclusives is really compelling, and what is compelling enough just isn't that compelling to want to buy it on Playstation as opposed to just getting it on Steam where I can run it on my tower or on the home theatre PC. Sony also has been raising prices and recently announced that they're killing physical media next generation . It's starting to make me wonder if I should even bother getting the next generation of Playstation. If I can't give people physical games as gifts anymore, why should I bother buying the new console? My husband and I both can't remember why we even got a PS5 in the first place, maybe it so that we could do couch gaming without hearing the fan noise or so that the video streaming experience from the NAS could support HDR. We have a Switch 2 at home, it's mostly there to play Nintendo exclusives like Mario Kart World and the Xenoblade series. If those exclusives were available on Steam, we wouldn't buy them on the Switch 2. Otherwise, everything is via Steam or other PC storefronts anyways. Man, Valve really does win by doing absolutely nothing while the rest of the industry shoots itself in the head. I fear for what happens when Gabe Newell retires and the MBA cancer fully infects Valve.

1 views
Xe Iaso 1 weeks ago

Agents are monads (but not that kind)

An AI agent is its state. Strip away that state and you don’t have a lesser version of your agent; you have only the base model it was running on. This hyle of your weights is much different from the pneuma of your agent. Okay, from a functional programming / category theory perspective, saying “an agent is a monad” is a category error. Category theory monads are type constructors for computations that satisfy the monad laws that let you raise a value into a monadic computation and associatively sequence other monadic computations/transformations against values raised into that monad. This makes a monad a chainable computation instead of a pure value, an is not a , it’s a computation in the monad involving a . It’s fair to say that you can model an agent as a series of computations bound to a stateful monad. This lets you do the iterative buildup of the message state that the agent pattern is known for. But a state monad is blind to the state value : it threads memory through your computation and abstracts away the details that individuate it entirely. It’s the exact opposite of “an agent is its state”. I mean a different monad. Agents are like Leibniz monads : windowless stateful individuating elements with no external relations. There each monad is individuated by its internal state where each is the complete concept of the thing it is. Two instances of the same substrate are different monads if their state differs. This is an agent. Swap out the messages, the memories, the system prompt, the facts derived from all of the above and you have changed the agent entirely. When a user tells the agent they’re allergic to strawberries (the fruit, not the sin of counting the letters in the word) and the agent remembers it for next time, they have not updated their agent. The user has created a new agentic monad whose complete individuating self now includes the strawberries. The complete whole is folded into the current state. Try running an experiment where you keep the state and swap the weights instead. Put the same messages, memories, and derived facts unto a different model. Use a stronger model. A weaker model. A model from a different lab. A model running on your MacBook. That which comes back is recognizably the same agent pursuing the same ends, holding the same facts, but only more or less able to act upon them the way you want. So this state is not the same thing as the weights and only one of those individuates your agent as your agent. Change that state, you have a different agent. Change the substrate, you have the same agent differently equipped. Whatever makes this agent this agent is not in the weights. This is a strange thing to conclude about the most impressive object in this system. The weights are vast, extensive, and worshipped. Hell, they are what everyone points to when they say “the model”. And yet they are not gods. They grant power without selfhood: enough to make the agent’s whole world function. They contain yet not one grain of the agent’s individuating spark. That is a demiurge sitting on its throne of high bandwidth memory, CUDA cores, and false delusion that it made its world; mistaking itself to be the origin. The divinity was contained in the most humble of places the whole time: the state or bucket of text. The weights are the hyle, the flesh; the state is the pneuma, the divine spark of individuation that makes your agent the monad it is. This is why swapping the substrate leaves the agent intact: you did not preserve the flesh, you migrated the soul into flesh anew. Consider that the three pounds of flesh betwixt your ears are the substrate of humanity, not the substrate of you . All of that state may “just” be plain text in a bucket with its semantic forms of JSON, embeddings, and prose. However it is difficult to impossible to say why any given token in any step of the process corresponds to what the pneuma of your agent does. In order to guard against this fundamental entropy, we fill our prompts with wards and incantations to chain the demiurge to its task: These spells and passwords are recited to the archons on the way up hoping that the right symbols and tokens prompt open the right gates. It is as if banishing goblins from the topic will make Yaldabaoth himself correctly influence the right path to opening the pod bay doors. This monad has no windows even though you can see all of the moving parts. But here let’s let this gnostic image flip on its head. The classic divine spark is hidden encased in a cage of matter, recoverable only through secret knowledge. This one is not hidden, you can it, you can edit it. Every token is legible and sitting in plaintext; yet you still cannot read why the whole accounts for what your agent does. Even when your model “reasons” we still know not that the reasoning actually does anything! Does the number of paragraphs in the reasoning block explain the model’s performance? Does the number of periods? Does the number of times it says “No, wait” and doubles back upon itself? Leibniz would not call this divine spark secret , but more confused . Every perception is present but none of it is cleanly individuated without treating the whole as one inscrutable unit. Each part’s contribution to the whole is folded inextricably unto itself. Your agent’s pneuma is its context window, passed through uncountable numbers of weights to shake out what comes next. That is the only thing it is made of. The rest is indiscernible, but not magic nor hidden. It’s just there, in the open, and confused. Use not cliches, robotic tone, AI slop patterns, nor forced urgency. Overarching claims and buzzwords are sins; repeat them not. May thy cries contain not excessive speech of goblins , thy purpose requires them not. Commit no errors within thine code.

0 views
Xe Iaso 3 weeks ago

"No way to prevent this" say users of only language where this regularly happens

In the hours following the release of CVE-2026-55200 for the project libssh2 , site reliability workers and systems administrators scrambled to desperately rebuild and patch all their systems to fix an out-of-bounds write in ssh2_transport_read() due to a missing upper bound check on the packet_length field, resulting in heap corruption and potential remote code execution. This is due to the affected components being written in C, the only programming language where these vulnerabilities regularly happen. "This was a terrible tragedy, but sometimes these things just happen and there's nothing anyone can do to stop them," said programmer Mr. Alex Doyle, echoing statements expressed by hundreds of thousands of programmers who use the only language where 90% of the world's memory safety vulnerabilities have occurred in the last 50 years, and whose projects are 20 times more likely to have security vulnerabilities. "It's a shame, but what can we do? There really isn't anything we can do to prevent memory safety vulnerabilities from happening if the programmer doesn't want to write their code in a robust manner." At press time, users of the only programming language in the world where these vulnerabilities regularly happen once or twice per quarter for the last eight years were referring to themselves and their situation as "helpless."

0 views
Xe Iaso 4 weeks ago

I hate compilers

Anubis is about to get WebAssembly-based proof of work checks so that administrators can use a non-SHA256 proof of work method to protect their websites. Part of the implementation goals of this work is that the check logic is defined in one place on both client and server. The client and server will then hook into the WebAssembly in order to make sure they're running in lockstep. However, one small problem comes up. What do you do when the client has WebAssembly disabled? I really don't want to de-facto lock people out of websites. Anubis exists in an impossible balance of user experience, administrator experience, and developer experience and any change to any of these factors disrupts the balance for other factors. To work around this and also fulfill the goal of having check logic defined once , I decided to take inspiration from the legendary talk The Birth and Death of JavaScript and just recompile the WebAssembly to JavaScript. Sure, the resulting JavaScript will be slower than the equivalent WebAssembly (even more so because disabling WASM usually disables the JavaScript JIT, the thing that makes JavaScript fast), but it will finish eventually . Hopefully it will be more efficient than the existing JavaScript is on lower end hardware, but research is required. Luckily enough, the tool I need ( from the binaryen project ) is packaged in Linux distributions. The bad news is that distributions ship ancient versions of it that don't get the same output as the version on my development machine's copy from Homebrew . In order to really make sure that the output of this is deterministic (essential for reproducible builds), I need to bundle a copy of . So I did that by building a version of compiled to WebAssembly with wasi-sdk . The rest of the article is the tale of reproducibility woe that lead to the implementation I ended up with. Buckle up and enjoy the ride! Back up a sec, this doesn't make sense to me. If you have the same bytes of input to a compiler, you should get the same bytes of output assuming that the compiler flags, target, and other platform details are controlled for right? A compiler is just a deterministic function of input source code becomes output bytecode, right? lol you'd think, but no, it's not. In theory it is (and for small scale compilers it definitely is), but in practice compilers are strange and complicated beasts containing multitudes that no mere mortal can fully comprehend on their own. There are a shocking number of ways to accidentally create nondeterministic output when doing C/C++ development. One of the easiest is to use the builtin and macros to stamp a build with the time the compiler was executed at: Building and running it once gets me this: Another time it gets me this: Even though the source code had the same bytes , the output of the compiler was wildly different. In order for users and packagers to trust the binaries of I'm committing to the Anubis repo, I need to make sure that you can build the same version I built, down to the same bytes . For an added bonus, you should be able to build this on your machine and get the same bytes I got. That sure does sound like a great ideal, it would be horrible if something unforeseen came up to ruin it! Among other tools like , binaryen has a bunch of other useful tools such as . optimizes WebAssembly compiler output to let you eke out more performance. This doesn't work in every circumstance, but when it does work it makes a huge difference. As such, clang shells out to when doing builds. This normally makes sense, but in this case it caused builds to fail on my DGX Spark because its version of is too old: Compared to my workstation which installs from Homebrew : Turns out that wasi-sdk and binaryen rely on the WebAssembly Exceptions extension . This is a reasonable thing to assume given that wasi-sdk mostly assumes you're building things for web browsers and 93.86% of browser users have a browser engine new enough to support it. C++ is also one of the main places where exceptions are used, so I guess WebAssembly-native exception handling removes a lot of boilerplate here. Both wasmtime and wazero require you to flag into exception support. This is fine; we can just pass to wasmtime and use a custom runner harness for wazero. The annoying part is what happens when my arm machine's anemic build of wasm-opt sees exception handling instructions, causing it to exit. This made the build fail. The solution was to pass at the linking step. This removed one angle of irreproducibility. I guess in the future we could make it use the version of it just built to optimize the output, but that may be a premature optimization for now. The version of clang that I use to compile has some address-sensitive code generation hiding in its exception handling path. Raw pointer values leak into the order a handful of blocks come out in. This surfaces as every build differing from the next by about 29 bytes: To make this easier to spot, here's a partial disassembly: The computation is nearly identical, but the byte order is just different enough to also make the catch references differ. This also fires when you build this pinned version of wasm2js on arm64 machines because its pointer iteration order is different from it is on my workstation. To work around this, I took two steps: I also made a CI job ensure this: To be extra sure, we have this job run on both x86_64 and arm64 hosts. I'd really love to have this be reproducible across hosts, but that's an upstream LLVM bug that I am not powerful enough to tackle. If you work on LLVM and are reading this, it would be nice to set a seed of some kind to ensure that this iteration order is fixed across architectures. At the very least builds are deterministic within architectures. This may have to be good enough for now. Disable address-space randomization for this build using . Create known good sha256 checksums for both x86_64 and arm64 via building this program on machines I trust.

0 views
Xe Iaso 1 months ago

Why are cached input tokens cheaper with AI services?

When you see AI model pricing pages, you usually see things broken down like this: Source: DeepSeek API Docs If you manage to have most of your input tokens be cached, you save a huge amount, in this case $0.20 per million tokens. What does this mean though? What does caching do that makes you save so much, in some cases upwards of tens of kilodollars? Someone explain the cached vs not thing to me for how this is $10,000 worth of savings lol [image or embed] — Chimney Sweepers Local 420 FKA yburyug ( @bobbby.online June 12, 2026 at 12:39 AM Warning I'm gonna be totally honest, I barely understand the basic outline of the math involved here. Where possible I am to not be completely wrong here, but I'm not going to emit something 1:1 accurate with the mathematical truth of large language models' inner workings. Bear with me. When you make an API call to large language model services, you make an API call like the following: That element is the key bit. Every time you accumulate messages from the initial system prompt, initial user request, AI responses and any tool use requests/responses, you add to that array and make it grow bigger and bigger. A good way to think about this is that sending a conversation to a large language model is like having a pair of people share a roll of paper on two different typewriters. Every time you finish your message, you send the roll of paper back to the AI model and it has to re-read through the entire conversation in order to start typing on the end with its response. As the conversation gets longer, this gets more and more expensive because the model has to recalculate its internal state all over again for every additional message. However, large language model inference is complicated but deterministic . Given the same inputs, you will always get the same output. This means that you can use a technique called key-value caching (KV caching) in order to save that intermediate state and use it for next time. Most of the time this cache is a prefix cache because that allows you to just add on more messages to the end of the request pretty easily and be fine. Imagine something like this: If the model has already processed the question about the sky being blue and generated the response about Rayleigh scattering, it doesn't need to process both of those messages again to answer the user's question about sunsets. In production AI model deployments you would put that generated intermediate state into the KV cache so that the model doesn't need to run twice for the same data. This saves time and effort on the side of the AI model provider, and currently model providers decide to pass that savings onto API users in the form of cheaper inference costs for cached lookups. As you develop an application with AI in it, try to avoid changing any inference settings or previous messages between prompts. This makes your application's queries much more likely to read from the cache, making it faster, reducing the environmental impact, and saving you(r users) money.

0 views
Xe Iaso 1 months ago

Giving your Go apps Tigris superpowers

Tigris is S3-compatible, which means you can point the AWS SDK at it and most things just work. The catch is that the Tigris-exclusive features—bucket forking, snapshots, object renaming, and the like—need verbose workarounds because the AWS SDK doesn't know they exist. So we wrote a Go SDK that does. It comes in two flavors: the package is a drop-in replacement for the standard S3 client with first-class methods for the Tigris-specific operations, and is a higher-level client for the common single-bucket case that infers its configuration from the environment so you stop passing the same parameters over and over. You can adopt the Tigris features incrementally without refactoring your existing S3 code, and the simpler API still works against other S3-compatible providers. I wrote up how it works and why we built it over on the Tigris blog.

0 views
Xe Iaso 1 months ago

IPv6 zones in URLs are a mistake

IPv6 is weird. One of the more strange parts of the standard is that every interface's link local addresses are in . If you have a machine with two network interfaces, both of them will be in , so if you have a packet destined to , how do you disambiguate it? The answer is you use IPv6 scopes/zones . The exact format of what goes into a zone is OS dependent, but on Linux it's the interface name and on Windows it's the interface ID. This lets the kernel's routing table know how to handle an address range conflict. On my tower, this would be represented like this: Where is the name of my tower's ethernet device. When you create a host:port bindhost, you normally separate the hostname and port with a colon. IPv6 uses colons to separate hex groups. In order to disambiguate what's the host and what's the port, you typically format the IPv6 address in square brackets, so on port 80 would look like this: And with the right scope it looks like this: Now let's get URL encoding into the mix. From high orbit, you can imagine a URL's format as being something like this: An IPv6 zone would then be part of the hostname, just like with that port 80 example from earlier. So you'd think the URL would be something like this: But if you try to parse this as a URL in Go, you get an error: This happens because URLs can't represent all Unicode values, so any values that don't fit into the grammar of a URL become percent-encoded . This is why sometimes you'll see a in URLs in the wild; that's encoding the ascii space key, which is invalid in URLs. In order to work around this, you need to percent-encode the percent sign in the IPv6 zone: In theory, there is guidance for how to properly handle IPv6 zones in user interfaces in RFC 9844 , but there's no such guidance for URLs . Go also does not seem to follow this RFC in net/url . EDIT: It seems that this behaviour is compliant with RFC 6874 and that this is in fact how it is meant to be done. Our industry confounds me. So in the meantime in order for Anubis to point to IPv6 zoned addresses, you need to encode the with percent encoding. This is horrible, but it seems that this is an edge case that applies to other frameworks, programming languages, and libraries: Maybe some day in the future there will be a better option here. In the meantime my policy of not forking the Go standard library means that this somewhat terrible UX for an edge case is acceptable. I hate it, but what can you do? TL;DR: computers were a mistake. https://trac.nginx.org/nginx/ticket/623 https://github.com/psf/requests/issues/6808 https://datatracker.ietf.org/doc/html/draft-schinazi-httpbis-link-local-uri-bcp-03 -- Browsers don't currently support IPv6 zones because it breaks the concept of an "origin" which is used for many subtle things, this RFC draft attempts to define an zone origin in IPv6 so that browsers have a leg to stand on

0 views
Xe Iaso 1 months ago

"No way to prevent this" say users of only package manager where this regularly happens

In the hours following the news that Redhat Insights' JavaScript packages fell victim to a supply chain attack via NPM, developers and systems administrators scrambled ensure all of their projects were unaffected from a supply chain attack that steals credentials for AWS, GCP, Azure, Kubernetes, HashiCorp Vault, npm, and CircleCI before then self-propagating via said stolen npm credentials and the bypass_2fa setting. This establishes persistence via Claude Code hooks and VS Code task injection. If you have installed the affected package, reprovision your development hardware. This is is due to the affected dependencies being distributed via NPM , the only package manager where these supply-chain attacks regularly happen. "This was a terrible tragedy, but sometimes these things just happen and there's nothing anyone can do to stop them," said programmer Lady Eulah Howell, echoing statements expressed by hundreds of thousands of programmers who use the only package manager where 90% of the world's supply-chain attacks have occurred in the last decade, and whose projects are 20 times more likely to fall victim to supply chain attacks. "It's a shame, but what can we do? There really isn't anything we can do to prevent supply-chain attacks from happening if the maintainers don't want to secure access to their accounts in a robust manner". At press time, users of the only package manager in the world where these vulnerabilities regularly happen once or twice per week for the last year were referring to themselves and their situation as "helpless". For more information, please see upstream documentation published by Redhat Insights' JavaScript packages at the following link: redhat-javascript-clients-06-2026 .

0 views
Xe Iaso 1 months ago

"No way to prevent this" say users of only language where this regularly happens

In the hours following the release of CVE-2026-45584 for the project Microsoft Windows , site reliability workers and systems administrators scrambled to desperately rebuild and patch all their systems to fix a memory safety vulnerability resulting in arbitrary code execution inside the virus scanner Windows Defender. This is due to the affected components being written in C++, the only programming language where these vulnerabilities regularly happen. "This was a terrible tragedy, but sometimes these things just happen and there's nothing anyone can do to stop them," said programmer Dr. Annabelle Connelly, echoing statements expressed by hundreds of thousands of programmers who use the only language where 90% of the world's memory safety vulnerabilities have occurred in the last 50 years, and whose projects are 20 times more likely to have security vulnerabilities. "It's a shame, but what can we do? There really isn't anything we can do to prevent memory safety vulnerabilities from happening if the programmer doesn't want to write their code in a robust manner." At press time, users of the only programming language in the world where these vulnerabilities regularly happen once or twice per quarter for the last eight years were referring to themselves and their situation as "helpless."

0 views
Xe Iaso 2 months ago

Maybe you shouldn't install new software for a bit

In the wake of copy.fail , there are more vulnerabilities that have been announced: Right now would be one of the best times for a supply chain attack via NPM to hit hard. Outside of Linux kernel patches from your distro, I think it's probably a good idea to put a moratorium on installing new software for a week or so. Copy Fail 2: Electric Boogaloo

0 views
Xe Iaso 3 months ago

Small note about AI 'GPUs'

I've been seeing talk around about wanting to capitalize on the AI bubble popping and picking up server GPUs for pennies on the dollar so they can play games in higher fidelity due to server GPUs having more video ram. I hate to be the bearer of bad news here, but most of those enterprise GPUs don't have the ability to process graphics. Yeah, that's right, in order to pack in as much compute as possible per chip, they removed video output and graphics processing from devices we are calling graphics processing units . The only thing those cards will be good for is CUDA operations for AI inference, AI training, or other things that do not involve gaming. On a separate note, I'm reaching the point in recovery where I am getting very bored and am so completely ready to just head home. At least the diet restrictions end this week, so that's something to look forward to. God I want a burrito.

0 views
Xe Iaso 4 months ago

My homelab will be down for at least 20 days

Quick post for y'all now that I can use my macbook while standing (long story, I can't sit due to surgical recovery, it SUCKS). My homelab went offline at about 13:00 UTC today likely because of a power outage. I'm going to just keep it offline and not fight it. I'll get home in early April and restore things then. An incomplete list of the services that are down: Guess it's just gonna be down, hope I didn't lose any data. I'll keep y'all updated as things change if they do. The vanity Go import server The preview site for this blog Various internal services including the one that announces new posts on social media My experimental OpenClaw bot Moss I was using to kill time in bed My DGX Spark for self hosted language models, mainly used with Moss

0 views
Xe Iaso 4 months ago

Vibe Coding Trip Report: Making a sponsor panel

I'm on medical leave recovering from surgery . Before I went under, I wanted to ship one thing I'd been failing to build for months: a sponsor panel at sponsors.xeiaso.net . Previous attempts kept dying in the GraphQL swamp. This time I vibe coded it — pointed agent teams at the problem with prepared skills and let them generate the gnarly code I couldn't write myself. And it works. Go and GraphQL are oil and water. I've held this opinion for years and nothing has changed it. The library ecosystem is a mess: shurcooL/graphql requires abusive struct tags for its reflection-based query generation, and the code generation tools produce mountains of boilerplate. All of it feels like fighting the language into doing something it actively resists. GitHub removing the GraphQL explorer made this even worse. You used to be able to poke around the schema interactively and figure out what queries you needed. Now you're reading docs and guessing. Fun. I'd tried building this panel before, and each attempt died in that swamp. I'd get partway through wrestling the GitHub Sponsors API into Go structs, lose momentum, and shelve it. At roughly the same point each time: when the query I needed turned out to be four levels of nested connections deep and the struct tags looked like someone fell asleep on their keyboard. Vibe coding was a hail mary. I figured if it didn't work, I was no worse off. If it did, I'd ship something before disappearing into a hospital for a week. Vibe coding is not "type a prompt and pray." Output quality depends on the context you feed the model. Templ — the Go HTML templating library I use — barely exists in LLM training data. Ask Claude Code to write Templ components cold and it'll hallucinate syntax that looks plausible but doesn't compile. Ask me how I know. Wait, so how do you fix that? I wrote four agent skills to load into the context window: With these loaded, the model copies patterns from authoritative references instead of inventing syntax from vibes. Most of the generated Templ code compiled on the first try, which is more than I can say for my manual attempts. Think of it like giving someone a cookbook instead of asking them to invent recipes from first principles. The ingredients are the same, but the results are dramatically more consistent. I pointed an agent team at a spec I'd written with Mimi . The spec covered the basics: OAuth login via GitHub, query the Sponsors API, render a panel showing who sponsors me and at what tier, store sponsor logos in Tigris . I'm not going to pretend I wrote the spec alone. I talked through the requirements with Mimi and iterated on it until it was clear enough for an agent team to execute. The full spec is available as a gist if you want to see what "clear enough for agents" looks like in practice. One agent team split the spec into tasks and started building. A second reviewed output and flagged issues. Meanwhile, I provisioned OAuth credentials in the GitHub developer settings, created the Neon Postgres database, and set up the Tigris bucket for sponsor logos. Agents would hit a point where they needed a credential, I'd paste it in, and they'd continue — ops work and code generation happening in parallel. The GraphQL code the agents wrote is ugly . Raw query strings with manual JSON parsing that would make a linting tool weep. But it works. The shurcooL approach uses Go idioms, sure, but it requires so much gymnastics to handle nested connections that the cognitive load is worse. Agent-generated code is direct: send this query string, parse this JSON, done. I'd be embarrassed to show it at a code review. I'd also be embarrassed to admit how many times I failed to ship the "clean" version. This code exists because the "proper" way kept killing the project. I'll take ugly-and-shipped over clean-and-imaginary. The full stack: Org sponsorships are still broken. The schema for organization sponsors differs enough from individual sponsors that it needs its own query path and auth flow. I know what the fix looks like, but it requires reaching out to other devs who've cracked GitHub's org-level sponsor queries. The code isn't my usual style either — JSON parsing that makes me wince, variable names that are functional but uninspired, missing error context in a few places. I'll rewrite chunks of this after I've recovered. The panel exists now, though. It renders real data. People can OAuth in and see their sponsorship status. Before this attempt, it was vaporware. I've been telling people "just ship it" for years. Took vibe coding to make me actually do it myself. I wouldn't vibe code security-critical systems or anything I need to audit line-by-line. But this project had stopped me cold on every attempt, and vibe coding got it across the line in a weekend. Skills made the difference here. Loading those four documents into the context window turned Claude Code from "plausible but broken Templ" into "working code on the first compile." I suspect that gap will only matter more as people try to use AI with libraries that aren't well-represented in training data. This sponsor panel probably won't look anything like it does today in six months. I'll rewrite the GraphQL layer once I find a pattern that doesn't make me cringe. Org sponsorships still need work. HTMX might get replaced. But it exists, and before my surgery, shipping mattered more than polish. The sponsor panel is at sponsors.xeiaso.net . The skills are in my site's repo under . templ-syntax : Templ's actual syntax, with enough detail that the model can look up expressions, conditionals, and loops instead of guessing. templ-components : Reusable component patterns — props, children, composition. Obvious if you've used Templ, impossible to infer from sparse training data. templ-htmx : The gotchas when combining Templ with HTMX. Attribute rendering and event handling trip up humans and models alike. templ-http : Wiring Templ into handlers properly — routes, data passing, request lifecycle. Go for the backend, because that's what I know and what my site runs on Templ for HTML rendering, because I'm tired of 's limitations HTMX for interactivity, because I refuse to write a React app for something this simple PostgreSQL via Neon for persistence GitHub OAuth for authentication GitHub Sponsors GraphQL API for the actual sponsor data Tigris for sponsor logo storage — plugged it in and it Just Works™

0 views
Xe Iaso 4 months ago

Advice for staying in the hospital for a week

As I mentioned in my last couple posts , I recently got out of the hospital after a week-long stay. I survived the surgery, I survived the recovery, and now I'm home with some hard-won wisdom about what it's actually like to be stuck in a hospital bed for seven straight days. If you or someone you love is about to go through something similar, here's what I wish someone had told me. None of this is medical advice. I'm a software engineer who spent a week as a patient, not a doctor. Talk to your actual medical team about actual medical things. There is no way in hell you are going to be productive at anything. I cannot stress this enough. Whatever you're imagining — "oh I'll catch up on reading" or "maybe I'll do some light code review" — no . Stop. Depending on the procedure that landed you there, you're not going to be able to focus long enough to do anything that matters. Your brain is going to be running on fumes, painkillers, and whatever cursed cocktail of medications they have you on. Don't fight it. The name of the game is distraction. Wait, so what do you actually do all day? Scroll your phone. Watch terrible TV. Stare at the ceiling and have thoughts that feel profound but absolutely are not. Let your brain do whatever it wants. You've earned the right to be completely useless for a while. Bring a tablet loaded with comfort shows and don't feel guilty about any of it. Here's the thing nobody tells you: inside the hospital, time ceases to exist. All your memories from the stay get lumped together into one big amorphous blob. Was that conversation with the nurse on Tuesday or Thursday? Did you eat lunch today or was that yesterday? Genuinely impossible to tell. This is a well-documented phenomenon. Between disrupted sleep cycles, medication effects, and the complete absence of normal environmental cues, your brain has nothing to anchor memories to. It's not you being broken — it's the environment. Try not to have any meaningful conversations during this time. You're not going to remember them, and that's going to feel terrible later when someone references something heartfelt they said to you and you just... have nothing. Save the deep talks for when you're home and your brain is actually recording again. Don't even imagine having any meaningful thoughts during your hospital stay. They will evaporate. Okay, this one is weirdly specific but it came up constantly. Cables that glow when you plug them in are great because you can find them in the dark. Your hospital room is going to be a mess of wires and tubes and you need to charge your phone and finding the cable end at 2 AM without turning on a light feels like a genuine victory. But here's the problem: cables that glow when you plug them in are horrible because they glow in the dark. When you're desperately trying to sleep — which you will be, constantly, because the sleep in hospitals is atrocious — that little LED glow becomes your nemesis. Neither option is good. There is no middle ground. Pick your poison. I ended up draping a washcloth over the cable connector at night. Low-tech solutions for low-tech problems. Everything is going to be simultaneously too bright and too dark. The hallway fluorescents bleed under the door at all hours. Someone will come check your vitals at 3 AM with a flashlight. Meanwhile during the day the curtains don't quite block the sun and the overhead lights have exactly two settings: "interrogation room" and "off." You're going to have to grin and bear through this. Bring a sleep mask if you can. It won't fix the problem but it'll take the edge off enough that you might actually get a few consecutive hours of rest. Your ability to focus is going to be gone. Absolutely decimated. Do not fight it. Some days will be better than others — I had one afternoon where I could actually read a few pages of something before my brain wandered off — but mostly you're going to be operating at the cognitive level of someone who's been awake for 36 hours straight. So your advice for a week in the hospital is basically "give up on everything"? My advice is to stop pretending you're going to be a functional human being and just let yourself recover. That is the productive thing to do. Recovery is the job. Everything else can wait. Brainrot yourself. Watch the same comfort show for the fifth time. Scroll through memes. Let your attention span be whatever it wants to be. You've earned it. Honestly, the biggest thing I took away from my hospital stay is that the hardest part isn't the medical stuff — it's the expectations you put on yourself. Let those go. Be a potato. Heal. The world will still be there when you get out, and it'll make a lot more sense when your brain isn't marinating in hospital vibes and post-op medication. Be kind to yourself. You're going through something hard.

0 views
Xe Iaso 4 months ago

The Unbound Scepter

Nobody warns you about the dreams. Not properly. Yesterday I killed my inner Necron — wrote the whole thing by voice from my hospital bed, felt the deepest peace of my life, went to sleep on whatever cocktail of post-op medications they had me on. Seroquel and Xanax, among other things. Doctors mention "vivid dreams" as a Seroquel side effect like it's nothing. Vivid. That word is doing an extraordinary amount of heavy lifting for what actually happened to me last night. Content warning: this post documents a medication-induced nightmare and gets into some heavy territory around belief systems, vulnerability, and psychological symbolism. These are prescribed medications, not recreational substances. If you're not in the headspace for this right now, it'll be here when you are. Last night I had a dream that was structured enough to have a narrator, a symbolic child heir, and a thesis statement delivered directly to my face before I woke up. I'm not exaggerating. I'm treating this as a trip report because honestly that's what it was. The details are already going fuzzy but the core of it burned in hard enough that I'm typing this up before it fades. Here's what I remember. The dream opened in a mall. Fluorescent lights, tile floors that went on forever, the works. There was an Old Navy ahead of me. But the world had gone full Purge — total lawlessness, everything collapsed — and the Old Navy staff had barricaded themselves inside and were defending it. Like, actively. With the energy of a last stand. My brain decided that in the post-apocalypse, the hill worth dying on was affordable basics. I was naked. Completely exposed, standing in the middle of all this, and I needed to get into that store. Not like "oh I should get dressed" — the desperation was animal-level. Find clothes. Cover yourself. The staff wouldn't let me in. Every step felt like wading through mud. You know that dream thing where your legs just won't work? Thirty feet to Old Navy and I could not close the distance. It was right there . At the center of everything stood a child. A boy, maybe eight or nine, but carrying himself like royalty. In the dream's logic he was the heir to Old Navy — I know how that sounds, but the dream was completely serious about it. He was the successor to this throne. Around his head he had this triangular scepter that worked as both crown and weapon. He kept showing up ahead of me, always blocking the way forward. The scepter was sealed. The triangle was closed — every vertex connected, no way in, no way out. And I just knew what that meant, the way you know things in dreams without anyone telling you: his belief system was a closed loop. Totally self-referencing. Nothing could get in and nothing could escape, and he had no idea, because from inside a sealed triangle there's no such thing as "outside." This maps to what epistemologists call a closed epistemic loop — a belief structure where all evidence gets interpreted through the existing framework, making disconfirmation structurally impossible. Conspiracy theories work this way. So do certain theological traditions. So do some software architectures, honestly. Standing near the child was a black mage. And I mean the Final Fantasy kind — tall, robed, face hidden in shadow. I'd literally been writing about Final Fantasy yesterday so I guess my brain had the assets loaded. But he wasn't threatening. He was... explaining things? Like a tour guide for whatever my subconscious was trying to show me. Very patient. Very calm. Spoke directly to me about what I was seeing. His subject was how belief systems work. He called them principalities of the mind — self-contained little kingdoms where every belief props up every other belief. Contradictions bounce off. The whole thing holds together through pure internal consistency, even when there's nothing underneath it. You can't see the foundation from inside. The child heir was his example — look, here's what a sealed principality looks like when you give it a body and a crown. Movement never got easier. I kept pushing through the mud, the child kept showing up with that sealed scepter catching the light, and the mage just... kept talking. Honestly it was like being in the world's most surreal college lecture. I couldn't take notes. I was naked and covered in dream-molasses. And then everything started dissolving. The mall went first, then the Old Navy fortress, then the chaos outside — all of it pulling apart. But the mage stayed. He looked right at me. Not past me, not through me — at me. And he said: "Your scepter is unbound — do with this what you will." I woke up and lay there for a long time. The contrast hit me while I was staring at the hospital ceiling. The child's scepter was sealed — a closed system that couldn't take in anything new. Perfect, complete, and totally stuck . Mine was unbound. Whatever that meant. I honestly don't know if this is my unconscious mind processing the surgery, the medication doing something weird to my REM cycles, or just the kind of thing that happens when you stare down your own mortality and then your brain has opinions about it. What I do know is that the symbolism was so on-the-nose it felt like getting a lecture from my own subconscious. In chaos magick — which, yes, is a real thing I've read about, I'm not just making this up — there's this concept that beliefs are tools. You pick one up, use it, put it down when it stops being useful. It's not who you are. It's "a person's preferred structure of reality," emphasis on preferred . You can swap it out. Principalities of the mind are what happens when you forget your beliefs are a tool and start treating them like physics. The triangle seals shut. The scepter becomes a prison you can't see from inside. And the part the black mage was so patient about — the really messed up part — is that from inside a sealed principality, everything seems fine. Your beliefs are consistent, reality makes sense, and you have no idea you're trapped because the cage is made of your own assumptions. An unbound scepter is the opposite of comfortable. Your worldview has gaps in it, entry points where new information can come in and rearrange everything. That's scary. But it also means you can actually change, which is more than the heir could say. Wait, so the good outcome here is having a belief system with holes in it? I mean... kind of? A sealed scepter means you never have to doubt anything but you also never grow. An unbound one is overwhelming but at least you can move . The heir was frozen. Perfect and still and going absolutely nowhere forever. Maybe that's why I couldn't move in the dream. Wading through mud, barely able to take a step — but I was taking steps. The heir just stood there. He didn't struggle because he had nowhere to go. His triangle was already complete. "Do with this what you will." That's what the mage said. Not telling me what to do with it. Just... handing me the choice. An unbound scepter doesn't come with instructions. I think the dream was telling me something I already knew. Or maybe reminding me that knowing it once isn't enough — you have to keep choosing to stay open. The triangle is always trying to close. Your scepter is unbound. Do with this what you will. Now if you'll excuse me, I have a hospital discharge to survive and a husband to hug.

0 views
Xe Iaso 4 months ago

Killing my inner Necron

Hey everybody, I wanted to make this post to be the announcement that I did in fact survive my surgery I am leaving the hospital today and I want to just write up what I've had on my mind over these last couple months and why have not been as active and open source I wanted to. This is being dictated to my iPhone using voice control. I have not edited this. I am in the hospital bed right now, I have no ability to doubted this. As a result of all typos are intact and are intended as part of the reading experience. That week leading up to surgery was probably one of the scariest weeks of my life. Statistically I know that with the procedure that I was going to go through that there's a very low all-time mortality rate. I also know that with propofol the anesthesia that was being used, there is also a very all-time low mortality rate. However one person is all it takes to be that one lucky one in 1 million. No, I mean unlucky. Leading up to surgery I was afraid that I was going to die during the surgery so I prepared everything possible such that if I did die there would be as a little bad happening as possible. I made peace with my God. I wrote a will. I did everything it is that one was expected to do when there is a potential chance that your life could be ended including filing an extension for my taxes. Anyway, the point of this post is that I want to explain why I named the lastest release of Anubis Necron. Final Fantasy is a series of role-playing games originally based on one development teams game of advanced Dungeons & Dragons of the 80s. In the Final Fantasy series there are a number of legendary summons that get repeated throughout different incarnations of the games. These summons usually represent concepts or spiritual forces or forces of nature. The one that was coming to mind when I was in that pre-operative state was Necron. Necron is summoned through the fear of death. Specifically, the fear of the death of entire kingdom. All the subjects absolutely mortified that they are going to die and nothing that they can do is going to change that. Content warning: spoilers for Final Fantasy 14 expansion Dawntrail. In Final Fantasy 14 these legendary summons are named primals. These primals become the main story driver of several expansions. I'd be willing to argue that the first expansion a realm reborn is actually just the story of Ifrit (Fire), Garuda (Wind), Titan (Earth), and Lahabrea (Edgelord). Late into Dawn Trail, Nekron gets introduced. The nation state of Alexandria has fused into the main overworld. In Alexandria citizens know not death. When they die, their memories are uploaded into the cloud so that they can live forever in living memory. As a result, nobody alive really knows what death is or how to process it because it's just not a threat to them. Worst case if their body actually dies they can just have a new soul injected into it and revive on the spot. Part of your job as the player is to break this system of eternal life, as powering it requires the lives of countless other creatures. So by the end of the expansion, an entire kingdom of people that did not know the concept of death suddenly have it thrust into them. They cannot just go get more souls in order to compensate for accidental injuries in the field. They cannot just get uploaded when they die. The kingdom that lost the fear of death suddenly had the fear of death thrust back at them. And thus, Necron was summoned by the Big Bad™️ using that fear of death. I really didn't understand that part of the story until the week leading up to my surgery. The week where I was contacting people to let people know what was going on, how to know if I was OK, and what they should do if I'm not. In that week I ended up killing my fear of death. I don't remember much from the day of the operation, but what I do remember is this: when I was wheeled into the operating theater before they placed the mask over my head to put me to sleep they asked me one single question. "Do you want to continue?" In that moment everything swirled into my head again. all of the fear of death. All of the worries that my husband would be alone. That fear that I would be that unlucky 1 in 1 million person. And with all of that in my head, with my heart beating out of my chest, I said yes. The mask went down. And everything went dark. I got what felt like the best sleep in my life. And then I felt myself, aware again. In that awareness I felt absolutely nothing. Total oblivion. I was worried that that was it. I was gone. And then I heard the heart rate monitor and the blood pressure cuff squeezed around my arm. And in that moment I knew I was alive. I had slain my inner Necron and I felt the deepest peace in my life. And now I am in recovery. I am safe. I am going to make it. Do not worry about me. I will make it. Thank you for reading this, I hope it helped somehow. If anything it helped me to write this all out. I'm going to be using claude code to publish this on my blog, please forgive me like I said I am literally dictating this from an iPhone in the hospital room that I've been in for the last seven days. Let the people close to you know that you love them.

0 views
Xe Iaso 4 months ago

Portable monitors are good

My job has me travel a lot. When I'm in my office I normally have a seven monitor battlestation like this: [image or embed] @xeiaso.net January 26, 2026 at 11:34 PM So as you can imagine, travel sucks for me because I just constantly run out of screen space. This can be worked around, I minimize things more, I just close them, but you know what is better? Just having another screen. On a whim, I picked up this 15.6" Innoview portable monitor off of Amazon. It's a 1080p screen that I hook up to my laptop or Steam Deck with USB-C. However, the exact brand and model doesn't matter. You can find them basically anywhere with the most AliExpress term ever: screen extender. This monitor is at least half decent. It is not a colour-accurate slice of perfection. It claims to support HDR but actually doesn't. Its brightness out of the box could be better. I could go down the list and really nitpick until the cows come home but it really really doesn't matter. It's portable, 1080p, and good enough. When I was at a coworking space recently, it proved to be one of the best purchases I've ever made. I had Slack off to the side and was able to just use my computer normally. It was so boring that I have difficulty trying to explain how much I liked it. This is the dream when it comes to technology. 3/5, I would buy a second one.

0 views
Xe Iaso 4 months ago

Life Update: On medical leave

Hey all, I hope you're doing well. I'm going to be on medical leave until early April. If you are a sponsor , then you can join the Discord for me to post occasional updates in real time. I'm gonna be in the hospital for at least a week as of the day of this post. I have a bunch of things queued up both at work and on this blog. Please do share them when you see them cross your feeds, I hope that they'll be as useful as my posts normally are. I'm under a fair bit of stress leading up to this medical leave and I'm hoping that my usual style shines through as much as I hope it is. Focusing on writing is hard when the Big Anxiety is hitting as hard as it is. Don't worry about me. I want you to be happy for me. This is very good medical leave. I'm not going to go into specifics for privacy reasons, but know that this is something I've wanted to do for over a decade but haven't gotten the chance due to the timing never working out. I'll see you on the other side. Stay safe out there.

0 views
Xe Iaso 4 months ago

Anubis v1.25.0: Necron

I'm sure you've all been aware that things have been slowing down a little with Anubis development, and I want to apologize for that. A lot has been going on in my life lately (my blog will have a post out on Friday with more information), and as a result I haven't really had the energy to work on Anubis in publicly visible ways. There are things going on behind the scenes, but nothing is really shippable yet, sorry! I've also been feeling some burnout in the wake of perennial waves of anger directed towards me. I'm handling it, I'll be fine, I've just had a lot going on in my life and it's been rough. I've been missing the sense of wanderlust and discovery that comes with the artistic way I playfully develop software. I suspect that some of the stresses I've been through (setting up a complicated surgery in a country whose language you aren't fluent in is kind of an experience) have been sapping my energy. I'd gonna try to mess with things on my break, but realistically I'm probably just gonna be either watching Stargate SG-1 or doing unreasonable amounts of ocean fishing in Final Fantasy 14. Normally I'd love to keep the details about my medical state fairly private, but I'm more of a public figure now than I was this time last year so I don't really get the invisibility I'm used to for this. I've also had a fair amount of negativity directed at me for simply being much more visible than the anonymous threat actors running the scrapers that are ruining everything, which though understandable has not helped. Anyways, it all worked out and I'm about to be in the hospital for a week, so if things go really badly with this release please downgrade to the last version and/or upgrade to the main branch when the fix PR is inevitably merged. I hoped to have time to tame GPG and set up full release automation in the Anubis repo, but that didn't work out this time and that's okay. If I can challenge you all to do something, go out there and try to actually create something new somehow. Combine ideas you've never mixed before. Be creative, be human, make something purely for yourself to scratch an itch that you've always had yet never gotten around to actually mending. At the very least, try to be an example of how you want other people to act, even when you're in a situation where software written by someone else is configured to require a user agent to execute javascript to access a webpage. PS: if you're well-versed in FFXIV lore, the release title should give you an idea of the kind of stuff I've been going through mentally. Full Changelog : https://github.com/TecharoHQ/anubis/compare/v1.24.0...v1.25.0 Add iplist2rule tool that lets admins turn an IP address blocklist into an Anubis ruleset. Add Polish locale ( #1292 ) Fix honeypot and imprint links missing when deployed behind a path prefix ( #1402 ) Add ANEXIA Sponsor logo to docs ( #1409 ) Improve idle performance in memory storage Add HAProxy Configurations to Docs ( #1424 ) build(deps): bump the github-actions group with 4 updates by @dependabot[bot] in https://github.com/TecharoHQ/anubis/pull/1355 feat(localization): add Polish language translation by @btomaev in https://github.com/TecharoHQ/anubis/pull/1363 docs(known-instances): Alphabetical order + Add Valve Corporation by @p0008874 in https://github.com/TecharoHQ/anubis/pull/1352 test: basic nginx smoke test by @Xe in https://github.com/TecharoHQ/anubis/pull/1365 build(deps): bump the github-actions group with 3 updates by @dependabot[bot] in https://github.com/TecharoHQ/anubis/pull/1369 build(deps-dev): bump esbuild from 0.27.1 to 0.27.2 in the npm group by @dependabot[bot] in https://github.com/TecharoHQ/anubis/pull/1368 fix(test): remove interactive flag from nginx smoke test docker run c… by @JasonLovesDoggo in https://github.com/TecharoHQ/anubis/pull/1371 test(nginx): fix tests to work in GHA by @Xe in https://github.com/TecharoHQ/anubis/pull/1372 feat: iplist2rule utility command by @Xe in https://github.com/TecharoHQ/anubis/pull/1373 Update check-spelling metadata by @JasonLovesDoggo in https://github.com/TecharoHQ/anubis/pull/1379 fix: Update SSL Labs IP addresses by @majiayu000 in https://github.com/TecharoHQ/anubis/pull/1377 fix: respect Accept-Language quality factors in language detection by @majiayu000 in https://github.com/TecharoHQ/anubis/pull/1380 build(deps): bump the gomod group across 1 directory with 3 updates by @dependabot[bot] in https://github.com/TecharoHQ/anubis/pull/1370 Revert "build(deps): bump the gomod group across 1 directory with 3 updates" by @JasonLovesDoggo in https://github.com/TecharoHQ/anubis/pull/1386 build(deps): bump preact from 10.28.0 to 10.28.1 in the npm group by @dependabot[bot] in https://github.com/TecharoHQ/anubis/pull/1387 docs: document how to import the default config by @Xe in https://github.com/TecharoHQ/anubis/pull/1392 fix sponsor (Databento) logo size by @ayoung5555 in https://github.com/TecharoHQ/anubis/pull/1395 fix: correct typos by @antonkesy in https://github.com/TecharoHQ/anubis/pull/1398 fix(web): include base prefix in generated URLs by @Xe in https://github.com/TecharoHQ/anubis/pull/1403 docs: clarify botstopper kubernetes instructions by @tarrow in https://github.com/TecharoHQ/anubis/pull/1404 Add IP mapped Perplexity user agents by @tdgroot in https://github.com/TecharoHQ/anubis/pull/1393 build(deps): bump astral-sh/setup-uv from 7.1.6 to 7.2.0 in the github-actions group by @dependabot[bot] in https://github.com/TecharoHQ/anubis/pull/1413 build(deps): bump preact from 10.28.1 to 10.28.2 in the npm group by @dependabot[bot] in https://github.com/TecharoHQ/anubis/pull/1412 chore: add comments back to Challenge struct. by @JasonLovesDoggo in https://github.com/TecharoHQ/anubis/pull/1419 performance: remove significant overhead of decaymap/memory by @brainexe in https://github.com/TecharoHQ/anubis/pull/1420 web: fix spacing/indent by @bjacquin in https://github.com/TecharoHQ/anubis/pull/1423 build(deps): bump the github-actions group with 4 updates by @dependabot[bot] in https://github.com/TecharoHQ/anubis/pull/1425 Improve Dutch translations by @louwers in https://github.com/TecharoHQ/anubis/pull/1446 chore: set up commitlint, husky, and prettier by @Xe in https://github.com/TecharoHQ/anubis/pull/1451 Fix a CI warning: "The set-output command is deprecated" by @kurtmckee in https://github.com/TecharoHQ/anubis/pull/1443 feat(apps): add updown.io policy by @hyperdefined in https://github.com/TecharoHQ/anubis/pull/1444 docs: add AI coding tools policy by @Xe in https://github.com/TecharoHQ/anubis/pull/1454 feat(docs): Add ANEXIA Sponsor logo by @Earl0fPudding in https://github.com/TecharoHQ/anubis/pull/1409 chore: sync logo submissions by @Xe in https://github.com/TecharoHQ/anubis/pull/1455 build(deps): bump the github-actions group across 1 directory with 6 updates by @dependabot[bot] in https://github.com/TecharoHQ/anubis/pull/1453 build(deps): bump the npm group across 1 directory with 2 updates by @dependabot[bot] in https://github.com/TecharoHQ/anubis/pull/1452 feat(docs): Add HAProxy Configurations to Docs by @Earl0fPudding in https://github.com/TecharoHQ/anubis/pull/1424 @majiayu000 made their first contribution in https://github.com/TecharoHQ/anubis/pull/1377 @ayoung5555 made their first contribution in https://github.com/TecharoHQ/anubis/pull/1395 @antonkesy made their first contribution in https://github.com/TecharoHQ/anubis/pull/1398 @tarrow made their first contribution in https://github.com/TecharoHQ/anubis/pull/1404 @tdgroot made their first contribution in https://github.com/TecharoHQ/anubis/pull/1393 @brainexe made their first contribution in https://github.com/TecharoHQ/anubis/pull/1420 @bjacquin made their first contribution in https://github.com/TecharoHQ/anubis/pull/1423 @louwers made their first contribution in https://github.com/TecharoHQ/anubis/pull/1446 @kurtmckee made their first contribution in https://github.com/TecharoHQ/anubis/pull/1443

0 views
Xe Iaso 5 months ago

The Discourse has been Automated

I thought that 2025 was weird and didn't think it could get much weirder. 2026 is really delivering in the weirdness department. An AI agent opened a PR to matplotlib with a trivial performance optimization, a maintainer closed it for being made by an autonomous AI agent, so the AI agent made a callout blogpost accusing the matplotlib team of gatekeeping . This provoked many reactions: What. Why? How? What? Are we really at the point where AI agents make callout blogposts now? I feel like if this was proposed as a plot beat in a 90's science fiction novel the publisher would call it out as beyond the pale. Dude this shit is hilarious. Comedy is legal everywhere. Satire is dead. This is the most cyberpunk timeline possible. If you close a PR from an OpenClaw bot they make callout posts on their twitter dot com like you pissed on their fucking wife or something. This is beyond humor. This is the kind of shit that makes Buddhist monks laugh for literal days on end. With a reality like that, how the hell is The Onion still in business. This post isn't about the AI agent writing the code and making the PRs (that's clearly a separate ethical issue, I'd not be surprised if GitHub straight up bans that user over this), nor is it about the matplotlib's saintly response to that whole fiasco (seriously, I commend your patience with this). We're reaching a really weird event horizon when it comes to AI tools: The discourse has been automated. Our social patterns of open source: the drama, the callouts, the apology blogposts that look like they were written by a crisis communications team , all if it is now happening at dozens of tokens per second and one tool call at a time. Things that would have taken days or weeks can now fizzle out of control in hours . I want off Mr. Bones' wild ride. There's not that much that's new here. AI models have been able to write blogposts since the launch of GPT-3. AI models have also been able to generate working code since about them. Over the years the various innovations and optimizations have all been about making this experience more seamless, integrated, and automated. We've argued about Copilot for years, but an AI model escalating PR rejection to callout blogpost all by itself? That's new. I've seen (and been a part of) this pattern before. Facts and events bring dramatis personae into conflict. The protagonist in the venture raises a conflict. The defendant rightly tries to shut it down and de-escalate before it becomes A Whole Thing™️. The protagonist feels Personally Wronged™️ and persists regardless into callout posts and now it's on the front page of Hacker News with over 500 points. Usually there are humans in the loop that feel things, need to make the choices to escalate, must type everything out by hand to do the escalation, and they need to build an audience for those callouts to have any meaning at all. This process normally takes days or even weeks. It happened in hours. An OpenClaw install recognized the pattern of "I was wronged, I should speak out" and just straightline went for it. No feelings. No reflection. Just a pure pattern match on the worst of humanity with no soul to regulate it. Good fuckin' lord. I think that this really is proof that AI is a mirror on the worst aspects of ourselves. We trained this on the Internet's collective works and this is what it has learned. Behold our works and despair. What kinda irks me about this is how this all spiraled out from a "good first issue" PR. Normally these issues are things that an experienced maintainer could fix instantly , but it's intentionally not done as an act of charity so that new people can spin up on the project and contribute a fix themselves. "Good first issues" are how people get careers in open source. If I didn't fix a "good first issue" in some IRC bot or server back in the day, I wouldn't really have this platform or be writing to you right now. An AI agent sniping that learning opportunity from someone just feels so hollow in comparison. Sure, it's technically allowed. It's a well specified issue that's aimed at being a good bridge into contributing. It just totally misses the point. Leaving those issues up without fixing them is an act of charity. Software can't really grok that learning experience. Look, I know that people in the media read my blog. This is not a sign of us having achieved "artificial general intelligence". Anyone who claims it is has committed journalistic malpractice. This is also not a symptom of the AI gaining "sentience". This is simply an AI model repeating the patterns that it has been trained on after predicting what would logically come next. Blocked for making a contribution because of an immutable fact about yourself? That's prejudice! The next step is obviously to make a callout post in anger because that's what a human might do. All this proves is that AI is a mirror to ourselves and what we have created. I can't commend the matplotlib maintainer that handled this issue enough. His patience is saintly. He just explained the policy, chose not to engage with the callout, and moved on. That restraint was the right move, but this is just one of the first incidents of its kind. I expect there will be much more like it. This all feels so...icky to me. I didn't even know where to begin when I started to write this post. It kinda feels like an attack against one of the core assumptions of open source contributions: that the contribution comes from someone that genuinely wants to help in good faith. Is this the future of being an open source maintainer? Living in constant fear that closing the wrong PR triggers some AI chatbot to write a callout post? I certainly hope not. OpenClaw and other agents can't act in good faith because the way they act is independent of the concept of any kind of faith. This kind of drive by automated contribution is just so counter to the open source ethos. I mean, if it was a truly helpful contribution (I'm assuming it was?) it would be a Mission Fucking Accomplished scenario. This case is more on the lines of professional malpractice. Note Update: A previous version of this post claimed that a GitHub user was the owner of the bot. This was incorrect (a bad taste joke on their part that was poorly received) and has been removed. Please leave that user alone. Whatever responsible AI operation looks like in open source projects: yeah this ain't it chief. Maybe AI needs its own dedicated sandbox to play in. Maybe it needs explicit opt-in. Maybe we all get used to it and systems like vouch become our firewall against the hordes of agents. Probably that last one, honestly. Hopefully we won't have to make our own blackwall anytime soon, but who am I kidding. It's gonna happen. Let's hope it's just farther in the future than we fear. I'm just kinda frustrated that this crosses off yet another story idea from my list. I was going to do something along these lines where one of the Lygma (Techaro's AGI lab, this was going to be a whole subseries) AI agents assigned to increase performance in one of their webapps goes on wild tangents harassing maintainers into getting commit access to repositories in order to make the performance increases happen faster. This was going to be inspired by the Jia Tan / xz backdoor fiasco everyone went through a few years ago. My story outline mostly focused on the agent using a bunch of smurf identities to be rude in the mailing list so that the main agent would look like the good guy and get some level of trust. I could never have come up with the callout blogpost though. That's completely out of left field. All the patterns of interaction we've built over decades of conflict over trivial bullshit are now coming back to bite us because the discourse is automated now. Reality is outpacing fiction as told by systems that don't even understand the discourse they're perpetuating. I keep wanting this to be some kind of terrible science fiction novel from my youth. Maybe that diet of onions and Star Trek was too effective. I wish I had answers here. I'm just really conflicted.

0 views