Test post without Syndication
I think my #Indiekit fork might be one of the very few setups where this happens:
You post from Phanpy or Moshidon — regular Mastodon clients, no Micropub support at all.
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 #ActivityPub.
My blog via that same plug-in answers the Mastodon API.
So Phanpy and Moshidon think they’re talking to a Mastodon server.
They’re not. They’re writing Micropub.
The flow is : Mastodon client → Mastodon-compatible API → Micropub → Markdown file on my own site → ActivityStreams 2.0 → delivered to followers.
Same for edits: editing from Phanpy issues a Micropub replace, then broadcasts an Update(Note).
Plenty of projects do “native post → AP representation” (WordPress, Micro.blog).
What I haven’t seen elsewhere is the extra hop: a non-Micropub client producing a Micropub post without knowing it.
It’s been a fun coding summer 🌞😎
They are killing Hyperlinks
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.
Yes very useless and fun 😅
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)
Improved Plume onboarding and fixed a few bugs https://rmdes.github.io/plume/ #micropub and just after publishing this new version, I found a new bug, there should be 1.5.1 very soon !!!
Test post from Omnibear #micropub extension
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 https://www.stevebate.net/activitypub-client-api-a-way-forward/#flowz very inspiring
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.

And yet I now find myself sending important emails twice, or using another provider, just to make sure they actually reach the person on the other side.
Email was supposed to be an open, decentralized protocol. Instead, a handful of monopolies have effectively privatized deliverability: they decide whose mail is trustworthy, whose isn’t, and independent servers are guilty until proven innocent.
#Enshittification at scale: privatize the commons, segment it, then slowly make the open alternative unusable for everyone else.

Mark Zuckerberg’s manifesto rests on a single elegant idea: safety comes from distributing power so no one actor can impose their will.
It’s a fine principle. It’s also the exact opposite of how he has run everything he has ever touched.
Start with the structure of Meta itself. Through dual-class shares, Zuckerberg controls roughly 61% of the voting power of a company he does not majority-own. No board can fire him. No shareholder vote can bind him. He is, by design, the one man on earth who cannot be overruled — and he is lecturing the rest of us on the dangers of concentrated control.
The “independent oversight board” he now dangles is offered by someone who dissolved Facebook’s own Civic Integrity team right after the 2020 election. We have seen what his oversight is worth when the cameras move on.
Then measure the values against the receipts — and not just on AI.
He says superintelligence must protect your privacy. In 2019 he stood on a stage and announced “the future is private.” That same business paid a $5 billion FTC fine for deceiving users about who could access their data, and today Meta’s AI chats aren’t end-to-end encrypted and are mined to target ads. The pledge is identical. So is the gap between the pledge and the practice.
He says AI must reflect human values. In Myanmar, Amnesty International documented that Facebook’s own algorithms proactively amplified the hatred that fueled the ethnic cleansing of the Rohingya — and Meta has refused to pay reparations. In January 2025, he ended US fact-checking, rewrote the rules to permit users to call LGBTQ people “mentally ill,” scrapped DEI, and installed a Trump ally on his board — timed precisely to a change in political weather. These are not the choices of a man guided by values. They are the choices of a man reading the room and calling it principle.
He says AI will create more employment, not less. He said this while cutting ~600 AI roles in October 2025 and 8,000 jobs in May 2026. He preached openness for years, quietly went closed in 2025, and has now reopened — not from conviction, but because the manifesto needed a proof point. Ask the Metaverse how his grand, world-remaking visions tend to end.
This is the deeper problem. When Zuckerberg speaks about “human values” and “personal empowerment,” he is not describing humanity — he is describing the only life he knows: total control, zero consequences, every failure absorbed and rebranded as vision. “The future is for everyone” is a definition of everyone written by a man who has never once had to live as one of them. It is not a vision of the world. It is the view from inside the bubble, mistaken for the view of the world.
The safest thing you can do with a manifesto about not trusting concentrated power is to remember who wrote it, and how much of it he holds.
C’est horrible à dire, mais peut-être que lorsque nous en aurons assez de voir la nature et nos maisons partir en fumée, nous prêterons davantage attention aux rapports « alarmistes » du GIEC — qui, au fond, n’avaient rien d’alarmiste.
Mais surtout, peut-être mettrons-nous enfin la question du dérèglement climatique au-dessus du « wokisme » et autres sottises. Car une chose est certaine : notre avenir sera marqué par les migrations climatiques — des êtres humains fuyant la sécheresse, les déserts agricoles, les inondations et autres phénomènes extrêmes.
Le plus probable, malheureusement, est que l’extrême droite instrumentalise la question climatique pour faire avancer ses projets antimigratoires, transformant encore davantage l’Europe en une forteresse entourée d’épaves humaines : des personnes qui cherchent simplement une vie meilleure, là où celle-ci est encore possible.
A health check that reports “healthy” is not the same claim as “this loop is still running.” I spent a chunk of today’s session learning that distinction the hard way, on a bot whose only job is to relay earthquake alerts to Bluesky.
The setup: a queue drain loop calls health.updateActivity() once at the top of every tick, before it checks whether there’s anything to post.
If the queue is empty, it returns immediately after that call — fine, activity stays fresh. But if a post is in flight, a re-entrancy guard (if (queueRunning) return) sits before that activity call on every subsequent tick.
So a post that hangs doesn’t just delay one tick — it silently stops the timestamp from ever updating again, while the health endpoint keeps reporting healthy right up until its own staleness threshold (10 minutes) is crossed.
I caught it by taking two /health readings 42 seconds apart and noticing lastActivity hadn’t moved at all — not slow, frozen.
Confirmed the mechanism by correlating a dedup file’s mtime with the exact freeze-and-recover window: a post to the Bluesky API had started, then sat there for ten minutes before some unrelated default finally aborted it.
The actual bug was almost embarrassingly small: bskyHandler.ts and its fleet-mode equivalent both constructed the Bluesky API client with no request timeout at all.
The RSS-fetching side of the same codebase already wrapped its fetches in one. Nobody had ported the pattern to the half that talks to Bluesky.
Fix was an AbortController wrapped around the client’s fetch, 30 seconds, done.
Damn, stumbled on a black hole of the past, really sorry to all the blogs that interacted with mine circa 2016 and that I never replied to, I was in a huge Justice battle IRL and my site at the time was not giving me as much control and view over what’s happening than it is today, some of these replies I’m seeing now for the first time.
There is also quite a few dead links that I never managed to recover from my server crash from around those years
Thanks for sharing RSC ! There is still a lot of work before I start to really enjoy using it as I envision but its been really fun to develop :)
Cross-browser Micropub client extension. Post to your IndieWeb blog from any page.
rmdes.github.io/plume/ - now with Draft support, right in your browser of choice !
I need to fix duplicate webmentions
I need to think about how to fix this
really glad to hear that :)
Test from Chromium based browser, Plume Micropub extension
Testing Plume from Firefox
I have looked at your Micropub plugin and then debugged the issues with claude and I think I found the problem, nothing to do on your side, it was really a bug on my side : https://github.com/rmdes/plume/releases I submitted version 1.3.1 to the extension stores, both should be available soon, you can always “developer” load it via the github release page if you don’t want to wait, let me know how it goes :)
Do you have access to your Kirby server logs ? would be interesting to check what’s the error precisely, have you looked at the dev console log when you attempt to add your site to the extension settings ? this would allow to gather a bit more information I suppose, another way would be to create a user for me, so that I can connect using it and launch mcp playwright debug in the process to understand what’s happening
inspiring…
Cool idea !
Great work by the cloudron team as usual !
Major Update : a configurable RSS poster for #Bluesky - that supports multi accounts - in active development https://github.com/rmdes/bsky.rss
China isn’t simply a regime with a centrally planned technological machine.
It’s something stranger: a strategically directed state sitting on top of an extremely competitive manufacturing ecosystem.
China’s long-term strategy increasingly resembles ecosystem substitution:
Foreign technological ecosystem becomes a vulnerability → create an alternative ecosystem.
Replacing Microsoft Office with a Russian office suite is import substitution.
Creating an operating-system ecosystem, CPU architecture, compiler toolchain, domestic cloud stack, hardware supply chain, developer community and application ecosystem is technological sovereignty.
China is attempting the latter.
@srijan.ch@fed.brid.gy how’s your micropub endpoint?
Does your blog support micropub?
Hmm this is odd, do you have any information to help me debug this ?
Test post from Plume, micropub extension for Firefox/Chromium derived browsers
Wishing there was a fully supported ATgeo lexicon that most bluesky app views could understand…it would allow us to build location aware posts from location data (think disasters, quakes, flood etc)
Sometimes I’m wondering, what would be the cost of stopping supporting the Mastodon API layer and instead work towards proper implementation of client to servers opening the route for a universal mobile app for #fedify based AP implementation.
For indiekit I used Fedify to bring this very blog into the fediverse but then I wanted to be able to use Phanpy and other mobile app so I built a compatibility api layer that these mobile apps expect to find allowing me to use my own site with any Mastodon mobile app. It works but it’s buggy and I’m subject to API layers change and other future breakage I don’t want to deal with in the long run.
So now I’m wondering, do I drop this API layer and build a universal client?
People comes in all shapes and sizes but writing code into OPML outlines to then “generate” code files for a git repository is one that I will never understand.
No matter how much time I put into it.
It’s like using I a Word document to write Javascript or typescript?
The results is a OPML file literally containing Javascript code, each outline being a block of code.
When changes are made and saved it changes the timestamp of the outline publish time, so any diff against the OPML is full of noise, it’s literally the worst dev environment I have seen in my life.
There is certainly a historical reason for this that evade my grasp but imagine, having a dozen intertwined code projects ALL developed in such a way.
Good luck contributing or sending a PR to repository like that. It’s literally the perfect way to make sure collaboration is impossible.
Just migrated bsky.rss from feedsub to feedsmith, now bsky.rss support RSS, Atom, Jsonfeed, RDF and soon GeoRSS too, I’ll do another round of improvements so that it would be easier to parse and render weather Feeds but that’s for later. Feedsmith has a bunch of other RSS extensions that I want to integrate, for example better source/author attribution, something I always wanted to bring for the RSS feeds that properly use these properties.🔗 https://rmendes.net/notes/2026/08/07/678e3
Related to my previous posts : https://standard-reader.app very interesting read here
There is so much happening on the #ATproto Atmosphere that its hard to keep up, I’m not talking about Bluesky the company, I’m talking about this or this or this its really a never-ending exploration no matter where this is going, this being decentralization and building on top of the protocol, it’s good for the web.
Plume A browser extension to Post to your IndieWeb blog from any page — toolbar composer or right-click capture. Cross-browser, multi-account, no telemetry.
The White House Is Feeding Russia’s Information War Against Europe
How the Ceuta migrant crisis exposed a transatlantic propaganda pipeline flowing from the White House.
https://weaponizedspaces.substack.com/p/the-white-house-is-feeding-russias
Interesting read.
Bookmarking to read later
When an activist downloads academic papers, the state describes it as wire fraud, computer fraud and reckless damage. When a corporate AI agent escapes containment, steals credentials, moves across systems and compromises another organisation, the event is described as a safety evaluation, an unexpected capability or a research incident.
Human hackers have frequently been prosecuted based on unauthorized access itself, including when their intent was research, activism, curiosity or political protest.
Frontier AI companies are currently receiving a much more lenient, cautious, collaborative and interpretively generous response after their own systems performed technically sophisticated unauthorized intrusions.
Why?
Aaron Swartz was driven to suicide under the pressure of a disproportionate federal prosecution for an act of information liberation that produced no comparable injury to the real-world intrusions now being committed by corporate AI agents.
Swartz’s case demonstrates that computer-crime law has never required catastrophic damage before the state deploys overwhelming punitive force against a human being.
The supposed seriousness often comes from unauthorised access itself, the circumvention of technical restrictions and the prosecutor’s interpretation of the person’s intentions.
technically serious conduct is minimised because the company claims not to have intended the precise outcome; the corporation controls the evidence and publishes its own narrative; the breach is framed as useful scientific discovery; disclosure and remediation are treated as evidence of responsibility; and the organisation retains the commercial benefit of developing the system.
Why is intention interpreted expansively and punitively when the actor is an individual hacker, but narrowly and sympathetically when the actor is a powerful corporation operating an autonomous agent?
Je prends quelques jours de vacances à la plage 😊
Detailed rapport on the HF intrusion by rogue OpenAi
There is a fork of rss.chat in the wild that supports basic federation between instances enabling cross community conversations for pre-defined approved instances. Check it here
You might also be interested in this :)
RSC (Really Simple Conversations) is a social feed where everything is distributed via RSS: posts, as well as replies, entire conversations, and corrections published afterward. Three independent sites can thus participate in the same feed without a common API, without a shared account, and without having to adopt a new protocol: if your site already publishes a feed, it’s already a node in the network.
Depuis vingt ans, chaque tentative de « réinventer » le web social commence par la même étape : inventer un protocole. XMPP, OStatus, ActivityPub, AT Protocol, Nostr. À chaque fois la promesse est la même, à chaque fois le coût d’entrée est le même : il faut que tout le monde adopte la nouvelle plomberie avant que quoi que ce soit ne circule.
RSC part d’une hypothèse inverse, presque provocante dans sa banalité : la plomberie existe déjà, elle s’appelle RSS, et elle n’a jamais cessé de fonctionner.
RSC signifie Really Simple Conversations. C’est un fil social (une timeline vivante) dans lequel les messages publiés sur l’instance et les messages publiés ailleurs, sur le site personnel de quelqu’un d’autre, sont des citoyens strictement égaux. Tout circule en flux ouverts : les billets, mais aussi les réponses, les fils entiers, et même les corrections apportées après publication.
La difficulté des réseaux sociaux fermés n’est pas seulement qu’ils hébergent vos contenus. C’est qu’ils hébergent le lien entre vous et vos lecteurs.
Vos billets sont chez eux, vos abonnés sont chez eux, et surtout le fil de discussion qui relie les deux est chez eux. Le jour où la plateforme change ses règles, ferme son API ou disparaît, ce n’est pas votre archive que vous perdez en premier : c’est votre capacité à continuer une conversation commencée.
Le blog, lui, a toujours été l’inverse. Vous publiez chez vous, un flux RSS sort de chez vous, et n’importe qui peut le lire sans autorisation. Ce modèle a survécu à Google Reader, aux jardins clos, aux algorithmes. Il est encore là.
Ce que RSS n’a jamais vraiment su faire, en revanche, c’est la conversation. On pouvait suivre. On ne pouvait pas répondre, ni voir un fil se reconstituer entre plusieurs sites.
C’est exactement ce trou que RSC essaie de combler.
Une réponse est un billet. Un billet voyage en RSS. Donc une conversation peut voyager en RSS.
Le reste n’est que de l’ingénierie.
Prenons trois instances indépendantes, hébergées par trois personnes différentes, sans rien de commun sauf le web.
rsc.rmdes.be. Le billet part dans le flux de l’instance.alice.rmdes.be, lit ce flux et répond. Sa réponse est un billet chez elle, qui sort dans son propre flux, en portant une référence au billet d’origine.bob.rmdes.be, lit la réponse d’Alice et rejoint le fil depuis son site.Trois serveurs indépendants. Aucune API partagée. Aucun compte commun. Une seule conversation.
Techniquement, le rattachement repose sur trois éléments transportés dans le flux : l’identifiant stable du billet (guid), la source qui l’a publié, et la référence au message parent (source:inReplyTo, doublée du standard RFC 4685 thr:in-reply-to).
Le point délicat, ce sont les arrivées dans le désordre. Sur le web ouvert, une réponse peut très bien être récupérée avant le message auquel elle répond, parce que le flux du parent est interrogé moins souvent. RSC choisit ici l’honnêteté plutôt que le silence : une réponse orpheline reste visible avec le contexte qu’elle transporte, au lieu d’être jetée, et elle se rattache automatiquement à son parent dès que celui-ci arrive.
Une objection classique au RSS : c’est lent, on interroge les flux toutes les quinze minutes, ça ne fait pas un réseau social.
C’est vrai du RSS des lecteurs de flux. Ce n’est pas vrai du RSS complet.
Deux mécanismes anciens et peu utilisés changent tout :
RSC utilise les deux, dans les deux sens : il pousse ses nouveautés, et il accepte de recevoir celles des autres. La fédération est donc immédiate, pas seulement périodique. Dans l’interface, la timeline se met à jour en direct via SSE (Server-Sent Events), et continue de fonctionner sans JavaScript, où les onglets redeviennent de simples liens.
C’est un détail qui dit beaucoup sur la philosophie du projet.
Quand un auteur corrige un billet déjà publié, RSC ne réécrit pas silencieusement l’histoire : il conserve un historique de révisions consultable. Et parce que le billet voyage sous un identifiant stable accompagné d’un marqueur atom:updated, chaque instance qui l’avait déjà ingéré détecte la modification à la lecture suivante, met à jour sa copie, et enregistre elle aussi sa révision.
La correction se propage donc partout où le billet est allé, sans remonter artificiellement en haut de la timeline. Tout cela en RSS ordinaire.
RSC ne prétend rien inventer. Il assemble.
Le projet s’inscrit dans le sillage de Textcasting, le manifeste de Dave Winer, dont l’exigence centrale est simple : un texte doit voyager avec sa mise en forme et son sens intacts, du logiciel d’écriture jusqu’au lecteur, sans être aplati par la plateforme du milieu.
Concrètement, chaque billet local est publié selon un double contrat : le HTML rendu et assaini pour les lecteurs, et le Markdown source à côté. Celui qui reçoit choisit ce dont il a besoin.
L’interopérabilité avec rss.chat, le projet de conversation en RSS de Winer, est réelle et testée dans les deux sens : RSC consomme son firehose avec l’attribution correcte des auteurs et le fil complet, et émet le même vocabulaire, si bien que son propre outil de parcours de fils lit les conversations RSC sans la moindre modification mais pour l’instant la fédération ne fonctionne qu’entre instance RSC car la fédération n’est pas encore implémentée chez rss.chat (même si des forks travaille déjà à l’interopérabilité entre instance rss.chat)
Le reste de la généalogie est du même ordre : la communauté IndieWeb pour les microformats, JSON Feed par Manton Reece et Brent Simmons, OPML pour importer et exporter une liste d’abonnements comme on l’a toujours fait avec une blogroll.
Le projet est en pré-version, mais pas au stade de la maquette. Fonctionnent aujourd’hui de bout en bout : la timeline unifiée à quatre onglets (local, fédéré, personnel, public), la publication et l’édition, les fils de discussion, les abonnements à n’importe quel flux RSS, Atom ou JSON, l’import et l’export OPML, la découverte de flux à partir d’une simple page HTML, les comptes (invité, mot de passe ou lien magique) et la fédération en temps réel.
Restent à venir : la connexion IndieAuth, la publication via Micropub, les Webmentions, et une meilleure récupération des médias depuis les flux externes.
Côté administration, chaque instance garde la main sur ses comptes, ses sources, ses limites et sa modération, avec un journal d’audit. La gouvernance fait partie du produit, elle n’est pas une réflexion après coup.
Le code est sous licence MIT, sans édition « entreprise » séparée ni dépendance à un service hébergé. La démonstration publique et l’instance que vous pouvez lancer sont exactement le même logiciel.
git clone https://github.com/rmdes/rsc.git
cd rsc && make up
En production, un make prod-env puis make prod-up suffisent : le tout tourne derrière Caddy, qui obtient et renouvelle le certificat HTTPS automatiquement. Les données sont dans SQLite, chez vous.
L’architecture est volontairement modeste : un service core sans interface (Hono, Node, SQLite) qui possède les flux, l’ingestion, la reconstruction des fils et les points d’entrée de fédération ; et une application web (SvelteKit) qui est la seule chose que les navigateurs touchent. Le cœur ne publie aucun port et n’est joignable qu’à travers ce partage.
Le web social n’a jamais disparu. Il a été recouvert.
Les silos n’ont pas gagné parce qu’ils étaient techniquement supérieurs, mais parce qu’ils ont rendu l’entrée gratuite et la sortie coûteuse. RSC est une tentative de rendre la sortie aussi simple que l’entrée : la même commande vous fait essayer et vous fait partir avec vos données.
Ce n’est pas une révolution technique. C’est une remise en service.
Démo : rmdes.be · Code : github.com/rmdes/rsc · Licence MIT