Latest Posts (20 found)

How I Customised Pure Blog for This Site

A few people have reached out to me to ask how I did X, or Y with my site, so I thought I'd talk about the customisations I've made to this site, and how they work. Firstly, this site runs on Pure Blog , a CMS that I've been building over the last year or so. As it's matured, I've added features that allow more advanced users to do clever things without having to fiddle with the core platform. This means that people generally shouldn't have to fork the project and should continue to get all the new goodness as I release it. This site is no different. I haven't done anything clever that Pure Blog can't do out of the box - everything is documented so by reading the docs and using a bit of creativity, you can do quite a lot with this plucky little CMS. I'll link out to the appropriate docs as we go through this post. Ok, so what customisations have I made? This is going to be a fairly long post, so I'll list them here with links to each header so you can jump around and read the parts that interest you. If you want to see specific code examples for any of these customisations, feel free to contact me . I have three custom post types on this site - notes , links , and books . Notes are used as short-form social media type posts, links are links to other blog posts that I've enjoyed, and books are short reviews of the books I read. Each has their own layout and in the case of notes, they have a different view on the homepage too. To do this I've created a custom partial, but we will come to that later. I could just use the default post type for all these posts, but I prefer to have a customised UI at the back-end for each. Here's what books and links look like in my editor: Notes are a little different as I use a custom page for them that only I can access. This looks more like a social media post window than a blog post window: Read the custom post layout docs ➡ I like to think of hooks as little tripwires that are set to go off when certain conditions are met. For example, something happens when an image is uploaded, or a new post is published. They're extremely useful and I have a number of them on this site: Read the hooks docs ➡ Beyond custom post types, Pure Blog lets you drop PHP files into . These can either override default pieces of the site (like navigation or post footers), or serve as entirely bespoke standalone pages, like my quick-publish notes screen, or the terminal 404 page . Here's a full list of the templates and partials used on this site: Read the layout partials docs ➡ I've replaced the default feed with one that allows for filtering on post type. So one feed file, 5 feeds - one for each post type, and a fifth for everything. My custom feed template allows you to visit for everything, or (e.g. ) for the posts of that particular type. This custom feed file lives in and I then used redirects to redirect the default URL to . All the feed URLs are available here . I use a self-hosted instance of Sendy to send out email "newsletters" whenever I publish a new post. These emails always contain the entire post, so people can read my content from their inbox if they wish. Because I write notes much more frequently than long-form posts, I let readers choose what they receive: everything, long-form content only, or notes only. To make that work without sending people through clunky third-party forms, I wrote a custom server-side handler ( ). When someone submits the form on the subscribe page , the handler: This not only helps segregate the emails people receive, but it has also had a dramatic effect on spammy sign ups. Which, if you've ever run a newsletter, you will know is a common problem. Pure Blog allows you to add your own PHP helper functions for all kinds of things. On my site, I only have 1 function defined: which transforms fractional score strings in my book posts (e.g. ) into accessible star glyph strings (e.g. ). I just think that looks far nicer in a post than . But how is this star rating accessible? Well, it's rendered on the front-end like this so screen readers can parse it: Read the custom functions docs ➡ I don't do anything magical with the design on this site. I use the Victor Mono font , and around 850 lines of CSS, which I've added to the custom CSS field within settings. Combined with the custom , and files above, it gives me everything I need to customise the site from the default look to what you see now. I have a custom theme palette that I've defined too, also in settings. The colours used can be found at the bottom of my colophon . Read the design customisation docs ➡ One of the most powerful things about using a static site generator is the ability to use data files. With data files you can have a structure data file, like YAML, that contains repeated data, which can then be looped through on the front-end to render content. I really wanted Pure Blog to be able to support data files, so I added support very early on. Personally, I use two data files on this site: Data files are fantastic as they reduce the amount of repetitive code you have to write. Instead of typing , after , after manually, you write your once, then loop through it with a data file and Pure Blog does the rest. Read the data files docs ➡ The final thing I customise is my file. There's a number of things I do to the standard Pure Blog file to either redirect URLs, or protect various locations: This ended up being an even longer post than I anticipated, but hopefully it shows just how much you can bend Pure Blog to your will, by design . None of this requires hacks to the core code, or maintaining your own fork. Everything you see here is achieved using Pure Blog as designed: settings, custom CSS, hooks, custom layouts, and partials. Because all these files live inside , , and , I can upgrade Pure Blog the moment a new release drops without worrying about overwriting my site's bespoke features. That was always my goal with Pure Blog - a super simple, distraction-free blogging platform out of the box, with enough flexibility under the hood for tinkerers (like me!) to build whatever they want. If you're running Pure Blog and have built your own customisations, or if this post inspired you to try something new with your setup, hit the reply button below, or find me on Mastodon. I'd love to see what you've done with it. Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️ You can reply to this post by email , or leave a comment . Post layouts Hooks and automations Templates and partials RSS feed enhancements Newsletter subscriptions Functions and helpers Design and typography Data driven pages .htaccess rules Final thoughts Email Obfuscation ( ) : Scans rendered content and encodes the site email address into hexadecimal HTML entities to protect against scrapers. This has been pretty effective at reducing spam - I wrote more about this feature in this post . Post Sanitisation & Metadata Preservation ( ) : Automatically generates date/time titles for new notes. Normalises layout values by stripping quotes (turning layout: "notes" into layout: notes), ensuring posts written in external editors like Obsidian don't break layout checks. Preserves in post frontmatter when saving via the admin interface so the Mastodon card at the bottom of every post continues to work. Image Optimisation ( ) : Automatically resizes images exceeding 2560px width whilst maintaining aspect ratio, also converts them to lossless WebP, and cleans up original unoptimised files. Mastodon Cross-Posting & Syndication ( ) : Automatically crossposts all published post types to Fosstodon via the Mastodon API. Notes posts are cross-posted with full body text and media attachments (uploaded to Mastodon's media endpoint). Articles, links, and books are crossposted with their description and permalink URL. Captures the returned Mastodon status URL and automatically persists into the post's frontmatter which is then used for the Mastodon card at the bottom of every post. Custom Font for Open Graph Images ( ) : Makes dynamic Open Graph image generation to use my custom font. (partial) : This replaces the default and adds post-type filter buttons, preserving query parameters across pagination. It also displays notes in full, while other post types show only the title and excerpt. (partial) : A customised version of the default file from Pure Blog. On top of the default tag list and post pagination, this version adds the obfuscated "Reply by email" button, a client-side Mastodon conversation card displaying live stats (favourites, boosts, replies) as well as a link to the post on Fosstodon, Pure Comments integration, and a subscription call-to-action. (template) : Dedicated discovery hub combining Pure Blog's full-text search with an alphabetical, weighted tag cloud showing post frequencies. (template) : An interactive metro map that lists all of the pages on this site. There's also an option to see the pages as a list. (template) : My quick-publish admin screen for composing and publishing short-form note posts. (template) : Dashboard for tracking the 100 Days to Offload challenge streaks in batches of 100 posts. (partial) : This replaces the default template in Pure Blog. It adds a custom layout, as well as 404 handoff ( ) to render the custom template without modifying core Pure Blog files. (template) : A fun interactive terminal-styled 404 page with custom commands that include goats! (template) : Endpoint that resolves and redirects visitors to a randomly chosen published post . Checks a simple verification question ("What is Kev's surname?") to keep bots at bay. Silently discards submissions that trigger a honeypot field, or exceed IP rate limits. Subscribes the user to the correct Sendy list(s) via Sendy's API in a single click. which is then used to render my blogroll page . which is used for my projects . Admin Access Restriction : I restricts access to specific allowed IP addresses. Legacy URL & Feed Redirects : 301 redirects mapping historical and URLs to clean root and routes that Pure Blog uses. Redirects for legacy feed and social endpoints ( , , , , , etc.) to or to make sure the feed URLs from various versions of this site don't break. Route Rewrites : clean URL routing for all my RSS feeds so they have simple to share URLs.

0 views

Tangled, hire a front-end accessibility expert

Not me, this is just friendly advice from a struggling user. Alongside Codeberg I’d consider Tangled to be a real GitHub replacement. We desperately need to leave GitHub behind. It’s difficult to recommend any tech these days. I used to spread the gospel of Proton and that backfired . From what I’ve seen, Tangled seem to be saying and doing the right things so far. I have trepidations about their venture capital funding (see Deno’s demise ) but pessimism is no fun. Tangled’s recent blog post on federated code forges piqued my interest. I self-host Forgejo and a big downside is that no one else can participate easily. Forgejo federation is under development. Maybe the two can co-exist? But that’s not what I’m here to discuss. In the same post Tangled revealed their new UI design. We’ve redone the UI on top of our new architecture (described further below), in Svelte. Things should now be quicker, visually consistent and prettier! The keen eyed of you might’ve also spotted that we’ve swapped out Inter for Timeless Sans. The federated code forge - Anirudh (Tangled CEO) I quiped on Bluesky: “keen eyed? eagle-eyed maybe!” — the new font size is exceedingly tiny. It’s coded as with line height. Tangled is practically unusable for me at this size. It was small before but I could zoom in. The way the new front-end is designed and built doesn’t leave much room for personal remedy. This is not just a subjective opinion there are real accessibility failures here. Below is a screenshot from Tangled’s new user interface design. Visit and experience the new UI yourself. 12 pixels is too small for any meaningful text (which is typically all text). Maybe you feel the size is totally fine? That’s fine for you. But it’s not fine for a significant number of people. You won’t find any accessibility expert happy with that size. (Low-DPI displays may even struggle to render the font legibly.) WCAG 2.2 accessibility guidelines don’t recommend a minimum font size. 1.4.4 Resize Text does require that text can be resized up to 200% “without loss of content or functionality”. Tangled uses pixel units in CSS for font size † . That means the UI won’t adapt to the browser default setting. I can force a minimum font size and look what happens. † Correction: I was wrong about pixel units everywhere (I misread the computed values), it’s on the element that blocks the relative units from scaling properly with browser settings (an easier fix) . Text lines get too close for comfort. Characters are starting to get clipped. See the “g” descender in “Tangled” for example. And if I force a 200% resize at this happens. Oh dear! Text that is “clipped, truncated or obscured” is a failure. Remember that the WCAG guidelines are a floor. Nothing can be perfectly accessible, but a font size and basic front-end failures are a concern. A proper audit would reveal other issues (e.g. with how media/container queries adapt to font size). I’m not posting this to seek employment myself or to provide answers. I want to remind readers that accessibility concerns affect everyone. Serious projects should seek professional expertise. It’s disappointing to see yet another tech start-up fail the basics. I’ll provide two suggestions for free though: (Edit: see correction above, the fix is even easier.) Frankly, what Tangled’s redesign suggests to me is that nobody involved with the process gave accessibility enough thought (if any) (edit: that part was unfair, there was some effort but far from adequate testing) . That may sound harsh but it’s usually the reality from my experience. Whatever the case, Tangled must do better in this area. If I may answer a few predictable but hypothetical comments. This is just v1. Things will improve. I’m sure they will and maybe even pushed by my criticism. The struggle is that accessibility concerns must be integral to design from day one, not an afterthought to patch. It’s open source, where’s your merge request? Sorry, once a project crosses the line into venture capital “open source” takes on a different meaning. If people want to contribute that’s their prerogative. Personally, I’m not in the habit of giving away professional expertise for free to a for-profit business. Such expectations are especially a problem for accessibility specialists (of which I am not). Aha! What about this accessibility failure on your website?! That’s a bit embarrassing, but thanks for the heads-up! It’s far easier to hire an accessibility expert before you ship but it’s never too late to retroactively make improvements. I’ve been making accessibility improvements on my own website for decades. I like Tangled and I want to see it do well. Maybe someone will share a milkshake duck or they donate to fascist Linux and I’ll eat my words. I really hope not! I hope Tangled improves so that those lingering in GitHub’s slop graveyard have fewer excuses to hang around. Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds. Use relative units for font sizes Use unit-less numbers for line height

0 views

A Mastodon bot powered by iOS Shortcuts

In short: I use iOS Shortcuts to run a Mastodon bot. I run a Mastodon bot that posts random quotes from The Legend of Zelda: Link’s Awakening . (The writing in that game is so charming!) I used to run it off a server, but for the past few days, it’s used an iOS Shortcut on my phone. The bot is called Ulrira, named after a beloved Link’s Awakening character . Ulrira (the bot, not the character) samples a line from the text dump, then makes an HTTP request to post it. Here’s a screenshot of the full thing: As you can see, everything here is hard-coded, from the server credentials to the file name. (It probably wouldn’t be hard to make this more generic, but I didn’t bother.) This used to be a short, hand-written Bash script. I used the new AI-powered Shortcut creator and prompted this into existence. I said something like, “Here’s a Bash script. Turn this into a Shortcut.” Like a lot of LLM output, it wasn’t quite right, but it was useful for getting started. Shortcuts doesn’t seem to have an elegant way to express something like “run this every 6 hours”, so I created four additional scheduler Shortcuts that call the main one. They run at 12am, 6am, 12pm, and 6pm. That means there are five shortcuts in total: one to actually make the post, and four to schedule the main Shortcut at different times. I didn’t want to pay for my server anymore, nor did I want to maintain it. When I went looking for alternatives, they either (1) cost money (2) had some significant limitation (for example, GitHub Actions requires me to update the repo every 60 days). This solution runs on a device with high uptime and is effectively free. If you’re a pro software genius, you might complain that this is not reliable! It doesn’t work if my phone is offline, for example. Or what if I change timezones? But in the words of Link’s Awakening : You’re good! You’re a pro, aren’t you? ………… Well, beat it! Pros aren’t allowed in here! Follow the bot here .

0 views
Hugo Yesterday

PaaS, Coolify, Terraform and AI: How to Manage Your Infrastructure in 2026 When Launching a Startup

I created my first company which went well 14 years ago and I was able to grow that company from 0 to over 700 employees. You can imagine that the constraints when starting, the working methods, the tools, are very different from what you might encounter in most companies you know. You don't work the same way at 0 and at 700. You need to be fast, you need to build an application that people want to use without burning mountains of money you haven't earned yet and it's for all these reasons that I chose not to take care of the entire software infrastructure part at the beginning. What I call infrastructure is the servers, databases, backups, everything that's invisible to most people but essential for an application to function. It's essential, but overall everyone doesn't care about it. It's not that which allows you to sell a product. Good infrastructure but with a bad application doesn't work. And if you spend too much time on infrastructure, you don't make a good product. Obviously it still needs to work but you can delegate it, I would even say you should delegate it. Infrastructure should be a non-issue for several years when you start. So back then I chose to use a PAAS, a platform as a service, which precisely allows you to delegate all the infrastructure to people whose job it is. And whenever I saw people starting companies but starting to tell me about Kubernetes or Docker, I would systematically tell them it was far too early to talk about that. I always saw that as a bad signal whenever someone spent their time explaining to me how they were making their product, not what product they were making. The nuance is important. Now, I'm changing my mind. Except for Kube. I just launched a new product, Kula , the world has changed, company creation has changed and it might be time to reconsider some choices. So we're going to talk about PAAS, coolify, dokploy, easypanel, terraform, AI and how we can deploy applications in today's world. In 2014 I wrote an article on exactly this subject (in french). Because in 2014 we were leaving Heroku, our PAAS at the time to go to an OVH server. A PAAS is, in very simplified terms, an execution environment that allows you to run your applications. A PAAS manages for you web servers, databases, backups. It should allow you to collect and analyze errors that occur, alert you if you're running out of memory or CPU. We left Heroku because in 2014 we were starting to hit the limits of what PAAS could offer. Among the important limitations I could mention: In 2014 with Malt we needed precisely to be able to route Web requests to several different applications. For example the /search page was a separate application from the one that served the /profil page. Despite everything, in hindsight, it was a dangerous choice. The company was only 2 years old and I had to do a lot of ops to reproduce a satisfying developer experience on OVH. That's time I didn't spend elsewhere. Fortunately I already had experience on the subject and good mastery of certain automation tools like Ansible which limited the damage. But it was also an economic choice. A PAAS could quickly become expensive. Each resource (a database, a server, a process) is billed independently. And in 2014 at Malt, I can tell you we counted every euro spent very carefully. Okay, but I'm talking about Malt in 2014. Then the company grew well, we doubled in size every year. In 2017 we hired our first ops. We started doing OVH Cloud. In 2018 we went to GCP and we were no longer off by 100 euros. But that's not today's subject. What interests me is the startup phase. Since 2024 I left Malt and started creating products again. I love doing that. I find the first steps exciting. You have to know how to deal with constraints, be creative. I first launched Broadcast in 2024, a newsletter sending service for static blogs. Then Pulse in 2025 while I was living in Japan, an analytics service for blogs. Connect in 2026, a comment as a service (like Disqus). Writizzy in 2026 as well, a blogging and newsletter platform, a competitor to Substack or Beehiiv. Until now, it was the most ambitious and largest project. And for all these projects I used a new range of tools that I discovered in 2024, self hosted PAAS. They are PAAS, but they are PAAS that you can host yourself. I chose Coolify, which I already talked about in an old article . First of all, obviously, that changes the price. Today I run Coolify on two machines, with all my applications, all my databases. That represents more than thirty resources and it costs me 45 euros per month. Remember, I'm back in startup mode, so with very little money and it's therefore a heavyweight argument. No commercial PAAS can allow me to run all these resources for that amount. It would be at minimum between 300 and 1000 euros per month. I lose time on it, I have had some cold sweats with system updates, connection losses, machines that break down. But the fact of using a PAAS, so software that takes care of all deployment, monitoring, logs is a significant gain. Even if I need to understand how it works, I'm not obligated to spend as much time on it as if I had to manage everything manually and dive into the workings of Kubernetes for example. But, with more than 30 managed resources, I started to feel some limitations and especially, I realized that maybe, maybe I was going in the wrong direction. What if AI could become an excellent ops for me? I love Coolify, but there are still important limitations: This last point, if you have only one application, it's not very serious. But I already have too many applications. If I need to bring up an entire server, I'll have to reconfigure everything and I really don't want to. I'm exaggerating, Coolify's database itself is backed up in snapshot mode but it's a bit more painful and it doesn't allow me to easily migrate to another service, like Dokploy or EasyPanel. So I tested something else. I asked AI… Yes, ops takes time, it can be complex and you can't mess up. But writing code that allows you to automate your infrastructure, your network topology, your backups, your observability, that remains an excellent idea, much better than making dozens hundreds of clicks on an interface. Because code can be versioned. And I'm telling you that, I've already done Ansible, Capistrano and shell batches, so I'm not discovering that in 2026. But I also know that writing code is long and once again, it's time you don't spend on the product. Except… if AI writes it. In October 2026 I decided to take advantage of the experience I acquired on Writizzy and Broadcast around email sending to launch another product: Kula . Kula is a marketing and transactional email sending tool. I manage sequences, segmentation, analytics tracking, deliverability management and it's now the email sending backend for Writizzy and Broadcast. If you're already a customer of sendgrid, mailjet, brevo, or resend, don't hesitate to test. Plus I'm generally cheaper . Except this time I didn't want to use Coolify again for Kula. So I used AI to create Terraform scripts to control my infrastructure (at Hetzner, Bunny.net and AWS). I added continuous deployment, rolling upgrades with Caddy , incremental backups with WAL , logs collected in dozzle . And all that took me less than 1 hour to set up. I can bring up my entire infrastructure more easily, I manage and version my secrets with Sops, I lowered my RPO from several hours to 1 minute (RPO is the maximum possible data loss) and I can control everything from my code, by running scripts. Finally, my LLM can control everything. Now, if you didn't understand RPO, Sops, WAL, rolling upgrade and overall what I just said seems as clear as Chinese to you, it's because I may have misled you… In reality I haven't totally changed my mind. I still believe you should delay ops as late as possible but with much more nuance than before. You do ops anyway, even with a PAAS, but a large part is simplified, pre-digested for you. Except that precisely, you delegate choices to people who know how to do it without always understanding the compromises they made for you. You hadn't necessarily understood before now that your backups were imperfect. You hadn't perhaps realized that your secret management was a mess before I mentioned it to you. Creating IT projects is constantly making compromises between costs, risks and gains. And you can't maximize all three. Low risks and many gains requires a lot of budget. Low budget to get many gains, it's necessarily because you're taking risks. Etc… It's not a problem to solve, these are choices to make. So if you lack general knowledge, if you decide to do everything directly with AI, it might send you crashing into a wall because you won't understand the compromises that were made. It's true, there's no longer as much argument about loss of time as before. You can go very fast. But going fast into a wall isn't necessarily an advantage. In my case, I wasn't starting from scratch, far from it. So I knew where to go. I was already doing ops by choosing to use Coolify in self-hosted mode and then I had some experience, including in much larger companies. I understand the compromises I'm making. When I say that I launch a new company using terraform, I'm taking a shortcut. I've been launching products since 2011. And since leaving Malt, I have 2 years under my belt with Hakanai, Writizzy and Kula. When I say I took 1 hour to set everything up. It's true, but I took 25 years to learn to set it up in 1 hour. So let me rephrase. If you have no knowledge or experience of ops, infrastructure, take a PAAS. A very simple PAAS that you don't host yourself (Clever Cloud, Scalingo, Sevalla for example). The cost will remain acceptable and you'll have the opportunity to learn on a stack that's managed for you. (I came across koyeb too while writing the article but I'm having trouble positioning it between PAAS and IAAS, don't hesitate to give me info if you know) If you have knowledge but you're still in prototyping phase with still few applications to manage, choose a market PAAS or a self hosted PAAS, Coolify, Dokploy or EasyPanel. Here you'll prioritize cost and flexibility. If you're really knowledgeable, you can go to dedicated servers controlled with terraform. It's the advanced version of the previous option, focused on cost and flexibility. As soon as you have volume, and several applications, some architectural complexity and a budget to finance it, then you can start looking at IAAS (infrastructure as a service), DBAAS etc… I recommend Scaleway or Hetzner. In short, it's hard to launch a company. It's even harder to learn all the necessary trades at once. Even with AI. Don't waste time on what you don't yet know how to do. However, as soon as you've gained the experience, tell yourself that many things that were very time-consuming before is now much more accessible. Revisit your preconceived ideas on the subject and test. You might be surprised. There was no notion of private network. A private network is what allows your application to communicate with a database without going back through the internet. So the database is only accessible within your network. Most PAAS offerings didn't provide that. There was no notion of web frontend. A web frontend is a server that we place in front of one or more applications. This allows, among other things, to have different applications that are used for different parts of a website. Coolify doesn't allow multiple nodes of the same application There's no secret management. All environment variables are in plain text. You have to use a service like infisical . Monitoring exists but remains quite light. Backups are only in snapshot mode. That is to say you take photos of the database at regular intervals but in case of a crash, you lose all information since the last backup. it's clickodrome. You can hardly automate the fact of rebuilding resources, especially since the api is limited.

0 views
Sean Goedecke Yesterday

How to get assigned important work in big tech companies

To get a good reputation in tech companies, you need to work on important projects. However, you need a good reputation first in order to get assigned important projects. Doesn’t that make it impossible to get started? I get a lot of emails from engineers who are struggling with this problem. They go like this: I work with a strong senior engineer. I feel like my manager structures work so that strong engineer always gets the visible work, and the more they do, the more opportunities they get, while I sit on the sidelines. My manager agrees with me that it’s time for me to start leading work myself, but every time a new project appears it always goes to the strong engineer. What do I do? This is a good case study for what I think of as “tech company theory of mind”: understanding the actual incentives that motivate decisions in tech companies, instead of the formal process. According to the formal process, projects should probably be assigned round-robin to whoever has capacity and isn’t currently working on one. But (as my emails complain) this is almost never how it works in practice. Managers care about giving their employees chances to build a reputation, but they care more about developing their own reputation as someone who can deliver. High-profile projects are the best opportunity for new people to step forward and get known, but blowing up a project 1 like that is the easiest way for a manager to tank their own reputation. They will thus typically hand these projects to someone they know can deliver, while simultaneously promising (including to themselves) that next time they’ll take the risk of letting another person lead it. Of course it’s a vicious cycle. The more you rely on one person, the more reliable they become and the less reliable their colleagues become, since they aren’t getting the relevant experience. It’s not very sustainable. However, the average manager tenure in big tech is only a couple of years 2 . Given that, it’s rational for individual managers to take the long-term risk in exchange for mitigating the short-term risks of project failure. So what can you do about it? I wrote about the classic approach years ago in Ratchet effects determine engineer reputation at large companies : Note that this plan does not involve convincing 3 your manager that you need projects for your career development, or that it’s unfair for you to be overlooked, or that the formal process would mean you should get to lead projects. You are not going to be able to change your manager’s incentives, but you may be able to position yourself so that your manager believes their incentives line up with yours. The problem with this plan is that it’s slow . It takes months or even years to piece together a reputation like this. That’s slow enough for bad luck to intervene by handing you a failure you can’t avoid, or having your manager leave, or for the fundamental nature of software engineering to change . What can you do that’s faster? The fast path to getting assigned interesting work involves taking risks. This is all dangerous advice . Follow it at your own peril. One way is to build a relationship with your skip-level . If your manager’s manager thinks you’re a stone-cold killer, you are basically guaranteed to get assigned interesting projects. They will straight-up tell your manager “why not put X on this?”, and your manager will rationally decide (a) that it’s in their best interests to do it, and (b) that if you screw it up, it won’t be their responsibility. But it’s not so easy to build a relationship like this. Very senior managers are skilled political operators 4 who are good at identifying when people are trying to persuade them. If they think you’re coming on too strong, that will hurt you far more than it helps. Unfortunately, the most reliable technique for building a relationship with your skip-level is to just be reliably useful to them over a long period of time, which puts us back to the slow way. Another fast way is to make side bets . I wrote about that here , but the idea is simple: figure out and implement your own projects. Work that you decide to do is work that doesn’t have to be assigned to you, so if you independently identify something important that needs doing, then do it, you’ve manufactured your own project out of thin air. I think every senior engineer should be trying to do this all the time. The risk of making side bets is that if they don’t work, or turn out to be less important than you think, you’ve entirely wasted your time. Worse, many managers will get annoyed at engineers who try this, because it can make managers look in meetings like they don’t know what their team is working on. Finally, the best fast way is to impress your engineer colleagues . This only really works on a team with a healthy culture, but when it works it’s very smooth. Managers are slow to form opinions because they’re not close enough to the engineering coalface to know who’s doing quality work 5 . Engineers are informed enough to form opinions quickly. At least I am: it only takes a few “oh, you saw something I didn’t” moments for me to decide someone’s good. On a healthy team those engineers will tell their manager that, who will decide that you must be good, and will give you important work far earlier than if you’d had to prove yourself from scratch. On a kind of crappy team, engineers might not be good enough to recognize strong engineers, or they might not communicate freely enough to tell your manager about it. On a really unhealthy team, engineers will actively trash-talk competent colleagues because they (correctly) see them as the biggest threats. If you’re on a team where all the interesting work is going to someone else, you have a reputation problem. It’s probably not personal: your manager is simply incentivized to give new work to known reliable engineers, which is a vicious cycle that leaves you out in the cold. Fixing that can be a safe slow process or a risky fast process. Either way, I don’t recommend simply trying to convince your manager in 1:1s that it’s unfair to leave you out of projects. Tech companies are not supposed to be fair , they are supposed to make money. You’re better off finding a way to make it look like it’s in your manager’s best interests to assign you that work: either by appealing to your skip-level, finding projects of your own, or building a reputation with engineers your manager already trusts. One reason some people find this point tricky to grasp is that they underrate just how hard it is to ship anything . Projects fail all the time . No manager can afford to be sanguine about the risks. I linked the first crappy source I could find, but my main source for this is just noticing how long the managers in my workplaces stick around. You don’t even necessarily have to tell your manager you’re looking for bigger projects, though I think you probably should. Almost certainly more skilled than you, due to selection effects and the fact that they get way more practice. They typically have to rely on results, which is a slow proxy for technical ability. Focus on reliably shipping small, low-risk pieces of work Communicate to your manager and team that you’ve done that Use that reputation to get slightly higher-risk pieces of work Avoid any mistakes that will ratchet up the perception of you as unreliable Eventually you will be considered a safe prospect to handle important work One reason some people find this point tricky to grasp is that they underrate just how hard it is to ship anything . Projects fail all the time . No manager can afford to be sanguine about the risks. ↩ I linked the first crappy source I could find, but my main source for this is just noticing how long the managers in my workplaces stick around. ↩ You don’t even necessarily have to tell your manager you’re looking for bigger projects, though I think you probably should. ↩ Almost certainly more skilled than you, due to selection effects and the fact that they get way more practice. ↩ They typically have to rely on results, which is a slow proxy for technical ability. ↩

0 views
Unsung Yesterday

Pac-Man’s siren call

(It’s the last day of Halloween Week on Unsung, where we’re sharing scary, spooky, and creepy stories. This is a story of how my bug scared others.) In 2010, Google’s homepage celebrated various occasions with reimaginings of its own logo called doodles, but we wanted to do something extra special for Pac-Man’s upcoming 30th anniversary – and through a set of circumstances that began with me randomly sitting in the cubicle right next to the doodle team, I was asked to write the code. It was, frankly, a terrifying proposition. The homepage was then a very important destination, and my job title was only adjacent to “software engineer.” But I started researching the game and recreating it all in HTML and CSS, not dissimilarly to the iPod Apple just put on their pages to celebrate a different anniversary . (The research was tricky because we didn’t want to reach out to Namco for help too soon, instead planning to wow them with a close-to-finished doodle. Luckily, some nerds on the internet researched Pac-Man intensely , so I could stand on their pixellated shoulders.) It was important for me to stay truthful to the original game, with only some very deliberate exceptions – the price of entry was the playfield having to resemble Google’s logo, and I also added a Ms. Pac-Man mode as an easter egg; the already-classic I’m Feeling Lucky button was reimagined as Insert Coin. I even added a few bugs that I learned existed in the original Pac-Man. But I also introduced at least one important bug of my own making, one that backfired on launch day. We wanted the game to have sound, because so many of Pac-Man’s sounds are beyond iconic: the starting melody, the waka-wakas, the death jingle. This presented a little technical challenge, since I hoped for the doodle to be a showcase of what pure HTML and CSS could do, but sound still needed quiet (huh) support from Flash. However, Flash was, by then, installed in a lot of browsers, so that worked out okay. The project was all was going really well. I had fun coding the game and we seemed to have fun playing it. Namco eventually got onboard, too, including greenlighting the Ms. Pac-Man addition that I only later learned had a pretty complex political story . We felt so happy about the progress, as a matter of fact, that the leadership wanted the doodle to feel even bigger. And at some point, we thought about the game autoplaying on the homepage after 10 seconds of inactivity – just to let you know that you could have some fun in a place you might not have expected it. I was happy with that – if there was anything scary about it at the time, it was only the thought of my code getting even more exposure – but I wasn’t worried about distraction, since the homepage was not a destination page you would ever linger on. As you can piece together, Pac-Man would also, as a consequence of all these decisions, autoplay with sound. We knew that, I think, and in that moment it felt like… it would probably be okay. In hindsight, it wasn’t okay, but it also was not okay in a way that none of us expected. = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/pac-mans-siren-call/2.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/pac-mans-siren-call/2.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/pac-mans-siren-call/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/pac-mans-siren-call/3.1600w.avif" type="image/avif"> The launch day came. A couple of people on the team and I pulled an all-nighter that included putting in some finishing touches, and preparing an internal tournament version of Pac-Man. Personally, I was petrified. I was but a designer on the user experience team. Sure, my code went through all the proper reviews – but I still couldn’t believe it would be allowed, verbatim, on one of Google’s most valuable properties. We toggled the switch at 9am San Francisco time. Within hours, the world once again went wild for Pac-Man. Soon, I watched feedback arrive in torrents too huge for me to ever catch up with. I was asked to do press interviews. I saw Twitter crash. Most importantly, I witnessed reports from all over the world of people playing Pac-Man in all sorts of circumstances, on all sorts of devices (HTML!). And indeed, we got a few reports of the “there is a really scary sound coming out of my computer” variety. But they didn’t come through the channels we expected. And when we suggested “the quick workaround is just to close the tab with Pac-Man,” invariably the answer would be: “What Pac-Man?” This is what we figured out over the next frantic few hours. Some people using the then-ultrapopular Firefox installed an extension called CoolPreviews, which allowed them to quickly preview pages by hovering over links. The extension would quietly start at the same time Firefox was opened. And it would immediately, in the background, invisibly and unbeknownst to the user, open a website. I am not sure if that decision was to prime the cache, or whether it was just a forgotten placeholder. That website was Google’s homepage. You probably already know what happened. On that particular Friday, google.com had an auto-playable Pac-Man doodle with the sound on. If you used Firefox with CoolPreviews installed, the plugin would quietly open Google’s homepage in the background whenever you launched the browser, and 10 seconds later… Imagine this for a second. You sit down Friday morning and power up your computer. For you, there’s nothing unusual about this Friday. You don’t have to use, or even know about Google. You might not know what browser you use — or what a browser is. As a matter of fact, you might not even be using your browser; perhaps it has been minimized and sits unobtrusively in the toolbar at the bottom of your screen. You might not know about CoolPreviews, or even the concept of plugins or extensions. Perhaps you’re just checking your mail or warming up for today’s first round of Solitaire. Then, out of a sudden, out of your speakers comes blasting a siren of an invisible Pac-Man game having infiltrated your computer in the most unusual manner. I know Google feels different now, 16 years after this story took place. I know we are all tired of websites that autoplay sound and that decision we’ve made feels uncomfortably close to “growth hacking.” But the story takes place in that slightly more naïve era of 2010. I pushed a patch within hours. It ended up being the same solution many browsers do by default today – we added a visible mute button, and you now had to first touch the game in some way (a keystroke, a click, multitouch, or the Insert Coin button) for the sound to activate. Since CoolPreviews didn’t do that, it fixed the “possessed computer” problem. Ironically, I don’t believe we ever heard of normal people being bothered by the autoplay – it seemed that indeed, few people stayed on the homepage for 10 seconds doing absolutely nothing. The funny thing is that emergency live-patching internet’s at the time most valuable homepage was perhaps the scariest part of that day for me, but that completely went over my sleep-deprived head. And eventually, my job title changed. How close it felt to a “software engineer” is up to you to decide: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/pac-mans-siren-call/5.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/pac-mans-siren-call/5.1600w.avif" type="image/avif"> (I wrote a story with the same title in 2015, but it got mangled online, and I’m unhappy with the writing now – so this is basically a complete rewrite of that essay. You can still play Google Pac-Man doodle , with the sound now reimplemented sans Flash.)

0 views
Unsung Yesterday

“This wasn’t a thoughtfully designed menu.”

(It’s the last day of Halloween Week on Unsung, where we’re sharing scary, spooky, and creepy stories.) On the morning of January 13, 2018, residents and tourists in Hawaii saw a frightening message on their phone screens: = 3x)" srcset="https://unsung.aresluna.org/_media/this-wasnt-a-thoughtfully-designed-menu/1-framed.1600w.avif" type="image/avif"> In addition to being sent to 1.4 million people, a version of the alert also interrupted local TV and radio programs. Quickly, the officials realized that something went wrong and seeked to undo what ended up being a false alarm. The siren warning system that would normally follow wasn’t activated, and various channels were used to inform people to ignore the alarming message – however, a second phone alert to follow the original one wasn’t sent out for 38 more minutes: = 3x)" srcset="https://unsung.aresluna.org/_media/this-wasnt-a-thoughtfully-designed-menu/2-framed.1600w.avif" type="image/avif"> In the meantime, many Hawaii residents sought shelter, flooded 911 lines, and called their families to say good-bye. What was the reason for the mistake? Industry veteran Jared Spool wrote a post explaining it in detail . We are not 100% sure, but the interface to deploy alerts likely looked like these two examples: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/this-wasnt-a-thoughtfully-designed-menu/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/this-wasnt-a-thoughtfully-designed-menu/3.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/this-wasnt-a-thoughtfully-designed-menu/4.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/this-wasnt-a-thoughtfully-designed-menu/4.1600w.avif" type="image/avif"> First, it seems like it was too easy to send a message that wasn’t a test. There was no friction for the consequence this heavy – not even a dialog box to click through, let alone something that more deliberately slows the user down, perhaps even spelling out the consequences (“you are about to send an all-caps message to 1.4 million people”), and generally feeling heavier and more cumbersome to complete than drills or local messages normally sent out. But the true root of the problem happened earlier than that. Spool: This wasn’t a thoughtfully designed menu, any more than any random collection of user-named objects are. In the menu, it wasn’t just that the ordering felt completely random and the capitalization and labelling inconsistent, so neither could be used to help guide the user (for example, by putting drills above real messages, or by using all caps only for most serious, non-test commands). It was also the fact that and were really hard to distinguish from one another. In the end, it wasn’t just about stress and panic that engulfed the Hawaii islands for a better part of a morning hour. It was also about undermining the trust in the entire system, as any “text message that cried wolf” will see people become desensitized, or even opt out . = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/this-wasnt-a-thoughtfully-designed-menu/5.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/this-wasnt-a-thoughtfully-designed-menu/5.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/this-wasnt-a-thoughtfully-designed-menu/6.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/this-wasnt-a-thoughtfully-designed-menu/6.1600w.avif" type="image/avif"> You might never be tasked with creating an interface to do this kind of stuff, but there are some universal lessons in here about information architecture, labelling, and friction. At some point when I was at Medium, I fought with this kind of a thing, where three similar words to popular destinations appeared in the menu right next to each other: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/this-wasnt-a-thoughtfully-designed-menu/7.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/this-wasnt-a-thoughtfully-designed-menu/7.1600w.avif" type="image/avif"> And today, the general industry flattening of visual style leads to an occasional conflation like this one : = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/this-wasnt-a-thoughtfully-designed-menu/8.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/this-wasnt-a-thoughtfully-designed-menu/8.1600w.avif" type="image/avif"> The consequences of this design doppelganging won’t be nearly as severe as in Hawaii, but if you’ve read Unsung even for just a bit, you will know what is my general point of view on this: we are better equipped to understand big events like the one in 2018, but it’s harder to see and impossible to tally up the frustrations of everyday small confusions and paper cuts adding up over the years.

0 views

Animals

“Dad was the first to say, ‘Something is killing animals.’ He was the first to say, ‘It could be that we’re the carriers. We’re the ones making them sick.’ He was the first to say, ‘Something is bringing them back.’” Teddy is fifty when he decides to tell the story of his childhood, both the terror and the grief and the brief moments of astonishing, incredible intermingling, as a pandemic rewrites animal and human DNA and gives children a glimpse of what might have been, just as it’s been forever lost. Part plague tale, part zombie lore, Animals is a story of what happens when humans wreck the animal kingdom and the animals fight back. View this post on the web , reply via email , or become a supporter .

0 views
Unsung Yesterday

“In the middle of the game, slowly and surely wiggle the cartridge.”

(It’s the last day of Halloween Week on Unsung, where we’re sharing scary, spooky, and creepy stories.) Blowing onto a cartridge before inserting it into a game console has been a longstanding source of debate. It’s an image so iconic it could be juxtaposed with a pencil next to a cassette tape, or holding the TV aerial for better reception – yet modern understanding of the issue is that it actually makes things worse, as bits of your saliva on contacts make them corrode over time. But what if you ventured out to do the opposite? What if you wanted to intentionally mess up with the cartridge connection and see what happens? Well, this is apparently called cartridge tilting , and is a curious pastime: Cartridge tilting is not a glitch, but rather the process which creates glitches. This can only be done on any NES, SNES, Nintendo 64, Leapfrog LeapPad, Sega Genesis/​Mega Drive, Sega Master System, or Game Boy series console. Most other consoles either use CDs/​DVDs, or the design of the system doesn’t allow for cartridge tilting, and thus cannot perform these glitches. In the middle of the game, slowly and surely wiggle the cartridge and move it from side to side. If you do it too slow, nothing will happen, and doing it too fast will disconnect the game. Eventually, the cartridge will enter a state where it’s not fully connected to the console but not completely disconnected. Thus, enough information from the cartridge is blocked to glitch up the game, but not enough to make it freeze, crash, or otherwise error out. The page above lists a bunch of examples and there are tons of videos on YouTube. I’ll let you find them if you want, but I want to show you the most famous one. This is the regular opening of 1997’s GoldenEye game for Nintendo 64: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/in-the-middle-of-the-game-slowly-and-surely-wiggle-the-cartridge/yt1-play.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/in-the-middle-of-the-game-slowly-and-surely-wiggle-the-cartridge/yt1-play.1600w.avif" type="image/avif"> And this is what happens when you wiggle a cartridge as it’s playing . This results in music being garbled, and as for the visuals – well, see for yourself: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/in-the-middle-of-the-game-slowly-and-surely-wiggle-the-cartridge/yt2-play.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/in-the-middle-of-the-game-slowly-and-surely-wiggle-the-cartridge/yt2-play.1600w.avif" type="image/avif"> For some reason I find this so, so funny. Knowing everything you know about how games work, you definitely would not expect this to happen. Somehow, this glitch (which became a meme ) has a positively analogue quality : Doing this can cause some games to corrupt or erase their save data. Doing this can ruin your cartridge and possibly damage hardware. Doing this can freeze, hang (permanently freeze), or crash your game. This will also glitch your sounds and can even be loud. Doing this also can cause short circuits.

0 views
Unsung Yesterday

“An unnamed arcade in some sleepy suburb of Portland”

(It’s the last day of Halloween Week on Unsung, where we’re sharing scary, spooky, and creepy stories.) A great video about Polybius from Ahoy/​Stuart Brown: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/an-unnamed-arcade-in-some-sleepy-suburb-of-portland/yt1-play.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/an-unnamed-arcade-in-some-sleepy-suburb-of-portland/yt1-play.1600w.avif" type="image/avif"> Polybius was a rumoured rare or secret 1981 arcade game published by Sinneslöschen that was addictive and had adverse effects on its players, causing hallucinations, amnesia, and seizures. In contrast with some of the August 32 videos which sport a certain “we know the authors denied this, but ” posture, this video doesn’t waste time pretending Polybius is anything more than an urban legend. Instead, it goes straight to investigating what happened and who might have started the rumour. It’s a really fun watch – and a really well-made mini-documentary, too – and ends up being a meditation on mythmaking in general.

0 views
Kev Quirk Yesterday

Discoverability Is Only Solved If You Can Be Discovered

by Widdershins This is a follow up to my post where Widdershins talks about how they agree with certain parts of my argument, but that the discoverability piece is flawed. Read post ➡ Saw this in my RSS feed and thought it was an interesting take that's worth sharing - also Widdershins' blog is excellent. I'd recommend adding it to your feed reader. I think the argument around other people controlling the gate to discoverability is a sound one, generally, but sites like Bubbles tend to add most sites, unless they're somehow obnoxious. So inclusion (and therefore discoverability) is only an email away . Having said that, one person's obnoxious is another person's heaven, so it's all subjective. Either way, it's an interesting debate and I'm glad we're having it. Go check out Widdershins' blog too! Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️ You can reply to this post by email , or leave a comment .

0 views
fLaMEd fury Yesterday

Open Tabs October 2026

What’s going on, Internet? If you don’t follow my Bookmarks through the feed , then here’s the bookmarks from October. Enjoy. Bit of a theme this month, the old web was messier and more fun, and running a site now keeps getting harder. For more, check out the bookmarks archive, and subscribe to the feeds if you want these as they happen. Hey, thanks for reading this post in your feed reader! Want to chat? Reply by email or add me on XMPP , or send a webmention . Check out the posts archive on the website. Jenny O’Connor on why the embarrassing internet was the good internet . My old fan pages agree. Winnie Lim on why running a personal website is not fun anymore . Rough read. Between AI bots scraping the fuck out of the open web and hackers using AI agents to find holes, no wonder. Aaron’s Early Web Links is a one-person directory of personal homepages, covering all types of personal websites. wulfpaper on why making websites shouldn’t seem so hard . Start with the writing, worry about code and design later. A big alphabetised list of old linkware webset graphics sites . Handy if you’re after that old-school look.

0 views
ava's blog 2 days ago

rose ▪ bud ▪ thorn - october 2026

Bear with Krobus, poor guy doesn't understand the game... Published 31 Oct, 2026 At the moment I have none for days like these, but I would love to have one so I am not bound to the home as much and my wife can at least push me on a walk or to the café, even when that is still exhausting; at least I could experience the outside without having to walk and having to sit down from exhaustion very soon. It would also save me from the barren wasteland that events and conventions usually are for seating. I'm aware that there is still a lot of stigma around using wheelchairs, walking sticks and the like, and there are still ignorant strangers out there who think you are faking it if you can get up from your wheelchair for a minute or so or don't need it literally all the time, but my comfort and mobility is honestly more important to me than the opinions of jackasses. I've wished for a wheelchair like that since I was just about 15 years old, for reference. Half my life. I just don't know where to get a lightweight, affordable, possibly secondhand one yet, because insurance wouldn't pay for that in this case. ↩ I had a great start studying for this semester :) I set up everything on the 4th: Downloaded all materials, signed up for all live sessions, put all dates in the calendar, ordered all books I need, and hit my reading goal all in one day, despite my struggles (aided by medication and lots of support from my wife). I was very consistent with it since! Went hard at the gym when I had painfree times in the middle of the month. Sent a care package filled with coffee, tea, baked cookies, and cat socks to a friend. I finally bought FFXIV and a subscription after spending ~330h in the Free Trial. Treated myself to nice stuff this month and going out more with my wife. I asked a matcha café in the city to please add allergen information to their order terminals and they did! I went to the Spiel convention in Essen. Got a good annual performance review, with lots to look forward to in the next few years, and applied for additional courses paid for by my employer. Learning how to deal with (or entirely avoid) food noise that has plagued me for years. It's going well. Working on a big blog post that still takes me a lot of time... it is draining... Planning a cool project with the Gazette people. The blog has been a bit quiet, but not forgotten. Most of the month, I suffered with extreme exhaustion, fatigue and pain. Sleep was great and plenty, but I was still soooo tired all the time and could barely do or think anything. Dealt with a lotttt of burning pain in my bones, muscle weakness and pain, and under my skin as well as in my hips and lower back; standing was hard. It brought back wishes for a foldable wheelchair 1 . These monthly posts made me realize there is always some short of illness stuff going on, and this month was especially bad, so next month I will switch medication. Goodbye, adalimumab. I made a mistake in my study plans and it affected my entire planning until the exams in March :/ I've been having issues with my main laptop and random restarts and kernel panics... may need to wipe and reinstall. My indoor spin bike broke and we haven't managed to fix it yet :( Time passed super fast. I blinked and it had been weeks between messages, emails, blog posts... I had to prioritize differently this month, but I hope I'm gonna be better next month. At the moment I have none for days like these, but I would love to have one so I am not bound to the home as much and my wife can at least push me on a walk or to the café, even when that is still exhausting; at least I could experience the outside without having to walk and having to sit down from exhaustion very soon. It would also save me from the barren wasteland that events and conventions usually are for seating. I'm aware that there is still a lot of stigma around using wheelchairs, walking sticks and the like, and there are still ignorant strangers out there who think you are faking it if you can get up from your wheelchair for a minute or so or don't need it literally all the time, but my comfort and mobility is honestly more important to me than the opinions of jackasses. I've wished for a wheelchair like that since I was just about 15 years old, for reference. Half my life. I just don't know where to get a lightweight, affordable, possibly secondhand one yet, because insurance wouldn't pay for that in this case. ↩

0 views
Evan Hahn 2 days ago

Notes from October 2026

Happy Halloween! Here’s a little of what I got up to in this spooky month. I moved this site from an Apache-powered VPS to CDN-frontend object storage. This means I pay less money, I do less maintenance, and my site loads faster in most parts of the world. Hopefully nobody noticed this change, except that things should be a little snappier! (Also, my old site had a small amount of PHP, which I’m happy to have removed given PHP’s remote code execution vulnerabilities this month.) In an effort to fill in the gaps of the internet , I published a short list of Vim forks . At Ghost, my team shipped two additions to our automations feature: analytics and more granular triggers . Both of these should help our independent publishers grow. More automations stuff on the way! Like every month, I wrote a few articles at Zelda Dungeon , including a debate over, perhaps, the most trivial disagreement possible . The surveillance state takes another step: pinpointing addresses based on interior photos . Thanks, AI! “How Technology Empowers—and Imperils—Dictators” is a reminder that technologists have a social duty. Two lists of tech fascists: “Fashware” and “Weird little guys of FOSS” . Continued to love David Rosenthal’s blog about the (seemingly unsustainable) economics of AI companies. “Keyboard differences between Windows and Macs” is a deep dive into Control and Command and Copilot keys. Data centers are unpopular, a problem Amazon is trying to spend its way out of . “Programming Isn’t Special” argues that programming is art, and that most art isn’t “mystical”, and that using AI to do art has disadvantages. “If we use AI to erase all the copy-writing, all the graphic design, all the boring mundane art, and yes, all the boring custom WordPress theme development, then we will be removing all the practical opportunities for the vast amounts of practice and contemplation required for people to elevate their craft to eventually achieve great things.” A fun AGENTS.md that says, “All LLM contributions are strictly forbidden.” Part biography, part memoir, part hopeful, part depressing… Why Fish Don’t Exist captivated me this month. I plan to consult The Ultimate List of DRM-free Bookshops next time I buy an ebook. Bookmarked this list of “every weird film ever (with a special emphasis on trash)”. As a lifelong Diddy Kong Racing fan, I felt personally insulted by “Bloke Who Preferred The Thinking Man’s Mario Kart Growing Up Also A Weird Contrarian In Other Aspects Of His Strange Life” . Hope you had a good October. I moved this site from an Apache-powered VPS to CDN-frontend object storage. This means I pay less money, I do less maintenance, and my site loads faster in most parts of the world. Hopefully nobody noticed this change, except that things should be a little snappier! (Also, my old site had a small amount of PHP, which I’m happy to have removed given PHP’s remote code execution vulnerabilities this month.) In an effort to fill in the gaps of the internet , I published a short list of Vim forks . At Ghost, my team shipped two additions to our automations feature: analytics and more granular triggers . Both of these should help our independent publishers grow. More automations stuff on the way! Like every month, I wrote a few articles at Zelda Dungeon , including a debate over, perhaps, the most trivial disagreement possible . The surveillance state takes another step: pinpointing addresses based on interior photos . Thanks, AI! “How Technology Empowers—and Imperils—Dictators” is a reminder that technologists have a social duty. Two lists of tech fascists: “Fashware” and “Weird little guys of FOSS” . Continued to love David Rosenthal’s blog about the (seemingly unsustainable) economics of AI companies. “Keyboard differences between Windows and Macs” is a deep dive into Control and Command and Copilot keys. Data centers are unpopular, a problem Amazon is trying to spend its way out of . “Programming Isn’t Special” argues that programming is art, and that most art isn’t “mystical”, and that using AI to do art has disadvantages. “If we use AI to erase all the copy-writing, all the graphic design, all the boring mundane art, and yes, all the boring custom WordPress theme development, then we will be removing all the practical opportunities for the vast amounts of practice and contemplation required for people to elevate their craft to eventually achieve great things.” A fun AGENTS.md that says, “All LLM contributions are strictly forbidden.” Part biography, part memoir, part hopeful, part depressing… Why Fish Don’t Exist captivated me this month. I plan to consult The Ultimate List of DRM-free Bookshops next time I buy an ebook. Bookmarked this list of “every weird film ever (with a special emphasis on trash)”. As a lifelong Diddy Kong Racing fan, I felt personally insulted by “Bloke Who Preferred The Thinking Man’s Mario Kart Growing Up Also A Weird Contrarian In Other Aspects Of His Strange Life” .

0 views
Ratfactor 2 days ago

Inktober 2026

Just finished Inktober 2026. Thought I should post it to my website. (I'm not sure why I don't post more art to my website?) Happy with a fair number of the drawings this month, especially the ones towards the end...

0 views
Abhinav Sarkar 2 days ago

An LC-3 Disassembler in Haskell

LC-3 assembly is an educational programming language. It is simple enough that complex programs can be written directly in it without needing a compiler, and thus it is often used in teaching assembly. An LC-3 textual assembly program is compiled to a binary object file by an assembler, and then executed by a virtual machine . Writing a virtual machine for LC-3 is a fun little exercise. However, in this post, we implement a disassembler for compiled LC-3 binaries back to textual assembly programs. This post was originally published on abhinavsarkar.net . LC-3 has a simple instruction set with only 18 instructions. It works with eight 16-bit registers (numbered from 0 to 7), and 16-bit addressable memory. LC-3 instructions are also 16-bit, with first four bits used for opcodes, and the rest for instruction arguments. There are instructions for doing arithmetic and bitwise logical operations, conditional branching, executing subroutines, loading from and storing to memory, handling interrupts and doing system calls. Some of them take source, destination, and base registers as arguments ( , , and respectively in the diagram above). Some other take integer immediate values, program counter, and address offsets ( , , and respectively in the diagram above). The instruction take a code for the syscall to execute. Notice that we count the bits from right to left, zero-indexed. When written in the textual assembly format, we use mnemonics for the opcodes and syscalls. The eight registers are written as to . The instructions can be labeled and referred from other instructions using them. Let’s start by looking at a simple LC-3 assembly file: As seen above, the assembly file can also contain assembler directives such as , , , , and . Quoting the docs: We assemble the program with the assembler, and then execute the resultant binary with the VM 1 : It works as expected! As much fun as it would be to write an assembler and a VM, in this post, we don’t assemble or run LC-3 programs, we disassemble them. We don’t care what the instructions do, only how they are encoded. Unlike an object file generated from X86 or Arm assembly, an LC-3 object file does not contain section tables separating code from data, symbol tables indicating function and variable names, relocation information, or debug symbols 2 . It contains only raw binary instructions and data that are freely intermixed in a single address space. This is made necessary by the fact that LC-3 has only 16-bit addressable memory. So data blocks and read-write memory addressed from code has to be within \(2^{16}\) bits or 8192 bytes of the code addressing it. Consider these bytes: A disassembler looking only at binary code has no context. A 16-bit word that decodes perfectly as a legal instruction may actually be a character, a part of a packed string, a number/byte literal, or a memory address. We need context to decode correctly, so the disassembler works in multiple passes: Let’s go over the disassembler part-by-part. First, the imports: We use the vector library for instruction lists, and the monad for manipulating them mutably. We also use bytestring for doing binary IO. Here are the data types we use: The type enumerates the eight LC-3 registers. The type represents the condition codes used for conditional jumping, which are negative, zero and positive. The type enumerates the eight standard LC-3 trap codes used for doing IO and halting the programs: The type is the heart of the disassembler. It doesn’t represent only the real LC-3 instructions, but also adds more constructors that are useful for disassembling: This representation lets us handle ambiguous data. Also note that we capture the raw bytes in some instructions like and . Finally, represents entire 16-bit binary code, and is the type for representing an LC-3 object file with an origin address and the binary code. Since we work a lot with bits here, we define some patterns to make it easier and less error-prone: Each LC-3 instruction has a 4-bit opcode, and many have 3-bit register or flag fields. So, we define two new types: (3-bit) and (4-bit), with pattern synonyms for exhaustive pattern matching. By defining patterns through , we map directly to the ISA specification. For example, visually shows the bit pattern for the opcode. GHC’s pragma enforces exhaustiveness, so no fallback cases are needed. The smart constructor functions and take the least significant 3 or 4 bits of the passed 16-bit parameter respectively, and return respective typed bits. First, we decode the registers and trap routines: We see the bit patterns in action here. The trap routines codes are as defined in the ISA. Next, the function extracts the opcode nibble (the most significant four bits), and decodes the arguments by calling , which dispatches on the opcodes: Now, we go over decoding of each instruction one-by-one. has two variations: one that takes two source registers, and another that takes one source register and one immediate value. First, we extract and decode the destination and first source register. Then depending on the sixth bit, we either decode the second source register or the value. The value is sign extended by calling the helper function . When decoding the second register, if we find that the forth and fifth bits are not , that means this is not a valid instruction. In that case, we return the raw bytes wrapped in the constructor, because the malformed instructions are far more likely to be data that happens to have an opcode prefix. Capturing them as lets us treat them as data in the later steps. This same pattern is used in decoding other instructions as well: extract and decode registers, flags, and values, and check fixed bits for validity. If valid, return the decoded instruction, or else the raw bytes. The instruction has exactly same format as the instruction, except for the different opcode. To decode the instruction, we decode the registers and check for the fixed bits. Decoding the instruction requires us to decode the condition flags, which is a straightforward mapping from their bit patterns. In case no flags are set, the instruction is likely to be an ASCII character instead with the high byte set to , so we add a special check for that. Note that we capture the raw byte in the output instruction, to be used later. The and instructions have same opcode, but differ in the bits 7–9, which are set to for . Note that the function also checks for the fixed bits, failing which it returns a instruction. The and instructions have the same opcode, differing in the 12th bit. Decoding the , and instructions is a straightforward matter of decoding their registers and offsets. Notice that the and instructions also capture the raw bytes. Decoding the , and instructions is similar to the , and instructions. Again, straightforward decoding of register and offset: The instruction is a constant byte pattern. Decoding the instruction requires us to decode the trap routines. We don’t care about the rest of the bytes if the opcode is for the instruction. That’s it for decoding the bytes to instructions. But that was the easy part. Up next, we get into the heuristic operations. , the function below, is our main entry point to disassembling the binary code. It runs in the monad so that we can work with a mutable vector of instructions. First we allocate the mutable vector, and then we do a basic disassembly of the binary code into it by calling . After that, we go over the disassembled instructions in , and use heuristics to guess better ones. Finally, we clean up by combining the character data and inserting the labels, and return the final immutable vector of instructions. is where our first heuristic is applied. We go over the binary code vector element-by-element, decoding each raw word using the function we wrote earlier. But we don’t stop there, we do an additional check. If a freshly decoded instruction is one of some instructions, preceded by some particular instructions, we use it to further disassemble some data. We recognize these three patterns: These patterns are very common and almost standard, so we can confidently use them for detecting character and string data. Also, note the checks in the beginning of that prevent already disassembled char/string data from being overwritten. At this point, we have decoded the instructions and char/string data. But there are more possibilities of improving the disassembly quality. In this pass, we revisit the decoded instructions and correct them based on their targets and neighbours: runs till a fixed-point is reached, that is to say, till the instructions stop changing. It does a backward sweep with the function, then a forward sweep, then repeats until no changes occur. We do this because a rewrite can create conditions for another rewrite. Doing this till fixed-point is safe because of the way is written: it only changes code-like instructions to data-like instructions, and never the other way. That makes the whole pass monotonic, causing it to eventually terminate. We do the sweep in both directions to make the changes order-independent. Next up is : The idea behind is that, certain instructions that point to other instructions are likely to be data. Different instructions have different confidence levels for their target addresses, encoded as : below carries out the actual rewrites: The two helper predicates distinguish definite data and speculative data: checks for , , , and the original side of . checks for the speculative data alternative. Note how speculative data can cause neighbouring instructions to become data, but cannot alone cause a branch/call instruction to change, thus limiting speculation from spreading. After the previous pass the instructions become stable. We now process them to do some cleanups. First, we merge consecutive characters into strings: uses to walk the instruction list and combine: If a run is not -terminated, we revert the characters in it to . Finally, we insert the labels before the instructions that other instructions point to: We also change the pointing instructions to use the labels instead of offsets. This concludes the entire disassembly of LC-3 binary code. To finish off, we need functions to print the instructions and to read the binary files. is our top-level function that takes an object file and returns the disassembly as text: simply pretty prints each disassembled instruction and wraps the result with and directives from LC-3 assembler format. Here is the pretty printer: The instructions are rendered in the LC-3 assembly syntax. words become directives. values become with proper escape sequences. instructions are rendered with both interpretations: the speculated data form followed by the original instruction as a comment. This preserves ambiguity for human review. The helper pretty-printers: The registers are printed as – . Numeric values are prefixed with , and the escape sequences ( , , etc.) are properly encoded in strings. The trap routines are looked up by their standard codes and output as their names. After all we’ve been through, this is a piece of cake: Only important thing to note is to combine the byte pairs in the big-endian order. The function reads a binary file from STDIN, parses it, and disassembles it to STDOUT: Error messages are printed and the program exits with status 1 on failure. And, we are done! Let’s test it on the “Hello World!” program : Amazing! We assembled the disassembled program and ran it, and it produced the same output. The assembly is also pretty much the same. To make sure the disassembler works correctly, let’s run it on a the binary code for a larger program: lc3-fizzbuzz.asm that output the solution for the Fizzbuzz problem. It works perfectly. You can also see the word-wise diff between original and disassembled assembly below: Except for the data section at the end, the assembly is pretty much same other than the label names. Perfect! Building a disassembler for a format without metadata is a fun exercise. You have to find the patterns in the data, come up with heuristics, and use them to write your disassembler. You may need to go over the output multiple times to refine it. While the approach here is specific to LC-3, the principles generalize to other code/data separation problems in binary analysis and reverse engineering. The full code for this disassembler is available here . If you have any questions or comments, please leave a comment below. If you liked this post, please share it. Thanks for reading! I patched the VM to not print when halting. ↩︎ Most LC-3 assemblers produce .sym files containing the debug symbols. But we don’t use them for disassembling the binaries in this post. ↩︎ Actually, the ISA defines opcode as reserved for future use. ↩︎ Thanks for reading this post via feed. Feeds are great, and you're great for using them. ♥ This post was originally published on abhinavsarkar.net . Read more of my posts and notes . Introduction to LC-3 Problem in Disassembling LC-3 Decoding Instructions Basic Disassembly Fixed-Point Cleanup Postprocessing Pretty-Printing Reading the Binary Finishing Up First, we decode instructions that are unambiguous. Then, we use the context of the decoded instructions to speculatively decode the rest of the instructions/data. We repeat this till a fix-point is reached. Next, we clean up the data by combining bytes. Finally, we insert labels at the right places. to are the real LC-3 instructions. represents the one reserved opcode that the ISA defines as invalid 3 . is for capturing raw encoded binary data. represents a single character. represents a string, that is a sequence of characters. is a textual label used to annotate instructions that other instructions may jump to. It doesn’t exist in binary data, and is inserted by the disassembler. is a speculated instruction. It holds both the original instruction decoded from the binary data, and the guessed instruction depending on the context. followed by : This pattern loads a character at the relative into the registers and prints it. If we see this pattern, we know that the instruction at current index plus is a character. So we disassemble it immediately as a character in . followed by : This signals that the data at the relative is a null-terminated one-character-per-word string. So we disassemble it character-by-character till we reach the null bit in . followed by : This pattern is for a null-terminated two-characters-per-word string, so we disassemble accordingly in . , used for , : If the target is known to be data or does not exist, this instruction must be wrong, because these instructions are for jumping to code. Rewrite the instruction to . , used for : may or may not point to data. But if the instruction is in a neighbourhood that mostly has data, it is very likely to be data itself. Rewrite such instruction as , capturing both the data and instruction forms. , used for , , : The target doesn’t strongly indicate code or data. However, if is as well, the instruction is likely to be data if present in a data-heavy neighbourhood. In such case, rewrite as , otherwise ignore. a run of s followed by to become a single with the terminator, and a run of two-character entries followed by to become a single combined . I patched the VM to not print when halting. ↩︎ Most LC-3 assemblers produce .sym files containing the debug symbols. But we don’t use them for disassembling the binaries in this post. ↩︎ Actually, the ISA defines opcode as reserved for future use. ↩︎

0 views
iDiallo 2 days ago

College will only cost $20 a month

From 2020 to 2022, I've encouraged a steady stream of students to pursue their education in computer science. Tech companies were hiring like crazy. I would interview 3 candidates a week on some occasions. The future of tech seemed to be paved with gold. Any day now, several of those students will graduate. I dread opening my inbox and get an email from them asking: "So... about those jobs?" Things have changed since those crazy old days. Hiring has come to a stop. Those graduates will step into a market that looks nothing like what they signed up for. Getting a job will be a struggle. If I could see the future, I would have recommended a different path. But then again, how could I have known? Hindsight is always 20/20. So this leaves me with a dilemma as a parent. What do I tell my own kids? Am I going to push them to pursue the same traditional colleges? Will I disburse life savings so they could attend a prestigious university? Or will I just buy them a $20 a month AI Subscription? Imagine handing a student a textbook straight from a university syllabus. They read a lesson, and then you have an AI tutor to quiz them, debate concepts, and break down difficult ideas until they fully grasp the material. Is that a good replacement for college? Some argue that college is about the experience. It's the friendships you make along the way, the networking, the independence. These same people often omit the lifetime of crippling debt that hangs over those friends twenty years later. When I was in college, I focused almost entirely on mastering the material in the books, completing all assignments quickly. I spent the rest of the semesters tutoring my peers and applying the material I had learned. For me replacing the entire college system, the brick-and-mortar university with a set of books and an AI subscription seems like it would have done the job. I was the target candidate for this model. Yet, now that I have these AIs to experiment it myself, I found two flaws in the model: When I wrestled with dense textbooks in college, solutions didn't arrive at the click of a button. Instead, I struggled. I hit dead ends. I tried solutions that seemed promising only to abruptly stop two hours in the process only to realize that the whole thing was wrong. Sitting with the problem, the trials, the errors, giving up and going for a walk to clear my head, that was the process that taught me how to think. It taught me how to debug. Even when I found solutions online and pasted them into my code, I had to encounter the same problem repeatedly before the concept finally made sense. You have to work your way through a solution to understand a problem . This is why I feel concerned when we throw Millennium Prize Mathematical problems at AI. Imagine an AI presents a complete proof to one of these unsolved problems tomorrow? If or when AI solves it, we still have two problems. The second one is often overlooked, but ask yourself, where do these problems in Mathematics come from? They come from mathematicians attempting to solve hard problems, taking detours and failing along the way. Remove that step, and you... Well, you don't find any new problems. Not just in mathematics, I feel we will see something similar in code where fewer applications rely on frameworks . Frameworks solve real issues in programming, but why use a framework when the AI can just give you all the answers. I lived through the JS framework mania. I am not suggesting we create more, but I think we will miss out on discovering new problems that need solving. If we rely on a system that just hands us a solution, we lose the ability to uncover new questions because we never went through the steps of trying something new. I don't think a $20-a-month AI subscription paired with a textbook is the ultimate solution. Not when we still need some friction in order to inculcate concepts in our minds. But traditional higher education has changed so drastically and the skyrocketing costs and changing employment realities don’t help. There is no turning back to the old model either. The challenge for learning remains understanding. How we grasp concepts and develop critical thinking in an era of instant answers. Maybe that's where we should turn our focus to. Figuring out how to design learning that somehow preserves productive struggle. If AI can solve this issue and turn students into masters of crafts instead of prompt engineers, I mean, I'll gladly keep that college tuition in my pocket. Understanding takes time. Not having an immediate answer forces you to strain your brain until you figure things out. We still have to understand the solution. Having an AI produce a proof doesn't mean we understand how or why it works. We don't get to discover new problems.

0 views
Stratechery 2 days ago

2026.44: At Long Last…

Welcome back to This Week in Stratechery! As a reminder, each week, every Friday, we’re sending out this overview of content in the Stratechery bundle; highlighted links are free for everyone . Additionally, you have complete control over what we send to you. If you don’t want to receive This Week in Stratechery emails (there is no podcast), please uncheck the box in your delivery settings . On that note, here were a few of our favorites this week. Presented by When I write about tech companies, I am often writing about businesses that depend on Stripe , because Stripe provides the foundation for Internet-native companies — including Stratechery. Consider Substack: building Stratechery was complicated and involved gluing together disparate pieces; Substack made it easy by delivering an integrated offering. One piece that was the same, however, was Stripe: Substack creators are also Stripe customers, as are creators on many other platforms. Zoom out and the pattern repeats. Fintechs can build entire business models around card programs without ever having to build the issuing and processing infrastructure underneath it. AI companies can charge for what customers actually use, which is particularly important when usage also drives costs, without having to build the systems to track and bill for it themselves. No business succeeds because of Stripe. Stripe doesn’t answer the hard questions about what to build or whether anyone will actually use it. But it does make more things practical to try. This week’s Stratechery video is on Do You Trust Apple? . Finally, Some Anthropic Numbers.  Monday morning brought us Anthropic’s S-1, and not a moment too soon. After four years of arguments about the economics at frontier labs, we now have some real numbers to sink our teeth into, and Ben did just that with his Update on Tuesday . Come for that analysis, and then head over to this week’s Sharp Tech where we talked in depth about what Anthropic is telling investors, questions that remain unanswered, plus why the SEC forced Anthropic to help us understand Meta’s Muse bet . — Andrew Sharp The End of the Internet as We Know It (and I Feel Fine) . Arriving on the heels of a handful of ominous cybersecurity incidents and with continued upheaval guaranteed, Monday’s Article made two distinct predictions . First, the pressure applied by AI will eventually (or imminently?) rupture the global internet that we’ve come to know for the past 25 years. But second, as society moves to more localized solutions and products, that may in fact be a welcome development for all of us who have come to accept degraded experiences throughout our technological lives. As an avid group chatter who’s more or less abandoned public social media, I can certainly get behind the second take!  — AS Autocracies Then and Now. On Sharp China this week, we began with an extended look at the climate of fear across the Chinese bureaucracy as Xi Jinping continues an anti-corruption crackdown that was absolutely necessary but may be going further than Xi’s earlier proponents ever expected. Then, we turn to a glorious mess surrounding Mao Zedong and international soccer star Kylian Mbappé. On both that episode and in this week’s Sharp Text , I make the point that connipitions like this one, anchored in a bizarre debate over Mao’s governing history, are evidence that rumors of a Chinese century have been greatly exaggerated.  — AS The End of the Internet — The old Internet, where anyone could host a server is over, but it’s just the final blow in an ending that has been coming for years. The future, though, is brighter than it appears. Anthropic S-1, The Cost of Compute, Who Is Paying? — Anthropic’s IPO is finally here; the core business is very profitable, but competition may eat all of the profits, even as investors are set up for endless dilution. Meta Earnings, Muse and the Frontier, Musebook — Meta’s earnings come in the context of Zuckerberg delivering on his promise; if investors believe in Muse they must support Meta’s spending on compute. An Interview with Palantir CTO Shyam Sankar About the AI Religious War — An interview with Palantir CTO Shyam Sankar about AI diffusion and safety, forward-deployed engineer, and what the battle in tech is actually about. Kylian Mbappés Little Red Card — Surveying the biggest scandal in China this week, and another reminder that the CCP cannot get out its own way. The End of the Internet Touchscreen MacBook Pros How Linux (and Windows) Ate UNIX Silicon Valley Walks the Jagged Edge Five Questions on the Fifth Plenum; Mbappé Hysteria and a Chinese Own Goal; The STAR 50 AI Bubble Has Burst The Opening Week in Review, Nuggets Darkness and Eastern Conference Angst, A True Catastrophe for OKC Anthropic Opens the Kimono, Bubble Questions and Frontier Costs, Q&A on Meta, Starlink, Brewers

0 views
Kev Quirk 2 days ago

SocialSpec Seems...Pointless

I've seen a few people talking about SocialSpec which claims that "the future of social media is websites" . Something I strongly agree with. However, I don't see the point of this fledgling spec on top of all the other IndieWeb complexity that's flying around. From what I can gather, it's 3 files that you upload to which provide a bio, a means of contact, and what blogs you follow. Step one is to have an RSS feed, actually, but everyone should have an RSS feed anyway . But aside from this, I already have a bio , a means of contact , and a list of blogs I follow . So what is SocialSpec trying to achieve? Again, from what I can gather from the site, you publish these 3 files on your site and you're magically enrolled in the new website social network . Where you can peruse a timeline of posts from fellow bloggers, based on who you follow in your OPML file. Fuck yeah! Win for the open web. Sign me up! But hang on a second. This open spec , based on open protocols , for the open web doesn't even have a web app. Nope. The only client that actually uses it is sitting behind a fucking iOS app. Now I'm sure other apps will come with time, but if this were truly a platform for the open web, wouldn't a website that supports a PWA have been a better solution initially? I think so. Even if someone takes the time to publish and maintain these files, what does SocialSpec offer over an RSS feed reader, and a couple of pages on your site? I like how people are thinking of ways to interconnect sites in this way, but I don't think this is the right approach. It's trying to solve a problem that doesn't really exist in my opinion. The only issue it may fix is discoverability. But I still think it's flawed as the service would need a decent user base to make discoverability viable. Sites like Bubbles , PowRSS , and Bear Discover are far better than this solution as they're easier to use and have no barrier for entry. Maybe I'm being a curmudgeon here, but I really don't get it. This is a solved problem, and has been for decades. Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️ You can reply to this post by email , or leave a comment .

0 views