# AutoPass — Roadmap & Proces de Dezvoltare
> **Sursa unica de progres + procesul de lucru.** O sesiune noua are nevoie doar de promptul:
> *"Citeste docs/ROADMAP.md si continua roadmap-ul [optional: livrabila X.Y]."*
> Sesiunea isi detecteaza singura faza (§5.7), planifica SAU executa, verifica si inchide —
> cu doua porti umane: aprobarea PRD-ului si confirmarea commit-ului.
>
> Contractul RAR (sursa de adevar de contract) = `docs/api-rar-contract.md`. Acolo unde un plan
> difera de contract, **contractul are dreptate**.
>
> Status fara emoji (preferinta proiect): **TODO** neinceput · **WIP** in lucru · **DONE** gata ·
> **BLOCAT** blocat de o dependenta · **AMANAT** deferat/taiat cu motiv.
---
## 1. Context
Gateway central care declara prestatiile de service-auto la **RAR AUTOPASS** (Legea 142/2023,
OM 210/2024), portat din clasa Visual FoxPro `RarAutoPass` (ROAAUTO). Stack: **Python/FastAPI +
SQLite (WAL) + httpx + Jinja2/HTMX**. Un container (API) + un proces separat (worker).
Doua canale de intrare, ambele **LIVE pe endpoint-ul de test RAR**:
- **Treapta 1** — canal API (`POST /v1/prezentari`) pentru ROAAUTO / soft propriu.
- **Treapta 2** — import xlsx/csv + mapare coloane + UI web (HTMX) pentru service-uri non-ROA.
---
## 2. Arhitectura (rezumat)
```
Canal API (ROAAUTO) ─┐
Upload web (xlsx/csv) ─┴─▶ Gateway FastAPI ─▶ validare → mapare op→cod → enqueue (PII criptat)
│
▼
WORKER (proces separat): claim atomic → login RAR → postPrezentare → retry
│
Dashboard (Jinja2+HTMX) ◀───────┴── monitorizare live RAR + coada + editor mapari + audit CSV
```
Reguli de contract (detalii in `docs/api-rar-contract.md`): `FINALIZATA` e terminal la RAR
(fara anulare/corectie prin API); idempotency = hash de continut server-side; JWT TTL = 30h.
---
## 3. Stadiu Implementare (dashboard)
> **Singurul loc din document care se modifica pe parcurs.** Detaliile NU intra aici — stau in
> PRD-uri (`docs/prd/prd-X.Y-*.md`), linkate in coloana Detalii. La fiecare livrabila terminata:
> schimba statusul + data + linkul PRD si actualizeaza "Ultima actualizare".
**Ultima actualizare**: 2026-06-29 — 5.18 LIVRAT + VERIFY PASS + CLOSE (corpus k-NN exemple etichetate, pe `feat/5.18-corpus-knn-exemple-etichetate`). Cele 7 stories (US-001..007, inclusiv badge sursa) implementate TDD; seed real **17181 operatii** produs cu subagenti Haiku (blocantul GPU LM Studio rezolvat fara GPU — abatere documentata de la D4, validare Haiku>>Groq la dezacorduri); SILVER populat in productie (era gol); embeddings k-NN pe corpusul etichetat (nu pe cele 18 categorii generice); pre-filtru NUL + precedenta NUL>GOLD>exact>k-NN; badge `confirmat`/`similar`/`non-operatie` pe sugestia fuzzy in editor. VERIFY context curat **1392 passed, 1 deselected (live)** + smoke seeder (17181/NUL=2200/idempotent) + E2E render live badge-uri. `/code-review high` (3 finder x 8 unghiuri): runtime curat, invariant #13 intact, 3 findings cosmetice REPARATE+lock-uite. Commit-uri `756f777`+`308fee6`. PRD: [prd-5.18](prd/prd-5.18-corpus-knn-exemple-etichetate.md). | ISTORIC: 2026-06-29 — 5.16 + 5.17 LIVRAT + VERIFY PASS + COMMIT (`c9f9a1c` pe `feat/5.16-5.17-design-tiers`, nepush-uit). Doua PRD-uri in paralel printr-un agent team (lead orchestreaza, NU scrie cod; teammates Sonnet pe valuri cu fisiere disjuncte; `base.html`/`routes.py`/`_status.html`/`landing.html` serializate ca fisiere fierbinti), 5 valuri / 8 lane-uri: W1-A model 5.17 ∥ W1-B bug-fix chips 5.16 → W2 base.html (fonturi system-stack + scala `--fs-*` + dot RAR + antet ROMFAST + /login brandeit + selector tema + fix Renunta) → W3 enforcement 5.17 ∥ W4-B landing copy ∥ W4-C wizard import → W4-A UI plan → W5 verify. **5.16**: system font stack (zero `@font-face`/`/static/fonts/`, IBM Plex scos — decizie user), scala uniforma in tokeni, contoare separate desktop + bara compacta mobil, antet branded + nume service + badge plan, cele 4 bug-uri chips reparate (picker cod+denumire, add_extra mod operatii, cod ales salvat fara „+", Renunta inchide via `closest`), wizard colapsat + landing Autentificare->/login. **5.17**: `accounts.tier`+`trial_until` (migrare aditiva defensiva) + `app/plans.py` sursa unica (`FREE_MONTHLY_LIMIT=60`, `effective_tier` cu `now` injectabil, `monthly_usage`, `CONSUMED_STATUSES`), trial Pro 30z la creare, CLI `set-tier`, enforcement DUR INAINTE de `build_key` (volum 60 + gate API Pro+, erori 3-niveluri `PLAN_LIMITA_LUNARA`/`PLAN_FARA_API` + `log_event`; `valideaza`/`nomenclator` permise; downgrade lazy; flag `AUTOPASS_ENFORCE_PLANS` kill-switch), UI plan (badge antet + linie burger + consum N/60 + warn>=80% + 6 stari + banner one-time trial->Gratuit + pagina Cont). Regresie autoritara **1380 passed, 0 failed, 1 deselected (live)**; E2E browser real (Playwright 390/1280, logat): /login brandeit, dashboard antet+contoare+dot RAR, burger cu separatoare + RAR + plan. **1 defect prins DOAR de E2E** (invizibil la TestClient): contoare duplicate pe 390px — inline `style="display:flex"` pe `.contoare-desktop` batea `@media` -> mutat in CSS + test-lock. Backend trimitere (worker/masina stari/idempotenta/contract RAR) + `mapping`/`validation` NEATINS. **Igiena commit (decizie user): doar 5.16/5.17** — lucrul paralel 5.18 (corpus kNN: `mapping.py`/`embeddings.py`/`operatii_seed.py`/`tools/mapare-llm/*`/`prd-5.18` + teste corpus, plus `config.py`/`db.py` partial si `conftest.py`/`test_mapare_integrare_l14.py` cuplate) lasat NECOMIS; separare verificata prin worktree izolat la HEAD (booteaza + 69 teste verzi fara niciun fisier 5.18). PRD: [prd-5.16](prd/prd-5.16-tipografie-uniforma-bugfix-editare.md), [prd-5.17](prd/prd-5.17-tipuri-cont-planuri-trial.md). | ISTORIC: 2026-06-28 — 5.16 + 5.17 PLAN: autoplan review rulat in paralel pe ambele PRD-uri (2 agenti Opus; faze CEO/Design/Eng pe 5.16, CEO/Design/Eng/DX pe 5.17), single-voice (Codex la plafon de utilizare pana 2026-07-18, fara consens cross-model). Portile umane inchise cu user: **5.16** User Challenge -> system-ui (scoate IBM Plex self-hostat; risc per-OS + design slop acceptat constient), pre-ship teste Eng E1/E3; **5.17** User Challenge -> enforcement DUR direct de la deploy (CRITICAL GAP migrare legacy = MOOT, pre-productie/fara conturi legacy) + flag `AUTOPASS_ENFORCE_PLANS` optional + 3 taste decisions rezolvate (limita 60 = constanta config; banner one-time trial->Gratuit; `valideaza` dry-run permis pe orice plan). Ambele: 0 decizii deschise, gata de implementare; audit trail + GSTACK REVIEW REPORT scrise in fisierele PRD; niciun commit/push. | ISTORIC: 2026-06-28 — 5.15 + 5.14 IMPLEMENTATE + VERIFY PASS + CLOSE (asteapta confirmare commit). Doua PRD-uri in paralel pe `feat/5.15-propagare-design` (5.15 = propagare design + dashboard editare, 12 stories; 5.14 = mapare LLM distilata, 6 stories). `/code-review high` -> 8 buguri reale reparate TDD (modal rand slim, `/repune` trunchia prestatii, picker chips gol pe re-render, obs re-derivat dupa stergere, GOLD poluat cu cod_op_service, typo `nume_prestatie`, bucketare timp `+3h` gresita iarna -> `localtime`+TZ). Decizie user la CLOSE: **embeddings wire-uit functional** (corpus din nomenclator, gated `AUTOPASS_EMBEDDINGS_ENABLED` default off; era „mort dar scump") + corectie marime model ~50MB->~230MB (estimare PRD gresita). Regresie **1256 passed, 1 deselected (live)**. Backend trimitere (worker/masina stari/idempotenta/contract RAR) NEATINS; embeddings/shared store = suggestion-only (nu intra in enqueue). PRD: [prd-5.15](prd/prd-5.15-propagare-design-dashboard-editare.md), [prd-5.14](prd/prd-5.14-mapare-llm-distilata.md). | ISTORIC: 2026-06-27 — 5.13 IMPLEMENTAT + VERIFY PASS (asteapta confirmare commit). Responsive compact (mobil/tableta) + sistem de butoane + design.md, prin agent team (lead orchestreaza, NU scrie cod; teammates Sonnet pe valuri cu fisiere disjuncte; `base.html` serializat ca fisier fierbinte). Wave 0 BLOCANT (cauza probabila a revert-ului anterior, prinsa de eng review): cele 2 teste responsive feliau ferestre fixe `[idx:idx+5000]` de la PRIMUL `@media (max-width:767px)` -> rescrierea cardului impingea regulile (`min-height:0`/`100vw`) peste fereastra si pica fals; refacut sa ancoreze pe un SENTINEL CSS (`SENTINEL-TESTE-MOBIL`) + slice pana la sfarsitul `` (ar fi terminat elementul ``), cauza probabila a revert-ului anterior. Wave 1: FIX P0 break vertical (`min-width:120px` eliminat -> card stivuit), sistem butoane `.btn-secondary/.btn-ghost/.btn-danger/.btn-sm` + `.act/.act-save/.act-del` + macro `act_btn` (aria-label invariant) + `icon()` Lucide, stepper `.stepper-track`/`.stepper-collapsed`, cardificare <=1024px (zero `repeat(2`), versiune ascunsa mobil, sticky-bar compacta. Wave 2: `_stepper.html` rescris, `_mapari.html` icon-btn->act_btn (4 butoane), `_submissions.html` guard „Eroare/Eroare" pill-only + linie meta `actualizat`. Wave 3: `test_web_mapari_actiuni.py` -> `.act` (superseda 5.10) + 5 teste responsive noi + fix `test_web_import_stepper.py` (`facut`->`is-done`). VERIFY context curat: **992 passed, 1 deselected (live)** + E2E browser Playwright 390/820/1280 (mobil fara break vertical, tableta o coloana, desktop tabel neschimbat, wizard slim pe o linie). Bulk-select declarat desktop-only by design (checkbox ascuns mobil). Backend trimitere + schema NEATINSE (pur CSS + markup: 6 template-uri + design.md + 2 teste). Debt: timp relativ ramane absolut; SVG inline (sprite = optimizare viitoare). PRD: [prd-5.13](prd/prd-5.13-responsive-compact.md) |
| 5.12 | Editare unificata in modal (preview = acelasi formular ca Trimiteri, scoate editarea inline rupta + eroarea htmx `htmx-internal-data`) + calendar `` pe data prestatiei + cont cu companie/email/CUI obligatorii (`accounts.email` + gate activare) + mapare cu antet+prima inregistrare + un singur Salveaza pe operatii + preview compact fara coloana „Verificat?" + responsive tableta/mobil (header fara suprapuneri) | TODO | | Nascut din dogfooding first-run E2E (Playwright pe `exemple/prezentari_test.csv`, 2026-06-26): reprodus modul de editare inline colapsat pe verticala (`tr.preview-edit` in `table-layout:fixed`) + `TypeError htmx-internal-data` la Anuleaza; data prestatie doar text; toate conturile cu `cui=NULL` + conturi CLI/teste fara email; mapare coloane fara cap de tabel/valori; N butoane Salveaza pe operatii; coloana „Verificat?" neclara; pe tableta/mobil header-ul se suprapune (grila desktop fara breakpoint 768–1024). 8 stories (3 valuri). Decizii user (AskUserQuestion 2026-06-26): calendar = `` nativ; email canonic pe `accounts` (model A); coloana „Verificat?" scoasa (gate `needs_review` mutat in modal). Backend trimitere NEATINS; singura schema = `accounts.email` (migrare defensiva). PRD: [prd-5.12](prd/prd-5.12-editare-modal-cont-obligatoriu-import.md) |
| 5.15 | Propagare design landing in aplicatie + dashboard editare (teme aditive, componente slim, dashboard contoare + strip sanatate, lista slim, form editare slim cu chips prestatii multi-cod, obs editabil, bulk-fix, salvare mapare din chip, account-scope pe GET-urile de listare, analytics device-mix) | DONE | 2026-06-28 | 12 stories, verify-pass, prin agent team (lead orchestreaza, teammates Sonnet, TDD per story, `base.html`+`routes.py` serializate ca fisiere fierbinti). US-004 lista slim (`trimitere-slim`), US-006 prestatii multi-cod (`form.getlist` pozitional), US-007 form editare slim + chips + obs, US-009 salvare mapare din chip, US-011 account-scope pe fragmentele de listare (404-before-leak pe id strain), US-012 analytics device-mix fara PII. **CLOSE (`/code-review high` -> reparare TDD 2026-06-28):** 8 buguri reale reparate — (1) HIGH modalul nu se deschidea pe randul slim (`base.html` verifica doar `trimitere-row`, nu `trimitere-slim`, in click+keyboard handler); (2) HIGH `/repune` trunchia prestatii (itera `enumerate(codes)`=1 select -> pierdea prestatii[1:] -> declaratie incompleta la RAR ireversibil; fix: iterare peste `existing`, codes pozitional); (3) HIGH picker chips GOL pe re-render dupa eroare validare/coliziune (`_detaliu_ctx` fara `conn`/`account_id` -> `nomenclator_rar=[]`; fix pe toate 4 ramurile post_corectie); (4) MED obs re-derivat dupa stergere explicita (`_merge_override` pop pe obs -> derive-on-empty il reinvia; fix: pastreaza obs='' explicit); (5) MED mapare salvata fara denumire poluă GOLD partajat cu cod_op_service ca cheie (fix: helper `_record_gold_validation` care sare scrierea cand denumire lipseste/==cod_op_service, aplicat la toate 4 callsite-urile); (6) MED typo `nome_prestatie`->`nume_prestatie` in select /repune; (7) MED bucketare timp `+3 hours` fix gresita iarna (RO=UTC+2 EET; fix: SQLite `localtime` DST-aware + `TZ=Europe/Bucharest` in Docker/compose + tzdata); cleanup: hoist `load_*` din bucla bulk-fix, `import re` la top. Regresie **1256 passed, 1 deselected (live)**. E2E browser real OPEN (Playwright indisponibil in sandbox). PRD: [prd-5.15](prd/prd-5.15-propagare-design-dashboard-editare.md) |
| 5.14 | Mapare LLM distilata: etichetator offline (OpenRouter NVIDIA) + temporal holdout + shared store GOLD partajat cross-account (suggestion-only) + SILVER LLM + embeddings in-proces (fastembed/ONNX) + held-out eval + integrare Layer 2/3 in editor | DONE | 2026-06-28 | 6 stories (S1-S6), verify-pass, in paralel cu 5.15 pe acelasi branch (piese disjuncte de fisier rulate paralel; integrarea L14-S6 in editor venita DUPA 5.15, suggestion-only, fara a atinge designul, D9). Auto-send DOAR GOLD propriu; SILVER/GOLD-partajat/embeddings = sugestie, niciodata auto-send (#11/#13, `resolve_prestatii`/`load_mapping` nu citesc tabelele de sugestii). Gate holdout = SLABA (validare temporala imposibila — CSV fara timestamp; non-blocant). **CLOSE (`/code-review high` 2026-06-28):** bug embeddings „mort dar scump" reparat — `enrich_suggestions` apela `is_available()` neconditionat -> lazy-load model ~230MB sincron in thread-ul de cerere desi corpus gol (`index_corpus` nu era wired) -> zero beneficiu. **Decizie user CLOSE: WIRE embeddings functional** (PRD #15: embeddings in v1): `ensure_embeddings_corpus(conn)` construieste corpus din nomenclator, gated pe `AUTOPASS_EMBEDDINGS_ENABLED` (default OFF -> /mapari instant + teste rapide; ON -> lazy-load la prima cerere, re-index pe semnatura nomenclator); `enrich_suggestions` ramane query ieftin cu garda `has_corpus()`. Corectata marimea modelului in PRD/cod: ~50MB (estimare gresita) -> ~230MB real masurat (`paraphrase-multilingual-MiniLM-L12-v2` ONNX quantizat). Regresie **1256 passed**. PRD: [prd-5.14](prd/prd-5.14-mapare-llm-distilata.md) |
| 5.16 | Tipografie uniforma (system-ui, scoate IBM Plex self-hostat) + scala tipografica uniforma + rebrand antet/login profesional + bug-fix formular editare (4 bug-uri reale) + E2E | TODO | | PRD draft + autoplan (CEO/Design/Eng; DX skip — UI operator) rulat 2026-06-28, single-voice (Codex la plafon de utilizare pana 2026-07-18). **User Challenge #1 REZOLVAT = system-ui** (decizia user; challenge respins, Approach A/IBM Plex picat; risc randare per-OS + design slop #11 „system-ui ca font primar" = ACCEPTAT CONSTIENT). Cele 4 bug-uri confirmate in cod: US-007 (`base.html` `hasAttribute` la buton cu copii -> click pe text nu inchide), US-006 (`post_corectie` nu citeste `chips_add_cod_flat` -> save no-op), US-004 (picker plat doar cod vs op-mode cod+denumire), US-005 (`add_extra` lipseste din `post_form_chips`). Pre-ship (Eng `issues_open`, 0 critical gaps): test E1 (grep literale `IBM Plex` ramase fara fallback) + E3 (by-index op corecta). Audit trail + GSTACK REVIEW REPORT scrise in PRD; niciun commit. PRD: [prd-5.16](prd/prd-5.16-tipografie-uniforma-bugfix-editare.md) |
| 5.17 | Tipuri de cont (free/standard/pro/premium, sursa unica `app/plans.py`) + trial Pro 30 zile automat la creare + enforcement DUR (volum 60/luna Gratuit pe ambele canale + gate API Pro+) + downgrade lazy la expirare + alocare manuala admin (CLI set-tier). Fara billing self-service (non-goal) | TODO | | PRD draft + autoplan (CEO/Design/Eng/DX) rulat 2026-06-28, single-voice (Codex la plafon pana 2026-07-18). **User Challenge REZOLVAT = enforcement DUR direct de la deploy** (decizia user); **CRITICAL GAP „migrare conturi legacy" = MOOT** (fara conturi legacy, pre-productie/in teste). Feature-flag `AUTOPASS_ENFORCE_PLANS` = OPTIONAL (kill-switch de operare, nu blocant). 3 taste decisions rezolvate cu user (toate pe recomandare): limita 60 = constanta config tunabila (sursa unica); banner one-time la trecerea trial->Gratuit; `valideaza` dry-run ramane permis pe orice plan. Limita Gratuit scade 100->60/luna. 0 decizii deschise, gata de implementare. Audit trail + GSTACK REVIEW REPORT scrise in PRD; niciun commit. PRD: [prd-5.17](prd/prd-5.17-tipuri-cont-planuri-trial.md) |
| 5.18 | Corpus k-NN din exemple reale etichetate (mapare operatii): pre-filtru determinist NUL + etichetator offline multi-backend + generator seed pe frecventa + seeder `mapping_suggestions` (SILVER populat in productie) + embeddings indexeaza corpusul etichetat (nu nomenclatorul) + `enrich_suggestions` = NUL > GOLD > exact > k-NN + badge sursa in editor (US-007). Suggestion-only (#13), zero LLM la runtime | DONE | 2026-06-29 | 7 stories (US-001..007) TDD. **Seed real produs cu subagenti Haiku** (decizie user 2026-06-29 — abatere documentata de la D4/LM Studio: GPU box jos; Haiku = motor mai bun, validare 157 op Haiku ~22/30 corect vs Groq ~0 la dezacorduri): `app/data/operatii-etichetate.json` rescris 3758 (Groq partial) -> **17181 operatii distincte** (`source="haiku_seed"`, ordine frecventa, NUL=2200). Seeder `init_db` INSERT OR IGNORE idempotent; embeddings k-NN pe `denumire_normalizata` (query normalizat simetric, F1); precedenta NUL>GOLD>exact>k-NN cu abtinere sub prag. US-007 badge `confirmat`/`similar`/`non-operatie` pe sugestia fuzzy (cerere user la CLOSE). **VERIFY context curat PASS**: suita **1392 passed, 1 deselected (live)**; smoke `init_db` seed=17181/NUL=2200/idempotent; toate codurile in nomenclator (zero cod gunoi -> zero risc HTTP 500/ORA-12899); E2E render live al badge-urilor (confirmat/similar/non-operatie). **CLOSE `/code-review high`** (main..HEAD, 3 finder x 8 unghiuri): calea runtime curata, invariant #13 intact; 3 findings low/cosmetic REPARATE + lock-uite (FD leak tool offline -> `with open`; `cod` whitespace -> NULL in `seed_suggestions` + test; docstring embeddings). Config: `seed_operatii_enabled=True` + `embeddings_enabled=True` default (ambele suggestion-only, dezactivabile prin env; embeddings lazy-load ~230MB la prima cerere /mapari). Commit-uri `756f777` (core+seed) + `308fee6` (fix lateral start-test ONNX). Calitate seed la scara ~95%; coduri rare (avarii grave) sparse, ne-verificate uman -> ramane recomandarea esantion uman (Decision #19) inainte de orice auto-send. PRD: [prd-5.18](prd/prd-5.18-corpus-knn-exemple-etichetate.md) |
### Etapa 4 — Deprioritizat (post Etapa 5, daca apare nevoia din uz real)
| # | Livrabila | Status | Data | Detalii |
|---|-----------|--------|------|---------|
| 4.1 | Mapare AI / conector MCP (sugestie peste fuzzy) | AMANAT | | deprioritizat 2026-06-22 in favoarea ergonomiei/integrarii (Etapa 5) |
| 4.2 | Editare/anulare prezentari trimise | BLOCAT | | `FINALIZATA` terminal la RAR — fara flux API; corectia = suport RAR |
### Amanat / taiat (cu motiv)
| Livrabila | Status | Motiv |
|-----------|--------|-------|
| Drop-fisier SFTP / email-to-import | AMANAT | Valideaza intai upload-ul manual (wedge-ul real), apoi re-evalueaza |
| Contor volum + prag freemium | AMANAT | Metrici de pret inainte sa existe useri; trivial de adaugat post-validare |
| Billing complet (Stripe etc.) | AMANAT | Dupa validarea pragului de volum |
---
## 4. Open questions / riscuri acceptate
- **Un cont = un agent RAR sau mai multi** — afecteaza maparea creds in UI + filtrarea monitorizarii.
Relevant pentru Etapa 3.
- **Valori reale `sistemReparat`** — azi se trimite `"null"`; ce alte valori accepta RAR ramane de probat.
- **R4 (acceptat constient):** creds RAR durabile-at-rest (Treapta 2) → la scurgerea cheii Fernet toate
parolele sunt decriptabile (vs. doar in-flight pe canalul API). Mitigare: rotatie cheie + redactare loguri.
---
## 5. Proces de implementare
### 5.1 Principii
1. **PLAN separat de EXECUTE/VERIFY, pe sesiuni distincte.** Planificarea consuma mult context
(model puternic) si produce **PRD-ul** ca artefact de predare. Executia reia intr-o **sesiune noua**
bazat doar pe PRD — nu pe transcriptul planificarii. **Starea persista in PRD**, nu in conversatie.
2. **TDD ca contract:** testul scris ÎNAINTE = forma executabila a criteriilor de acceptare. Un worker
cu test rosu clar nu poate declara fals victoria — testul decide.
3. **Story atomic = unitate de paralelizare SI de rollback:** un story = un commit logic = un worker =
un test-suite verde.
4. **VERIFY in context curat:** un subagent dedicat care primeste DOAR PRD-ul + instructiunile §5.6,
NU transcriptul executiei (altfel mosteneste partinirea de confirmare a celui care a implementat).
5. **Single writer:** doar sesiunea lead scrie in PRD, ROADMAP si git. Workerii scriu doar cod si teste.
6. **E2E pe canalul real:** un flux se verifica prin canalul lui (upload web prin browser, API prin
`POST /v1/prezentari`), nu doar prin apel intern. RAR test = endpoint real.
### 5.2 Cele 4 faze (separabile pe sesiuni)
```
SESIUNE A (Opus/Fable) SESIUNE B (lead + agent team Sonnet)
┌─────────────────────┐ ┌──────────────────────────────────────────────────┐
│ FAZA 1: PLAN │ PRD │ FAZA 2: EXECUTE FAZA 3: VERIFY FAZA 4: CLOSE │
│ citeste ROADMAP+cod │ aprobat │ TeamCreate + subagent context /code-review │
│ scrie PRD (stories │ ───────▶ │ workeri Sonnet curat: pytest + writeback dash │
│ atomice + teste) │ (in PRD) │ TDD per story E2E RAR test propune commit │
│ plan-reviews gstack │ │ lead bifeaza PRD raport in PRD │
│ ▼ POARTA UMANA │ │ ▼ POARTA UMANA │
│ aprobare PRD │ │ confirmare commit│
└─────────────────────┘ └──────────────────────────────────────────────────┘
```
PLAN poate rula singur intr-o sesiune (scump, model puternic) si se opreste la poarta de aprobare.
EXECUTE → VERIFY → CLOSE reiau intr-o sesiune noua din PRD-ul aprobat. Pot fi si inlantuite in
aceeasi sesiune daca vrei — starea din PRD le face reluabile oricum.
### 5.3 PRD per livrabila
- **1 PRD per livrabila** din dashboard: `docs/prd/prd-X.Y-.md` (skill `/prd`).
- Prima linie dupa titlu: `**Stare**: draft` (vezi §5.7 pentru tranzitii).
- Contine obligatoriu: obiectiv, **Non-Goals** (anti scope-creep), stories atomice (§5.4),
riscuri, intrebari deschise (rezolvate cu utilizatorul ÎNAINTE de executie), graful de valuri.
- PRD-ul **nu repeta** strategia/contractul — le linkeaza (`docs/api-rar-contract.md`, acest ROADMAP).
- **Review-uri de plan** (aplicate IN PRD inainte de cod): `/plan-ceo-review` (valoare/scope) +
`/plan-eng-review` (fezabilitate/teste) — obligatorii; `/plan-design-review` — doar daca atinge UI.
### 5.4 Story atomic (template)
```markdown
### US-003:
**Ca** **vreau** **pentru ca** .
- **Depinde de**: US-001
- **Fisiere**: `app/.py`, `app/web/templates/.html` (~N fisiere)
- **Test intai (RED)**: `tests/test_.py` — `test_`, `test_`
- **Acceptance criteria**:
- [ ]
- [ ]
- **Verificare E2E**:
```
Testul de atomicitate: (a) poate un Sonnet sa-l termine intr-o singura sesiune, cu teste, fara sa
intrebe nimic? daca nu → sparge-l. (b) lasa sistemul **functional** daca e ultimul story? (c) `Fisiere`
+ `Depinde de` complete (decid ce se paralelizeaza). (d) backend + UI pentru acelasi comportament = **2 stories**.
### 5.5 Executie — agent team (lead orchestreaza, NU scrie cod)
- `TeamCreate` creeaza echipa + lista de task-uri partajata; `Agent` cu `team_name` + `name` +
`model: sonnet` spawneaza **teammates adresabili**. Lead-ul ii coordoneaza prin `SendMessage`
(clarificari/re-directionare la cald, fara re-spawn) si `TaskUpdate` (atribuire/inchidere task).
- **Valuri (waves):** lead-ul grupeaza stories pe graful de dependente. Val 1 = stories fara
`Depinde de` si fara fisiere comune → teammates paraleli. Val 2 = deblocate de Val 1. Etc.
- **Reguli hard:** max 2-3 teammates simultan (server dev + SQLite partajate); **fisiere comune = nu
paralel** (sau `isolation: worktree` + merge de catre lead); teammates **nu** comit, nu scriu in
PRD/ROADMAP, nu pornesc/opresc servere, nu rezolva ambiguitati singuri (escaladeaza la lead).
- **Raport teammate** (prin `SendMessage`): test RED citat → implementare → test GREEN citat →
fisiere atinse → abateri; apoi `TaskUpdate` → `completed`.
- Dupa fiecare val: lead-ul ruleaza regresia (`python3 -m pytest -q`) si bifeaza stories in PRD.
- Livrabile mici pot rula **fara TeamCreate** (un singur worker sau lead direct) — dar PRD-ul,
verificarea in context curat si writeback-ul raman obligatorii.
### 5.6 VERIFY (subagent cu context curat)
Lead-ul spawneaza un subagent dedicat care primeste DOAR PRD-ul + aceste instructiuni, NU transcriptul:
> Esti verificator independent pentru livrabila {X.Y} (PRD: `docs/prd/prd-{X.Y}-.md`).
> Citeste PRD-ul; NU porni de la premisa ca implementarea e corecta.
> 1. Suita: `python3 -m pytest -q` — verde (citeaza output-ul).
> 2. Criteriile de acceptare ale fiecarui story din PRD.
> 3. E2E pe canalul atins: UI web → `./start.sh test both --send`, browser pe `http://localhost:8000/`
> (Playwright MCP sau `/browse`), fluxul din PRD; canal API → `POST /v1/prezentari` pe RAR test.
> 4. **Regresia de aur:** fluxul existent nu are voie sa se strice — `POST /v1/prezentari` (sau
> import → commit) → worker → `FINALIZATA` la RAR test, vizibil in dashboard (`./start.sh test finalizate`).
> 5. Raport PASS/FAIL per criteriu cu dovezi. FAIL-urile NU le repari (`/qa-only`, nu `/qa`) — le documentezi.
Lead-ul scrie raportul in PRD ca `## Raport VERIFY`. Toate PASS → CLOSE. Exista FAIL → inapoi la
EXECUTE (stories de fix), apoi VERIFY din nou cu subagent NOU.
### 5.7 Bootstrap sesiune (detectie faza din starea PRD)
Starea persista in PRD (prima linie dupa titlu), actualizata de lead la fiecare tranzitie:
`**Stare**: draft → aprobat → in-executie → verify-pass → inchis`. Asta face procesul reluabil
din orice sesiune noua — starea e in fisiere, nu in conversatie.
| Stare gasita | Faza de pornire |
|---|---|
| nu exista `docs/prd/prd-{X.Y}-*.md` | PLAN |
| PRD `**Stare**: draft` | PLAN (reia stories/review-uri) |
| PRD `**Stare**: aprobat` / `in-executie`, stories nebifate | EXECUTE |
| toate stories bifate, fara `## Raport VERIFY` cu PASS | VERIFY |
| `## Raport VERIFY` = PASS | CLOSE |
| PRD `**Stare**: inchis` | livrabila gata — alege urmatoarea din dashboard |
La bootstrap: daca utilizatorul a numit `{X.Y}`, aceea e; altfel prima `WIP` din dashboard, apoi
prima `TODO` in ordinea etapelor. **Confirma alegerea cu utilizatorul** — singura intrebare permisa la start.
### 5.8 CLOSE + porti umane
1. `/code-review` pe diff-ul livrabilei. Probleme → fix acum (worker) sau story nou (inapoi in PRD).
2. **Writeback:** in §3 dashboard — status `DONE` + data + link PRD; actualizeaza "Ultima actualizare".
PRD: `**Stare**: inchis`.
3. **POARTA UMANA:** propune commit-ul (mesaj conventional commits, fara emoji; vezi git rules) si
ASTEAPTA confirmarea explicita — niciodata commit automat.
### 5.9 Anti-patterns (opreste-te daca observi)
| Anti-pattern | Corectia |
|---|---|
| Teammate "termina" fara output de test citat | Raportul e invalid — cere dovezi prin `SendMessage` |
| Test scris DUPA implementare ca formalitate | Nu e TDD — testul e contractul; refa bucla |
| Lead-ul scrie cod "ca e mai rapid" | Pierde orchestrarea; spawn teammate chiar si pt un fix mic |
| Stories paralele care ating acelasi fisier | Re-planifica valurile sau worktree + merge de catre lead |
| PRD modificat in executie fara re-review | Schimbare de scope → inapoi la PLAN |
| Lead verifica singur, fara subagent VERIFY | Partinire de confirmare — VERIFY cere context proaspat |
| Continua peste poarta umana | Aprobarea PRD si confirmarea commit sunt ale utilizatorului — opreste-te |
---
## 6. Skill-uri in proces
| Faza | Skill | Rol |
|------|-------|-----|
| PLAN | `/prd` | genereaza PRD-ul (`docs/prd/prd-X.Y-.md`) |
| PLAN | `/plan-ceo-review`, `/plan-eng-review`, `/plan-design-review` | review de plan (primele 2 obligatorii; design doar UI) |
| EXECUTE | `/investigate` | bug neinteles raportat de worker — root cause, nu patch orb |
| VERIFY | `/browse`, `/qa-only` | browser headless / QA doar-raport (nu repara — pastreaza independenta) |
| CLOSE | `/code-review` | review pe diff-ul livrabilei |
| oricand | `/learn` | salveaza gotcha-uri in `.claude/rules/` (nu in acest doc) |
---
## 7. Intretinere
Acest document se actualizeaza la **schimbari de proces** (nu per livrabila) si la **dashboard**
(la fiecare livrabila terminata — §3). Lectiile operationale (gotchas, pattern-uri descoperite in
executie) merg in `.claude/rules/` via `/learn`, nu aici.