<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>A Node on the Web</title>
    <link>https://rmendes.net/</link>
    <description>This site is my personal hub for long-form writing, curated bookmarks, and open-web experiments — where ideas about tech, autonomy, democracy, and digital culture meet.
Since February 2026, this site is also my personal ActivityPub instance, every posts you see on this blog can be fetched from the fediverse.</description>
    <language>en</language>
    <atom:link href="https://rmendes.net/feed.xml" rel="self" type="application/rss+xml"/>
    <atom:link href="https://websubhub.com/hub" rel="hub"/>
    <lastBuildDate>Wed, 26 Aug 2026 18:40:07 GMT</lastBuildDate>
    <item>
      <title>Another reason to leave WordPress behind</title>
      <link>https://rmendes.net/articles/2026/08/26/another-reason-to-leave-wordpress/</link>
      <guid isPermaLink="true">https://rmendes.net/articles/2026/08/26/another-reason-to-leave-wordpress/</guid>
      <pubDate>Wed, 26 Aug 2026 18:40:07 GMT</pubDate>
      <description>&lt;p&gt;So today it was fires both at work and privately :&lt;/p&gt;
&lt;p&gt;I successfully intercepted what appears to have been an attempt to compromise &lt;a href=&quot;http://chardonsbleus.org/&quot;&gt;chardonsbleus.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Two administrator accounts were created within a very short period of time. At first, I assumed the usual suspects: an outdated WordPress plugin, WPML, or some other vulnerable component.&lt;/p&gt;
&lt;p&gt;But that doesn’t appear to be what happened.&lt;/p&gt;
&lt;p&gt;The traces left in the logs and database indicate that both administrator accounts were created through a backend API request with administrative privileges. Everything I have found so far points toward the WPMU DEV API key as the attack vector.&lt;/p&gt;
&lt;p&gt;What surprised me most is that I had no idea credentials associated with that service could potentially be used in a way that results in the creation of WordPress administrator accounts — apparently without needing the password of an existing administrator.&lt;/p&gt;
&lt;p&gt;There is still another possibility: that my main administrator account itself was compromised. It uses a strong password, though, and based on the traces I have, I consider that considerably less likely.&lt;/p&gt;
&lt;p&gt;So I’m not claiming to have reconstructed every step of the attack yet. What I do know is that two unauthorized administrator accounts appeared, and the database and logs point to an API-level administrative operation rather than a normal WordPress login.&lt;/p&gt;
&lt;p&gt;I don’t know how many people will ever read this, but for me the conclusion is becoming increasingly obvious:&lt;/p&gt;
&lt;p&gt;WordPress has to go.&lt;/p&gt;
&lt;p&gt;The main reason &lt;a href=&quot;http://chardonsbleus.org/&quot;&gt;chardonsbleus.org&lt;/a&gt; is still running WordPress is GiveWP. It is a genuinely good donation plugin, although an expensive one, and replacing that functionality has always been the main obstacle to migrating the site.&lt;/p&gt;
&lt;p&gt;I’m going to find another solution for donations.&lt;/p&gt;
&lt;p&gt;After that, I’ll probably move the site to Indiekit and finally decommission the WordPress installation altogether.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Oups… Accidentally turned my geekom IT15 off but thanks to herdr recovered my op...</title>
      <link>https://rmendes.net/notes/2026/08/21/a4db9/</link>
      <guid isPermaLink="true">https://rmendes.net/notes/2026/08/21/a4db9/</guid>
      <pubDate>Fri, 21 Aug 2026 20:15:00 GMT</pubDate>
      <description>&lt;p&gt;Oups… Accidentally turned my geekom IT15 off
but thanks to herdr recovered my opencode session without an ounce of stress 😊&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Hi Aaron, is there any path to have one’s own domain added to the allowed client...</title>
      <link>https://rmendes.net/replies/2026/08/21/b183a/</link>
      <guid isPermaLink="true">https://rmendes.net/replies/2026/08/21/b183a/</guid>
      <pubDate>Fri, 21 Aug 2026 19:21:12 GMT</pubDate>
      <description>&lt;p&gt;Hi Aaron, is there any path to have one’s own domain added to the allowed client list on indielogin service ?&lt;/p&gt;
</description>
    </item>
    <item>
      <title>I shipped my comment plugin to a service that could never accept it</title>
      <link>https://rmendes.net/articles/2026/08/21/ai-shipped-comment-plugin-indielogin/</link>
      <guid isPermaLink="true">https://rmendes.net/articles/2026/08/21/ai-shipped-comment-plugin-indielogin/</guid>
      <pubDate>Fri, 21 Aug 2026 17:45:00 GMT</pubDate>
      <description>&lt;p&gt;I’ve been rebuilding the comment system on this site with Claude Code. Visitors sign in with their own website to leave a comment — IndieAuth, the way it’s meant to work.&lt;/p&gt;
&lt;p&gt;Overnight we migrated it from IndieAuth to &lt;a href=&quot;http://indielogin.com/&quot;&gt;IndieLogin.com&lt;/a&gt;. At 05:40 this morning it published to npm and deployed. By 08:00 I’d opened an incognito window, typed in my own domain, and got this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Request Error
This client_id is not registered (https://rmendes.net)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The migration could never have worked. Not “had a bug” — could never have worked, for any visitor, on any site not already on a list I didn’t know existed.&lt;/p&gt;
&lt;h2 id=&quot;why-it-looked-right&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://rmendes.net/articles/2026/08/21/ai-shipped-comment-plugin-indielogin/#why-it-looked-right&quot;&gt;Why it looked right&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The reasoning behind the change was sound, which is what makes it worth writing up.&lt;/p&gt;
&lt;p&gt;The plugin discovered each visitor’s own &lt;code&gt;authorization_endpoint&lt;/code&gt; and sent them there. Visitors without one fell back to &lt;code&gt;indieauth.com&lt;/code&gt;. That fallback is the part that dates: &lt;a href=&quot;http://indieauth.com/&quot;&gt;indieauth.com&lt;/a&gt;’s own home page says it “will eventually be replaced,” and points developers at &lt;a href=&quot;http://indielogin.com/&quot;&gt;IndieLogin.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;IndieLogin also promised more providers — Bluesky, GitLab, Codeberg — and one genuinely appealing property. When you discover each visitor’s endpoint, you inherit an obligation from &lt;a href=&quot;https://indieauth.spec.indieweb.org/#profile-url-response&quot;&gt;IndieAuth §5.4&lt;/a&gt;: if the profile URL the server returns isn’t the one the visitor typed, you &lt;strong&gt;must&lt;/strong&gt; re-discover it and confirm it declares the same authorization endpoint. Skip that, and any authorization endpoint can return any &lt;code&gt;me&lt;/code&gt; and be believed — including mine. My plugin was skipping it. Delegating to one trusted service makes that whole class of problem structurally impossible rather than merely fixed.&lt;/p&gt;
&lt;p&gt;Good argument. Built on documentation nobody tested.&lt;/p&gt;
&lt;h2 id=&quot;the-part-the-docs-dont-mention&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://rmendes.net/articles/2026/08/21/ai-shipped-comment-plugin-indielogin/#the-part-the-docs-dont-mention&quot;&gt;The part the docs don’t mention&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;IndieLogin’s API docs describe &lt;code&gt;client_id&lt;/code&gt; as informational: “the home page of the application the user is signing in to.” Nothing about registration.&lt;/p&gt;
&lt;p&gt;The source says otherwise. In &lt;code&gt;app/Authenticate.php&lt;/code&gt;, on the authorize path:&lt;/p&gt;
&lt;pre class=&quot;language-php&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$client&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name static-context&quot;&gt;ORM&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;for_table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;clients&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;client_id&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$client_id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find_one&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$client&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token variable&quot;&gt;$errors&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&#39;This client_id is not registered (...)&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That table is queried in two places and written in none. Registration happens by opening a GitHub issue asking to be added. There’s a queue of them, requests from April and August this year sit unregistered, and an issue asking for a self-service registration form has been open since &lt;strong&gt;2018&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The ideal would have been a solution to automate client website registration, there is a github issue for it, but to the best of my knowledge it has not been developed.&lt;/p&gt;
&lt;p&gt;When Claude first told me this, I didn’t believe it — it sounded like a hallucination. aaronpk advocates for this stuff; the idea he’d maintain a manual allowlist seemed absurd. It restated the claim twice before I pushed hard enough that it stopped arguing and designed a test instead: same endpoint, same parameters, a deliberately-broken &lt;code&gt;redirect_uri&lt;/code&gt; on both.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;indiebookclub.biz&lt;/code&gt; → &lt;em&gt;“The client_id and redirect_uri must be on the same domain”&lt;/em&gt; appears to indicate this site is on the list of allowed clients.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rmendes.net&lt;/code&gt; → &lt;em&gt;“This client_id is not registered”&lt;/em&gt; indicate I’m not the list and the opened github issues appear to indicate there is no way to get in without poking the indieweb people on IRC or via email.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A known consumer clears the client check and trips the &lt;em&gt;next&lt;/em&gt; rule. Mine never gets that far. That’s not a reading of the source, it’s the live service behaving differently based only on the domain.&lt;/p&gt;
&lt;p&gt;None of this is a knock on IndieLogin. It’s free, someone pays to run it, and an anti-abuse step simply never got automated — issue #20 says as much. But “free for anyone to use” and “requires a manual step that isn’t happening” are both true at once, and only the first one is documented.&lt;/p&gt;
&lt;h2 id=&quot;the-actual-failure&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://rmendes.net/articles/2026/08/21/ai-shipped-comment-plugin-indielogin/#the-actual-failure&quot;&gt;The actual failure&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One &lt;code&gt;curl&lt;/code&gt; to &lt;code&gt;/authorize&lt;/code&gt; would have caught this before a line of code was written. It never happened. The whole migration — design, implementation, publish, deploy — rested on an API description that was accurate about the protocol and silent about the policy, and nobody poked the real endpoint.&lt;/p&gt;
&lt;p&gt;My assumption was, its working like &lt;a href=&quot;http://indieauth.com/&quot;&gt;indieauth.com&lt;/a&gt;, why would anyone want to maintain a list of allowed clients ???&lt;/p&gt;
&lt;p&gt;That’s the AI-assisted failure mode worth naming, and it isn’t “the AI wrote bad code.” The code was fine. The tests passed. The commit message was better than mine usually are. It was confidently, fluently wrong about something it could have checked in ten seconds, and confident fluent output is exactly what stops you asking.&lt;/p&gt;
&lt;p&gt;What caught it was me, in an incognito window, doing the thing a user does : testing&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Docs describe the protocol. Deployments enforce the policy. Only one of them rejects you.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;back-to-indieauth-but-better&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://rmendes.net/articles/2026/08/21/ai-shipped-comment-plugin-indielogin/#back-to-indieauth-but-better&quot;&gt;Back to IndieAuth, but better&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We reverted, which restored a working system that still had the §5.4 hole. So the rest of the day went on fixing that properly instead of delegating around it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Profile URL verification.&lt;/strong&gt; When the returned &lt;code&gt;me&lt;/code&gt; differs from what was typed, re-discover it and require the same authorization endpoint. An endpoint claiming &lt;code&gt;rmendes.net&lt;/code&gt; now gets refused. Failure to re-discover fails closed. Verified against live discovery, not just stubs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Discovery via microformats instead of pattern matching.&lt;/strong&gt; The old code matched &lt;code&gt;&amp;lt;link rel=&amp;quot;x&amp;quot; href=&amp;quot;y&amp;quot;&amp;gt;&lt;/code&gt; with a regex. Measured against real markup, it handled one shape out of five:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;markup&lt;/th&gt;
&lt;th&gt;regex&lt;/th&gt;
&lt;th&gt;mf2&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;relative &lt;code&gt;href=&amp;quot;/auth&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/auth&lt;/code&gt; — unresolved&lt;/td&gt;
&lt;td&gt;resolved&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;single quotes&lt;/td&gt;
&lt;td&gt;missed&lt;/td&gt;
&lt;td&gt;found&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rel=&amp;quot;me authorization_endpoint&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;missed&lt;/td&gt;
&lt;td&gt;found&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;a rel=...&amp;gt;&lt;/code&gt; (spec-legal)&lt;/td&gt;
&lt;td&gt;missed&lt;/td&gt;
&lt;td&gt;found&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;None of those failed loudly. A missed rel silently routes someone running their own authorization server to the third-party fallback instead — the opposite of what this plugin is for. &lt;code&gt;microformats-parser&lt;/code&gt; was already in the dependency tree. It just wasn’t being used, so we started using it !&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Server metadata discovery.&lt;/strong&gt; Servers publishing &lt;code&gt;rel=&amp;quot;indieauth-metadata&amp;quot;&lt;/code&gt; now get that document preferred over the rels. It’s also the only place an &lt;code&gt;issuer&lt;/code&gt; is published, so the &lt;code&gt;iss&lt;/code&gt; on the authorization response can finally be checked. The spec mandates &lt;em&gt;simple string comparison&lt;/em&gt; there, not URL normalisation — a trailing-slash difference is a mismatch, which is the opposite of what you’d assume. Worth checking before you ship it, as we’d just learned.&lt;/p&gt;
&lt;p&gt;Amusingly, this site served a metadata document all along and never advertised it. One &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; in the theme fixed that.&lt;/p&gt;
&lt;p&gt;The plugin went from 3 tests to 32, and &lt;code&gt;npm test&lt;/code&gt; runs for the first time.&lt;/p&gt;
&lt;h2 id=&quot;what-im-taking-from-it&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://rmendes.net/articles/2026/08/21/ai-shipped-comment-plugin-indielogin/#what-im-taking-from-it&quot;&gt;What I’m taking from it&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The failed migration was worth more than a clean one would have been. It forced an articulation of &lt;em&gt;why&lt;/em&gt; delegating would have been safer, which turned out to be the exact argument for doing the verification properly in-house.&lt;/p&gt;
&lt;p&gt;But the durable lesson is about how I work now. An AI can hold more of the IndieAuth spec in its head than I can, write better commit messages than I do, and produce a migration that is coherent, tested, well-documented and completely unshippable — because it never touched the thing it was integrating with.&lt;/p&gt;
&lt;p&gt;If you have implemented IndieAuth for commenting on your blog, what was your approach ?&lt;/p&gt;
</description>
    </item>
    <item>
      <title>This is actually a cool idea ! In short: it’s a social, RSS-friendly radar for t...</title>
      <link>https://rmendes.net/notes/2026/08/20/99879/</link>
      <guid isPermaLink="true">https://rmendes.net/notes/2026/08/20/99879/</guid>
      <pubDate>Thu, 20 Aug 2026 16:07:39 GMT</pubDate>
      <description>&lt;p&gt;&lt;a href=&quot;https://rssfriends.com/&quot;&gt;This&lt;/a&gt; is actually a cool idea !&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In short: it’s a social, RSS-friendly radar for the open web, self-hosted, with magic-link auth, and connected to the fediverse (ActivityPub).&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    <item>
      <title>Bernie is right⁠ . If healthcare, decent wages, taxing billionaires and protecti...</title>
      <link>https://rmendes.net/notes/2026/08/19/50583/</link>
      <guid isPermaLink="true">https://rmendes.net/notes/2026/08/19/50583/</guid>
      <pubDate>Wed, 19 Aug 2026 10:44:37 GMT</pubDate>
      <description>&lt;p&gt;Bernie is &lt;a href=&quot;https://www.theguardian.com/commentisfree/2026/aug/19/poll-progressive-candidates-election-economy&quot;&gt;right⁠&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If healthcare, decent wages, taxing billionaires and protecting workers are now “radical” or “extreme”, then the current US administration is practicing something much closer to state terror against its own population.&lt;/p&gt;
&lt;p&gt;Americans are fed up. The tragedy is that a huge part of that anger was successfully redirected — and many of those who wanted to punish the system ended up voting its most brutal incarnation into the White House.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Github down… 404 on any repo I visit, just another reason I’m going to switch to...</title>
      <link>https://rmendes.net/notes/2026/08/17/788a6/</link>
      <guid isPermaLink="true">https://rmendes.net/notes/2026/08/17/788a6/</guid>
      <pubDate>Mon, 17 Aug 2026 16:10:06 GMT</pubDate>
      <description>&lt;p&gt;Github down… 404 on any repo I visit, just another reason I’m going to switch to &lt;code&gt;code.rmendes.net&lt;/code&gt; as primary and github as mirror for my own repos.&lt;/p&gt;
&lt;p&gt;Moving Orgs repo : that’s beyond my current scope for now&lt;/p&gt;
&lt;p&gt;GitHub status page show a day in hell for the engineers working over there&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Google Workspace now receives mail for 21.8% of MX-publishing domains and Micros...</title>
      <link>https://rmendes.net/notes/2026/08/17/667be/</link>
      <guid isPermaLink="true">https://rmendes.net/notes/2026/08/17/667be/</guid>
      <pubDate>Mon, 17 Aug 2026 11:49:27 GMT</pubDate>
      <description>&lt;blockquote&gt;
&lt;p&gt;Google Workspace now receives mail for 21.8% of MX-publishing domains and Microsoft 365 for 16.8%. Together that is 38.6% of the measured Internet’s inbound mail behind two companies. Nobody else comes close: the next named provider, Proofpoint, sits at 1.9%.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://labs.ripe.net/author/artem-berezin/two-providers-a-stubborn-plateau-and-a-very-long-tail-email-in-the-tranco-top-1m/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Quite happy with the way Plume evolved in just a few weeks ! (to use this, you n...</title>
      <link>https://rmendes.net/notes/2026/08/16/9a76e/</link>
      <guid isPermaLink="true">https://rmendes.net/notes/2026/08/16/9a76e/</guid>
      <pubDate>Sun, 16 Aug 2026 17:05:39 GMT</pubDate>
      <description>&lt;p&gt;Quite happy with the way &lt;a href=&quot;https://rmdes.github.io/plume/&quot;&gt;Plume&lt;/a&gt; evolved in just a few weeks !&lt;/p&gt;
&lt;p&gt;(to use this, you need a blog that support Micropub)&lt;/p&gt;
</description>
    </item>
    <item>
      <title>White House authorizes private companies to launch ‘hack-back’ cyberattacks that...</title>
      <link>https://rmendes.net/notes/2026/08/16/6cdeb/</link>
      <guid isPermaLink="true">https://rmendes.net/notes/2026/08/16/6cdeb/</guid>
      <pubDate>Sun, 16 Aug 2026 15:10:25 GMT</pubDate>
      <description>&lt;p&gt;White House authorizes private companies to launch ‘hack-back’ cyberattacks that destroy data and systems, targeting foreign cybercrime organizations — vetted organizations can now conduct offensive cyber operations | Tom’s Hardware&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://share.google/vkx5E0RRVXU2Mwi42&quot;&gt;https://share.google/vkx5E0RRVXU2Mwi42&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;What could go wrong?&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Damn… There isn’t one single actively developed IndieWeb/Micropub mobile app on...</title>
      <link>https://rmendes.net/notes/2026/08/16/971cf/</link>
      <guid isPermaLink="true">https://rmendes.net/notes/2026/08/16/971cf/</guid>
      <pubDate>Sun, 16 Aug 2026 15:08:59 GMT</pubDate>
      <description>&lt;p&gt;Damn… There isn’t one single actively developed IndieWeb/Micropub mobile app on the Android playstore. Even IndiePass has been discontinued. I don’t want to start from scratch but I’m considering if I should do something about it. I’m fine publishing on mobile using my browser but IndiePass was quite handy and better integration with Android Share to targets.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Test post without Syndication</title>
      <link>https://rmendes.net/notes/2026/08/15/679f2/</link>
      <guid isPermaLink="true">https://rmendes.net/notes/2026/08/15/679f2/</guid>
      <pubDate>Sat, 15 Aug 2026 22:00:26 GMT</pubDate>
      <description>&lt;p&gt;Test post without Syndication&lt;/p&gt;
</description>
    </item>
    <item>
      <title>I think my #Indiekit fork might be one of the very few setups where this happens...</title>
      <link>https://rmendes.net/notes/2026/08/15/c23ae/</link>
      <guid isPermaLink="true">https://rmendes.net/notes/2026/08/15/c23ae/</guid>
      <pubDate>Sat, 15 Aug 2026 20:40:20 GMT</pubDate>
      <description>&lt;p&gt;I think my &lt;a href=&quot;https://rmendes.net/categories/indiekit/&quot; class=&quot;p-category hashtag&quot;&gt;#Indiekit&lt;/a&gt; fork might be one of the very few setups where this happens:&lt;/p&gt;
&lt;p&gt;You post from Phanpy or Moshidon — regular Mastodon clients, no Micropub support at all.&lt;/p&gt;
&lt;p&gt;My custom Fedify AP answers the Mastodon client API, turns that request into a Micropub post, writes it to my own site as Markdown, and then federates it as &lt;a href=&quot;https://rmendes.net/categories/activitypub/&quot; class=&quot;p-category hashtag&quot;&gt;#ActivityPub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;My blog via that same plug-in answers the Mastodon API.&lt;/p&gt;
&lt;p&gt;So Phanpy and Moshidon think they’re talking to a Mastodon server.&lt;/p&gt;
&lt;p&gt;They’re not. They’re writing Micropub.&lt;/p&gt;
&lt;p&gt;The flow is : Mastodon client → Mastodon-compatible API → Micropub → Markdown file on my own site → ActivityStreams 2.0 → delivered to followers.&lt;/p&gt;
&lt;p&gt;Same for edits: editing from Phanpy issues a Micropub replace, then broadcasts an Update(Note).&lt;/p&gt;
&lt;p&gt;Plenty of projects do “native post → AP representation” (WordPress, Micro.blog).&lt;/p&gt;
&lt;p&gt;What I haven’t seen elsewhere is the extra hop: a non-Micropub client producing a Micropub post without knowing it.&lt;/p&gt;
&lt;p&gt;It’s been a fun coding summer 🌞😎&lt;/p&gt;
</description>
    </item>
    <item>
      <title>They are killing Hyperlinks</title>
      <link>https://rmendes.net/notes/2026/08/15/cdb44/</link>
      <guid isPermaLink="true">https://rmendes.net/notes/2026/08/15/cdb44/</guid>
      <pubDate>Sat, 15 Aug 2026 20:14:40 GMT</pubDate>
      <description>&lt;p&gt;They are &lt;a href=&quot;https://paul.jottit.org/link-penalties-on-social-media-platforms&quot;&gt;killing&lt;/a&gt; Hyperlinks&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Had fun coding a small python script for weechat that relay mentions of my handl...</title>
      <link>https://rmendes.net/notes/2026/08/15/3a302/</link>
      <guid isPermaLink="true">https://rmendes.net/notes/2026/08/15/3a302/</guid>
      <pubDate>Sat, 15 Aug 2026 20:07:39 GMT</pubDate>
      <description>&lt;p&gt;Had fun coding a small python script for weechat that relay mentions of my handle to my self hosted private ntfy sever allowing me to get IRC notifications while on the go, the notification carries the actual message of the user on IRC so I can quickly check if it needs a reply or not.&lt;/p&gt;
&lt;p&gt;Yes very useless and fun 😅&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Testing Plume from Firefox, now you can see the steps indieauth take against you...</title>
      <link>https://rmendes.net/notes/2026/08/15/14376/</link>
      <guid isPermaLink="true">https://rmendes.net/notes/2026/08/15/14376/</guid>
      <pubDate>Sat, 15 Aug 2026 19:33:37 GMT</pubDate>
      <description>&lt;p&gt;Testing Plume from Firefox, now you can see the steps indieauth take against your site for the initial connection, there is also a welcome tab for onboarding (Inspired by Omnibear)&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Improved Plume onboarding and fixed a few bugs https://rmdes.github.io/plume/ #m...</title>
      <link>https://rmendes.net/notes/2026/08/15/21ba2/</link>
      <guid isPermaLink="true">https://rmendes.net/notes/2026/08/15/21ba2/</guid>
      <pubDate>Sat, 15 Aug 2026 19:15:21 GMT</pubDate>
      <description>&lt;p&gt;Improved Plume onboarding and fixed a few bugs &lt;a href=&quot;https://rmdes.github.io/plume/&quot;&gt;https://rmdes.github.io/plume/&lt;/a&gt; &lt;a href=&quot;https://rmendes.net/categories/micropub/&quot; class=&quot;p-category hashtag&quot;&gt;#micropub&lt;/a&gt;
and just after publishing this new version, I found a new bug, there should be 1.5.1 very soon !!!&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Test post from Omnibear #micropub extension</title>
      <link>https://rmendes.net/notes/2026/08/15/test-post-from-omnibear-micropub-extension/</link>
      <guid isPermaLink="true">https://rmendes.net/notes/2026/08/15/test-post-from-omnibear-micropub-extension/</guid>
      <pubDate>Sat, 15 Aug 2026 12:54:39 GMT</pubDate>
      <description>&lt;p&gt;Test post from Omnibear &lt;a href=&quot;https://rmendes.net/categories/micropub/&quot; class=&quot;p-category hashtag&quot;&gt;#micropub&lt;/a&gt; extension&lt;/p&gt;
</description>
    </item>
    <item>
      <title>I’m refactoring my AP implementation first so that I can properly build C2S late...</title>
      <link>https://rmendes.net/replies/2026/08/15/53cc8/</link>
      <guid isPermaLink="true">https://rmendes.net/replies/2026/08/15/53cc8/</guid>
      <pubDate>Sat, 15 Aug 2026 11:42:58 GMT</pubDate>
      <description>&lt;p&gt;I’m refactoring my AP implementation first so that I can properly build C2S later on, for now I’ll keep the API layer, since it already covers a lot of ground but the refactoring will allow me to have a more robust implementation and I’m finding this &lt;a href=&quot;https://www.stevebate.net/activitypub-client-api-a-way-forward/#flowz&quot;&gt;https://www.stevebate.net/activitypub-client-api-a-way-forward/#flowz&lt;/a&gt; very inspiring&lt;/p&gt;
</description>
    </item>
    <item>
      <title>It really sucks to have a properly configured email server, running on your own...</title>
      <link>https://rmendes.net/notes/2026/08/15/1cbda/</link>
      <guid isPermaLink="true">https://rmendes.net/notes/2026/08/15/1cbda/</guid>
      <pubDate>Sat, 15 Aug 2026 09:44:36 GMT</pubDate>
      <description>&lt;p&gt;It really sucks to have a properly configured email server, running on your own domain — thanks, Cloudron — only to have Google, Microsoft, and the other giants systematically dump your messages into spam anyway.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://rmendes.net/media/photos/2026/08/15/email-checks.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;And yet I now find myself &lt;strong&gt;sending important emails twice&lt;/strong&gt;, or using another provider, just to make sure they actually reach the person on the other side.&lt;/p&gt;
&lt;p&gt;Email was supposed to be an open, decentralized protocol. Instead, a handful of monopolies have effectively &lt;strong&gt;privatized deliverability&lt;/strong&gt;: they decide whose mail is trustworthy, whose isn’t, and independent servers are guilty until proven innocent.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://rmendes.net/categories/enshittification/&quot; class=&quot;p-category hashtag&quot;&gt;#Enshittification&lt;/a&gt; at scale: privatize the commons, segment it, then slowly make the open alternative unusable for everyone else.&lt;/p&gt;
</description>
      <enclosure url="https://rmendes.net/media/photos/2026/08/15/email-checks.png" type="image/jpeg" length="0"/>
      <media:content url="https://rmendes.net/media/photos/2026/08/15/email-checks.png" medium="image"/>
    </item>
  </channel>
</rss>
