Files
echo-core/tasks/lessons.md

5.8 KiB
Raw Permalink Blame History

Lessons Learned

Lecții capturate din corectările lui Marius. Citește acest fișier la începutul oricărei sesiuni de cod (înainte de plan mode) și aplică lecțiile relevante. Iterează neobosit pentru a evita rate drop-uri pe greșeli repetate.

Format per lecție:

## <titlu scurt>
**Data:** YYYY-MM-DD
**Context:** ce făceam când a apărut corectarea
**Greșeala:** ce am făcut greșit
**Regula:** ce să fac în schimb, în viitor
**Când se aplică:** trigger-uri concrete (fișiere, task-uri, situații)

Intră în plan mode ÎNAINTE de a executa orice modificare de cod

Data: 2026-05-28 Context: Marius a descris o cerință de îmbunătățire a comenzii /audio cu URL (chunk by chunk). Am implementat direct fără plan mode. Greșeala: Am sărit peste pasul de planificare și am modificat fișierele fără aprobarea lui Marius. Regula: Pentru orice modificare de cod (nu doar task-uri cu 3+ pași), intră în plan mode, prezintă planul, și AȘTEAPTĂ aprobarea înainte de a atinge vreun fișier. Când se aplică: Orice cerere de cod/implementare, indiferent de simplitate aparentă. Dacă e tentant să implementezi direct pentru că pare simplu — e exact momentul să te oprești și să planifici.

Supertonic rejectează ghilimelele curly (Unicode) cu HTTP 500

Data: 2026-05-27 Context: Marius a dat o comandă audio pe Discord cu un URL, iar răspunsul lui Claude conținea „foo" (ghilimele românești curly). Supertonic a returnat HTTP 500: synthesis failed: Found 1 unsupported character(s): ['„'] și răspunsul nu s-a mai auzit. Fără retry logic vizibil în UX — pur și simplu tace. Greșeala: Am presupus că normalize_for_tts produce text deja "TTS-safe" pentru Supertonic. În realitate strip_markdown păstrează ghilimelele Unicode ( U+201E, " U+201D, U+2014, U+2026, etc.) pe care Supertonic le refuză. Regula: Înainte de orice apel HTTP la Supertonic, sanitizează punctuația Unicode la echivalentele ASCII ( " "", ' ' ', -, ..., « »"). Funcția sanitize_punctuation în src/voice/normalize.py face asta și e apelată chiar după strip_markdown în pipeline. Dacă apar caractere noi care crapă Supertonic (ex: simboluri matematice, săgeți), adaugă-le în _TTS_PUNCT_MAP. Când se aplică: Orice cod care trimite text la Supertonic (tools/tts.py, src/voice/tts_stream.py). Inclusiv testare manuală cu curl — folosește text românesc realistic (include „foo", em-dash , ellipsis ).

Mai multe threads ≠ mai rapid — fitează cpu_threads pe physical cores, nu logical

Data: 2026-05-27 Context: Benchmark tools/voice_bench.py pentru faster-whisper small int8 pe i7-6700T (4 physical / 8 logical cores). Marius a urcat VM-ul de la 2 → 4 → 6 cores online, așteptând că mai multe = mai rapid. Greșeala: Presupoziție implicită că cpu_threads=N scalează liniar cu N. La 6 threads small.p50 a regresat la 2.79s vs 2.25s la 4 threads (+24% MAI LENT). Era ușor de ratat dacă rulam doar un singur pass. Regula: Pentru workload-uri compute-bound (int8/fp16 ML inference, video encode, criptografie) setează cpu_threads = numărul de PHYSICAL cores, NU logical. Hyperthreads adaugă synchronization overhead și memory bandwidth contention fără paralelism real. Sweet spot tipic: min(num_physical_cores, $optimal_threads). Verifică cu lscpu (Core(s) per socket × Socket(s) = physical; CPU(s) = logical). Dacă faci benchmark, rulează SWEEP nu single point — 2/4/6/8 threads să vezi unde e curba reală. Când se aplică: Configurare cpu_threads, OMP_NUM_THREADS, MKL_NUM_THREADS, torch.set_num_threads(), ffmpeg -threads, sau orice runtime ML/inference. Mai ales pe Proxmox VM-uri unde "more cores online" sună ca îmbunătățire. Întreabă-te: e workload compute-bound (yes → physical only) sau IO-bound (yes → logical OK)?

Nu șterge crontab-uri din sistem fără confirmare explicită

Data: 2026-05-20 Context: Marius a cerut să șteargă "newsletter test din cron jobs". Am interpretat că check_newsletter_cercetasi.py din crontab de sistem face parte din "newsletter test". Greșeala: Am inclus în scop un crontab de sistem care nu fusese menționat explicit. "newsletter test" se referea doar la job-ul newsletter-test din cron/jobs.json. Regula: Crontab-ul de sistem (crontab -l) este separat de cron/jobs.json. Nu îl modifica fără instrucțiuni explicite. Dacă scope-ul nu e clar, întreabă înainte de a acționa pe crontab sistem. Când se aplică: Orice task care implică ștergerea sau modificarea cron jobs — distinge întotdeauna între cron/jobs.json (APScheduler) și crontab-ul de sistem.

Nu scrie manual în index.json — rulează update_notes_index.py

Data: 2026-04-29 Context: Salvam o notiță din Facebook reel în memory/kb/. Am adăugat manual o intrare în index.json cu schema greșită (id + path în loc de file), ceea ce a blocat notes.html pe "Se încarcă..." cu un TypeError în renderNoteCard. Greșeala: Am editat index.json direct, cu o schemă diferită față de ce produce update_notes_index.py. Regula: Niciodată nu scriei manual în memory/kb/index.json. Fluxul corect: (1) creezi fișierul .md în memory/kb/<categorie>/, (2) rulezi python3 tools/update_notes_index.py. Dacă ai nevoie să salvezi o notiță din Facebook/video, folosești scripts/transcribe_video.sh <URL> <lang> --save-kb care face totul corect. Când se aplică: Orice salvare de notiță în KB (Facebook, YouTube, coaching, insights, orice). Dacă ești tentat să json.dump în index.json — stop, rulează scriptul.