Files
atm-curs-dl/PROGRESS.md
Claude Agent c28e08b3aa Fix: transcribe.py nu mai sterge audio daca transcrierea nu pare completa
Cauza: am rulat `find transcripts -size -1k -delete` cat transcribe.py scria
in acelasi director. faster_whisper scrie bufferat, deci o transcriere de o
ora sta sub 1KB minute in sir; find a sters fisierul de sub proces, Python a
logat "Transcribed" pe un inode disparut, si audio-ul a fost sters. Lectia
11 (25.11.2025) pierduta complet, re-descarcata.

- transcribe_file() intoarce bool, verifica nr. cuvinte vs durata audio
- pull_moltbot.sh: staging + mutare doar peste 1KB, in loc de find -delete
- PROGRESS.md: documentat, ca sa nu se repete

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtSTyTmt6AbCL9j5ajEDm1
2026-09-12 18:35:06 +00:00

13 KiB

Progres — atm-curs-dl (2026-09-12)

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)

Modul Lecții Status
Modulul 1 10 ✅
Catalizatori economici 8 ✅
Modulul 2 16 ✅
Modulul 3 6 (5 video + 1 text) ✅
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.

În curs: Q&A (28 sesiuni) — pornit 2026-09-12 15:18

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.

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 îș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.

A/B pe modele, deja făcut — 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).

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.

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.

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.

Modificări de infrastructură făcute pentru asta

  • extract_audio.py: --only <modul> 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.

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.

Conținutul vine din câmpul html al /api/membership/lecture/<id>, împreună cu tot CSS-ul paginii — scriptul curăță <style>/<script>, apoi tagurile. Rulează-l după extract_audio.py, pe aceleași module: \.venv/bin/python extract_text_lessons.py [--only "<modul>"]

Rulează-l și pe Q&A / Analiză Zilnică înainte să declari un modul complet — nu presupune că tot ce e acolo are video.

Gardă nouă în render_html.py

O linie goală în interiorul unui <svg> face python-markdown să rupă blocul HTML, iar browserul aruncă restul elementelor — diagrama se randează pe jumătate, fără nicio eroare. S-a întâmplat de două ori (a doua oară în 2026-09-12, ștergând un <text> și lăsând linia cu spații). render_html.py crapă acum cu numărul liniei în loc să publice o diagramă stricată. Verificat că garda chiar prinde cazul.

Ce a rămas — blocat de acces (purchase_required)

Modul 5 (7), Modul 6 (6), Master ATM 1-4 (4+3+5+3=15) = 28 lecții. Dacă userul primește acces: rulează din nou .venv/bin/python extract_audio.py (skip automat pe ce există + pe ce tot blocat) → transcribe.py → lansează agenți de sumarizare ca mai jos.

Ce NU s-a atins din start (decis cu userul, conținut efemer/recurent)

Analiză Zilnică (147), Q&A (28), Live Trading Room (5), Rezultate Clienți Mentorat (3), + 5 lecții unice (1:1 Daniel R, MG, IM, LC, DR, AP) = ~189. Nu au fost incluse în CORE_MODULES din extract_audio.py. De reluat doar dacă userul cere explicit.

Cum se reia sumarizarea (dacă apar lecții noi)

  1. Verifică ce transcrieri nu au încă .md în summaries/: diff <(find transcripts -name "*.txt" | sed 's/\.txt$//') <(find summaries -name "*.md" | sed 's/\.md$//') (numele de fișier diferă — compară manual pe conținutul folderelor, nu literal cu diff)
  2. Lansează un agent per lecție (Agent tool, subagent general), cu prompt care:
    • trimite la citit STYLE.md (integral) + summaries/05_MODUL_4/01_patternuri_complexe_partea_a_doua.md (exemplul de referință canonic) + o lecție înrudită deja scrisă
    • dă calea transcrierii sursă (spune explicit "citește-o integral cu Read")
    • cere output la calea potrivită în summaries/<modul>/
    • obligă verificare vizuală Playwright individuală pe fiecare <svg> (tab nou dedicat via browser_tabs, server local python3 -m http.server pe port propriu în summaries/, apoi render_html.py) — regulă din STYLE.md, nu opțională nici pentru diagrame "simple"
    • interzice explicit rularea transcribe.py/extract_audio.py (un agent confuz a pornit-o din greșeală o dată, a dus la procese concurente)
  3. După fiecare agent: git add -A && git commit && git push (commit-uri mici, per lecție sau grup mic — nu aștepta să acumulezi zeci de fișiere).

Reguli de stil — STYLE.md

Document complet cu toate cerințele acumulate din conversația cu userul (fără emoji, română + termeni trading în engleză, mecanisme concrete nu afirmații, diagrame la scară cu context de trend, DA/NU pentru capcane, exemple long+short, minim 2-3 exemple numerice, secțiune obligatorie "Cum tranzacționezi efectiv X" — de ce/ce faci/trigger/intrare-SL-TP, referințe web reale). Citește-l integral înainte de orice lecție nouă.

Probleme întâlnite + fix-uri

  • NU rula find <transcripts> -size -1k -delete cât rulează transcribe.py. Greșeală făcută pe 2026-09-12: am folosit-o ca să curăț fișierele goale aduse de pe moltbot, în timp ce transcrierea locală scria în același director. faster_whisper ține fișierul deschis și scrie bufferat — o transcriere de o oră stă sub 1KB minute în șir. find a șters fișierul de sub proces; la final Python a închis un handle către un inode dispărut, a logat "Transcribed" ca și cum ar fi reușit, iar transcribe.py a șters și audio-ul. Lecția 11 (25.11.2025) a fost pierdută complet și a trebuit re-descărcată. Fix-uri aplicate:

    • pull_moltbot.sh — aduce în staging, mută doar fișierele peste 1KB. Folosește-l în loc de scp + find -delete.
    • transcribe.py — transcribe_file() întoarce acum bool și verifică numărul de cuvinte față de durata audio (prag: 15% din 100 cuvinte/min) înainte ca apelantul să șteargă audio-ul. Un fișier dispărut sau o transcriere suspect de scurtă păstrează audio-ul, deci pierzi doar timp de CPU, nu și descărcarea.
  • Halucinație whisper (propoziții repetate în buclă): a apărut la 05_MODUL_4/02_3_STRATEGIA_5_MDSRT.txt. Fix: re-extrage audio pentru lecția aia (extract_audio.py are funcțiile reutilizabile), retranscrie cu condition_on_previous_text=False în loc de setările default din transcribe.py. Verifică orice transcriere sub ~15% din numărul de cuvinte așteptat pt durata audio — semn de halucinație sau eșec silențios.

  • Procese lungi mor la reset de sesiune Claude (nu la reboot de container — LXC-ul rulează continuu). Fix: pornește orice job de ore în tmux new-session -d -s <nume> "<comanda> 2>&1 | tee -a <log>", verifică cu tmux has-session -t <nume>, nu cu ps aux pe un PID salvat. Detalii + motiv complet în memorie: feedback_tmux_pentru_procese_lungi.md.

  • Browser Playwright partajat între agenți paraleli: tab-urile se "fură" reciproc. Fix folosit de agenți: tab dedicat via browser_tabs, sau verificare document.title/URL înainte de fiecare screenshot, sau (când a fost prea instabil) un script Playwright/Node de sine stătător în afara MCP-ului partajat.

  • Lecții fără conținut tehnic (intro-uri, workshop-uri de psihologie): nu forța diagrame — STYLE.md permite adaptare, precedent stabilit în 01_MODUL_1/01_bun_venit_in_atm.md și 10_workshop_increderea_in_tine.md.

Fișiere cheie ale proiectului

  • download.py / extract_audio.py — login systeme.io + extragere audio direct din URL (fără video pe disc)
  • transcribe.py — faster-whisper (CPU, model medium, int8)
  • render_html.py — .md → .html responsive, rulează după orice modificare
  • .env — credențiale (gitignored, nu se comite)
  • STYLE.md — regulile de format, citește-l mereu primul

Ce ar putea urma (neconfirmat, doar idei)

  • Userul poate cere reluarea Analiză Zilnică / Q&A dacă găsește valoare în ele, deși au fost deprioritizate.
  • Dacă userul primește acces la modulele blocate, reia pipeline-ul.
  • Userul a spus că va pune întrebări punctuale pe conținutul deja scris — following-up conversations pot referi direct fișierele din summaries/.