Federated via graft
0

Configure Feed

Select the types of activity you want to include in your feed.


marp: true paginate: true backgroundColor: "#fff" theme: gaia lang: fr-FR style: | section { font-size: 25px; } h1 { color: #1a5fb4; } h2 { color: #1a5fb4; } h3 { color: #555; font-size: 24px; margin-bottom: 0.2em; } table { font-size: 21px; } code { font-size: 18px; } section.wide table { font-size: 18px; } section.part { background-color: #1a5fb4 !important; } section.part h1, section.part h2, section.part p { color: #fff !important; }#

Forges & web décentralisé#

État des lieux au 10 septembre 2026 (test alice->f1)


1. Cadrage#

code et collaboration#


Automatisation de la mise en miroir#

Le transport du code est résolu depuis 2005 : git est distribué par construction, un dépôt peut exister à plusieurs endroits.

L'orchestration n'existe pas. Chaque miroir se configure à la main, instance par instance. Chaque projet écrit elle-même l'intégration continue qui l'entretient.


Éléments non couverts par git#

Le véritable obstacle, c'est tout ce qui entoure un dépôt : tickets, propositions de modification, relectures, identité, droits.

Ces éléments sont stockés dans la base de données d'un serveur Forgejo, en dehors de git.

ActivityPub, le protocole de la fédiverse, les fait circuler : il transporte de petits messages (« créé », « aimé », « suivi »), pas des fichiers.


2. État de la fédération dans Forgejo#

Fonctionnalités livrées et fonctionnalités manquantes#


bg right:33% fit

Périmètre fonctionnel de la fédération Forgejo#

Fonctionne#

  • Le favori fédéré : un fork mis en favori transmet ce favori au dépôt d'origine.
  • Le suivi de comptes distants, avec un flux de leur activité.
  • Les fondations techniques : pages d'acteur, découverte, requêtes signées.

Pas implémenté#

Tickets, commentaires et propositions de modification fédérés. Modération et contrôle d'accès entre serveurs.


Fonctionnement du favori fédéré#

@alice@forgeA   --(c'est quoi, ce dépôt ?)-->   acteur du dépôt sur forgeB
                --(« aimé », signé)--------->   boîte de réception sur forgeB
forgeB vérifie la signature  -->  compteur de favoris +1, favori ajouté au profil d'alice

Le message part à sens unique, il est signé, il ne contient aucun texte : rien à modérer.

C'est le test le plus simple pour vérifier que l'échange entre deux serveurs fonctionne.


Suivi de comptes entre Forgejo et la fédiverse#

Un compte Forgejo peut suivre un compte Mastodon ou GoToSocial, et l'inverse. Les commits et les versions apparaissent alors dans un fil social.

C'est la première fonction de fédération visible pour quelqu'un qui ne développe pas.

Seuls Forgejo, Mastodon et GoToSocial sont acceptés pour l'instant.


Risque associé à l'activation de la fédération#

Le projet se réserve le droit de casser la fédération sans préavis.

Les autres serveurs mémorisent le domaine et les clés d'une instance dès que la fédération est active. Une rupture peut rendre ce domaine définitivement inutilisable pour tout usage ActivityPub.


bg right:38% fit

Adoption en production#

La fédération est désactivée par défaut, et les grandes instances publiques ne l'activent pas.

Les points d'entrée de la fédération répondent 404 sur codeberg.org, disroot et verdigado.


3. Autres solutions#

Des solutions indépendantes d'ActivityPub#


Mise en relation de deux forges par miroir#

Forgejo push ou pull déjà un dépôt vers une autre instance. Le code passe, les tickets non.

Deux projets comblent une partie du manque :

  • forgesync copie tous les dépôts d'une Forgejo vers une autre, tickets et propositions compris.
  • gitea-mirror fait la même chose avec une interface web, et transfère aussi étiquettes, jalons, versions et wikis.

F3 : migrer un projet, pas le fédérer#

F3 est un format d'export qui contient tout un projet : dépôt, tickets, propositions, commentaires, comptes.

Le code de migration de Forgejo s'en sert déjà.


bg right:33% fit

Authorized Integrations : authentification entre serveurs#

Forgejo v16, juillet 2026 : Authorized Integrations. La CI d'une instance peut désormais s'authentifier sur les dépôts d'une autre, sans secret partagé ni jeton à renouveler.

Un lien automatisable, arrivé cette année, sans ActivityPub. Nous l'avons testée en conditions réelles entre deux instances, f1 et f2.cyberwild.org.


Mise en place : exécuteur et confiance#

Un runner Forgejo (forgejo-runner), en mode host et sans Docker, est enregistré sur f1. Côté f2, une intégration autorisée fait confiance aux JWT émis par l'émetteur de f1, filtrés par une revendication.

forgejo admin user create-authorized-integration \
  --username forgeadmin \
  --issuer https://f1.cyberwild.org/api/actions \
  --claim-eq repository=forgeadmin/testrepo \
  --scope write:repository \
  --repo forgeadmin/testrepo

Le CI de f1 demande un jeton OIDC à sa propre instance#

jobs:
  inspect:
    runs-on: linux-host
    enable-openid-connect: true
    steps:
      - run: |
          AUD="u:1:11412bf9-...-f06c"
          curl -s -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
            "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=$AUD"

Revendications du JWT reçu : iss, repository, ref, workflow, sub. Le jeton est signé par f1 et vérifiable par f2 sans contact préalable.


Le jeton sert directement à s'authentifier sur f2#

curl -X POST \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  --data '{"title":"Proposition de test depuis le CI de f1","head":"f1-ci-run-6","base":"main"}' \
  https://f2.cyberwild.org/api/v1/repos/forgeadmin/testrepo/pulls

Aucun jeton n'est stocké côté f2 pour f1 : la confiance repose sur la signature du JWT et les règles de revendications, pas sur un secret échangé à l'avance.


Résultat : trois actions inter-instances réussies#

Action déclenchée depuis f1 Résultat sur f2
Créer un fichier HTTP 201
Créer une branche HTTP 201
Ouvrir une proposition de modification HTTP 201

4. Comparaison avec d"autres systèmes décentralisés#

Panorama des systèmes comparés#


bg right:33% fit

ForgeFed : une spécification distincte de Forgejo#

ForgeFed est une extension d'ActivityPub pensée pour les forges : dépôts, tickets, propositions, versions.

Vervis en est l'implémentation de référence : une forge complète et séparée, pas un module à brancher sur Forgejo.

Forgejo construit sa propre fédération. Le blog ForgeFed n'a rien publié depuis janvier 2025.


Comparaison des modèles techniques#

ActivityPub ATProto IPFS Radicle
Organisé autour de le serveur l'utilisateur le contenu le dépôt
Identité une adresse sur un serveur un identifiant portable une clé une clé, sans compte
Données stockées sur le serveur pointées par l'identifiant partout où copiées sur les nœuds relais
Droits signatures, plus l'admin des clés, on peut déménager aucun une liste de clés signée
Point faible changer de serveur = changer d'identité une société écrit les règles pas de contrôle d'accès sans relais, le projet disparaît

Radicle range tickets et propositions dans le dépôt git lui-même .


bg right:26% fit

Comparaison des modèles de gouvernance#

Code Gouvernance
ActivityPub Mastodon, PeerTube, GoToSocial : AGPL spécification W3C figée en 2018. Threads est propriétaire et fédère quand même
ATProto référence ouverte, auto-hébergeable une société écrit le protocole, tient l'infrastructure
IPFS Kubo et Helia, MIT fondation, mais Protocol Labs possède les domaines et arrête son financement le 30 septembre 2026
Radicle Heartwood, MIT et Apache 2.0 mené par ses mainteneurs, financé par le DAO Radworks

Ni ActivityPub ni Radicle ne dépendent d'une société..


bg right:33% fit

Ponts entre réseaux sociaux décentralisés#

Bridgy Fed relie la fédiverse, Bluesky et le web ouvert dans les deux sens. granary, en dessous traduit entre les formats.

Ce sont des projets personnels.


Tentatives d'hébergement de git sur IPFS#

Projet État
Gitlawb/node, ipgit actifs en 2026, une centaine de favoris chacun
git-remote-ipfs, pando, brig génération précédente, abandonnée

Rien n'est utilisable en production.

ATProto s'inspire du même principe : chaque contenu est identifié par une empreinte plutôt que par une adresse, comme sur IPFS. Mais contrairement à IPFS, ATProto associe ce contenu à des comptes utilisateurs identifiables.


bg right:33% fit

Portabilité de l'identité#

Keyoxide produit des preuves d'identité décentralisées, déjà utilisées par Forgejo pour ses propres contacts. did:web permet à un domaine de publier une identité portable dès aujourd'hui.

Mais quitter une instance reste synonyme d'abandonner son identité, ses contributions et ses relations. Radicle évite ce défaut en fondant l'identité sur des clés plutôt que sur un compte.


5. Démonstration pratique#

Radicle testé entre r1 et r2.cyberwild.org#


Mise en place : identités et connexion directe entre pairs#

Radicle 1.10.3 est installé sur les deux nœuds. Pas de serveur central : chaque nœud a sa propre identité (clé Ed25519) et écoute en pair-à-pair. Comme r1 et r2 sont sur le même réseau local, la connexion est directe, sans tunnel.

rad auth --alias radicle1
radicle-node --listen 0.0.0.0:8776

# depuis r1, connexion directe au nœud r2
rad node connect z6Mkfqb...2nbFDJg@192.168.1.108:8776

Un dépôt partagé, sans serveur#

# sur r1 : publier un dépôt existant sur le réseau
rad init --name testrepo --default-branch master --public
# -> rad:z2YWuPL53okTkr5mgb7WCKsfxG7h8

# sur r2 : récupérer le même dépôt directement depuis r1
rad clone rad:z2YWuPL53okTkr5mgb7WCKsfxG7h8

Le dépôt, avec ses fichiers, est répliqué intégralement entre les deux nœuds via le protocole pair-à-pair, sans jamais passer par un serveur HTTP.


Un patch (l'équivalent Radicle d'une proposition de modification)#

# sur r2 : proposer un changement
git checkout -b feature-dummy4
git commit -am "add dummy4.txt"
git push rad HEAD:refs/patches
# -> Patch 922387e... ouvert

# sur r1 (mainteneur) : relire et fusionner
rad patch checkout 922387e
git merge --no-ff feature-dummy4-review
git push rad master

Résultat : fédération pair-à-pair, sans passerelle HTTP obligatoire#

Étape Résultat
Connexion directe r1 et r2 établie
Réplication du dépôt sur r2 fichiers identiques
Patch ouvert sur r2, visible sur r1 propagé automatiquement
Fusion du patch sur r1 master mis à jour

Contrairement à Forgejo, aucune passerelle HTTP n'est nécessaire pour fédérer : l'identité et le partage reposent sur les clés des nœuds, pas sur un serveur public, cohérent avec le tableau de comparaison de la section précédente.


6. Faire dialoguer Forgejo et Radicle#

graft : un miroir entre les deux mondes déjà testés#


Ce que fait graft#

Un démon qui synchronise, entre une instance Forgejo et un nœud Radicle : le code, les tickets, et les propositions de modification dans les deux sens.

Il tourne à intervalle régulier, garde son état dans une base SQLite locale, et ne force jamais un push. Les vraies divergences sont signalées et laissées à l'arbitrage humain plutôt que résolues automatiquement.

Projet récent (GPLv3, quatre commits, aucune version publiée) : une démonstration de faisabilité, pas un outil éprouvé.


Relier f1 et r1#

sync_interval: 5m
state_db: /var/lib/graft/state.db

repos:
  - name: testrepo
    forgejo:
      base_url: https://f1.cyberwild.org
      owner: forgeadmin
      repo: testrepo
      token_file: /etc/graft/testrepo.token
    radicle:
      rid: rad:z2YWuPL53okTkr5mgb7WCKsfxG7h8
      http_base_url: https://r1.cyberwild.org
      rad_home: /home/graft/.radicle
    sync:
      git: true
      issues: true
      patches: true

Le même dépôt que dans la démonstration Radicle, maintenant relié à f1 plutôt qu'à r2 seul.


Ce qui se synchronise et limites actuelles#

  • Code : la branche par défaut, uniquement en avance rapide.
  • Tickets : un ticket Forgejo devient un ticket Radicle et inversement, mais seulement à la création.
  • Propositions de modification : une PR Forgejo ouvre un patch Radicle en poussant son commit de tête vers refs/patches, et inversement un patch Radicle ouvre une PR Forgejo.

Aucun force-push.#

Complémentarité#

graft ne tranche pas entre Radicle et Forgejo, il les traite comme complémentaires : le même projet existe sur les deux à la fois.

Ce que ça ne résout pas : l'identité reste double, un compte Forgejo d'un côté, une clé Radicle de l'autre.


7. Fonctions sociales de graft#

Un tableau de bord, et des ponts vers Discourse, Zulip, Tangled#


bg right:40% fit

Le tableau de bord graft#

Une page HTML unique, régénérée à chaque cycle de synchronisation : la liste des dépôts, leur nombre de miroirs, et un flux d'activité récente (les 10 derniers commits, tickets, patches et commentaires).

Volontairement plat : pas de base de données à interroger, pas d'authentification, juste un fichier HTML servi par le démon lui-même.


bg right:38% fit

Une identité fédiverse par dépôt#

Chaque série synchronisée (constitution, federation-x, graft-source...) obtient sa propre identité ActivityPub : @série@graft.cyberwild.org, avec WebFinger, Actor et Outbox interrogeables.

Une entrée AT Proto / Bluesky par série existe aussi dans le modèle, prête à être activée dès qu'une clé d'app y est associée — « not configured » pour l'instant.


Ponts vers Discourse, Zulip et Tangled#

Faire vivre l'activité de graft ailleurs que sur une forge#


bg right:35% fit

Pont vers Discourse#

Un démon séparé (graft-discourse), branché sur le flux ActivityPub de graft : chaque série synchronisée devient une catégorie Discourse (« Federated Repos »), chaque ticket ou patch un sujet.

Les réponses sur Discourse repartent en commentaire vers le ticket Forgejo/Radicle d'origine, marquées « via Fediverse ». Le pont ignore ses propres messages pour ne pas boucler.


bg right:35% fit

Pont vers Zulip#

Même principe, décliné pour Zulip (graft-zulip) : un canal par série (ici constitution), un fil (topic) par ticket. Zulip distingue le canal et le sujet là où Discourse n'a qu'une catégorie et un sujet — les deux démons partagent l'essentiel de leur code, seule la couche protocole change.


bg right:35% fit

Vers Tangled et AT Proto#

Tangled (une forge Git construite sur AT Proto/Bluesky) demande une identité signée par un PDS pour enregistrer un serveur Git (knot). Un PDS a été installé pour produire ce DID, tangled.cyberwild.org a été enregistré et vérifié : la prochaine étape naturelle est d'y raccrocher les mêmes séries que sur Forgejo et Radicle.


bg right:28% fit

Synthèse et questions#

Discussion :

  • Qui modère une proposition de modification abusive venue d'un autre serveur ?
  • Les miroirs et F3 marchent déjà. ActivityPub résout-il le vrai problème ?
  • Radicle et Forgejo : rivaux, ou deux moitiés de la même réponse ?