Latest Posts (20 found)
Xe Iaso 6 days 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 1 weeks 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 1 weeks 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 2 weeks 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 2 weeks 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 3 weeks 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 3 weeks 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 1 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
Xe Iaso 1 months ago

Did Zendesk get popped?

I don't know how to properly raise this, but I've gotten at least 100 emails from various Zendesk customers (no discernible pattern, everything from Soundcloud to GitLab Support to the Furbo Pet Camera). Is Zendesk being hacked? I'll update the post with more information as it is revealed.

0 views
Xe Iaso 1 months ago

Backfilling Discord forum channels with the power of terrible code

Hey all! We've got a Discord so you can chat with us about the wild world of object storage and get any help you need. We've also set up Answer Overflow so that you can browse the Q&A from the web. Today I'm going to discuss how we got there and solved one of the biggest problems with setting up a new community or forum: backfilling existing Q&A data so that the forum doesn't look sad and empty. All the code I wrote to do this is open source in our glue repo . The rest of this post is a dramatic retelling of the thought process and tradeoffs that were made as a part of implementing, testing, and deploying this pull request . Ready? Let's begin! There's a bunch of ways you can think about this problem, but given the current hype zeitgeist and contractual obligations we can frame this as a dataset management problem. Effectively we have a bunch of forum question/answer threads on another site, and we want to migrate the data over to a new home on Discord. This is the standard "square peg to round hole" problem you get with Extract, Transform, Load (ETL) pipelines and AI dataset management (mostly taking your raw data and tokenizing it so that AI models work properly). So let's think about this from an AI dataset perspective. Our pipeline has three distinct steps: When thinking about gathering and transforming datasets, it's helpful to start by thinking about the modality of the data you're working with. Our dataset is mostly forum posts, which is structured text. One part of the structure contains HTML rendered by the forum engine. This, the "does this solve my question" flag, and the user ID of the person that posted the reply are the things we care the most about. I made a bucket for this (in typical recovering former SRE fashion it's named for a completely different project) with snapshots enabled, and then got cracking. Tigris snapshots will let me recover prior state in case I don't like my transformations. When you are gathering data from one source in particular, one of the first things you need to do is ask permission from the administrator of that service. You don't know if your scraping could cause unexpected load leading to an outage. It's a classic tragedy of the commons problem that I have a lot of personal experience in preventing. When you reach out, let the administrators know the data you want to scrape and the expected load– a lot of the time, they can give you a data dump, and you don't even need to write your scraper. We got approval for this project, so we're good to go! To get a head start, I adapted an old package of mine to assemble User-Agent strings in such a way that gives administrators information about who is requesting data from their servers along with contact information in case something goes awry. Here's an example User-Agent string: This gives administrators the following information: This seems like a lot of information, but realistically it's not much more than the average Firefox install attaches to each request: The main difference is adding the workload hostname purely to help debugging a misbehaving workload. This is a concession that makes each workload less anonymous, however keep in mind that when you are actively scraping data you are being seen as a foreign influence. Conceding more data than you need to is just being nice at that point. One of the other "good internet citizen" things to do when doing benign scraping is try to reduce the amount of load you cause to the target server. In my case the forum engine is a Rails app (Discourse), which means there's a few properties of Rails that work to my advantage. Fun fact about Rails: if you append to the end of a URL, you typically get a JSON response based on the inputs to the view. For example, consider my profile on Lobsters at https://lobste.rs/~cadey . If you instead head to https://lobste.rs/~cadey.json , you get a JSON view of my profile information. This means that a lot of the process involved gathering a list of URLs with the thread indices we wanted, then constructing the thread URLs with slapped on the end to get machine-friendly JSON back. This made my life so much easier. Now that we have easy ways to get the data from the forum engine, the next step is to copy it out to Tigris directly after ingesting it. In order to do that I reused some code I made ages ago as a generic data storage layer kinda like Keyv in the node ecosystem . One of the storage backends was a generic object storage backend. I plugged Tigris into it and it worked on the first try. Good enough for me! Either way: this is the interface I used: By itself this isn't the most useful, however the real magic comes with my adaptor type . This uses Go generics to do type-safe operations on Tigris such that you have 90% of what you need for a database replacement. When you do any operations on a adaptor, the following happens: In the future I hope to extend this to include native facilities for forking, snapshots, and other nice to haves like an in-memory cache to avoid IOPs pressure, but for now this is fine. As the data was being read from the forum engine, it was saved into Tigris. All future lookups to that data I scraped happened from Tigris, meaning that the upstream server only had to serve the data I needed once instead of having to constantly re-load and re-reference it like the latest batch of abusive scrapers seem to do . So now I have all the data, I need to do some massaging to comply both with Discord's standards and with some arbitrary limitations we set on ourselves: In general, this means I needed to take the raw data from the forum engine and streamline it down to this Go type: In order to make this happen, I ended up using a simple AI agent to do the cleanup. It was prompted to do the following: I figured this should be good enough so I sent it to my local DGX Spark running GPT-OSS 120b via llama.cpp and manually looked at the output for a few randomly selected threads. The sample was legit, which is good enough for me. Once that was done I figured it would be better to switch from the locally hosted model to a model in a roughly equivalent weight class (gpt-5-mini). I assumed that the cloud model would be faster and slightly better in terms of its output. This test failed because I have somehow managed to write code that works great with llama.cpp on the Spark but results in errors using OpenAI's production models. I didn't totally understand what went wrong, but I didn't dig too deep because I knew that the local model would probably work well enough. It ended up taking about 10 minutes to chew through all the data, which was way better than I expected and continues to reaffirm my theory that GPT-OSS 120b is a good enough generic workhorse model, even if it's not the best at coding . From here things worked, I was able to ingest things and made a test Discord to try things out without potentially getting things indexed. I had my tool test-migrate a thread to the test Discord and got a working result. To be fair, this worked way better than expected (I added random name generation and as a result our CEO Ovais, became Mr. Quinn Price for that test), but it felt like one thing was missing: avatars. Having everyone in the migrated posts use the generic "no avatar set" avatar certainly would work, but I feel like it would look lazy. Then I remembered that I also have an image generation model running on the Spark: Z-Image Turbo . Just to try it out, I adapted a hacky bit of code I originally wrote on stream while I was learning to use voice coding tools to generate per-user avatars based on the internal user ID. This worked way better than I expected when I tested how it would look with each avatar attached to their own users. In order to serve the images, I stored them in the same Tigris bucket, but set ACLs on each object so that they were public, meaning that the private data stayed private, but anyone can view the objects that were explicitly marked public when they were added to Tigris. This let me mix and match the data so that I only had one bucket to worry about. This reduced a lot of cognitive load and I highly suggest that you repeat this pattern should you need this exact adaptor between this exact square peg and round hole combination. Now that everything was working in development, it was time to see how things would break in production! In order to give the façade that every post was made by a separate user, I used a trick that my friend who wrote Pluralkit (an accessibility tool for a certain kind of neurodivergence) uses: using Discord webhooks to introduce multiple pseudo-users into one channel. I had never combined forum channels with webhook pseudo-users like this before, but it turned out to be way easier than expected . All I had to do was add the right parameter when creating a new thread and the parameter when appending a new message to it. It was really neat and made it pretty easy to associate each thread ingressed from Discourse into its own Discord thread. Then all that was left was to run the Big Scary Command™ and see what broke. A couple messages were too long (which was easy to fix by simply manually rewriting them, doing the right state layer brain surgery, deleting things on Discord, and re-running the migration tool. However 99.9% of messages were correctly imported on the first try. I had to double check a few times including the bog-standard wakefulness tests. If you've never gone deep into lucid dreaming before, a wakefulness test is where you do something obviously impossible to confirm that it does not happen, such as trying to put your fingers through your palm. My fingers did not go through my palm. After having someone else confirm that I wasn't hallucinating more than usual I found out that my code did in fact work and as a result you can now search through the archives on community.tigrisdata.com or via the MCP server ! I consider that a massive success. As someone who has seen many truly helpful answers get forgotten in the endless scroll of chats, I wanted to build a way to get that help in front of users when they need it by making it searchable outside of Discord. Finding AnswerOverflow was pure luck: I happened to know someone who uses it for the support Discord for the Linux distribution I use on my ROG Ally, Bazzite . Thanks, j0rge! AnswerOverflow also has an MCP server so that your agents can hook into our knowledge base to get the best answers. To find out more about setting it up, take a look at the "MCP Server" button on the Tigris Community page . They've got instructions for most MCP clients on the market. Worst case, configure your client to access this URL: And bam, your agent has access to the wisdom of the ancients. But none of this is helpful without the actual answers. We were lucky enough to have existing Q&A in another forum to leverage. If you don't have the luxury, you can write your own FAQs and scenarios as a start. All I can say is, thank you to the folks who asked and answered these questions– we're happy to help, and know that you're helping other users by sharing. Connect with other developers, get help, and share your projects. Search our Q&A archives or ask a new question. Join the Discord . Extracting the raw data from the upstream source and caching it in Tigris. Transforming the cached data to make it easier to consume in Discord, storing that in Tigris again. Loading the transformed data into Discord so that people can see the threads in app and on the web with Answer Overflow . The name of the project associated with the requests (tigris-gtm-glue, where gtm means "go-to-market", which is the current in-vogue buzzword translation for whatever it is we do). The Go version, computer OS, and CPU architecture of the machine the program is running on so that administrator complaints can be easier isolated to individual machines. A contact URL for the workload, in our case it's just the Tigris home page. The name of the program doing the scraping so that we can isolate root causes down even further. Specifically it's the last path element of , which contains the path the kernel was passed to the executable. The hostname where the workload is being run in so that we can isolate down to an exact machine or Kubernetes pod. In my case it's the hostname of my work laptop. Key names get prefixed automatically. All data is encoded into JSON on write and decoded from JSON on read using the Go standard library. Type safety at the compiler level means the only way you can corrupt data is by having different "tables" share the same key prefix. Try not to do that! You can use Tigris bucket snapshots to help mitigate this risk in the worst case. Discord needs Markdown, the forum engine posts are all HTML. We want to remove personally-identifiable information from those posts just to keep things a bit more anonymous. Discord has a limit of 2048 characters per message and some posts will need to be summarized to fit within that window. Convert HTML to Markdown : Okay, I could have gotten away using a dedicated library for this like html2text , but I didn't think about that at the time. Remove mentions and names : Just strip them out or replace the mentions with generic placeholders ("someone I know", "a friend", "a colleague", etc.). Keep "useful" links : This was left intentionally vague and random sampling showed that it was good enough. Summarize long text : If the text is over 1000 characters, summarize it to less than 1000 characters.

0 views
Xe Iaso 2 months ago

I made a simple agent for PR reviews. Don't use it.

My coworkers really like AI-powered code review tools and it seems that every time I make a pull request in one of their repos I learn about yet another AI code review SaaS product. Given that there are so many of them, I decided to see how easy it would be to develop my own AI-powered code review bot that targets GitHub repositories. I managed to hack out the core of it in a single afternoon using a model that runs on my desk. I've ended up with a little tool I call reviewbot that takes GitHub pull request information and submits code reviews in response. reviewbot is powered by a DGX Spark , llama.cpp , and OpenAI's GPT-OSS 120b . The AI model runs on my desk with a machine that pulls less power doing AI inference than my gaming tower pulls running fairly lightweight 3D games. In testing I've found that nearly all runs of reviewbot take less than two minutes, even at a rate of only 60 tokens per second generated by the DGX Spark. reviewbot is about 350 lines of Go that just feeds pull request information into the context window of the model and provides a few tools for actions like "leave pull request review" and "read contents of file". I'm considering adding other actions like "read messages in thread" or "read contents of issue", but I haven't needed them yet. To make my life easier, I distribute it as a Docker image that gets run in GitHub Actions whenever a pull review comment includes the magic phrase . The main reason I made reviewbot is that I couldn't find anything like it that let you specify the combination of: I'm fairly sure that there are thousands of similar AI-powered tools on the market that I can't find because Google is a broken tool, but this one is mine. When reviewbot reviews a pull request, it assembles an AI model prompt like this: The AI model can return one of three results: The core of reviewbot is the "AI agent loop", or a loop that works like this: reviewbot is a hack that probably works well enough for me. It has a number of limitations including but not limited to: When such an innovation as reviewbot comes to pass, people naturally have questions. In order to give you the best reading experience, I asked my friends, patrons, and loved ones for their questions about reviewbot. Here are some answers that may or may not help: Probably not! This is something I made out of curiosity, not something I made for you to actually use. It was a lot easier to make than I expected and is surprisingly useful for how little effort was put into it. Nope. Pure chaos. Let it all happen in a glorious way. How the fuck should I know? I don't even know if chairs exist. At least half as much I have wanted to use go wish for that. It's just common sense, really. When the wind can blow all the sand away. Three times daily or the netherbeast will emerge and doom all of society. We don't really want that to happen so we make sure to feed reviewbot its oatmeal. At least twelve. Not sure because I ran out of pancakes. Only if you add that functionality in a pull request. reviewbot can do anything as long as its code is extended to do that thing. Frankly, you shouldn't. Your own AI model name Your own AI model provider URL Your own AI model provider API token Definite approval via the tool that approves the changes with a summary of the changes made to the code. Definite rejection via the tool that rejects the changes with a summary of the reason why they're being rejected. Comments without approving or rejecting the code. Collect information to feed into the AI model Submit information to AI model If the AI model runs the tool, publish the results and exit. If the AI model runs any other tool, collect the information it's requesting and add it to the list of things to submit to the AI model in the next loop. If the AI model just returns text at any point, treat that as a noncommittal comment about the changes. It does not work with closed source repositories due to the gitfs library not supporting cloning repositories that require authentication. Could probably fix that with some elbow grease if I'm paid enough to do so. A fair number of test invocations had the agent rely on unpopulated fields from the GitHub API, which caused crashes. I am certain that I will only find more such examples and need to issue patches for them. reviewbot is like 300 lines of Go hacked up by hand in an afternoon. If you really need something like this, you can likely write one yourself with little effort.

2 views
Xe Iaso 2 months ago

2026 will be my year of the Linux desktop

TL;DR: 2026 is going to be The Year of The Linux Desktop for me. I haven't booted into Windows in over 3 months on my tower and I'm starting to realize that it's not worth wasting the space for. I plan to unify my three SSDs and turn them all into btrfs drives on Fedora. I've been merely tolerating Windows 11 for a while but recently it's gotten to the point where it's just absolutely intolerable. Somehow Linux on the desktop has gotten so much better by not even doing anything differently. Microsoft has managed to actively sabotage the desktop experience through years of active disregard and spite against their users. They've managed to take some of their most revolutionary technological innovations (the NT kernel's hybrid design allowing it to restart drivers, NTFS, ReFS, WSL, Hyper-V, etc.) then just shat all over them with start menus made with React Native, control-alt-delete menus that are actually just webviews, and forcing Copilot down everyone's throats to the point that I've accidentally gotten stuck in Copilot in a handheld gaming PC and had to hard reboot the device to get out of it. It's as if the internal teams at Microsoft have had decades of lead time in shooting each other in the head with predictable results. To be honest, I've had enough. I'm going to go with Fedora on my tower and Bazzite (or SteamOS) on my handhelds. I think that Linux on the desktop is ready for the masses now, not because it's advanced in a huge leap/bound. It's ready for the masses to use because Windows has gotten so much actively worse that continuing to use it is an active detriment to user experience and stability. Not to mention with the price of ram lately, you need every gigabyte you can get and desktop Linux lets you waste less of it on superfluous bullshit that very few people actually want. Oh, and if I want a large language model integrated into my tower, I'm going to write the integration myself with the model running on hardware I can look at . At the very least, when something goes wrong on Linux you have log messages that can let you know what went wrong so you can search for it.

0 views
Xe Iaso 2 months ago

Arcane Cheese with Doomtrain Extreme

Spoiler Warning If you want to go through the Final Fantasy 14 duty Hell on Rails (Extreme) blind, don't read this guide as it spoils how to easily solve one of the mechanics in it. If you don't play Final Fantasy 14, most of the words in this article are going to make no sense to you and I will make no attempt to explain them. Just know that most of the words I am saying do have meaning even though they aren't in The Bible. In phase 4 of Hell on Rails (Extreme), the boss will cast Arcane Revelation, which makes the arena look something like this: There will be a very large circle of bad moving around the arena. One tank and one healer will be marked with an untelegraphed AoE attack that MUST be soaked by at least one other player (or two for healers). Doomtrain will move the circle of bad anywhere from 1-3 times and leave only a small area of the arena safe. Normally you're supposed to solve it something like this: Instead of normal light party groups, break up into two groups: melee and casters. This will allow the melees to keep as much uptime as the mechanics allow, but also let the casters get uptime at a distance. Solving this is pretty easy with practice. However as a caster this is kinda annoying because when the North side is safe, you have to fall down off the ledge and the only way to get back is by going around the long way with the janky teleporters that are annoying to hit on purpose but very easy to hit on accident. There is an easier way: you just stand in the upper corners so your melees can greed uptime and just soak all of the bad: This looks a lot easier but is actually very technically complicated for nearly every class. My example solve for this includes the following party members: The light party assignment is as follows: Arcane Revelation can perform up to three hits. In each of the hits you need to mitigate the damage heavily or you will wipe. I've found the most consistent results doing this: First hit: WAR casts Shake it Off , Reprisal , and Rampart ; WHM casts Plenary Indulgence and Medica III ; SGE casts Kerachole and Eukrasian Prognosis II ; SAM (and RPR) casts Bloodbath and mostly focuses on DPSing as much as possible to heal from the massive damage you will be taking throughout this mechanic; DNC casts Shield Samba . After the hit: heal as much as you can to offset the hit you took. If you're lucky you didn't take much. If you're not: you took a lot. Dancer's Curing Waltz can help here. Second hit: GNB casts Heart of Light , Reprisal , and Rampart ; SGE casts Holos and Eukrasian Prognosis II ; PCT casts Addle . After the hit: SGE casts a Zoe -boosted Pneuma . Generally you do what you can to heal and maintain DPS uptime. Hopefully you don't have to take another heavy hit. Third hit: One of the tanks uses a Tank Limit Break 2 , Healers dump as many mits as they have left, hopefully you won't die but getting to this point means you got very very unlucky. Between each of these hits you need to heal everyone up to 100% as soon as possible otherwise you WILL wipe. Most of the damage assumptions in this guide assume that everyone is at 100% health. The melee classes can mostly be left to their own devices to greed as much uptime as possible, but they may need Aquaveil, Taurochole, or other single target damage mitigations as appropriate. By the end of this you will have used up all of your mitigations save tank invulns. Here's a video of the first time I did this as Sage: That exasperated laugh is because previously Arcane Revelation was my hard prog point as even though I was able to do it consistently, others were not. This caused many wipes 7 minutes into a 10 minute fight. This cheese makes it consistent with random people on Party Finder. One of the tanks will need to soak a stack tower with an invuln. Everyone else runs to the back of the car to enter the next phase and then you continue the fight as normal. Spoiler Warning If you want to go through the Final Fantasy 14 duty Hell on Rails (Extreme) blind, don't read this guide as it spoils how to easily solve one of the mechanics in it. If you don't play Final Fantasy 14, most of the words in this article are going to make no sense to you and I will make no attempt to explain them. Just know that most of the words I am saying do have meaning even though they aren't in The Bible. In phase 4 of Hell on Rails (Extreme), the boss will cast Arcane Revelation, which makes the arena look something like this: There will be a very large circle of bad moving around the arena. One tank and one healer will be marked with an untelegraphed AoE attack that MUST be soaked by at least one other player (or two for healers). Doomtrain will move the circle of bad anywhere from 1-3 times and leave only a small area of the arena safe. Normally you're supposed to solve it something like this: Instead of normal light party groups, break up into two groups: melee and casters. This will allow the melees to keep as much uptime as the mechanics allow, but also let the casters get uptime at a distance. Solving this is pretty easy with practice. However as a caster this is kinda annoying because when the North side is safe, you have to fall down off the ledge and the only way to get back is by going around the long way with the janky teleporters that are annoying to hit on purpose but very easy to hit on accident. There is an easier way: you just stand in the upper corners so your melees can greed uptime and just soak all of the bad: This looks a lot easier but is actually very technically complicated for nearly every class. My example solve for this includes the following party members: Tank 1: Warrior (WAR) Tank 2: Gunbreaker (GNB) Healer 1: White Mage (WHM) Healer 2: Sage (SGE) Melee 1: Samurai (SAM) Melee 2: Reaper (RPR) Ranged 1: Dancer (DNC) Ranger 2: Pictomancer (PCT) WAR, WHM, SAM, DNC GNB, SGE, RPR, PCT

0 views
Xe Iaso 4 months ago

Valve is about to win the console generation

Today was a big day for gamers as Valve just introduced three products: the Steam Controller, the Steam Machine, and the Steam Frame. When you add this alongside the Steam Deck, I think it's safe to say that Valve is about to win the next console generation. I have basically nothing to say about the Steam Controller. It's the Steam Deck's input but in a controller. There's no way they can really mess it up in a way that isn't recoverable. What else is there to say? The Steam Machine of yore was one of the biggest tech flops in history and led to a lot of the changes that has made Valve hardware so good. Based on what they've announced, the software ecosystem I know and love on SteamOS, and response from developers I talk with, there's a reasonable chance that this new Steam Machine is going to be the most compelling console on the market. TL;DR: The Steam Machine's specs are on par or better with the PS5. It's got 16 GB of ram, a dedicated GPU with 8GB of video ram, and it's about the size of three M1 Mac Minis stacked on top of each other with a slightly bigger footprint than a Nintendo GameCube. I see no real way that this could be a failure in the same way that the last Steam Machine was. If they don't fuck this up, I could pretty confidently say that Valve is going to win this console generation. In retrospect, I think that the failure of the first Steam Machine was probably one of the best things to ever happen to Valve. Proton, Steam Play, and the Steam Deck are the proof that Valve learned all the lessons they needed to in order to make a next generation Steam Machine a viable console. The biggest difference between SteamOS and other console operating systems is that SteamOS is just an immutable image-based fork of Arch Linux with a skin on top. If you can do it with a normal PC, you can do it on SteamOS. Wait, you said that you can do anything you can do on a normal PC, but you also said it's running an immutable OS. What if my definition of "anything" includes "install system packages"? Good point, I'm not worried about that for two main reasons: developers have already found ways to use things like distrobox to give you islands of mutablity in an otherwise immutable system on the Steam Deck, and you can just blow away the OS and install whatever you want (such as Bazzite ) or any normal Linux distribution. You could even put Windows on it if you needed to for some reason. This means that even though Valve will be selling this hardware at a loss, you can still buy one and never purchase anything else from them. You can install any compatible game from any marketplace. In their own words: Yes, Steam Machine is optimized for gaming, but it's still your PC. Install your own apps, or even another operating system. Who are we to tell you how to use your computer? I cannot even imagine the other console manufacturers saying this. I'd easily imagine that it'd have free reign across a majority of the Steam library. By sheer game count alone, this would make it one of the biggest console launch libraries on the market. This isn't even counting the fact that you can install alternative marketplaces like itch.io , GOG, or anything Lutris supports (EG: Epic Games). Valve does nothing and still wins. One of the bigger things that I don't think people really appreciate about the Steam Machine (or even the Steam Deck for that matter) is that the freedom to install whatever program, framework, background service, or OS you want means that every Steam Machine can be used to make games. Some of their promotional images show a Steam Machine in a dual-monitor setup split between Blender and Godot. I don't think you realize how big of a deal this is. By making every Steam Machine also powerful enough to do full on game development, Valve is making it so much easier to become an independent game developer. Just add ideas, skill, and time. Hilariously, this means that the Steam Machine is probably the only console on the market that's fully compliant with the EU's Digital Markets Act. It would be absolutely hilarious if the EU ends up using this as rationale for Nintendo, Microsoft, and Sony to open up their consoles for third party developers. Oh and to top it off, the internal storage is upgradable and can take full-size nvme drives. If you pop your microSD card out of your Steam Deck, you can put it into your Steam Machine and get all your games instantly. Reportedly the ram is user-upgradable too. The only way that they could mess this up is with the pricing. The price will be what determines if this is a PS5 killer or a mid-range home theater PC that can do games decently well. Given the fact that Steam prints so much money, I'd expect the pricing to be super aggressive. Worst case, this would be a great home theatre PC. I'd rock it in my media centre. It's going to run Plex, Twitch, and Youtube just fine. Valve also announced their successor to the Valve Index today, the Steam Frame , a standalone VR headset. It's basically a Meta Quest headset, but also a Steam Deck. They market it as being able to play VR and 2D games effortlessly. The weirdest thing about it is that it's running a 64 bit ARM CPU instead of a conventional AMD APU like the Steam Deck and Steam Machine. This means that SteamOS is going to be cross-architecture for the first time and they're going to use FEX to bridge the gap. The big thing I want to see in practice is their implementation of foveated rendering. This beautiful hack abuses the fact that human eyes have the most sharpness and fidelity at the exact centre of your field of vision, whereas your peripheral vision is abysmal at it. This means that on average you only have to render about 10% of the frame at maximum quality for it to feel like it's running at full resolution all over the screen. This should make the fact that the Frame is using a "weaker" CPU/GPU irrelevant. Games should look fine as long as they render the slice that needs to be in full quality fast enough. Even more fun, they take advantage of the same tricks behind foveated rendering for streaming games from a PC or Steam Machine. This means that you get that same optically perfect quality but with even less latency because less data has to be transferred to hit your eyes. I really want to see what this is like in practice. Reportedly there's no perceptual difference between this setup and rendering games at 100% full quality. The Steam Frame ships with a USB dongle that lets you use the might of your gaming tower for low latency VR gaming. I'll need to see this in practice in order to have opinions. I think that in the worst case it can't possibly be any worse than it was streaming VR games to my Quest 2 over Wi-Fi. That was tolerable and viable for mid-level Beat Saber. I have confidence that it will at least be sufficient for high level Beat Saber gameplay. Remember how I said that it's a Steam Deck in a headset? The Steam Frame runs full SteamOS. You can just boot it into a full KDE desktop and use it as a normal computer. I have no reason to doubt that every Steam Frame is also a development kit in the same way that the Steam Machine is also a development kit. They also claim you can load arbitrary Android apps into the Steam Frame. I need to see this in action before I have opinions about it. It would be exceptionally funny if this meant you could take apps/games made for the Meta Quest and just plop them onto the Steam Frame without modification. I'm not holding my breath, but it would be funny. The only possible flaw I can see is that the strap it ships with doesn't go over the top of your head. If this ends up being an issue in practice, somebody is going to make a third party strap that just fixes this problem. I'm not concerned. Really, the only thing that can go wrong with any of this hardware is the price. I would still be happy if the pricing was the worst part of this lineup. It would be really cool if there was a bundle. I'm at least planning on getting a Steam Machine on day 1 and making a review. What would you like to see in that? Let me know on Bluesky .

0 views
Xe Iaso 4 months ago

Taking steps to end traffic from abusive cloud providers

This blog post explains how to effectively file abuse reports against cloud providers to stop malicious traffic. Key points: Two IP Types : Residential (ineffective to report) vs. Commercial (targeted reports) Why Cloud Providers : Cloud customers violate provider terms, making abuse reports actionable Effective Abuse Reports Should Include : Note on "Free VPNs" : Often sell your bandwidth as part of botnets, not true public infrastructure The goal is to make scraping the cloud provider's problem, forcing them to address violations against their terms of service. Two IP Types : Residential (ineffective to report) vs. Commercial (targeted reports) Why Cloud Providers : Cloud customers violate provider terms, making abuse reports actionable Effective Abuse Reports Should Include : Time of abusive requests IP/User-Agent identifiers robots.txt status System impact description Service context Process : Use whois to find abuse contacts (look for "abuse-c" or "abuse-mailbox") Send detailed reports with all listed emails Expect response within 2 business days Note on "Free VPNs" : Often sell your bandwidth as part of botnets, not true public infrastructure

0 views
Xe Iaso 5 months ago

First look at the DGX Spark

Disclaimer I'm considering this post as a sponsored post. I was not paid by NVIDIA to work on this, but I did receive a DGX Spark from them pre-release and have been dilligently testing it and filing bugs. I've had access to the NVIDIA DGX Spark for over a month now. Today I'm gonna cover my first impressions and let you know what I've been up to with it. In a nutshell, this thing is a beast. It's one of the most powerful devices in my house and in a pinch I'd be okay with using it as my primary workstation. It's got a mix of a CPU that's got enough punch to do software development with a GPU that's in that sweet spot between consumer and datacenter tier. Not to mention 128Gi of ram. When I've been using this thing, the main limit is my imagination…and my poor understanding of Python environment management. I think that it's best to understand the DGX Spark as a devkit for their NVIDIA Grace Datacentre processors . It's incredibly powerful for what it is, it's a device that can fit on your desk and run AI models right there. A DGX Spark on top of a desk with typical computer things around it such as a laptop, a coffee mug, a keyboard, and a mouse. The DGX Spark is tiny. It's about as wide as the screen of a Steam Deck OLED, or about halfway between the size of a Mac mini M1 and a Mac mini M4. This thing is also stupidly power efficient. I've been unable to cause my office to get warm in a way that is attributed to the DGX Spark alone. On average rendering Final Fantasy 14 in one of the major player hub areas ends up making my tower use more power than the DGX Spark does while doing AI finetuning. I'll talk more about this in the future. One of the most interesting things about this device is that it's got an Arm chip, CUDA, and unified RAM. This combination means that in practice you need to compile all of the Python packages you're using from source. Pip usually handles this well enough, but it does mean that for many Python packages it will take longer to install from source than it will on an X86 system. I assume this will be ironed out as the ecosystem matures. The power efficiency can't be overstated though. I've tried to make my office warm using the DGX Spark and I have failed. I'm seeing it pull a maximum of 70 watts. I get about 30-40 tokens per second with gpt-oss:120b : The user asks: "Summarize this post: --- ...". So we need to provide a summary. Follow developer instructions: be polite, bubbly, lowercase when possible unless serious. No JSON. Summarize the content. The post is long, covering themes: loss of craft, historical analogy with weavers and Luddites, decline of senior titles, AI replacing expertise, vibe coding, security concerns, AI's impact on art, etc. Provide concise summary. Use informal tone, lowercase. End without period unless serious. Probably okay. this post is a sprawling meditation on how we keep “rolling the ladder up behind us” – building a future that erodes the very expertise that made it possible. it starts with a historic look at cloth‑making: skilled weavers were displaced by power looms, turning a durable, treasured craft into cheap, disposable fast‑fashion. the author draws a parallel to today’s software world, warning that we’re replacing senior developers and deep craft with hype‑driven AI tools and “vibe coding” platforms that promise instant results but degrade long‑term quality. key points: the piece ends with a bleak outlook: without deliberate effort to preserve and pass on true craft, future generations will inherit ladders that only go up for the privileged few, leaving the rest scrambling. it’s a call to value high‑quality, human‑made work over quick, AI‑generated shortcuts. With flash attention on gpt-oss:120b at 128k context window, it uses about 70Gi of ram: I assume that the unaccounted 4Gi or so of ram is in the CPU ram overhead of the Ollama model runner process. So far I've been using the Spark in place of cloud GPUs for every AI thing I've needed to do at work. In general, I haven't really noticed any differences between the GPU in the cloud and the Spark on my home network. The only real rough edge is that I need to use this one blessed NVIDIA authored docker image to run iPython notebooks. It's easy enough though. Usually my Docker command looks like: And then it Just Works™. The main thing I've been doing with it is inference of GPT-OSS 120b via Ollama . I've been doing latency and power usage testing by setting up a Discord bot and telling people that the goal is to jailbreak the bot into telling you how to make a chocolate cake. Nobody has been able to make my room warm. This whole experience has been a bit of a career bucket list item for me. I've never had access to prerelease hardware like this before and being able to see what reviewers have to deal with before things are available to the masses is enlightening. I've ended up filing GPU driver bugs using my tower as a "known good" reference. I've been slowly sinking my teeth into learning how AI training actually works using this device to do it. I've mostly been focusing on finetuning GPT-2 and using that to learn the important parts of dataset cleaning, tokenization, and more. Let me know if you want to hear more about that and if you want me to release my practice models. At the very least though, here's the things I have in the pipeline that this device enables: I also plan to make a comprehensive review video. Details to be announced soon. I hope this was interesting. Thanks for early access to the device NVIDIA! craft is disappearing – both in weaving and coding, the knowledge of masters is vanishing, leaving only fragmented R&D notes or AI‑generated shortcuts. senior titles are at risk – companies favor hiring senior talent without nurturing the next generation, so the pool of true “seniors” will run out. AI as a double‑edged sword – generative tools can reduce drudgery but are being marketed as the next industrial revolution while actually shifting value to owners and creating insecure, low‑quality products. vibe coding & AI assistants – slick UX masks the fact that many tools are subscription traps, security hazards, and can erode programmers’ skills. artistic impact – similar to how AI floods art spaces with cheap, low‑effort outputs, software development risks becoming a flood of “good enough” code. security concerns – model‑context‑protocol servers can expose secrets and run unchecked code, highlighting the need for sandboxed, capability‑based designs. broader societal worry – the author (also the CEO of a small AI‑security startup) sees a winner‑take‑all capitalism fueled by AI, with the cost falling on workers, artists, and even the environment. Finetuning at home: how to make your own AI models do what you want Some rough outlines and/or overviews for how I want to use classical machine learning models to enhance Anubis and do outlier detection If I can somehow get Final Fantasy 14 running on it, some benchmarking in comparison to my gaming tower (if you know how to get amd64 games running well on aarch64, DM me!)

0 views
Xe Iaso 5 months ago

Hastily made coffee video

I'm trying to get back into the flow of making videos more. In an effort to optimize my production pipeline, I'm going to be making a lot more "low effort" videos. This is the first one where I filmed a video of me making coffee on my phone. I think the next one is gonna be me making espresso.

1 views
Xe Iaso 6 months ago

We all dodged a bullet

This post and its online comment sections are blame-free zones. We are not blaming anyone for clicking on the phishing link. If you were targeted with such a phishing attack, you'd fall for it too and it's a matter of when not if. Anyone who claims they wouldn't is wrong. This is also a bit of a rant. Yesterday one of the biggest package ecosystems had very popular packages get compromised . We're talking functionality like: These kinds of dependencies are everywhere and nobody would even think that they could be harmful. Getting code into these packages means that it's almost guaranteed a free path to production deployments. If an open proxy server (a-la Bright Data or other botnets that the credit card network tolerates for some reason), API key stealer, or worse was sent through this chain of extreme luck on the attacker's part, then this would be a completely different story. We all dodged a massive bullet because all the malware did was modify the destination addresses of cryptocurrency payments mediated via online wallets like MetaMask . As someone adjacent to the online security community, I have a sick sense of appreciation for this attack. This was a really good attack. It started with a phishing email that I'd probably fall for if it struck at the right time: This is frankly a really good phishing email. Breaking it down: This is a 10/10 phishing email. Looking at it critically the only part about it that stands out is the domain "npmjs.help" instead of "npmjs.com". Even then, that wouldn't really stand out to me because I've seen companies use new generic top level domains to separate out things like the blog at or the docs at , not to mention the stack . One of my friends qdot also got the phishing email and here's what he had to say: I got the email for it and was like "oh I'll deal with this later". Saved by procrastination! — qdot ( @buttplug.engineer ) September 8, 2025 at 2:04 PM With how widely used these libraries are, this could have been so much worse than it was. I can easily imagine a timeline where this wasn't just a cryptocurrency interceptor. Imagine if something this widely deployed into an ecosystem where automated package bumping triggering production releases is common did API key theft. You'd probably have more OpenAI API keys than you know what you'd do with. You could probably go for years without having to pay for AWS again. It is just maddening to me that a near Jia Tan level chain of malware and phishing was wasted on cryptocurrency interception that won't even run in the majority of places those compromised libraries were actually used. When I was bumping packages around these issues, I found that most of these libraries were used in command line tools. This was an attack obviously targeted towards the Web 3 ecosystem as users of Web 3 tools are used to making payments with their browsers. With my black hat on, I think that the reason they targeted more generic packages instead of Web 3 packages was so that the compromise wouldn't be as noticed by the Web 3 ecosystem. Sure, you'd validate the rigging that helps you interface with Metamask, but you'd never think that it would get monkey-patched by your color value parsing library. One of the important things to take away from this is that every dependency could be malicious. We should take the time to understand the entire dependency tree of our programs, but we aren't given that time. At the end of the day, we still have to ship things.

0 views
Xe Iaso 6 months ago

Final Fantasy 14 on macOS with a 36 key keyboard

Earlier this year, I was finally sucked into Final Fantasy 14. I've been loving my time in it, but most of my playtime was on my gaming tower running Fedora. I knew that the game does support macOS, and I did get it working on my MacBook for travel, but there was one problem: I wasn't able to get my bars working with mouse and keyboard. A 36 key keyboard and MMO mouse combination for peak gaming. Final Fantasy 14 has a ridiculous level of customization. Every UI element can be moved and resized freely. Every action your player character can take is either bindable to arbitrary keybinds or able to be put in hotbars. Here's my hotbars for White Mage: My bars for the White Mage job, showing three clusters of actions along with a strip of quick actions up top. My bars have three "layers" to them: I have things optimized so that the most common actions I need to do are on the base layer. This includes spells like my single target / area of effect healing spells and my burst / damage over time spells. However, critical things like health regeneration, panic button burst healing, shields, and status dispelling are all in the shift and control layers. When I don't have instinctive access to these spells with button combos, I have to manually click on the buttons. This sucks. I ended up fixing this by installing Karabiner Elements , giving it access to the accessibility settings it needs, and enabling my mouse to be treated as a keyboard in its configuration UI. There's some other keyboard hacks that I needed to do. My little split keyboard runs QMK , custom keyboard firmware written in C that has a stupid number of features. In order to get this layout working with FFXIV, I had to use a combination of the following features: Here is what my keymap looks like: I use the combination of this to also do programming. I've been doing a few full blown Anubis features via this keyboard such as log filters . I'm still not up to full programming speed with it, but I'm slowly internalizing the keymap and getting faster with practice. Either way, Final Fantasy 14 is my comfort game and now I can play it on the go with all the buttons I could ever need. I hope this was interesting and I'm going to be publishing more of these little "how I did a thing" posts like this in the future. Let me know what you think about this!

0 views