# Fabryka explainerów — mapa repo i arsenału

> **Zgubiony? Zacznij od `SLOWNIK.md` (sześć nazw) i `MAPA.md`** (jedna kartka: składniki, stan, routing, co czytać).
> Punkt wejścia dla człowieka i przyszłych sesji. **Stan bieżący i wznowienie:
> `HANDOFF-2026-09-02.md`**; dziennik decyzji z dowodami: `HANDOFF-2026-08-31.md` (§1–§30). **Audyt całości
> (co robiliśmy i co osiągnęliśmy, z listą kontrolną): `HANDOFF-AUDYT-2026-09-02.md`.** Porównanie z wytwórnią
> i kierunek dalej: `POROWNANIE-WYTWORNIA-vs-FABRYKA-2026-09-02.md`. CELOWO nie ma tu `CLAUDE.md` —
> agenci scen mają dostawać wyłącznie kurowaną wiedzę z promptów (efekt menu:
> kanon podany hurtem dał `dashed` w 173/173 plansz; samowolne czytanie źródeł
> silnika zjadało 15% kosztu biegu).

## Co to jest

Produkcja wideo-explainerów w stylu kanału RepoChad w architekturze V2:
**agent LLM pisze kod planszy** (`plansza.mjs`), silnik daje seek-safe runtime,
harness renderuje i waliduje, a wiedzą agenta jest kontrakt + biblioteka
wzorców na żądanie. Pełny workflow V3: **tekst wchodzi → film wychodzi**.

## Mapa katalogów

```
fabryka/
  komponenty*.mjs        silnik: wrapFrame, opy, kotwica (exact-first), walidujOps
  pilot/harness.mjs      pętla wizualna: kompozycja→check→render→podglad/ + harness.json
  pilot/infografika.mjs  infografika na żądanie agenta: --tryb pojeciowy (obraz-metafora,
                         INFOGRAFIKA_REGULY.md) | bogaty (schemat+tekst, nośnik treści,
                         INFOGRAFIKA_REGULY_BOGATE.md); codex pisze prompt → gpt-image-2 → assets/ig/NN.png;
                         `--regiony` = krok D: mapa regionów + snippet warstw do odsłaniania PO KOLEI
  pilot/schematy.py      REJESTR PRESETÓW kompozycji (rzad/proces:N, pion:N, stos:N, os-czasu[-pion]:N, mapa-mysli:N,
                         centrum-boki, porownanie, siatka:RxC, cykl:N, wolny): sloty w % (geometria v5) → layout
                         obowiązkowy dla rysownika + regiony dla wycinacza; `--test` (samokontrola), `--rejestr` (tabela
                         + tabela decyzyjna „forma treści → preset"); lab: przebiegi/_lab-wycinki/A/RAPORT.md
  pilot/prompt_szablon.py prompt rysownika składany z presetu BEZ LLM (`infografika.mjs --prompt szablon`)
  pilot/regiony.py       mapa regionów gotowej infografiki (qwen-flash :8020 | codex2 -i | piksele) → NN.regiony.json/.png
                         + maski PNG „LA” per region; DOMKNIĘCIE (iter. 7): szkielet bez tuszu — pył, sporne klamry i blade
                         wypełnienia idą do warstw właścicieli, reszta = sam papier (klatka 0 czysta z konstrukcji)
  pilot/kontrola_tresci.py  kontrola treści obrazu wizją qwen-flash :8020 (0 $): postacie + NAGOŚĆ → TYLKO flaga w infografika.mjs
                         (decyzja usera: zakazu nie wpisujemy do promptów, bo rysownik zacząłby wszystko zakrywać)
  avatar/                 PREZENTERKA 2D (moduł): avatar.mjs (nakładka: sprite'y ust + op `usta`), arkusz_na_sprity.py (arkusz gpt-image-2 →
                         PNG z alfą, wyrównane), postac_v1 (3 stany), postac_v2 (6 wizemów); włączanie: biblioteka/14_avatar.py --on|--off
  pilot/lab_wycinki_metryki.py  SĘDZIA bez LLM: symulacja odsłaniania, M1–M7 (M7a brud w klatce 0, M7b spłaszczone), werdykt
                         CZYSTY/UWAGI/ODRZUCONY → bramka w infografika.mjs (ODRZUCONY = obraz w całości, nigdy odrzucenie obrazu)
                         + MASKI pikselowe per region (NN.maska-rK.png, alfa po składowych tuszu) → warstwy bez dziur
                         + snippet: kopie <img> z clip-path per region, „reszta” z dziurami, podkład (HANDOFF §21)
  pilot/VADEMECUM.md     wiedza PEŁNA agenta (kanon 38 form) — standard produkcyjny
  pilot/VADEMECUM_V3.md  wiedza SLIM (odrzucona w review jako standard; zostaje wariantem)
  prompty/               REZYSER.md (stary), REZYSER_V3.md (podział na tablice; kicker w języku lektora od 2026-09-02,
                         dominanta+wsparcie), SCENOGRAF_V2/REDAKTOR (era silnika V1)
  skiny/  + SKINY.md     9 stylów + REJESTR (statusy: 1 podstawowy / gotowe / szkice)
  caption-skiny/         4 style napisów (mechanizm HyperFrames; u nas napisy off)
  fonty/                 woff2 dla wszystkich skinów — latin+latin-ext (PL!); Gochi Hand bez PL (README)
  wzorcownia/*.py        potok wzorcowni i masówki (niżej)
  biblioteka/*.py        potok biblioteki elementów i produkcji V3 (niżej)
  e2/                    era analizy: 14 analiz filmów, warsztat 49 kart, scenariusze
wzorcownia/              INPUT (mrożony): 601 scen-wzorców z 14 filmów kanału
                         (<VID>/tNN/: meta, BRIEF, wzor/klatki+wycinek, szkielet+TTS)
przebiegi/               OUTPUT (append-only): 1 katalog = 1 bieg; sceny <TID>/
produkcje/               sceny WŁASNE z planu REŻYSERA (format wzorcowni; PID bez „-")
baza/                    BIBLIOTEKA ELEMENTÓW: INDEKS.md = JEDYNE wejście agenta
                         (protokół drzewiasty; poziom 0 = 9 sekcji tematycznych z
                         _kategorie.json — przypisania codex), MODULY/*.yaml (poziom 1),
                         przyklady/<typ>/* (poziom 2), ELEMENTY.jsonl, ALIASY.tsv
bloki/                   ARSENAŁ HYPERFRAMES: INDEKS.md (poziom 0 dla agentów ~2 kB),
                         kategorie/*.md (poziom 1), compositions/* (poziom 2, kod),
                         KATALOG.md (widok ludzki), _katalog.json (źródło metadanych)
www/                     serwis przeglądowy (serwer z obsługą Range → przewijanie)
videos/                  era silnika V1 (r04 = film referencyjny BAo5)
```

## Potoki i narzędzia

### Wzorcownia + masówka (`fabryka/wzorcownia/`)
| skrypt | robi |
|---|---|
| `00_filmy.py` | tytuły kanału z workera → `FILMY.json` |
| `02_granice.py` | granice scen OCR-em kickera (tesseract, walidacja ±3 s) + `kickery.py` (naprawa M→H) |
| `03_tnij.py` | sceny samowystarczalne: klatki co 2 s, wycinek, lektor, BRIEF, `KATALOG.jsonl` |
| `04_szkielety.py` | TTS (Kokoro <1 h; wyżej moduł `:8772`) + projekt HyperFrames bez `plansza.mjs` |
| `06_masowka.py` | orkiestrator SDK: `--model` (Opus 5 = `claude-opus-5[1m]`!), `--tury 1\|2`, `--wiedza pelna\|slim`, `--biblioteka`, `--infografiki dowolne|zawsze|warstwy` (dowolne: agent decyduje TAK/NIE, obraz pojęciowy; zawsze: 1 bogata infografika na planszę jako nośnik treści, HF = omówienie; warstwy: jak zawsze + obraz odsłaniany regionami na kotwicach przez `--regiony`), `--zrodlo` (wzorcownia/produkcje), `--tidy`; claim `mkdir`, **STOP-flaga = drain bez sierot**, limit konta NIE zjada kolejki |
| `08_www.py` | serwis: przegląd wierszowy N przebiegów obok wzorca, sync-odtwarzanie; `--serwuj` (Range!) |
| `10_hyperframes.py` | detektor plansz w kanałach mieszanych (kryterium: udział NIERUCHOMYCH pikseli) |

### Biblioteka + produkcja V3 (`fabryka/biblioteka/`)
| skrypt | robi |
|---|---|
| `01_inwentarz.py` → `02_identyfikuj.py` → `03_synteza.py` → `05_wytnij.py` | budowa biblioteki: inwentarz → codex nazywa elementy (wizja) → scalenie typów + karty + egzemplarze → wycinki + `INDEKS.md` |
| `04_www.py` | galeria elementów wg typów (weryfikacja okiem) |
| `06_produkcja.py` | **workflow V3**: scenariusz → REŻYSER_V3 (tablice, dominanta+wsparcie) → TTS per tablica → drzewo `produkcje/`; `--skin` |
| `07_style.py` | macierz scen×skinów (reskin „tylko farbą", zero LLM) + strona porównawcza |
| `08_skiny.py` | lint konwencji skinów + generator `SKINY.md` |
| `09_bloki.py` | arsenał: miniatury/podglądy mp4 + `bloki/KATALOG.md`, `www/bloki.html` **i drzewo agentowe** `bloki/INDEKS.md` + `kategorie/*.md` (reguły `KATEGORIE`, sprzątanie gałęzi-sierot) |
| `13_przeglad.py` | strona `www/przeglad_ig.html`: filmy biegów + mozaiki per scena (licznik obrazów, warstwy) + wszystkie infografiki — bez LLM |
| `12_propaguj_audio.py` | po zmianie lektora: wgrywa audio/audio_meta/czasy do istniejących scen przebiegów (mają własne kopie) i przerenderowuje równolegle |
| `11_porownanie.py` | strona `www/produkcja_<PID>.html`: wersje filmu obok siebie (`--wideo`, `--sklej <RUN>` skleja sceny w FILM.mp4) + tabela tablic z PLAN.json |
| `14_avatar.py` | prezenterka w rogu sceny: `--on/--off`, `--postac postac_v1|postac_v2`, `--tryb amplituda|rhubarb`, `--strona prawa|lewa`, `--szer`, `--render`; usta z audio sceny (0 LLM) |
| `10_polski_glos.py` | polskie produkcje: podmiana Kokoro→omnivoice (`:8772`, bank m01) w szkieletach + words do `kotwica()` z faster-whisper + normalizacja czasów (stare audio zostaje jako `01.kokoro.wav`) |

### Standard produkcyjny (werdykty usera)
**Opus 5 · 2 tury · wiedza pełna**; T2 ogląda własny render (`KEEP_T1`/`ACCEPT_T2`/
`ROLLBACK_T1`). Tablice z planu REŻYSERA: **dominanta-gospodarz kadru + wsparcie
(0–3)**; **strefa ciszy ekranu** = żadne wejście w ostatnich 3 s sceny (twardy błąd
walidatora); scena trwa dokładnie tyle co lektor (ciągłość TTS w sklejce).

## Zasady twarde (z krwi)
- `wzorcownia/` mrożona; `przebiegi/` append-only; **zero retry**; sekrety nigdy w repo.
- Stop przez `touch przebiegi/<RUN>/STOP` (drain) — **nigdy pkill** (kille = 33 M
  tokenów w koszu jednego dnia; szczegóły: kanon `claude_code_sdk/03-claude-p-cli.md`).
- Prompty produkcyjne pisze **codex1 z briefów**.
- **Walidacja treści = FLAGI, nigdy odrzucenie** (doktryna wytwórni): narzędzie, które
  ma wątpliwość (etykiety, liczby, styl), zapisuje flagę w dzienniku i JEDZIE DALEJ;
  bez wyniku zostaje tylko fizyczna niemożność (brak pliku, brak sceny, limit budżetu).
- Reskin gotowych scen **tylko farbą** (radius/cienie/tekstury); zmiana typografii
  = produkcja w skinie (`06_produkcja.py --skin`).
- Koszt audytuj z **transkryptów** (`~/.claude/projects/…`), dedup po `message.id`
  (po `uuid` zawyża ~2×); koperty nie widzą sesji przerwanych.

## Arsenał HyperFrames — co jest NA MIEJSCU, a co w rejestrze

| warstwa | gdzie fizycznie | uwagi |
|---|---|---|
| CLI/runtime v0.8.22 | **lokalnie** w cache npx (`~/.npm/_npx/...`) — NIE w repo | działa offline po zbuforowaniu; w masówce pinuj `HF_BIN`, bo N równoległych `npx` bije się o cache |
| dokumentacja frameworka | **lokalnie**: `~/.claude/skills/hyperframes*` (core, animation, keyframes, audio, registry, cli, creative) + `npx hyperframes docs` | pełne referencje na dysku |
| **rejestr bloków: 357 pozycji** | **ZAINSTALOWANY W CAŁOŚCI** w `bloki/` (139 bloków + 218 komponentów) | ludzie: `bloki/KATALOG.md` + `www/bloki.html` · **agenci: `bloki/INDEKS.md`** — drzewo poziomów: 0 = 13 kategorii (~2 kB) → 1 = jedna kategoria (≤8 kB) → 2 = plik bloku przy wpinaniu; źródło metadanych: `bloki/_katalog.json` |
| przykładowe rodziny bloków | — | **mapy**: `us-map` (choroplet), `us-map-bubble`, `us-map-flow` (łuki), `us-map-hex`, `spain-map`, `world-map` (+globus); ~62 pozycje map/wykresów (`bar-chart-race`…); animacje kodu (VS Code/tereminale Apple, diff, morph, particle), przejścia shaderowe, 3D/kamera (`camera-dolly-zoom`), mock-UI (ChatGPT/Claude), HUD-y |
| style plansz | **nasza warstwa** `fabryka/skiny/` (rejestr: `SKINY.md`) | framework ma z pudełka tylko caption-skiny |

Instalacja bloku do projektu: `npx hyperframes add us-map` (kod ląduje w repo —
od tej chwili jest „na miejscu" i można go cytować w bibliotece jak nasze typy).

## Serwis www
**Stała usługa LaunchAgent** `pl.gileneo.fabryka-www` (autostart po reboocie,
KeepAlive wskrzesza po padzie; logi w `logs/www.*`). Sterowanie:
`launchctl bootout/bootstrap gui/$UID ~/Library/LaunchAgents/pl.gileneo.fabryka-www.plist`.
Zapasowo: `.claude/launch.json` → wpis `wzorcownia` uruchamia `08_www.py --serwuj --port 8899`
(własny serwer: `Range`/206 — `python3 -m http.server` NIE umie przewijania wideo).
Strony: `www/index.html` (przegląd wierszowy), `produkcja_MHsO.html` (V3 vs oryginał),
`style_<RUN>.html` (macierz stylów), `biblioteka_pilot.html` (elementy wg typów).

## Kanon zewnętrzny (dla orkiestratora, nie dla agentów scen)
`~/www_new/external_connections/`: konta i komendy (`claude1-3`, `codex1/2`,
`aicheck`), wzorzec `codex exec` (05), pułapki `claude -p` przy masówce (03),
endpointy TTS/worker YT. Routing wiedzy: narzędziowa-międzyprojektowa → kanon;
projektowa → to repo (HANDOFF/docs).
