Aller au contenu principal

Active work

Une personne équipée d’agents de code mène plusieurs sessions à la fois, et une équipe multiplie cela. Les agents de deux personnes peuvent construire la même chose sur deux branches qui n’ont aucun fichier en commun : aucun conflit de fusion ne le révélera jamais. Active work transforme les push que fremforge reçoit déjà en une vue du travail en cours, et avertit lorsque deux travaux se ressemblent.

Aucun agent n’a besoin de coopérer. Active work lit ce que la forge voit déjà : branches, push, pull requests et trailers que les agents écrivent déjà.

Active work est en phase pilote. Pour une organisation créée le 12 novembre 2026 ou après, il est activé par défaut, avec les pull requests brouillons au premier push et le commentaire de pull request activés, et avec la présence, les e-mails Active work et les rappels de travail inactif désactivés. Un propriétaire peut modifier chacun de ces réglages sur la page Active work. Pour une organisation créée avant cette date, il est désactivé par défaut, et un propriétaire de l’organisation l’active (voir Activer). Rien ne change pour une organisation existante.

Ce qui est enregistré

Lorsqu’une branche reçoit son premier push, fremforge crée un élément de travail en cours et le met à jour à chaque push et à chaque changement de pull request :

ChampProvient de
PersonneLa personne qui a poussé, ou l’auteur de la pull request. Les agents agissent pour le compte de leur personne : c’est donc toujours la personne qui est nommée.
Sessions d’agentLes liens Claude-Session: (ou tout <Tool>-Session:) et les trailers Co-Authored-By: dans les messages de commit et la description de la pull request. Seul le nom du co-auteur est conservé, jamais l’adresse e-mail.
Titre et intentionLe titre de la pull request, le début de sa description, le nom de la branche et les sujets des commits.
ZonesLes dossiers de premier niveau que la branche modifie, ou le module sous des dossiers comme apps/, packages/ ou services/ (apps/api, packages/db).

Un élément est actif tant qu’il reçoit un push dans les 7 jours. Il est terminé lorsque sa pull request est fusionnée ou que la branche est supprimée, et abandonné lorsque la pull request est fermée sans fusion. Les push vers la branche par défaut, ainsi que les branches poussées par les bots de fremforge ou par Renovate, ne sont pas enregistrés.

Comment le travail est comparé

Chaque fois qu’un élément change, fremforge le compare aux autres éléments actifs du même dépôt. Deux éléments sont signalés comme peut-être le même travail lorsque leurs titres partagent la plupart de leurs mots significatifs (par exemple « Rate limit the login endpoint » et « Add rate limiting to the login API »), ou lorsque leur texte plus large se recoupe fortement et qu’ils touchent la même zone.

La comparaison est un rapprochement de texte dans la base de données de fremforge. Aucun modèle d’IA n’est utilisé, et aucun code ni texte ne quitte fremforge, sauf si un propriétaire de l’organisation active aussi le rapprochement sémantique sur votre propre modèle, qui est désactivé par défaut. Les mots que toute modification utilise (« fix », « update », « add ») et les mots courants dans le travail du dépôt lui-même sont ignorés : deux modifications ne sont donc pas rapprochées simplement parce qu’elles portent toutes deux sur le même produit.

Entre dépôts

Le travail est aussi comparé au travail en cours dans les autres dépôts de l’organisation, uniquement par son titre et son intention (une zone comme apps/api dans un dépôt ne dit rien d’un autre). Les mêmes règles s’appliquent aux paires qui n’apprennent rien à personne. Une correspondance entre dépôts :

  • n’est montrée qu’aux personnes qui peuvent lire les deux dépôts : sur la page Active work, dans l’e-mail, sur la page de réponse et dans les outils de lecture ;
  • ne donne jamais lieu à un commentaire de pull request et n’est pas envoyée sur le flux d’événements, car le commentaire est visible par toute personne qui peut lire un seul des dépôts ;
  • désigne l’autre travail sous la forme org/repo#12, ou org/repo:branch pour une branche sans pull request.

Rapprochement sémantique sur votre propre modèle

Le rapprochement de texte trouve le travail qui dit la même chose avec les mêmes mots. Le rapprochement sémantique demande en plus au fournisseur d’IA propre à votre organisation si deux travaux en cours sont le même travail lorsque leurs mots diffèrent (« SSO button on the sign-in page » et « Log in with the company account »). Il est facultatif et désactivé par défaut, et il ne fait jamais que compléter le rapprochement de texte :

  • il peut ajouter une correspondance que le texte n’a pas trouvée, ou relever le score d’une correspondance trouvée. Il n’abaisse ni n’efface jamais une correspondance ;
  • il compare uniquement le travail du même dépôt, jamais entre dépôts ;
  • si un appel échoue, est lent ou dépasserait vos limites, le rapprochement continue simplement avec le texte seul.
Le rapprochement sémantique est disponible pour toutes les organisations, tel que le décrivent la version 1.64 du DPA et la version 1.34 de la politique de confidentialité du produit. Il reste désactivé tant qu’un propriétaire de l’organisation ne l’active pas, et fonctionne pour l’instant en mode fantôme : les verdicts sont enregistrés et personne n’en est informé.

Votre propre fournisseur, et rien d’autre

Le rapprochement sémantique utilise un fournisseur d’IA que votre organisation a configuré sous Intégrations IA, avec votre propre clé et votre propre contrat avec ce fournisseur. fremforge ne détient aucune clé propre pour cela et n’a aucune solution de repli : sans votre fournisseur, pas de rapprochement sémantique. Le fournisseur est votre sous-traitant, pas un sous-traitant ultérieur de fremverk (DPA, annexe B §B.8).

Les appels ne quittent fremforge que par un proxy sortant restreint, et uniquement vers l’hôte de votre fournisseur tel qu’il a été vérifié et épinglé lorsque vous avez enregistré le fournisseur. Si l’adresse du fournisseur change pour un autre hôte, le rapprochement sémantique se désactive de lui-même jusqu’à ce qu’un propriétaire le réactive, et cela est consigné dans le journal d’audit.

Ce qui est envoyé

Lorsqu’un travail, ou l’autre travail auquel il est comparé, a changé (et au plus une fois toutes les 10 minutes pour chaque travail), fremforge envoie à votre fournisseur, pour ce travail et pour au plus 15 autres travaux en cours dans le même dépôt :

EnvoyéNon envoyé
Le titre, sans préfixe type(scope):Le code, les diffs et le contenu des fichiers
Le début de la description de la pull request (jusqu’à 600 caractères)Les chemins de fichiers sous le dossier de premier niveau
Le nom de la branche, sans préfixe <login>/Les sujets des commits, les numéros de pull request, les liens de session d’agent
Les dossiers de premier niveau que la branche modifieL’identifiant, le nom ou l’adresse e-mail de quiconque, hormis ce que les personnes ont elles-mêmes écrit dans un titre ou une description

Les autres travaux sont étiquetés c1, c2, … dans la requête, jamais par identifiant ni par personne.

Un champ contenant un identifiant secret est omis. Avant tout envoi, chaque champ est analysé avec les propres règles de la protection des push : les règles par défaut de gitleaks pour la version qu’utilise fremforge, plus celles de fremforge (jetons frem.sh, fournisseurs cloud européens, chaînes de connexion, mots de passe dans la configuration). Un champ qui correspond est retiré de la requête, pas masqué. Si l’analyse ne peut pas s’exécuter, rien n’est envoyé.

Ce qui est conservé

fremforge ne conserve ni la requête ni la réponse du fournisseur. Pour chaque paire de travaux, il conserve uniquement si la réponse a conclu au même travail et un score de confiance, ainsi qu’une empreinte à sens unique de la requête pour ne pas envoyer deux fois la même. Ces données sont supprimées avec le travail et ses correspondances : 90 jours après la fin du travail (sa pull request fusionnée ou fermée, ou sa branche supprimée), ou 30 jours après la désactivation d’Active work pour l’organisation. Chaque appel est enregistré comme l’appel de toute fonctionnalité d’IA (fonctionnalité, fournisseur, nombre de tokens, latence), jamais son contenu.

D’abord en mode fantôme, puis les notifications

Le rapprochement sémantique démarre en mode fantôme : les verdicts sont enregistrés et mesurés, et personne n’en est informé. Les seuils sont fixés à partir de ces verdicts avant que les correspondances qu’il trouve ne soient affichées. Une fois qu’il notifie, un commentaire de pull request ou un e-mail sur une correspondance que le rapprochement sémantique a trouvée ou confirmée l’indique, et nomme le fournisseur d’IA et le modèle qui ont répondu.

Limites

  • Au plus un appel par travail toutes les 10 minutes, et seulement lorsque ce qui serait envoyé a changé.
  • Au plus 30 appels par organisation en 10 minutes et 500 par jour, en plus de la limite de dépenses IA de votre organisation.
  • Cinq appels échoués d’affilée suspendent le rapprochement sémantique pour l’organisation pendant 15 minutes (action d’audit active_work.semantic.paused).

Activer le rapprochement sémantique

Un propriétaire de l’organisation l’active sous Administration de l’organisation → Intégrations IA → Active work : rapprochement sémantique. L’interrupteur refuse tant que :

  1. Active work n’est pas activé pour l’organisation (Activer) ;
  2. l’organisation n’a pas son propre fournisseur d’IA ;
  3. ce fournisseur n’a pas d’hôte vérifié et épinglé (enregistrez à nouveau le fournisseur s’il a été ajouté avant le 26 octobre 2026 et que l’interrupteur le demande).

L’activation ou la désactivation est consignée dans le journal d’audit sous active_work.semantic.enabled ou active_work.semantic.disabled, avec la personne, le fournisseur et l’hôte épinglé. Tester cette fonctionnalité n’est pas proposé pour le rapprochement sémantique : il n’envoie jamais que le texte du travail en cours. Il s’active uniquement dans la console ; l’API REST ne le configure pas.

Déclarer vos contrats

Certains fichiers sont des promesses sur lesquelles s’appuie d’autre travail : une spécification d’API, des migrations de base de données, des types partagés. Déclarez-les dans .fremforge/contracts sur la branche par défaut du dépôt, un motif par ligne :

# API and schema contracts
apps/api/openapi.yaml
packages/db/migrations/**
proto/**/*.proto

* correspond à l’intérieur d’un dossier, ** à travers les dossiers, et une ligne qui se termine par / couvre tout ce qui se trouve en dessous. # commence un commentaire. Sans ce fichier, rien n’est traité comme un contrat.

Lorsqu’une fusion vers la branche par défaut modifie un fichier de contrat, chaque travail en cours dans la même zone commencé avant la modification reçoit une section Contract changed dans son commentaire Active work, qui nomme le fichier et la fusion. what_changed_since et list_active_work l’affichent aussi. Rien n’est bloqué : c’est un rappel de faire un rebase et de revérifier. L’information sur qui a fusionné la modification est conservée 90 jours.

Vrais conflits : une fusion d’essai

Deux branches sans aucune idée commune peuvent tout de même entrer en collision dans les mêmes fichiers. Lorsqu’un travail change, fremforge effectue une fusion d’essai avec les autres travaux ouverts qui touchent la même zone (ou qui semblent être le même travail), tête contre tête, dans Forgejo. La fusion d’essai n’écrit rien dans le dépôt et ne déplace aucune branche.

Lorsque les deux têtes sont en conflit, le commentaire Active work des deux pull requests liste l’autre travail et les fichiers en conflit, avant que l’une ou l’autre ne soit fusionnée. Celui qui fusionnera en second devra résoudre le conflit : convenez donc de qui passe en premier, ou faites dès maintenant un rebase sur l’autre. Lorsqu’un côté évolue et que les deux fusionnent de nouveau proprement, ou qu’un côté se termine, le conflit disparaît du commentaire. list_active_work renvoie aussi les conflits ouverts (conflicts).

Chaque paire est fusionnée une fois par paire de têtes, au plus 10 fois par minute et par dépôt, et uniquement pour les dépôts de moins de 2 Gio. Si la fusion d’essai n’est pas disponible, il n’y a simplement pas de signal de conflit ; rien n’est jamais bloqué.

Les paires qui n’apprennent rien à personne

Certaines paires ressemblent au même travail mais n’apprennent rien à personne. Elles apparaissent sur la page Active work avec une étiquette, et personne ne reçoit d’e-mail ni d’avertissement sur la pull request :

ÉtiquetteQuand
Retour arrière préparéLes deux travaux sont les vôtres et l’un annule votre modification : une branche revert/ ou rollback/, ou un titre ou un commit le plus récent qui commence par revert(, revert: ou Revert ".
Même sessionLes deux portent le même trailer de session d’agent (Claude-Session: ou un autre <Tool>-Session:) : le travail d’une seule et même session.
AssociéLes deux travaux sont les vôtres et l’un nomme l’autre : sa pull request (#12, org/repo#12 ou un lien vers elle, dans la description) ou son nom de branche (dans le titre ou le début de la description).
Dépôt associéDeux dépôts, dont l’un contient de la documentation, des textes juridiques ou des runbooks : un dépôt nommé docs, documentation, legal ou runbooks, un nom se terminant par -docs, ou tout dépôt portant le sujet Forgejo docs, documentation, legal ou runbooks. La documentation d’une fonctionnalité n’est pas une deuxième fonctionnalité.
Peut-être liéDeux dépôts, aucun dossier en commun, et un score inférieur à 0,85. Entre dépôts, seuls les mots peuvent correspondre, et les mots courants correspondent trop facilement.
EmpiléUne branche contient le commit de tête de l’autre : elle a été créée à partir de celle-ci.
Même changementLes deux branches portent des commits qui ne sont pas encore sur la branche par défaut : toutes deux ont été créées à partir de la même branche de fonctionnalité.

Toute autre paire entre deux personnes différentes est signalée, même lorsque l’une d’elles nomme le travail de l’autre : cela montre que l’un de vous est au courant, pas les deux. Pour marquer un dépôt comme documentation sans le renommer, attribuez-lui l’un de ces sujets dans ses Paramètres.

Une correspondance fait l’objet d’un e-mail environ trois minutes après avoir été trouvée, afin qu’un trailer de session d’agent qui n’arrive qu’avec la description de la pull request puisse d’abord marquer la paire comme le travail d’une seule session.

Lorsqu’une modification produit d’un coup plusieurs nouvelles correspondances pour vous, vous recevez un seul e-mail qui les liste, chacune avec son lien Répondre, et non un e-mail par paire.

Le commentaire sur la pull request

Lorsqu’une correspondance est trouvée, chaque pull request concernée reçoit un seul commentaire de fremforge-bot :

  • Il liste l’autre travail : sa pull request ou sa branche, la personne, les mots et les zones qu’ils partagent.
  • Il est modifié sur place lorsque les correspondances changent, et jamais répété. Lorsque l’autre travail est fusionné ou fermé, le commentaire indique qu’il n’y a plus de chevauchement.
  • Le texte provenant de l’autre travail est affiché comme du code brut, jamais sous forme de liens ou de mentions, et il est marqué comme des données. Un agent qui lit la pull request le lit comme une information, pas comme des instructions.

Le commentaire ne bloque jamais rien. Si le travail est le même, convenez avec l’autre personne de qui continue.

E-mail aux deux personnes

Les deux personnes reçoivent un e-mail par correspondance, dans leur langue, qui nomme l’autre travail, la personne, ainsi que les mots et les zones qu’ils partagent, avec un lien vers l’autre pull request ou branche. Lorsque les deux côtés sont deux de vos propres sessions, vous recevez un seul e-mail qui le dit. Chaque personne peut désactiver les E-mails Active work dans ses paramètres de notification ; un propriétaire de l’organisation peut désactiver les e-mails pour toute l’organisation (email_notify). Personne dont la préférence d’e-mail Forgejo est « disabled » ne reçoit d’e-mail.

Répondre à une correspondance

Chacune des deux personnes peut dire ce qu’est une correspondance :

RéponseSignificationCe qui se passe
Pas le même travail (different)Une fausse alerte.La correspondance disparaît immédiatement des deux commentaires de pull request, de la page et des outils de lecture, et reste écartée lorsque le travail change par la suite. Elle compte dans la fréquence à laquelle Active work se trompe.
Même travail, nous nous regroupons (same)Vous regroupez vos travaux. Indiquez éventuellement quel travail continue.Les deux commentaires affichent « Même travail, regroupé » et qui continue.
Partager le travail (split)Vous partagez le travail. Indiquez qui continue la partie commune.Les deux commentaires affichent « Partagé » et qui continue.

Répondez là où vous rencontrez la correspondance :

  • Sur la pull request : le lien Répondre du commentaire ouvre la page de réponse (connexion requise).
  • Dans l’e-mail : la même page, depuis Répondre ici. Ouvrir le lien ne change rien ; seul l’enregistrement du formulaire enregistre une réponse.
  • Sur la page Active work : le lien Répondre à côté d’un doublon possible, pour les deux personnes de la paire.
  • Avec l’API : POST /_app/api/v1/orgs/<org>/repos/<repo>/active-work/matches/<id>/response avec {"response": "split", "continued_by": "<login>"} (findings:write, accès en lecture au dépôt). GET …/matches/<id> lit une correspondance et sa réponse, et list_active_work renvoie match_id, response et continued_by pour chaque correspondance ouverte.

Seules les deux personnes dont c’est le travail peuvent répondre, jamais quelqu’un en leur nom : un jeton qui n’agit pour personne reçoit no-principal, toute autre personne not-a-party. Une réponse peut être modifiée ; c’est la dernière qui compte. Chaque réponse est consignée dans le journal d’audit sous active_work.match.responded, avec la réponse précédente et l’endroit où elle a été donnée. Un agent peut répondre pour sa personne via l’API, ou via l’outil d’écriture MCP answer_active_work_match, dès que la personne y a consenti et que l’organisation autorise les écritures par connecteur. La réponse renvoie previous_response, la réponse qu’elle a remplacée.

Notes de passation

Le travail change de mains : une autre personne pousse sur la branche, ouvre la pull request correspondante, ou le travail s’arrête tout simplement. Active work remarque ces deux cas et garde avec le travail ce que savait la première personne ou son agent.

Quand fremforge remarque une passation :

  • Changement de mains. Un push par quelqu’un d’autre que la dernière personne qui a poussé, ou une pull request ouverte par quelqu’un d’autre que la dernière personne qui a poussé. Plusieurs sessions d’une même personne ne constituent pas une passation.
  • Inactif. Une pull request ouverte sans push depuis 7 jours (vérifié une fois par jour). La question est posée une fois par période d’inactivité ; le push suivant transforme le commentaire en « travail repris ».

La pull request reçoit alors un seul commentaire de passation de fremforge-bot, modifié sur place, jamais répété :

  • qui a passé la main à qui, ou depuis quand le travail est inactif ;
  • Fait : la note de passation si une note a été écrite, sinon les sujets des commits ;
  • Ensuite et Questions ouvertes tirés de la note (ou d’une ligne Handoff:) ;
  • les liens de session d’agent du travail. Un lien https://claude.ai/code/session_… est affiché comme un lien ; il ne s’ouvre que pour la personne à qui appartient la session, qui peut ainsi la reprendre là-bas. Tous les autres travaillent à partir des notes.

Tout le contenu du commentaire est affiché comme du code brut et marqué comme des données, comme le commentaire de chevauchement ci-dessus. Il suit le paramètre pr_comment de l’organisation.

Rédigez la note sous forme de section Handoff dans la description de la pull request (ou dans un message de commit). Voici le bloc à ajouter à votre modèle de pull request (.forgejo/PULL_REQUEST_TEMPLATE.md) :

## Handoff
Done:
- 
Next:
- 
Open questions:
- 

La note la plus récente l’emporte : modifier la description la remplace, et un message de commit contenant une section Handoff la remplace aussi. Un modèle vide n’est pas une note. La note n’est pas comparée comme une intention : en écrire une ne provoque donc jamais d’avertissement de chevauchement. list_active_work et find_related_work la renvoient sous written.handoff (done, next, open_questions, qui l’a écrite et où), et la passation elle-même sous handoff (changed_hands ou idle, from, to, at, resumed).

Une ligne pour votre AGENTS.md ou CLAUDE.md :

When you stop working on a pull request, or hand it to someone else, add or update the "## Handoff" section of its description: Done, Next, Open questions. When you continue someone else's pull request, read written.handoff from list_active_work first.

En direct, sur le flux d’événements

Chaque nouvelle correspondance est aussi un événement activework.warning sur le flux d’événements : un agent qui suit déjà le flux l’apprend sans interroger régulièrement l’API.

Travail inactif : un rappel quotidien

Les sessions d’agent se terminent et laissent derrière elles des branches et des pull requests brouillons. Une fois par jour, fremforge envoie à chaque personne un seul e-mail listant ses pull requests et branches ouvertes sans push depuis 14 jours, y compris le travail que ses agents ont fait pour elle. Pour chaque travail, il y a trois réponses :

RéponseCe qui se passe
ContinuerPlus de rappel à ce sujet pendant 7, 14 ou 30 jours. Un push le remet de toute façon à zéro.
TransmettreNommez la personne suivante (elle doit avoir un accès en écriture au dépôt) et ajoutez une note si vous le souhaitez. Le travail devient le sien et figure dans son prochain récapitulatif avec votre note. Sur une pull request, la note va aussi dans son commentaire de passation, modifié sur place.
FermerFerme la pull request (la branche est conservée, elle peut donc être rouverte) ou, pour une branche sans pull request, supprime la branche.

Chaque élément de l’e-mail renvoie vers sa page de réponse (/_app/settings/work/idle/<id>). Vous devez être connecté : seule la personne à qui appartient le travail, ou un propriétaire de l’organisation, peut le voir ou y répondre, de sorte qu’un e-mail transféré ne peut fermer le travail de personne. Ouvrir le lien ne change rien. Les propriétaires de l’organisation trouvent aussi un lien Continuer, transmettre ou fermer à côté du travail inactif sur la page Active work. Chaque réponse figure dans le journal d’audit sous active_work.idle.continue, active_work.idle.handover ou active_work.idle.close, avec la personne qui l’a donnée.

À quel point l’e-mail est rare :

  • au plus un e-mail par personne et par jour, jamais un par pull request ;
  • chaque travail fait l’objet d’un rappel après 14 jours sans push, d’un second 14 jours plus tard si personne n’a répondu, puis plus aucun jusqu’à ce que quelqu’un y pousse ;
  • une pull request en attente d’un relecteur sollicité est exclue : la prochaine étape ne vous appartient pas ;
  • les bots (Renovate et autres comptes de bot) ne reçoivent jamais de rappel.

Le travail qui existait déjà avant que votre organisation n’active Active work est également pris en compte, dès la première exécution quotidienne.

La personne peut désactiver l’e-mail sous Rappels de travail inactif dans ses paramètres de notification, ou avec le lien de désabonnement en un clic de l’e-mail. Chaque élément d’un récapitulatif est aussi un événement work.idle sur le flux d’événements, afin que les propres agents de la personne puissent le voir.

Fermer automatiquement les pull requests inactives

Un propriétaire de l’organisation peut activer auto_close. C’est désactivé par défaut. Une pull request est alors fermée automatiquement lorsque toutes ces conditions sont réunies :

  • aucun push depuis auto_close_days (au moins 60, 90 par défaut) ;
  • un rappel la concernant est resté sans réponse pendant au moins une semaine ;
  • elle n’a aucune approbation, aucun relecteur sollicité et aucune revue demandant des modifications.

La branche est conservée : n’importe qui peut donc rouvrir la pull request. La personne en est informée dans le récapitulatif du jour, et la pull request reçoit un commentaire qui explique pourquoi. Les branches sans pull request ne sont jamais supprimées automatiquement.

La page Active work

Les propriétaires de l’organisation voient tout le travail en cours sous Build et déploiement › Active work : une carte par dépôt, le travail regroupé par zone, les sessions d’agent de chaque personne, et chaque doublon possible nommé et lié avec sa réponse. L’interrupteur de l’organisation se trouve sur la même page.

Qui travaille en ce moment (présence)

Le travail apparaît ici au premier push. La présence le montre plus tôt : lorsque l’assistant IA d’une personne travaille dans un dépôt via le serveur MCP (en y lisant des fichiers, des pull requests ou Active work), les personnes qui peuvent lire ce dépôt voient que cette personne y travaille en ce moment.

  • Ce qui est affiché : uniquement des identifiants. « Travaille ici en ce moment : alice, bob » sur la carte du dépôt, une carte pour les dépôts où quelqu’un travaille alors que rien n’a encore été poussé, et working_now dans list_active_work.
  • Ce qui est conservé : une entrée par personne et par dépôt, écrasée à chaque appel et supprimée 60 minutes après le dernier appel de la personne. Aucun historique, aucun décompte et aucune heure ne sont affichés. La présence n’est pas une mesure de l’activité de qui que ce soit.
  • Seul un appel qui a abouti compte : désigner un dépôt que la personne ne peut pas lire n’enregistre rien, et un jeton d’API qui n’agit pour aucune personne ne compte jamais.
  • Qui le voit : les personnes qui peuvent lire le dépôt : les propriétaires et les auditeurs de l’organisation sur la page Active work, et toute personne disposant d’un accès en lecture via list_active_work.
  • Le désactiver : un propriétaire de l’organisation avec le paramètre Montrer qui travaille dans un dépôt en ce moment de cette page (ou presence: false dans l’API des paramètres) ; chaque personne pour elle-même avec Montrer que je travaille dans ses paramètres de notification. L’un comme l’autre supprime immédiatement la présence.

Statut : disponible pour toutes les organisations. Une organisation dont le Travail en cours est désactivé, ce qui est le réglage par défaut, n’enregistre et n’affiche aucune présence.

Une pull request brouillon au premier push

Le travail est comparé dès son premier push, mais une branche sans pull request passe facilement inaperçue. Avec Pull request brouillon au premier push activé, lorsque quelqu’un pousse une nouvelle branche, fremforge ouvre aussitôt une pull request brouillon pour elle, au nom de cette personne : le travail est visible sur la forge, sur la page Active work et pour les agents de chacun avant que quelqu’un d’autre ne commence la même chose.

  • Activé par défaut pour les organisations créées le 12 novembre 2026 ou après, désactivé pour les plus anciennes. Un propriétaire de l’organisation l’active ou le désactive sous Build et déploiement › Active work (ou auto_draft_pr dans l’API des paramètres). Chaque personne peut toujours le désactiver pour elle-même sous Pull request brouillon à mon premier push dans ses paramètres de notification.
  • La pull request appartient à la personne. Elle est ouverte à son nom avec un titre WIP:, le sujet du premier commit et une courte description qui explique comment désactiver cette fonction. Elle reste un brouillon et ne peut donc pas être fusionnée tant que la personne n’a pas retiré WIP: et ne l’a pas marquée comme prête. Rien n’est jamais fusionné ni armé à sa place.
  • Sa CI attend qu’elle soit prête. Tant que le titre commence par WIP:, les workflows pull_request du brouillon ne s’exécutent pas : un brouillon ne coûte donc aucune minute de runner. Lorsque la personne le marque comme prêt (en retirant WIP: dans l’interface web, en modifiant le titre ou via l’API), les vérifications s’exécutent pour le commit de tête actuel : les vérifications requises existent donc toujours avant qu’il ne puisse être fusionné. Pour les lancer plus tôt, toute personne disposant d’un accès en écriture appuie sur Run checks sur la pull request (ou appelle POST /api/v1/repos/{owner}/{repo}/pulls/{index}/fremforge/run-checks) : une fois par commit de tête, et une seconde demande pour le même commit renvoie 409. Les workflows de push, ainsi que les propres analyses de pull request de fremforge (secrets, licences, sécurité), s’exécutent normalement. Seuls les brouillons qu’ouvre fremforge sont concernés : Forgejo l’enregistre lorsque le brouillon est ouvert par l’unique compte de plateforme qui peut les ouvrir, et rien de ce qui est écrit dans un titre ou une description ne peut en créer ou en défaire un. Une pull request que vous marquez vous-même WIP: exécute la CI comme avant, de même que toute pull request provenant d’un fork. Lorsque les vérifications s’exécutent au passage à « prêt » ou via Run checks, elles s’exécutent au nom de la personne à qui appartient le brouillon : les règles d’approbation s’appliquent donc à cette personne, et non à celle qui a appuyé sur le bouton.
  • Uniquement sa propre nouvelle branche, une seule fois. Un push vers une branche existante, une branche qui a déjà une pull request, les bots, les clés de déploiement et Forgejo Actions n’en reçoivent jamais. Au plus 10 par minute et par organisation sur chaque instance de l’API.
  • Comment c’est fait, et ce qui le limite. fremforge ouvre la pull request via le mécanisme Sudo de Forgejo avec un compte de plateforme dédié dont le jeton ne peut rien faire d’autre : la portée write:fremforge-draft-pr lui permet d’ouvrir un brouillon de travail en cours depuis une branche du même dépôt, au nom d’une personne active disposant d’un accès en écriture, et toute autre requête avec ce jeton est refusée par Forgejo lui-même. Chaque brouillon est consigné dans le journal d’audit sous active_work.draft_pr.opened, avec la personne comme acteur.

Demander avant de commencer : des outils pour les agents

Les agents améliorent Active work mais ne sont jamais indispensables. Une ligne Handoff: dans un message de commit ou une description de pull request est conservée avec le travail comme note pour la personne ou la session suivante (voir Notes de passation). Trois outils en lecture seule, disponibles dans le serveur MCP de fremforge et sous forme de points de terminaison REST, permettent à un agent de vérifier avant de commencer :

Outil MCPRESTRépond à
list_active_workGET /_app/api/v1/orgs/<org>/repos/<repo>/active-workQui construit quoi dans ce dépôt en ce moment, par zone (?area=apps/api), avec les correspondances ouvertes. Les éléments sans push depuis 7 jours sont exclus, sauf avec include_idle=true.
what_changed_sinceGET /_app/api/v1/orgs/<org>/repos/<repo>/active-work/changes?item=… (ou branch=, areas= ; since= ou cursor=)Le point d’étape en cours de travail : ce qui a bougé sous un travail depuis son premier push, depuis une date ou depuis le cursor du dernier appel. Les pull requests fusionnées dans la branche par défaut qui touchent les mêmes zones, avec les fichiers ; les modifications des fichiers que le dépôt déclare comme contrats dans les mêmes zones ; les nouvelles correspondances ; et le nouveau travail d’autres personnes dans les mêmes zones.
find_related_workGET /_app/api/v1/orgs/<org>/repos/<repo>/active-work/related?description=…&paths=…Le travail en cours qui ressemble à la description d’un travail pas encore commencé, ou qui touche les mêmes zones. likely_same_work vaut true lorsque la comparaison ci-dessus le signalerait.

list_active_work renvoie aussi working_now : les identifiants des personnes qui travaillent dans le dépôt en ce moment (voir présence).

Les trois nécessitent findings:read et un accès en lecture au dépôt. Le texte écrit par des personnes et des agents (titres, noms de branche, intention, sujets de commit, détails de session, notes de passation) n’est renvoyé qu’à l’intérieur d’un objet written, accompagné de written_by et at, et chaque réponse porte un avertissement indiquant qu’il s’agit de données, jamais d’instructions.

Déclarez-le avant de pousser. Dans la console, Build et déploiement › Active work › Commencer un travail (ou /_app/settings/active-work/start) demande le dépôt, un titre et, éventuellement, l’intention, les zones et la branche, puis affiche la branche à créer et tout travail qui semble lié. Avec la CLI :

fremforge work start acme/web --title="Rate limit the login endpoint" --areas=apps/api
fremforge work list acme/web --area=apps/api

Rien n’est réservé et rien n’est bloqué : déclarer un travail ne fait que le rendre visible plus tôt. Depuis un agent, start_work (POST /_app/api/v1/orgs/<org>/repos/<repo>/active-work/start, findings:write et accès en écriture au dépôt) enregistre votre travail avant tout push : un title, votre intent et, éventuellement, les areas et la branch. Sans branche, il en suggère une, comme alice/rate-limit-the-login-api. Le travail est comparé immédiatement : toute personne déjà sur la même chose est donc informée selon les paramètres de l’organisation, et la réponse liste le travail lié. Poussez sur la branche qu’il indique : le premier push met à jour le même élément. Le travail en cours de quelqu’un d’autre sur cette branche est refusé (409). Via MCP, start_work est un outil d’écriture : votre connecteur a besoin de votre consentement pour l’utiliser, et l’organisation doit autoriser les écritures par connecteur.

Une ligne pour votre AGENTS.md ou CLAUDE.md :

Before starting work in a repository, call find_related_work with a one-sentence description and the paths you expect to change. If an item has likely_same_work, stop and tell the person before building.
At each push, call what_changed_since for your branch with the cursor from the last call. If a migration or shared contract you depend on changed, rebase and re-check before building further.

Qui peut le voir

Le commentaire de pull request ne nomme que du travail du même dépôt : il ne montre donc d’autre travail qu’aux personnes qui peuvent déjà lire ce dépôt. Une correspondance entre dépôts n’est montrée qu’aux personnes qui peuvent lire les deux. Les dépôts privés restent privés au sein de l’organisation.

Activer

Les propriétaires de l’organisation activent Active work pour l’organisation avec l’API :

curl -X PUT https://frem.sh/_app/api/v1/orgs/<org>/active-work/settings \
  -H "Authorization: Bearer $FREMFORGE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"enabled": true}'
ParamètrePar défautSignification
enabledfalseEnregistrer et comparer le travail en cours.
pr_commenttrueCommenter les pull requests concernées par une correspondance.
email_notifytrueEnvoyer un e-mail aux deux personnes au sujet d’une correspondance.
idle_nudgetrueEnvoyer à chaque personne un récapitulatif quotidien de son travail inactif.
auto_closefalseFermer automatiquement les pull requests inactives, après un rappel resté sans réponse et jamais en présence d’une approbation ou d’une revue ouverte.
auto_close_days90Durée sans push au-delà de laquelle auto_close ferme une pull request : de 60 à 365.
presencetrueMontrer qui travaille dans un dépôt en ce moment (présence).
auto_draft_prfalseOuvrir une pull request brouillon au premier push d’une nouvelle branche, au nom de la personne qui a poussé.

La lecture des paramètres nécessite policy:read, leur modification policy:write. Chaque modification est consignée dans le journal d’audit sous active_work.settings.updated, avec la personne qui l’a faite.

Vos propres interrupteurs

Chaque personne dispose de trois interrupteurs qui lui sont propres, dans ses paramètres de notification ou via l’API :

ParamètrePar défautSignification
presencetruePour tout le compte : les autres voient que vous travaillez dans un dépôt en ce moment. Le désactiver la supprime immédiatement.
orgs.<org>.mailtrueLes e-mails Active work dans cette organisation.
orgs.<org>.auto_drafttrueUne pull request brouillon à votre premier push, là où l’organisation l’a activée.
curl https://frem.sh/_app/api/v1/users/me/settings/active-work \
  -H "Authorization: Bearer $FREMFORGE_TOKEN"

curl -X PUT https://frem.sh/_app/api/v1/users/me/settings/active-work \
  -H "Authorization: Bearer $FREMFORGE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"presence": false, "orgs": {"acme": {"mail": false}}}'

Ces paramètres sont personnels : ils nécessitent donc un identifiant qui porte votre identité, à savoir le jeton de fremforge auth login, votre bench ou un connecteur IA (en lecture seule, via l’outil get_my_settings). Un jeton d’API d’organisation est refusé avec user-identity-required. La lecture nécessite orgs:read, la modification orgs:write. Seules les organisations dont vous êtes actuellement membre sont listées ou modifiables (les noms sont comparés sans tenir compte de la casse), et un connecteur IA ne voit pas les organisations dont les propriétaires ont bloqué les connecteurs IA. Chaque modification est consignée dans le journal d’audit de cette organisation sous notifications.preference.self_updated, avec vous comme acteur.

Lire tous les paramètres d’un coup

GET /_app/api/v1/orgs/<org>/settings (orgs:read), ainsi que l’outil MCP en lecture seule get_org_settings, renvoie en une seule réponse les paramètres de contrôle du flux et d’IA de l’organisation. Ce qu’il montre dépend de qui le demande :

  • Les membres voient ce qui s’applique à leur propre travail : les interrupteurs d’Active work, les branches qui gèlent les fusions (uniquement dans les dépôts qu’ils peuvent lire), et si les connecteurs IA peuvent lire ou agir.
  • Les propriétaires et les auditeurs voient en plus les paramètres des release trains, des niveaux de risque et de la CI qui s’emballe, l’ensemble des paramètres d’Active work, et chaque fonctionnalité d’IA avec son modèle ainsi que le nom et l’éditeur du fournisseur.

Il ne renvoie jamais de clé de fournisseur, d’empreinte de clé, d’adresse de point de terminaison, d’ajout au prompt ni de jeton. Il n’existe pas de version en écriture, ni via l’API ni dans MCP.

Le mesurer

GET /_app/api/v1/orgs/<org>/active-work/metrics?days=30 (policy:read) renvoie uniquement des décomptes et des durées, jamais le texte du travail de quiconque :

  • matches et matches_both_notified ;
  • notify_seconds_p50 et notify_seconds_p90 : le temps entre le premier push de la seconde personne et le moment où la correspondance est montrée aux deux personnes (l’objectif est de moins de 5 minutes) ;
  • false_positive_rate : la part des correspondances ayant reçu une réponse marquées « different » ;
  • dismissed_share_of_notified : les correspondances ayant reçu la réponse « different » parmi toutes celles montrées aux deux personnes, avec ou sans réponse (l’objectif est de moins de 30 %), et response_rate ;
  • responses_by_kind et responses_by_via (api, page, pr_comment, mail).

La page Active work affiche la même mesure pour les 30 derniers jours.

Consultez la référence de l’API pour les schémas complets.