===================================================================
QA #51 — Frontend : classification, complexite & tag bf-disagree
page detaillee + liste  (parent epic #26, PR #29 -> dev)
Branche : feat/51-classification-display @ 19cd23e
Date : 2026-06-11   Agent : QA manuel (#25)
===================================================================

RESULTAT GLOBAL : PASS (tous les criteres OK)

------------------- Smoke test : portes de qualite ----------------
npx vitest run (complet)   : 458 passed / 86 fichiers   -> OK
  suites ciblees            : ticketMeta(12) + BfDisagreeTag(5)
                              + TaskRow(3) + TaskDetailPane(13) = 33 passed
npx tsc --noEmit           : exit 0                      -> OK
npx eslint .               : exit 0                      -> OK
npm run build              : exit 0 (log /admin ENVIRONMENT_FALLBACK
                              pre-existant, non bloquant) -> OK
Backend (api/.venv, PYTHONPATH=src) :
  test_task_board_use_cases.py : 13 passed
  dont test_list_project_tasks_flags_bf_disagree_from_description : OK
  (tests d'integration FastAPI test_tasks_api.py = besoin Postgres,
   hors smoke ; derivation couverte par le use-case unitaire)

----------------------- Criteres d'acceptation --------------------
[OK] TaskDetailPane affiche classification + note + explication
     -> carte triage read-only 'Classification & complexity'
        (TaskDetailPane.tsx:256-257 parseTicketMeta/stripTicketMetaBlock)
[OK] Tag bf-disagree (#FF9800 + tooltip) sur la page detaillee
     -> import @/components/atoms/BfDisagreeTag (TaskDetailPane.tsx:8)
[OK] Tag bf-disagree visible dans la liste des tickets
     -> TaskRow.tsx:6 import + :123 <BfDisagreeTag> inline sur rangees flaggees
        flag aliment par bf_disagree (backend) ; rangees ne lisent pas
        les descriptions -> enabler backend minimal :
        has_bf_disagree(description) -> TaskSummary.bf_disagree
        -> TaskSummaryOut.bf_disagree (aucun nouvel appel upstream)
[OK] Composant tag partage avec la previsualisation (#50), pas de reimpl.
     -> meme atome importe par TicketDraftPanel.tsx:6, TaskRow, TaskDetailPane
        couleur #FF9800 definie UNIQUEMENT dans l'atome (atoms/BfDisagreeTag.tsx:45)
[OK] FR/EN : cles ajoutees dans en.ts uniquement, fr.ts reexporte en
     -> tasks.triage.* + bfDisagreeTooltip (en.ts:435-459) ; fr.ts = typeof en
[OK] parseTicketMeta / stripTicketMetaBlock parsent + masquent le bloc meta
     -> exportes ticketMeta.ts:116/:132 ; 12 tests parser verts
[OK] Gate vert (vitest, tsc, eslint, build) + TDD

-------------------------- Smoke live UI --------------------------
Prod https://pipeliner.omdev.tech atteignable (200) mais derriere
authentification (page 'Sign in'). Pas d'identifiants utilisables
sans secret -> fallback sur les tests de rendu (Testing Library)
comme preuve visuelle, conformement au plan. Aucun secret manipule.

Preuves jointes :
  - qa-51-rapport.txt (ce fichier)
  - qa-51-vitest.txt  (sortie vitest complete)
===================================================================
