- Carte compositeur : en-tête + colonne d'arrivée, champ
pleine largeur, bouton primaire ; neutralise le
display:flex imposé par .board-toolbar aux formulaires.
- 'Ajouter une description' devient un <details> natif :
aucun JS requis, insensible au cache et aux erreurs de
scripts (le bouton 0.31.0 pouvait rester inerte).
- Assets du board versionnés (?v=APP_VERSION) contre les
mélanges de cache après redéploiement ; Ctrl+Entrée.
- Vérifié en Chromium réel sur le vrai board (captures
contrôlées) ; 261 tests verts.
- Tiroir : édition du titre et de la description (PATCH
forge, journal 'edited', EVENT_TYPES étendu), création
avec description dépliable.
- Pièces jointes Gitea de bout en bout : client
list/upload/delete/download (le téléchargement suit
browser_download_url — l'endpoint asset ne sert que du
JSON, attrapé au smoke réel), routes proxifiées avec
CSRF et plafond 25 Mio, UI liste/envoi/suppression ;
GitHub : supports_attachments=False, message propre.
- Clic carte en délégation d'événement : les écouteurs par
carte mouraient au premier rafraîchissement live.
- 261 tests verts (7 nouveaux, palier 21) ; cycle réel
complet validé sur une issue jetable du vrai Gitea
(création, édition, envoi, téléchargement, suppression).
Depuis 0.24.0, /mcp exige session ou Basic : le service d'agents s'y
faisait refuser en 401 (vu en production, panneau Spark du 2026-10-21).
- Table api_tokens (empreinte SHA-256 seule), CRUD dans Mon profil
- Bearer honoré par le middleware sur /mcp et /api/ uniquement —
jamais l'interface web ; révocation et désactivation immédiates
- 235 tests verts (3 nouveaux : cycle de vie, compte désactivé,
handshake MCP par jeton quand l'auth est active)
- Comptes en base (PBKDF2), rôles, désactivation qui tue la
session, audit ; secours environnement pour l'opérateur ;
liaison draco par utilisateur ; page /profile.
- Espaces de travail : connexions, membres, sélection de
projets ; board/notes/épingles/journal scopés par espace ;
sélecteur d'espace, badge connexion.
- Panneaux /admin (utilisateurs, connexions, espaces,
paramètres — l'environnement amorce, le panneau gouverne).
- /archives : archive locale réversible, archivage forge
confirmé, purge de l'état local, export Markdown, file
« à archiver ? » avec archivage en lot.
- Correctif session : les comptes membres résolus par la base
(la session n'est plus limitée à l'opérateur d'environnement).
- 231 tests verts (12 nouveaux au palier 19).
list_starred/set_starred sur /user/starred (vérité dans la
forge), endpoint POST /api/projects/{o}/{r}/star (CSRF), section
Épinglés hors onglets, bouton étoile sur les cartes et bascule
sans rechargement; les épinglés sortent de leur grille d'onglet.
slugify + branch_name_for (issue-<n>-<slug>, reconnu par #1/#2);
client create_branch; POST /api/issues/{o}/{r}/{n}/branch (nom
libre validé, idempotent si existante); la carte passe en En
cours, journalisée source branch, étiquette synchronisée;
formulaire dans la section Code lié du panneau détail.
app/code_links.py: appariement pur (#n dans titres/corps/messages,
numéro en jeton de branche). Client: list_branches/list_pulls/
list_commits. Badge sur les cartes (board + fragments live),
section Code lié du panneau détail, /api/issues/{o}/{r}/{n}/code.
Le faux omettait la clé pull_request sur les issues, ce qui a
masqué le bug de la 0.5.1 pendant que 84 tests restaient verts.
Clé désormais toujours présente (null = issue, objet = PR) +
4 tests dédiés dans test_regression_gitea_payload.py.
FakeGitea: labels (repo_labels/label_ops), milestones (Sprint 1 sur
issues 1 et 3), invalidate_cache compteur. Le flux SSE est testé au
niveau du générateur: les clients de test HTTP ne ferment pas
proprement un flux infini (vérifié empiriquement); le bout-en-bout
HTTP a été validé en smoke test réel (curl + webhook).
FakeGitea étendu (get_issue, commentaires); le test de réconciliation
suit le nouveau retour de reconcile_board_state; l'assertion de
version suit APP_VERSION.
from tests.conftest import ... levait ModuleNotFoundError en CI :
le binaire pytest n'ajoute pas le répertoire courant à sys.path,
contrairement à python -m pytest (utilisé en local, qui masquait le
problème). Correctifs : tests/__init__.py (package), pythonpath=[.]
dans la config pytest, et étape CI en python -m pytest.
Vérifié : 36/36 dans les trois modes d'invocation.