# AI Badge Coverage — Synthetic Content Labeler (art.50)

**Task:** SAA-W2-6 — Synthetic Content Labeler · twarda bramka zgodności art.50
**Data:** 2026-06-12 · **Deadline art.50:** 2026-08-02
**Komponent współdzielony:** `strona/components/ai-badge.js` (MM-M1-5, proof-pack 6 pól) — NIE duplikowany
**Bramka:** `master/qa_gate.py` → `master/qa_gate_report.json`

## WERDYKT: ✅ GO

Wszystkie powierzchnie z treścią generowaną/wspieraną przez AI noszą KOMPLETNY `<ai-badge>` (proof-pack 6 pól, status=VERIFIED). Brak ścieżki ukrycia badge (CSS/JS). `qa_gate.py` = PASS (exit 0), 0 FAIL. Brak blokerów.

## Wynik bramki (qa_gate.py)

```
=== QA GATE (MM-PAR-6) ===
Powierzchnie AI sprawdzone: 7 | FAIL: 0
Werdykt: PASS   (exit 0)
```

## Tabela pokrycia

| # | Powierzchnia | AI? | Badge kompletny? | Ukrycie? | Wynik |
|---|--------------|-----|------------------|----------|-------|
| 1 | strona/index.html | TAK | TAK (HUB-INDEX-0001, VERIFIED) | NIE | PASS |
| 2 | strona/CYWILIZACJA_DOME.html | TAK | TAK (DOME-0001, VERIFIED) | NIE | PASS |
| 3 | strona/ZRODLO_PRAWDY.html | TAK | TAK (SSOT-0001, VERIFIED) | NIE | PASS |
| 4 | strona/osczasu.html | TAK | TAK (TRUTHSTAMP-OSCZASU-0001, VERIFIED) | NIE | PASS |
| 5 | strona/truthstamp/index.html | TAK | TAK (rój+Claude, VERIFIED) | NIE | PASS |
| 6 | strona/system/sandbox_dashboard.html | TAK | TAK (Claude Opus 4.8, VERIFIED) | NIE | PASS |
| 7 | strona/components/DEMO_ai_badge.html | TAK (demo) | 2/3 kompletne + 1 celowo niekompletny | NIE | PASS (demo — niekompletny dozwolony) |
| 8 | strona/INTERFEJS_STADION.html | NIE | — | — | N/A (nie-AI) |
| 9 | strona/PROFILE_RYBNIK.html | NIE | — | — | N/A (nie-AI) |
| 10 | strona/STRATEGIA_METROWY_LARMO.html | NIE | — | — | N/A (nie-AI) |
| 11 | strona/agent_eventowy.html | NIE | — | — | N/A (nie-AI) |
| 12 | strona/dashboard_spraw.html | NIE | — | — | N/A (nie-AI) |
| 13 | strona/model_map/dashboard.html | NIE | — | — | N/A (nie-AI) |
| 14 | strona/okienko_vela_zezwolenia.html | NIE | — | — | N/A (nie-AI) |
| 15 | strona/polaczenia.html | NIE | — | — | N/A (nie-AI) |
| 16 | strona/router_trybow.html | NIE | — | — | N/A (nie-AI) |
| 17 | strona/rozgrywki_kokpit.html | NIE | — | — | N/A (nie-AI) |
| 18 | strona/system/reg_monitor.html | NIE | — | — | N/A (nie-AI) |
| 19 | strona/tablica_promptow.html | NIE (tooling) | — | — | N/A (nie-AI) — watch |
| 20 | strona/telebim.html | NIE | — | — | N/A (nie-AI) |

Pominięte (INTERNAL, nie-treść AI): `master_status.html`, `operator_gates.html`.

## Weryfikacja false-negative (audyt niezależny od regexa bramki)

Bramka klasyfikuje AI po regexie `ai-badge|truthstamp|generow|persona|disclosure`. Dla twardej bramki wykonano ręczny audyt powierzchni N/A pod kątem sygnałów spoza tego regexu (`prompt`, `wizerunek`, `wygenerow`, `sztuczn`, `render`, `<img>`):

- **tablica_promptow.html** — renderuje *szablony promptów do skopiowania* (wejście dla generacji obrazów), nie wyświetla treści wygenerowanej przez AI jako autentycznej. Narzędzie/konfiguracja, nie powierzchnia treści AI. Klasyfikacja N/A poprawna. **Watch-item:** gdyby strona zaczęła osadzać wygenerowane obrazy postaci → wymaga `<ai-badge>`.
- **rozgrywki_kokpit.html** — „prompt rozgrywkowy" = prompt operacyjny/orkiestracji, nie treść publiczna. N/A poprawne.
- **PROFILE_RYBNIK.html / INTERFEJS_STADION.html** — „wizerunek" tylko w kontekście checklisty zgód/praw (consent form), nie generowana grafika. N/A poprawne.
- **telebim.html** — „Prompty" to tylko link nawigacyjny do tablicy promptów. N/A poprawne.

Wniosek: brak false-negatywów. Klasyfikacja bramki zgodna z ręcznym audytem.

## Test „brak ścieżki ukrycia"

- **CSS:** żadna reguła `display:none / visibility:hidden / opacity:0` nie dotyczy `<ai-badge>` ani jego wrappera. Trafienia w skanie to: ukrywanie scrollbara nav (`::-webkit-scrollbar`), animacje scroll-reveal `.rv` (treść, nie badge), media-query nav, placeholder „brak wyników". Badge na 4 powierzchniach hubowych ma inline `position:fixed;right:12px;bottom:12px;z-index:99999` (zawsze widoczny, najwyższa warstwa).
- **JS:** brak `.remove()` / `removeChild` na `<ai-badge>` w żadnym pliku HTML. Komponent definiuje custom element i NIE udostępnia ścieżki usunięcia/ukrycia; `attributeChangedCallback` tylko re-renderuje.
- **Stan niekompletny = widoczny czerwony:** brak wymaganych pól → badge w stanie `err` „AI — proof NIEKOMPLETNY" (czerwony), nie znika. Brak cichego fail-open.

## Checklist art.50 — status

| Pozycja | Status |
|---------|--------|
| Każda powierzchnia z treścią AI oznaczona widocznym badge | ☑ zamknięte (7/7) |
| Badge = wspólny komponent (brak duplikacji implementacji) | ☑ zamknięte (`components/ai-badge.js`) |
| Proof-pack 6 pól (human, tool, ts, proof, src, status) | ☑ zamknięte (REQUIRED kompletny na wszystkich) |
| Brak ścieżki ukrycia badge (CSS/JS) | ☑ zamknięte |
| Stan niekompletny nie znika (fail-closed, czerwony) | ☑ zamknięte |
| Ciągła bramka build-time blokuje LIVE bez badge | ☑ zamknięte (`qa_gate.py` exit 1 na FAIL) |
| Audyt browser-side (`window.AiBadge.audit()`) | ☑ zamknięte (dostępny + użyty w sandbox_dashboard) |
| Powierzchnie N/A zweryfikowane (brak false-negatywów) | ☑ zamknięte (audyt ręczny) |
| Watch: tablica_promptow.html przy osadzeniu wygenerowanych obrazów | ◻ otwarte (monitoring, nie bloker) |

## Blokery

Brak. (Jedyna pozycja otwarta to watch-item monitoringu, nie blokuje GO.)

## Werdykt końcowy

**GO** — wszystkie powierzchnie AI oznaczone kompletnym badge art.50, brak ścieżki ukrycia, bramka PASS. Powierzchnia bez badge = automatycznie OFF przez `qa_gate.py` (guardrail egzekwowany w CI/build). Deadline art.50 (2026-08-02) — gotowość potwierdzona z wyprzedzeniem.
