diff --git a/PROGRESS.md b/PROGRESS.md index 61235e4..ee4fa57 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -1,11 +1,106 @@ -# Progres — atm-curs-dl (2026-09-12) +# Progres — atm-curs-dl (actualizat 2026-09-13, 06:00) Pipeline personal de transcriere + sumarizare pentru cursul de trading ATM (Bogdan Jinga, systeme.io), cont cu acces parțial. Repo: `romfast/atm-curs-dl` pe Gitea. Pagină publicată (Tailscale, doar în tailnet): **https://claude-agent.tailf7372d.ts.net/atm/index.html** -## Status: curriculum de bază 100% acoperit (53/53 lecții accesibile) +--- + +# CE E DE FĂCUT ACUM (citește asta prima) + +## 1. Sumarizări Q&A rămase — 12 din 27 + +**Gata de sumarizat imediat** (transcrierea există, sumarul nu): + +| Transcriere | Cuvinte | +|---|---| +| `09_09122025` | 21.876 | +| `15_14102025` | 21.137 | +| `18_23092025` | 17.171 | + +`02_18082026` NU se sumarizează — e duplicatul lui `03_11082026` (vezi mai jos). +`11_25112025` se transcrie chiar acum local. + +**Cum se face o sumarizare** — procedura exactă, urmată la toate cele 15: + +1. Citește `STYLE.md` integral dacă n-ai făcut-o în sesiunea asta. +2. Citește transcrierea **selectiv**, pe bucăți de ~200 de linii + (`sed -n '1,200p'`), nu integral — sunt 20-35 mii de cuvinte fiecare. +3. Scrie fișierul în `summaries/09_QA/_.md`. Numele vine din + transcriere: `13_28102025.txt` → `13_2025-10-28.md`. +4. **Folosește unealta de scriere (Write), nu heredoc-uri în Bash** — userul + a cerut asta explicit, pentru că heredoc-ul tipărește tot fișierul în + terminalul lui. Pentru corecturi mici (mutat o etichetă, schimbat un preț) + `sed` e în regulă. +5. Pentru diagrame cu candele sau cu entry/SL/TP: **generează-le cu + `svg_candles.py`**, nu le desena de mână. Vezi `gen/patternuri_candele.py` + ca exemplu de folosire. +6. `.venv/bin/python audit_diagrams.py summaries/09_QA/.md` → + trebuie să iasă 0 probleme. +7. Randează doar fișierul tău: + `.venv/bin/python -c "from render_html import render_file; from pathlib import Path; render_file(Path('summaries/09_QA/.md'))"` +8. **Screenshot pe fiecare SVG și citește-le efectiv** (Read pe .png). + Auditul mecanic nu vede text care stă peste o linie de preț. + `node /shot.mjs http://localhost:8137/09_QA/.html ` + (serverul local rulează pe portul 8137, din `summaries/`; dacă a murit: + `cd summaries && nohup python3 -m http.server 8137 &`) +9. Adaugă intrările în `summaries/09_QA/INDEX_TEMATIC.md`, pe secțiuni. + **Verifică ancorele** — headingurile cu `MP²` dau slug `mp2-...`, nu + `mp-...`, și am ratat asta de două ori. +10. `.venv/bin/python render_html.py` (regenerează tot + index.html), apoi + verifică link-urile interne (scriptul e mai jos), apoi commit + push. + +**Verificarea link-urilor interne** (rulează înainte de fiecare commit): +```python +import re, pathlib +bad = [] +for f in pathlib.Path("summaries").glob("*/*.html"): + for page, anch in re.findall(r'href="([\w.-]+)\.html#([^"]+)"', f.read_text()): + t = f.parent / f"{page}.html" + if not t.exists() or anch not in set(re.findall(r'id="([^"]+)"', t.read_text())): + bad.append(f"{f.name} -> {page}#{anch}") +print("link-uri rupte:", bad or "niciunul") +``` + +**Atenție la un eșec tăcut:** dacă scriptul care actualizează +`INDEX_TEMATIC.md` crapă (o ghilimea neescapată într-un titlu), verificatorul +de link-uri raportează „niciunul" — pentru că link-urile nici n-au ajuns în +fișier. Confirmă cu `grep -c "" INDEX_TEMATIC.md`. + +## 2. Transcrieri în curs — NU le opri + +**Local:** `tmux qa_local3`, lucrează la `11_25112025`. +Mai are după el: 23, 24, 25, 26, 28 (plus 09 și 11 gata). +Log: `transcribe_qa_local.log`. Viteză măsurată: **0.49x** durata audio. + +**moltbot:** `tmux qa_molt`, sub supervizor (`/root/atm/run.sh`). +Lucrează la `19_08092025`. Mai are: `22_04082025` (doar 5 min) și +`27_28052025`. Viteză: **1.01x** — de două ori mai lent decât local. + +**Cum aduci transcrierile de pe moltbot:** `./pull_moltbot.sh` +NU folosi `scp` + `find -size -1k -delete` (vezi incidentul de mai jos). + +**Când termină amândouă**, mai rămân de transcris: nimic. Toate cele 28 de +lecții Q&A vor avea transcriere. + +## 3. După Q&A — ordinea confirmată cu userul + +1. **Cele 5-6 lecții 1:1** (modulele 11, 17, 18, 20, 21, 22 — câte o lecție). + Formatul se decide **după** transcriere — nu știm dacă e mentorat personal + (irelevant) sau conținut tehnic. Rulează `extract_audio.py --only ""` + pentru fiecare. +2. **Analiza Zilnică (147 lecții).** Userul vrea un **sample separat** pe un + fișier, ca să aprobe un template, **înainte** de orice procesare în masă. + Nu porni fără asta. + Rulează `audio_fingerprint.py` pe toate ÎNAINTE de transcriere — acolo un + duplicat costă ore. + +--- + +# STATUS + +## Curriculum de bază: 53/53 lecții accesibile — complet | Modul | Lecții | Status | |---|---|---| @@ -16,219 +111,138 @@ pe Gitea. Pagină publicată (Tailscale, doar în tailnet): | Modulul 4 | 4 | ✅ | | Analiză Fundamentală | 9 | ✅ | -Toate transcrise (`transcripts/`) și sumarizate (`summaries/`), diagrame -verificate vizual (Playwright + server local), pe Gitea până la ultimul commit. +## Q&A: 15 din 27 sumarizate, 20 din 28 transcrise -## În curs: Q&A (28 sesiuni) — pornit 2026-09-12 15:18 +Sumarizate: 25.08, 11.08, 04.08, 28.07, 28.04, 19.02, 20.01.2026, +02.12, 18.11, 28.10, 21.10, 07.10, 30.09, 25.08, 18.08.2025. -Userul a cerut extinderea la Q&A, apoi cele 5-6 lecții 1:1, apoi Analiza -Zilnică (147). Decizii luate cu el: -- **Format Q&A**: un fișier per sesiune, dar structurat pe *subiecte* cu - titluri descriptive (nu pe dată), plus `summaries/09_QA/INDEX_TEMATIC.md` - care adună toate întrebările din toate sesiunile pe temă. -- **Întrebările administrative se aruncă** (o linie la final cu câte). -- **Diagrame doar unde adaugă ceva** (mecanism de preț, exemplu numeric, - setup) — nu pentru răspunsuri de proces/psihologie. -- **Sample aprobat**: `summaries/09_QA/01_2026-08-25.md` (commit `fc3c3f5`). - E referința canonică pentru restul sesiunilor Q&A. +## Blocat de acces (`purchase_required`) +Modul 5 (7), Modul 6 (6), Master ATM 1-4 (15) = **28 de lecții**. +Dacă userul primește acces: `extract_audio.py` → `transcribe.py` → sumarizare. -### Transcriere în curs — DOUĂ mașini -- **local (claude-agent)**: `tmux qa_local`, 16 fișiere, log - `transcribe_qa_local.log`. Măsurat: `medium` int8, 4 cores = 0.56x - durata audio. -- **moltbot** (LXC, 6 cores, fără GPU): `tmux qa_molt`, 12 fișiere în - `/root/atm/audio`, script `/root/atm/tr_worker.py`, log `/root/atm/tr.log`. - Rulează `medium` int8 cu `cpu_threads=5` (lasă 1 core pentru code-server - și ttyd, care rulează acolo). Venv: `/home/moltbot/echo-core/.venv`. - Acces: Tailscale SSH ca `root@moltbot` (userul a autorizat o dată). -- Split făcut LPT greedy **pe durată**, nu pe număr (sesiunile variază - 5 min - 3h24m). Backup audio pentru moltbot rămâne local în - `audio/09_Q_and_A_molt/`. -- **Viteze reale măsurate** (nu estima, folosește-le): local `medium` int8 - pe 4 cores = **0.49x** durata audio. moltbot `medium` int8 pe 5 cores = - **1.01x** — de două ori mai lent, are cores mult mai slabe. Split-ul - inițial (bazat pe o estimare de 0.75x pentru moltbot) a fost dezechilibrat - cu ~7h și a fost rebalansat la 16:10 mutând `26_11062025` și `09_09122025` - înapoi local. -- Local rulează în două pase: `tmux qa_local` (lotul inițial) și - `tmux qa_local2`, care așteaptă terminarea primei și reia `transcribe.py` - ca să prindă fișierele mutate. `transcribe.py` sare peste ce are deja - transcriere, deci pasele sunt sigure de repetat. -- **Workerul de pe moltbot moare fără urmă în loguri.** S-a întâmplat o dată - pe 2026-09-12 la 19:55, în mijlocul unui fișier de 2h11m: procesul python - ȘI serverul tmux au dispărut, fără traceback, fără linie de OOM (containerul - nu vede `dmesg`), fără reboot (uptime intact). Cel mai probabil OOM - nelogat — 8GB, `medium` int8 cu 5 threaduri. Coada s-a oprit 90 de minute - până am observat. - Fix: `cpu_threads` scăzut la 4, și `/root/atm/run.sh` — un supervizor care - relansează workerul de până la 40 de ori, cu 20s pauză, până apare - `ALL DONE` în log. Workerul e resumabil, deci o cădere pierde doar fișierul - în lucru. Pornește cu `tmux new-session -d -s qa_molt "/root/atm/run.sh"`, - NU cu workerul direct. -- **Workerul de pe moltbot își face `sorted(glob)` o singură dată la start** - — dacă muți/ștergi fișiere din `/root/atm/audio` cât rulează, repornește-l - (`tmux kill-session -t qa_molt` + relansare), nu te baza că observă - schimbarea. E resumable, pierzi doar fișierul în lucru. -- **După ce termină**: adu transcrierile de pe moltbot în - `transcripts/09_Q_and_A/` (`scp root@moltbot:/root/atm/transcripts/*.txt`), - apoi sumarizează în formatul din sample. +## Neatins, decis cu userul +Rezultate Clienți Mentorat (3), Live Trading Room (5). -### A/B pe modele, deja făcut — nu-l repeta +--- + +# UNELTE (scrise în sesiunea asta — folosește-le) + +| Fișier | Ce face | +|---|---| +| `svg_candles.py` | Generează diagrame de candele **din prețuri**, cu o singură scară px/unitate. Are `selftest`. | +| `audit_diagrams.py` | Verificare mecanică: text tăiat de viewBox, texte suprapuse, linii goale în ``, raport preț-vs-pixeli pe diagramele cu 3 niveluri. | +| `check_duplicates.py` | Duplicate pe transcrieri. Are `--selftest`. | +| `audio_fingerprint.py` | Duplicate pe audio, **înainte** de transcriere. Amprentă = RMS pe ferestre de 1s, corelat peste decalaje. Validat: 1.000 pe duplicat, 0.038 pe sesiuni diferite. | +| `pull_moltbot.sh` | Aduce transcrierile de pe moltbot în siguranță (staging + mutare doar peste 1KB). | +| `extract_text_lessons.py` | Lecțiile FĂRĂ video (`extract_audio.py` le sare). | +| `gen/patternuri_candele.py` | Regenerează `01_MODUL_1/05_patternuri_candele.md` întreg. Diagramele de acolo NU se editează de mână. | + +**Gărzi adăugate în cod:** +- `render_html.py` — crapă dacă găsește o linie goală într-un `` + (rupe blocul HTML tăcut și diagrama se randează pe jumătate). +- `transcribe.py` — verifică nr. de cuvinte vs. durata audio înainte ca + apelantul să șteargă audio-ul; și sare peste fișierele dispărute între timp. + +--- + +# INCIDENTE ȘI CAPCANE (nu le repeta) + +## Duplicat în curs +**Q&A 18.08.2026 = 11.08.2026**, aceeași înregistrare sub două date. +Verificat: durată identică, transcrieri 86.5% identice, amprentă audio 1.000. +Sumarizată o singură dată, sub 11.08.2026, cu notă în fișier și în index. +Scanat tot modulul Q&A: **un singur duplicat**. +Atenție: 13 și 16 diferă cu 0.288s dar sunt sesiuni **diferite** — verificat +prin transcrierea unor felii de 200s. + +## Transcriere pierdută dintr-un `find -delete` +Am rulat `find transcripts/ -size -1k -delete` cât `transcribe.py` scria în +același director. `faster_whisper` scrie bufferat — o transcriere de o oră +stă sub 1KB minute în șir. `find` a șters fișierul de sub proces, Python a +logat „Transcribed" pe un inode dispărut, iar audio-ul a fost șters. +Lecția 11 s-a pierdut complet și a trebuit re-descărcată. +→ Folosește `pull_moltbot.sh`. Garda din `transcribe.py` acoperă restul. + +## moltbot moare fără urmă în loguri +Pe 2026-09-12 la 19:55, procesul python ȘI serverul tmux au dispărut, fără +traceback, fără OOM în loguri (containerul nu vede `dmesg`), fără reboot. +Probabil OOM nelogat — 8GB, `medium` int8. Coada s-a oprit 90 de minute. +→ `cpu_threads` scăzut la 4 și `/root/atm/run.sh` relansează workerul de +până la 40 de ori. Pornește cu `tmux new-session -d -s qa_molt "/root/atm/run.sh"`, +NU cu workerul direct. + +## Coada locală oprită de un fișier mutat +`transcribe.py` își face lista o singură dată la start. Un fișier mutat la +rebalansare a oprit toată coada 13 ore mai târziu, cu `FileNotFoundError`. +→ Reparat, sare peste fișierele dispărute. + +## Tailscale SSH expiră +Accesul la moltbot cere reautentificare periodic. Când apare +`# To authenticate, visit: https://login.tailscale.com/a/...`, dă link-ul +userului. Workerul de pe moltbot rulează independent de accesul SSH. + +## A/B pe modele — nu-l repeta `whisper-small-ro-cv11-int8` (fine-tunat RO, există pe moltbot) e -**inutilizabil** pe conținutul ăsta: "MP4 short" → "empe patrat şort", -"PDF" → "pe-defect", "poziția" → "poliția". Fine-tunat pe Common Voice -(vorbire citită), se rupe pe live Zoom cu jargon englezesc. `medium` -generic câștigă clar și nu e nici mai lent (moltbot small-ro: 2.26x -realtime; local medium: 1.78x). +**inutilizabil**: „MP4 short" → „empe patrat şort", „PDF" → „pe-defect". +Fine-tunat pe Common Voice (vorbire citită), se rupe pe live Zoom cu jargon +englezesc. `medium` generic câștigă și nu e nici mai lent. -### Duplicate în curs — verifică ÎNTOTDEAUNA înainte de sumarizare -Cursul publică aceeași înregistrare sub două date. Găsit: **Q&A 18.08.2026 -este identic cu 11.08.2026** (lecțiile 2 și 3). Sumarizat o singură dată, -sub 11.08.2026, cu notă în fișier și în `INDEX_TEMATIC.md`. +--- -Două unelte, ambele în rădăcina repo-ului: -- `audio_fingerprint.py` — rulează pe mp3-uri **înainte** de transcriere. - Amprentă = RMS pe ferestre de o secundă, corelat peste decalaje de ±15s. - `md5` NU prinde duplicatele: cele două urcări sunt encodate separat, deci - bytes diferiți și durate care diferă cu ~0.08s. Validat pe perechea - cunoscută: **1.000** pentru duplicat, **0.038** pentru sesiuni diferite. - Prag: >0.90 = duplicat, 0.70-0.90 = verifică manual. - `\.venv/bin/python audio_fingerprint.py "audio/09_Q_and_A/*.mp3"` -- `check_duplicates.py` — pe transcrieri, pentru ce e deja transcris - (`transcribe.py` șterge audio-ul după succes). Are `--selftest`. +# CE A CERUT USERUL EXPLICIT -Rulate pe toate cele 28 de sesiuni Q&A: **un singur duplicat**, cel de mai -sus. Atenție la durate apropiate care NU sunt duplicate — 13_28102025 și -16_07102025 diferă cu 0.288s dar sunt sesiuni complet diferite; verificat -prin transcrierea unor felii de 200s din mijloc. +- **Format Q&A**: un fișier per sesiune, structurat pe **subiecte** cu titluri + descriptive (nu pe dată), plus `INDEX_TEMATIC.md` care adună toate + întrebările pe temă. Întrebările administrative se aruncă, cu o linie la + final despre câte. +- **Diagrame doar unde adaugă ceva** — nu pentru răspunsuri de proces sau + psihologie. La intro-uri și workshop-uri NU forța diagrame. +- **Diagramele trebuie să fie proporționale cu textul.** Reclamat explicit pe + `01_MODUL_1/05_patternuri_candele.md`: o țintă de 2R desenată la distanța + de 1R. Auditul a găsit același bug în fiecare modul. De aici `svg_candles.py` + și `audit_diagrams.py`. +- **Fiecare concept are nevoie de**: de ce îl urmărești, ce faci când îl vezi, + trigger DA/NU, exemplu complet cu intrare/SL/țintă. Nu doar „așa arată, așa + se numește". +- **Nu scrie fișiere cu heredoc-uri în Bash** — tipărește tot conținutul în + terminalul lui. +- Sample-ul aprobat, referința canonică pentru Q&A: + `summaries/09_QA/01_2026-08-25.md`. -**Rulează amândouă pe Analiza Zilnică (147 lecții) înainte de transcriere** — -acolo un duplicat costă ore, nu minute. +--- -### Ce urmează după Q&A -1. Cele 5-6 lecții 1:1 (module 11, 17, 18, 20, 21, 22 — câte 1 lecție). - Formatul se decide **după** transcriere — nu știm dacă e mentorat - personal (irelevant) sau conținut tehnic. -2. Analiza Zilnică (147). Userul vrea un **sample separat** pe un fișier - înainte, ca să aprobe un template — nu porni în masă fără asta. +# CE S-A REPARAT ÎN AUDITUL COMPLET (2026-09-12) -### Modificări de infrastructură făcute pentru asta -- `extract_audio.py`: `--only ` acum **ocolește** `CORE_MODULES` - (înainte filtra întâi pe ele); `--lectures N` limitează la primele N. -- `render_html.py`: adăugat extensia `toc`, ca headingurile să primească - `id` — fără ea link-urile din `INDEX_TEMATIC.md` n-au unde ateriza. +6 agenți Sonnet, câte un modul fiecare, plus verificare independentă de +mine. `audit_diagrams.py`: **0 probleme în toate fișierele**. -## Lecții FĂRĂ video — `extract_text_lessons.py` -`extract_audio.py` caută doar un MP4, deci sare peste lecțiile scrise. -Găsită una singură în curriculum-ul accesibil: **Modul 3 / #9 — Alte tipuri -de catalizatori** (expirări de opțiuni, witching, 0DTE). Avea 4.847 de -caractere de conținut real, nu era un quiz gol. Era numărată greșit ca -"acoperită" în versiunea anterioară a acestui fișier. +Bug-uri reale găsite, pe lângă cele de layout: +- **Bug de scară în fiecare modul**: 4.80R desenat ca 0.91R (divergențe), + 1.48R ca 0.47R (PIB), 2.84R ca 1.05R (Power), 6.5x în loc de 1.68x + (scanere), proiecție la 60px când referința era 75px (Inverted H&S). +- **Aritmetică**: spread scăzut de două ori în money management; „risc 5.90, + sub 1:1" când riscul era 1.90 și raportul 1:2.84; tabel Piotroski cu 3 + rânduri DA și total declarat 2/9. +- **Conținut**: o diferență de $814M numită „rotunjire" (4.7% din total) în + contul de profit și pierdere; un bar chart care arăta o valoare negativă ca + bară pozitivă; perechea DA/NU de la ATMI desenată cu adâncimi de 2x + diferență, deși lecția spune că diferența e invizibilă cu ochiul. +- **Goluri completate**: JOLTS n-avea secțiune de tranzacționare, Fed avea + doar minuta (nu ziua deciziei de dobândă), MDSRT n-avea de ce/ce faci/DA-NU, + R-multiple și portfolio heat lipseau complet. -Conținutul vine din câmpul `html` al `/api/membership/lecture/`, -împreună cu tot CSS-ul paginii — scriptul curăță `