Combined EBO · ClientsFlow Pipeline · Whole-Journey QA

Whole-Journey Master EBO — all EBOs combined

55 deduped rows / 12 journey stages · synthesized from 6 prior EBOs · plus the visual-QA screenshots

Visual QA — screenshots

The final visual QA was driven mostly via the live API + DOM reads (full-page CDP captures timed out, so we switched to Playwright per-card shots). Below is the genuine pixel evidence for the Studio card.

WJ-42 / WJ-43 — Studio card (booked): the 🎨 "Dizájn készül" chip + "Open in Studio" button render live.
ZZ Studio Walk card
Board viewport (context): full Pipeline board, 1480×1000 (Playwright). Card-level detail above is the primary evidence.
Pipeline board viewport

What this is

A single ordered master of every behavior the ClientsFlow Pipeline system must exhibit across the entire sales journey, deduped and asserted once at its strongest seam. It was synthesized by unioning six prior Expected-Behavior Oracles:

Source slugRows inDescription
studio-pipeline-integration13Studio↔Pipeline integration (S1–S12 + INV)
extended-ebo-2026-06-259 scenarios (B1–B6)Touchpoint history + UX critique extension
bnf-2026-06-24-r312Round-3 pipeline fixes (I1–I14)
bnf-2026-06-23-duo214DUO-2 live-test bugs BUG-01..11 + features
board-card-redesign17Board/stage/card behaviors
live-test-bug-fixes11Post-call → sign → pay journey

Pre-dedup source total: ~76 scenarios/rows across all sources Master rows after dedup: 55 rows (WJ-01 … WJ-55) Dedup principle: Many sources assert the same behavior (e.g. the red ❗ badge appears in both studio-S1 and bnf-2026-06-24-r3-S8). Each behavior is merged into ONE master row, asserted at the strongest observable seam, with all originating sources cited. No behavior appears twice.

Deployment state (correction 2026-06-25): the Studio↔Pipeline integration is BUILT and DEPLOYED — pipeline live at v110 (3cab5fa+v110), STUDIO_BASE_URL → the live Studio -rebuild instance (https://matyas--clientsflow-studio-rebuild-web.modal.run, all 8 API endpoints verified). The seam functions (studio_create_and_kick, studio_resume_on_url_save, studio_draft_send_message, studio_send_to_client, poll_studio_stages) and all dash UI (chip, badge, send modal, approval overlay, live-URL) are merged to main and deployed. The Studio rows (WJ-41..WJ-48) and WJ-26 are therefore drivable, not blocked.

QA buckets: live (driven by clicking the live dashboard / a ZZ sentinel deal in Chrome) · live-sim (drivable live but via API-injected state rather than a real external client action) · test (covered at a pytest seam) · blocked (needs a real external event / live infra not drivable with a sentinel).

---

Stage 1 — Ingestion & enrichment

_New lead arrives, website_url enrichment, name parser, cold-inbox "other" capture_

IDBehaviorStrongest seam🕓 Touchpoint history💡 UX critiqueQA bucketSources
WJ-01Enrichment fires automatically on new-lead entry and populates website_url, business fields, and legal info (entity type, tax number) — visible in Details panel before any bookingDetails panel → Legal Information shows filled fields immediately after ingestionNo visual progress indicator shows enrichment is running — a blank card on arrival could be confused with a bugblockedbnf-2026-06-24-r3-S8, bnf-2026-06-23-duo2-S14, studio-S1
WJ-02De-dup matches only on email address or unambiguous phone number — never website domain or company name; two people at the same company always get separate CRM cardsBoard shows two separate cards when same website appears in two different sender emailsDedup logic is invisible to the operator; a 'Új lead (nincs egyezés)' tag would build trustlivebnf-2026-06-24-r3-S1
WJ-03Cold-inbox "other" replies enter the pipeline as new cards; email touchpoints classified as 'Email' (icon/badge), NOT 'Note' (grey badge); none droppedBoard card present; history shows Email icon on both Outgoing and Incoming entriesTwo 'Email' entries (Outgoing + Incoming) with email icon, full body textIntermittent bug means first cold-email touchpoint sometimes renders as a grey 'Note' badge — unreliable classification signallivebnf-2026-06-23-duo2-S08, bnf-2026-06-23-duo2-S11
WJ-04AI first-reply draft on new-lead arrival ends with the standard Mátyás signature block; nothing is auto-sent — draft waits for human approval in Outbox tabOutbox tab shows draft with complete signature; ZZ lead's inbox has no email until approvedNo badge or nudge on the board card indicating 'draft waiting for approval'livebnf-2026-06-23-duo2-S11

---

Stage 2 — New lead on the board

_Card render, red ❗ website-missing badge, sort toggles, "Move to" dropdown, pinned-to-top_

IDBehaviorStrongest seam🕓 Touchpoint history💡 UX critiqueQA bucketSources
WJ-05New-lead card renders with: lead name + company (Row 1), no sequence pill (Row 2), website + county (Row 3), email + phone chip (Row 4), HTML-stripped plain-text 'Their last message' (full body, no truncation), action row = exactly 'Log Call' + 'Send Emails'; card pulses red when unreadBoard card in 'New Lead' column: pulse-red, no seq pill, clean plain-text message block, two-button action row'Their last message' includes signature block noise — a trim-signature heuristic would improve signal/noise ratioliveboard-card-redesign-S1, board-card-redesign-S3
WJ-06If enrichment found no website URL, card shows a prominent red ❗ badge — the only thing blocking Studio booking auto-kick; saving a valid URL clears the badge without re-bookingCard face: red ❗ badge visible; saving a URL removes it❗ badge has no inline tooltip explaining what to do — first-time operator won't know to add a website URLlivestudio-S1, studio-S3, bnf-2026-06-24-r3-S8
WJ-07Phone chip click copies the number to clipboard and shows 'Másolva ✓' tooltip that auto-dismisses after ~1.5 sCard phone chip: click → clipboard holds number + tooltip appears and fadesClean and correct; could add tel: link on mobile but desktop-first is appropriate hereliveboard-card-redesign-S2
WJ-08Status dropdown moves any card to any column instantly (optimistic UI); Notion syncs in background; real save failure shows error toast and returns card — never a silent snap-backCard stays in target column after ≥2 reload cycles; error toast visible on simulated failureStátusz változás touchpoint: icon 🔀, label 'Áthelyezve: {from} → {to}', Budapest timestamp'Áthelyezve' toast is ephemeral — no persistent indicator the move was manually vs system-initiatedliveboard-card-redesign-S6, bnf-2026-06-23-duo2-S02, live-test-bug-fixes-S1
WJ-09Negative Replies column cards show same 'Log Call' + 'Send Emails' button set as New Lead (no stray booking button or datetime-local picker); card stays in Negative Replies after reload (neg_reply flag persisted)ZZ card in Negative Replies: stays after reload; action row shows only Log Call + Send EmailsStátusz változás entry on move; subsequent 'Send Emails' creates 'Sorozat újraindítva' touchpointNegative Replies card looks identical to New Lead — an operator without context of the negative reply has no quick indicatorliveextended-ebo-2026-06-25-S7, extended-ebo-2026-06-25-S8

---

Stage 3 — Contacted / sequence

_AI reply draft, human-gate approve→send, follow-up sequences, neg-reply handling_

IDBehaviorStrongest seam🕓 Touchpoint history💡 UX critiqueQA bucketSources
WJ-10'Send Emails' opens sequence modal with pre-loaded copies; 'Send & schedule emails' button disables immediately on click (spinner) and is idempotent — rapid multi-click creates exactly ONE 'Szekvencia élesítve' touchpoint; intervals shorter than 5 min are blocked with a validation errorHistory after rapid multi-click: exactly one 'Szekvencia élesítve' entry; sequence modal shows validation error on <5 min inputEmail 1: 'Sent' (green tag); Email 2: 'Scheduled' (yellow tag) with correct future date; one 'Szekvencia élesítve' system noteNo preview of the 06:12–18:00 Mon–Fri send window in the modal — operators must remember from traininglivelive-test-bug-fixes-S2, bnf-2026-06-23-duo2-S01, board-card-redesign-S7
WJ-11After arming, card moves to 'Contacted — No Appointment Booked' with dim overlay + blue dashed animated border; hovering lifts the overlay, making the card fully readable without un-dimming the whole boardCard in Contacted: dimmed + blue dashed border visible; hover lifts overlayEmail 1 and Email 2 (scheduled) visible in history from WJ-10; no new touchpoint for column moveThe hover-to-reveal interaction is not discoverable — no affordance on the dimmed card indicates hovering reveals contentliveboard-card-redesign-S7, board-card-redesign-S10, bnf-2026-06-24-r3-S2
WJ-12Sequence cron dispatches Email 2 at its due time (next cron tick after due timestamp); Email 2 flips from yellow 'Scheduled' to green 'Sent' in history — does not remain stuck 'Scheduled' indefinitelyHistory panel: Email 2 tag changes from yellow to green at/after due timeEmail 2 entry updates from yellow 'Scheduled' to green 'Sent''Scheduled' tag shows date but not time — operator can't tell if Email 2 fires at midnight or middaylivebnf-2026-06-23-duo2-S01
WJ-13Lead reply mid-sequence: sequence cancelled immediately; card resurfaces to TOP of 'New Lead' column with pulsing-red unread state; blue dashed border goneCard leaves Contacted, appears at top of New Lead, pulse-red, seq armed=falseIncoming email touchpoint ('Email · Incoming') at top of history; 'Sorozat leállítva' system note belowResurfaced card carries no indicator of prior sequence state — how many follow-ups went out before this reply is not visible on the card faceliveboard-card-redesign-S11
WJ-14Manual action (log call, book appointment) on an armed-sequence lead calls sequences.stop(), clears the blue dashed border, dim lifts after board reconciliationAfter logging call/booking on dimmed-sequence card: blue dashed border disappears, dim lifted, seq_armed_at=nullHívás rögzítve or Foglalás touchpoint + 'Sorozat leállítva' system noteSequence-stop is silent — no toast confirming 'Szekvencia leállítva' when operator takes manual actionlivelive-test-bug-fixes-S8, bnf-2026-06-23-duo2-S03
WJ-15Reschedule and cancel confirmation emails show 'kattints ide' as an inline hyperlinked phrase — never a raw https:// URL as the visible link text; cancel link is working (not dead)ZZ lead's inbox: reschedule/cancel email shows 'kattints ide' as clickable link, not raw URL; clicking cancel link actually worksEven with 'kattints ide' there's no appointment datetime in the link text — leads could accidentally cancel the wrong appointmentlivebnf-2026-06-24-r3-S3

---

Stage 4 — Booked

_Own-booking, manual-booking parity → Sales-Call Prep + Booking-FUP arm, reschedule, Fireflies recording_

IDBehaviorStrongest seam🕓 Touchpoint history💡 UX critiqueQA bucketSources
WJ-16Unique per-contact booking link shows ONLY date+time picker + read-only email confirmation; no input fields; exactly 1 email sent (Meet invite, not two); card moves to 'Booked / Sales Call Prep' instantly; booking attaches to existing CRM contact (no duplicate created)Booking page: no input fields; ZZ inbox: 1 email received; board: card moves to Booked instantly with 'New booking' toastFoglalás touchpoint: icon 📅, label 'Foglalás · {datetime}', description 'Időpont foglalva, naptármeghívó kiküldve', Budapest timestampBooking confirmation page lacks a 'Következő lépések' block — missed onboarding moment for the leadlivebnf-2026-06-23-duo2-S04, bnf-2026-06-23-duo2-S10, bnf-2026-06-24-r3-S4
WJ-17Booked card stays DIMMED while appointment is >1 day away; dim lifts at 00:00 on the calendar day BEFORE the appointment; booking-follow-up sequence is disarmed on booking and its scheduled email entries disappear from historyBooked card: dim overlay present when >1 day away; history shows no 'Scheduled email' rows from booking-fup sequenceBooking touchpoint at top of history; no queued 'Scheduled email' rowsBooked card shows appointment date but no countdown — a '3 nap múlva' label would give glanceable urgencylivebnf-2026-06-24-r3-S4, board-card-redesign-S12, board-card-redesign-S15
WJ-18Booking slot grid shows only 30-min slots on weekdays 08:30–18:30 Europe/Budapest; GCal busy blocks excluded; 15-min buffer after each existing booked call enforced (no back-to-back)Booking page slot grid: no weekend slots, no out-of-hours, no slots within 15 min after a booked callNo timezone label visible on the slot grid — international leads may assume their local timezoneblockedbnf-2026-06-24-r3-S5
WJ-19GCal invite created with lead + rep (matyas@clientsflow.hu) as attendees and sendUpdates='all'; on DWD/config failure: warning touchpoint + orange badge on card face; QA does NOT mark step green on failureZZ lead's inbox: receives GCal invite; on failure: card shows orange warning badge + system warning in historyFoglalás touchpoint + optional 'Rendszerfigyelmeztetés: Naptár meghívó sikertelen' system entry (grey) on failureFailed invite is invisible on the card today — a failed invite directly causes no-shows, making the orange badge high-priorityblockedextended-ebo-2026-06-25-S5, extended-ebo-2026-06-25-S6
WJ-20Manual booking via Log Call → 'Book appointment': form shows prefilled-but-editable fields; invite sent only on explicit blue 'Book appointment' click; Foglalás touchpoint logged even if GCal fails (fail-open with warning toast)Log Call → Book appointment: form with prefilled+editable fields; after submit: Foglalás (manuális) touchpoint in history; GCal fail: warning toast + touchpoint still loggedFoglalás (manuális) touchpoint: icon 📅, label 'Foglalás · {datetime}', description 'Időpont rögzítve, meghívó elküldve (manuális). Megjegyzés: {note}'After blue 'Book appointment' click the panel just closes — operator unsure if invite was sent; a 2-second in-panel confirmation would close this feedback gapliveextended-ebo-2026-06-25-S9, live-test-bug-fixes-S7, board-card-redesign-S8
WJ-21Lead-side reschedule succeeds: original GCal event deleted, new event created; card stays in 'Booked' showing NEW date; reschedule touchpoint (old → new datetime) appended; 'időpont közben elkelt' error must NOT appearLead-side reschedule page: success message, not error; card in Booked column shows new date; history has 'Átütemezés' entry with both old and new datetimeÁtütemezés touchpoint: icon 🔄, label 'Átütemezés', description 'Régi: {old datetime} → Új: {new datetime}', initiated_by: leadReschedule success page confirms new time but not deletion of old — lead might wonder if they have two appointmentsblockedextended-ebo-2026-06-25-S3, extended-ebo-2026-06-25-S4, bnf-2026-06-23-duo2-S06
WJ-22Manual GCal reschedule (operator moves event in Google Calendar) logged as 'reschedule' touchpoint with source=manual (old_time → new_time, via gcal_watch); card meeting time updated; no duplicate booking touchpoint createdMove a GCal event manually: board card shows updated datetime; history shows reschedule (source=manual) touchpoint with both old and new timesReschedule touchpoint (source=manual): icon 🔁, description 'Manuális átütemezés: {old_time} → {new_time}'Card face doesn't distinguish rep-initiated from lead-initiated reschedule — a 'Manuális' label on the date badge would clarifyblockedstudio-S12, studio-pipeline-integration-EBO-11
WJ-23Booking widget gives instant feedback: confirm click → button disables + spinner immediately; optimistic success state ('Booking… → Confirmed ✓') within ~2 s independent of backend completionBooking widget: button disables + spinner immediately after click; success state within 2 s; no frozen UIOptimistic success before backend confirm means a late backend failure delivers a confusing success-then-error experiencelivebnf-2026-06-23-duo2-S05

---

Stage 5 — Sales call & transcript

_Transcript ingest, AI extract, call summary, log-call touchpoints_

IDBehaviorStrongest seam🕓 Touchpoint history💡 UX critiqueQA bucketSources
WJ-24Fireflies transcription: bot-free Meet recording used if confirmed available; otherwise Fireflies Note Taker bot auto-joins at ≥2 real participants, named 'Note Taker' with plain/boring avatar; bot must NOT join 1-person call2-participant ZZ call: 'Note Taker' appears in participant list (not 'Fireflies AI Notetaker'); transcript lands in CRMBot appearing as a participant might confuse the lead into thinking a third person joined their private callblockedbnf-2026-06-24-r3-S6
WJ-25Sales Call/Proposal card shows: (1) 'Sales call megvolt · {X} perc' status pill and (2) transcript-status tag cycling 'Transcript: betöltés…' → 'Transcript: hiányzik' → 'Transcript: megvan'; 'megvan' must not appear when no transcript exists in CRMSales Call card: both pills present; 'megvan' appears only after transcript confirmed in CRMSales call touchpoint: icon ☎, label 'Hívás', description with duration'hiányzik' tag gives no next step — operator doesn't know if they should wait, upload manually, or re-triggerlivebnf-2026-06-24-r3-S7
WJ-26Call transcript saved into CRM AND auto-pushed into Studio intake; summary generated alongside full transcript; both stored in collapsible toggles in BOTH touchpoint-history panel AND Details panel; only real call transcript pushed — never warmup/no-show noiseAfter transcript ingest: history panel and Details panel both show collapsible toggles with full transcript + summary; Studio intake received the pushTranscript touchpoint with collapsible toggle containing full transcript + summary; same in Details panelTwo different panels show the same transcript — a 'Ugyanaz a forrás' note or cross-link between the two would clarify which is canonicallivestudio-S6, studio-pipeline-integration-EBO-5
WJ-27Manual log-call timestamps render in Budapest local time in the History feed (14:15 Budapest → displayed '14:15', not '12:15' UTC)History touchpoint timestamp: logged at 14:15 Budapest; displayed timestamp reads '14:15'Hívás rögzítve touchpoint with correct 14:15 Budapest timestampTable-stakes correctness; no UX critique neededlivebnf-2026-06-23-duo2-S07
WJ-28Logged call touchpoint header reads 'Phone call' (human-readable label) with operator notes below — not a raw backend string/UUIDHistory feed header: reads 'Phone call' with notes below, not 'event_type_sales_call_init' or similarHívás rögzítve entry: header 'Phone call', body = operator notes'Phone call' is English in an otherwise Hungarian dashboard — consistent with the ENGLISH Control Panel UI rulelivebnf-2026-06-23-duo2-S09

---

Stage 6 — Proposal

_Proposal generation, discount/promo copy line, DocuSeal 3-part sign, proposal page_

IDBehaviorStrongest seam🕓 Touchpoint history💡 UX critiqueQA bucketSources
WJ-29Post-call wizard Step 1 sets agreed_price, price_expiry_date, proposal_due_date, and price_after_expiry (price × 1.25); Step 2 proposal preview always includes the deterministic price box: discounted price + struck-through anchor price + 'érvényes {exp}-ig aláírva — 20% kedvezmény'Proposal preview and DocuSeal doc part 1 both contain price box with struck-through anchor price and expiry datePost-expiry price (× 1.25) is stored but not shown in Step 1 — displaying the calculated value makes the consequence explicitlivelive-test-bug-fixes-S1, live-test-bug-fixes-S9
WJ-30Proposal creation + schedule emails moves card to 'Sign-Follow-Up' column INSTANTLY (optimistic UI) — no ~1-minute poll/cron waitCard appears in Sign-Follow-Up immediately after action (< 2 s); no page refresh requiredProposal sent (OUT) touchpoint at send time; proposal_chase sequence DEFINED un-armedInstant move is correct but operator may miss the column change if looking away; brief highlight animation on arrival would draw the eyelivebnf-2026-06-24-r3-S9, live-test-bug-fixes-S1
WJ-31'Route for approval' button shows spinner and disables while request runs — double-click is a no-op; /review page opens in a new tabClick 'Route for approval': button disables + spinner immediately; second click is no-op; /review tab opens/review tab opening in a new tab can be blocked by pop-up blockers silently; a fallback inline toast with the URL would prevent silent failurelivelive-test-bug-fixes-S1
WJ-32New lead entry triggers scraper + AI legal/CRM extraction; generated contract is pre-populated with legal entity type and tax number from CRM; enrichment must not silently no-opGenerated contract (DocuSeal part 1): legal entity type and tax number pre-filled; no blank legal fields when CRM has themIf enrichment ran but found no legal data, blank contract fields only surface at generation time — too late; an early 'Legal info: nem található' badge would surface the gap soonerblockedbnf-2026-06-24-r3-S8
WJ-33Self-sent proposal email re-ingested by Missive is recognized as outbound and dropped — NOT logged as 'Incoming reply', does NOT cancel proposal-chase sequence, does NOT resurface card to New LeadAfter proposal send: Missive re-delivers to webhook; history gains NO 'Incoming reply' touchpoint; card stays in Sign-Follow-Up; sequence stays armedNo touchpoint created for self-sent mail re-ingestion; existing 'Proposal sent (OUT)' is the only recordGuard firing is invisible — if it malfunctions, there's no audit trail of what was dropped; a grey 'Saját levél kiszűrve' system note would helplivelive-test-bug-fixes-S6

---

Stage 7 — Sign / follow-up

_Contract signed stage, sign-follow-up sequence_

IDBehaviorStrongest seam🕓 Touchpoint history💡 UX critiqueQA bucketSources
WJ-34Sign-Follow-Up card shows three tags: (1) next-call-date, (2) 'Ajánlat érvényes: {date}' offer-validity, (3) 'Emlékeztető {n}/{m}' reminder indexSign-Follow-Up card face: three status pills visibleReminder emails logged as outbound 'Email (OUT)' touchpoints as they sendThree pills may crowd the card if lead name is long; offer-validity date is most decision-critical and should be most visually prominentlivebnf-2026-06-24-r3-S10
WJ-35Signed deal with stage_key=contract_signed and days_in_stage > PAYMENT_OVERDUE_DAYS (default 3) shows a red overdue border; a freshly-signed card has no red borderBoard card in 'Proposal Signed / Fizetés FUP': red border when overdue; no border on fresh-signed cardRed border is passive — overdue-payment cards should also surface as task cards in the 'Today' tab to make the prompt activelivelive-test-bug-fixes-S5

---

Stage 8 — Payment

_Deposit→WON, balance/végszámla, Stripe, onboarding email draft + task_

IDBehaviorStrongest seam🕓 Touchpoint history💡 UX critiqueQA bucketSources
WJ-36On DocuSeal both-signed, payment reminder sequence self-arms automatically (owner-approved exception); first payment email sends immediately with Stripe pay link + bank-transfer details + exact amount; ~5 reminder emails drip at 1–2 day gaps; sequence stops as soon as payment is detectedDocuSeal webhook fires: card enters contract_signed, payment seq armed without manual click; ZZ inbox receives email #1 with Stripe link + utalási adatok + pontos összegContract signed touchpoint; Email #1 outbound touchpoint immediately after; reminder emails as outbound touchpoints until seq stopsNo acknowledgment to the operator that self-arm happened; a system note 'Fizetési emlékeztető szekvencia automatikusan élesítve' would document the exceptionlivebnf-2026-06-24-r3-S11, live-test-bug-fixes-S3
WJ-37Stripe checkout opens with lead's email pre-filled (prefilled_email on session); no billing address requested (already on contract)Stripe TEST checkout: email field pre-filled with lead's email; no billing address formCheckout has no reference to the contract or project — a description line 'ClientsFlow honlap csomag — {deal_name}' would reduce checkout drop-offblockedbnf-2026-06-24-r3-S11
WJ-38Stripe TEST payment completes → card moves to 'Payment Arrived / Adatbekérő FUP'; payment reminder sequence stops; DocuSeal auto-emails signed PDF to both parties (no manual DocuSeal click required)After Stripe TEST checkout.session.completed: card in 'Payment Arrived / Adatbekérő FUP'; seq_armed_at=null; signed PDF arrives by emaildeposit_paid touchpoint; 'Fizetési emlékeztető szekvencia leállítva' system note; 'Szerződés aláírva (PDF)' document touchpoint'Payment Arrived' column name is English in an otherwise Hungarian-mixed UI — standardizing to Hungarian would improve visual coherenceblockedlive-test-bug-fixes-S4, bnf-2026-06-24-r3-S12
WJ-39DocuSeal contract signature-date field is labelled 'Aláírás dátuma' (renamed from 'Megbízó dátum')DocuSeal contract: client signature date field label reads 'Aláírás dátuma''Aláírás dátuma' is unambiguous; old label was confusing about whether it meant contract date vs company founding datelivelive-test-bug-fixes-S11

---

Stage 9 — Onboarding

_Portal row, onboarding task_

IDBehaviorStrongest seam🕓 Touchpoint history💡 UX critiqueQA bucketSources
WJ-40After deposit_paid, card is in 'Payment Arrived / Adatbekérő FUP'; onboarding email draft generated for human review in Outbox; onboarding task appears in Feladatok tab; later stages (waiting_dev+) map to ongoing_build columnBoard: card in 'Payment Arrived / Adatbekérő FUP' after Stripe payment; Feladatok tab: onboarding task visible; Outbox: draft pending human approvaldeposit_paid touchpoint; onboarding task creation note in historyOnboarding email draft in Outbox but no task card in 'Today' tab nudging the operator — draft can age unnoticedblockedlive-test-bug-fixes-S4

---

Stage 10 — Studio design loop

_S1–S12: auto-create project on booking, Lab kick, status chip, transcript→Studio, send-to-client human-gated, comment/approve overlay, won→live URL, lost→archive, waiting_dev soft-removal_

IDBehaviorStrongest seam🕓 Touchpoint history💡 UX critiqueQA bucketSources
WJ-41Booking of URL-present deal: Studio project auto-created (crm_ref=deal_id, idempotent), Lab auto-kicked (home-page design + SEO audit + structure), single Studio chip walks 🎨 Dizájn készül → ✅ Dizájn kész; booking not blocked if Studio is slow (fail-open)Card in Booked: chip shows '🎨 Dizájn készül'; after Lab completes: '✅ Dizájn kész'; re-triggering creates no duplicate projectstudio_created (🎨) + studio_generating (⚙️) at booking; studio_ready (✅) when Lab completesChip gives no ETA for when design will be ready — an estimated time or progress % would reduce uncertainty before a sales calllivestudio-S2, studio-pipeline-integration-EBO-1
WJ-42Booking on red-❗ deal: no Studio project, no Lab kick; URL-prompt shown (studio_deferred=true); saving a valid URL clears ❗ and auto-kicks Studio — no re-booking, no manual project creationBook a card with ❗: no Studio chip appears; save a URL: ❗ clears and Studio chip appears without re-bookingNo Studio touchpoints until URL saved; then studio_created + studio_generating at URL-save timeURL prompt competes with other card elements — should be the most prominent visual element when it's the only blocker, ideally a full-width orange bannerlivestudio-S3, studio-pipeline-integration-EBO-2
WJ-43'Open in Studio' button deep-links to the deal's Phase-1 project; Phase-1 is sales-aid only — nothing emailed to the prospectClick 'Open in Studio' on Booked card: Studio opens on the correct deal's project; no outbound email triggeredDeep-link depends on Studio being in the correct state; a fallback Studio project URL in the history panel would handle failureslivestudio-S4
WJ-44Exactly ONE Studio status chip on the card face, cycling: 🎨 Dizájn készül / 📤 Elküldve / 💬 Ügyfél véleményez / ✅ Jóváhagyva; read-only (Studio owns it); does not go permanently staleCard face: exactly one chip; chip state matches Studio's actual state; chip updates within one board refresh cycleEach chip state change → Studio milestone touchpoint in historyChip is purely reflective — operator cannot force a Studio state refresh; a rate-limited 'Refresh Studio state' button would help when chip appears stalelivestudio-S5, studio-pipeline-integration-EBO-4
WJ-45'Send to client' button on BOTH pipeline card and Studio opens same modal (AI-drafted message + review link); nothing sends on click — human clicks 'Küldés'; chip flips to 📤 Elküldve; both surfaces reflect 'sent' immediately to prevent double-sendClick 'Send to client' on card: modal opens with AI draft + review link; click 'Küldés': chip → 📤 Elküldve on card and in Studio; no second send possiblestudio_sent touchpoint: icon 📤, label 'Design elküldve az ügyfélnek', includes review link, initiated_by: operatorDual send paths (card + Studio) require both surfaces to reflect 'sent' simultaneously — failure to sync would allow a double-send. QA: confirm AI draft + review link in the modal; do NOT click 'Küldés' against anything but a ZZ sentinel (human gate)livestudio-S7, studio-pipeline-integration-EBO-6
WJ-46On client approval in Studio: card gains pulsing green overlay ('✅ Dizájn jóváhagyva'); hover shows two buttons ('Move to next stage' and 'Move to next stage + open in Studio'); pipeline does NOT auto-advance; stage moves only on explicit human clickClient approves in Studio: pipeline card gains pulsing green overlay; hover shows two buttons; clicking one advances stagestudio_approved touchpoint: icon ✅, label 'Design jóváhagyva', initiated_by: clientTwo hover buttons are almost identical in action — making their icons clearly distinct would prevent clicks under time pressure. QA: set the Studio project approved via the -rebuild API, then confirm the pipeline card reflects the overlay after a poll/refreshlive-simstudio-S9, studio-pipeline-integration-EBO-8
WJ-47Won deal: NO separate 'Dev handoff' pipeline state; won project published live via Cloudflare API from Studio; live URL reflected back on deal card; Dani sees the same single pipeline view — no separate handoff boardWon deal card: live URL link to published site; no separate handoff column visible; Dani's view is the same boardstudio_won touchpoint (🎯); studio_published touchpoint (🌐) with live URLCollapsing dev handoff into Studio simplifies the workflow; main risk is Dani needing a documented SOP for which stage = his work. QA: drive trigger_won; live URL reflects on the card (Cloudflare publish is real Studio-side — tag any real-publish dependency as a residual)live-simstudio-S11, studio-pipeline-integration-EBO-10
WJ-48Marking deal 'Lost' auto-archives (never deletes) the linked Studio project; chip reflects '🗄️ Studio archiválva'; no orphan active Studio project leftMark booked ZZ deal as Lost: Studio project archived (not deleted); card chip reads '🗄️ Studio archiválva'; project recoverable from Studiostudio_archived touchpoint: icon 🗄️, label 'Studio projekt archiválva', initiated_by: systemArchive-not-delete is correct, but no 'Restore' link on the chip tooltip to recover from the pipeline sidelivestudio-S10, studio-pipeline-integration-EBO-9

---

Stage 11 — Cancellation

_Cancel success page polish + cancel logged as touchpoint_

IDBehaviorStrongest seam🕓 Touchpoint history💡 UX critiqueQA bucketSources
WJ-49Lead clicks cancel link: full-page 'Időpont lemondva' confirmation (no error); card moves Booked → 'Contacted — No Appointment Booked'; RED 'Lemondás · {date}' badge on card face (cancellation date, not original booking date); Lemondás touchpoint (🚫) logged; NO automatic email sent; AUTOSEND stays OFFCancel link → confirmation page; board card moves to Contacted; red badge 'Lemondás · {date}' on card face; history: Lemondás touchpoint; ZZ inbox: zero new emailsLemondás touchpoint: icon 🚫, label 'Lemondás · {date}', description 'Időpont lemondva', Budapest timestamp; NO email outbound touchpointCancel link text is generic ('Lemondás') with no datetime — lead might not know which appointment they're cancelling if they have multiple interactionsliveextended-ebo-2026-06-25-S1, extended-ebo-2026-06-25-S2
WJ-50Cancellation history touchpoint renders with 'Lemondás' label (not 'Call booked') and a visually distinct badge; colour-coding principle: red = cancellations/negatives; green = bookings; blue = emails; grey = system notesHistory panel after cancellation: top entry shows 🚫 Lemondás pill, NOT 'Call booked' pill; badge colour is red, distinct from booking entriesSee WJ-49Consistent colour-coding would make history scannable at a glance — single highest-value history UX improvementliveextended-ebo-2026-06-25-S1

---

Stage 12 — Cross-cutting invariants

_Human gate; AUTOSEND stays as-is; ZZ sentinel only; Notion archive-not-delete; touchpoint colour-coding_

IDBehaviorStrongest seam🕓 Touchpoint history💡 UX critiqueQA bucketSources
WJ-51Human gate: nothing sent to a lead/client without explicit human action (Jóváhagy / Küldés click); sole approved exception is payment-reminder sequence self-arm on DocuSeal both-signed (owner-authorized, documented); AUTOSEND never flipped during testingAny test: ZZ lead's inbox receives no email unless operator explicitly approved; AUTOSEND=false verified before each test runAUTOSEND flag is invisible on the dashboard until navigating to a specific settings area; a persistent header badge 'AUTOSEND: OFF' (green) would prevent accidental sendsliveboard-card-redesign-S7, live-test-bug-fixes-S2, bnf-2026-06-24-r3-S11, studio-S7, CLAUDE.md-invariants
WJ-52ZZ sentinel rule: all test deals use ZZ-prefix names; after each test run, ZZ deals are purged via Test Drive → ZZ purge; no live lead data used in QAAfter test run: Test Drive ZZ purge completes; no ZZ-prefixed cards remain on the boardZZ purge is a manual step that could be forgotten — a post-test 'teardown' endpoint would make the test lifecycle self-cleaningliveboard-card-redesign-S7, CLAUDE.md-invariants
WJ-53Notion destructive ops use archive (PATCH /pages/{id} {'archived': true}), never permanent DELETE; lost-deal Studio project archived (never deleted); all manual stage overrides are allowed (no locked stages)Any delete/archive action: Notion API call is PATCH with archived:true; Studio project on lost deal shows archived status but is recoverableArchive-not-delete is completely invisible to the operator — an 'Archívum' read-only tab would make the safety net discoverableteststudio-S10, bnf-2026-06-23-duo2-S02, CLAUDE.md-invariants
WJ-54Instantly warmup mail (campaign IDs 8ZP8HWG, i-am-happy, DMARC-related) is never logged to Notion and never appears on the pipeline board; auto-archived in Missive (not deleted)Warmup emails: not in any deal's touchpoint history; not in Notion; auto-archived in Missive inboxIf the warmup filter ever breaks, warmup mail will flood pipeline history — a daily health check counting dropped warmup messages would catch regressions earlytestCLAUDE.md-invariants
WJ-55Dim logic: card DIMMED when deadline is in the future OR on automated sequence; ACTIVE (no overlay) when due date is today or overdue; booked call on appointment day is ACTIVE even if on a sequence (due≤today wins over sequence-dim); overdue cards must never be wrongly dimmedBoard: overdue card is undimmed; future-deadline card is dimmed; today's appointment card is undimmed even if on a sequenceAll dimmed states use the same dark grey overlay — a card dimmed by a sequence looks identical to one with a future deadline; different border styles per reason would help triageliveboard-card-redesign-S15, bnf-2026-06-24-r3-S4

---

Coverage summary

_Updated for the v110 Studio-integration deployment (2026-06-25). New live-sim bucket = drivable live but via API-injected state rather than a real external client action._

StageRow countlivelive-simtestblocked
1 — Ingestion & enrichment43001
2 — New lead on the board55000
3 — Contacted / sequence66000
4 — Booked84004
5 — Sales call & transcript54001
6 — Proposal54001
7 — Sign / follow-up22000
8 — Payment42002
9 — Onboarding10001
10 — Studio design loop86200
11 — Cancellation22000
12 — Cross-cutting invariants53020
TOTAL55412210

---

Blocked rows — residual human actions for the live QA

These rows CANNOT be driven with a ZZ sentinel in the live QA. Each is listed with its reason; the orchestrator must flag these as human-action residuals in the QA report.

IDReason blocked
WJ-01Needs real new lead entering from zero via Missive/webhook; enrichment silently no-ops on manually-moved deals
WJ-18Requires Google Calendar with pre-populated busy blocks and DWD configured
WJ-19Requires DWD / GCAL_DRIVEN_CONFIRMATION enabled on Google Workspace; owner action: 'enable DWD calendar scope / GCAL_DRIVEN_CONFIRMATION'
WJ-21Lead-side reschedule requires a ZZ lead with a real booking; GCal event replace cannot be faked without real GCal access
WJ-22Requires Google Calendar domain-wide delegation (gcal_watch) live and configured
WJ-24Requires a real 2-person Google Meet call; Fireflies bot-free criteria must be verified via research; DWD config needed
WJ-32Needs a real new lead entering from zero (not manually moved) for enrichment to trigger
WJ-37Real card charge not drivable with a ZZ sentinel; the prefilled-email checkout PAGE rendering needs a real Stripe checkout. PARTIAL live-sim: the Test Drive tab simulates checkout.session.completed via handle_stripe_event (covers the downstream WON/onboarding effects, not the checkout page itself). Stripe still in TEST mode
WJ-38Real card charge not drivable with a ZZ sentinel. PARTIAL live-sim: Test Drive tab simulates checkout.session.completed via handle_stripe_event, so the card-move to 'Payment Arrived' + sequence-stop CAN be exercised; DocuSeal signed-PDF auto-email still needs config verification
WJ-40Downstream of Stripe payment. PARTIAL live-sim: Test Drive tab simulates checkout.session.completed via handle_stripe_event, so the onboarding email draft + task generation CAN be exercised (draft stays human-gated in Outbox); no real card charge drivable

Summary: 10 blocked rows (down from 17 after the v110 Studio-integration correction). Of these: 4 are blocked by real GCal/DWD configuration (WJ-18, WJ-19, WJ-22, WJ-24); 3 are blocked by Stripe real-charge state but have a PARTIAL live-sim path via the Test Drive handle_stripe_event simulator (WJ-37, WJ-38, WJ-40); 2 are blocked by needing a real new-lead entry (WJ-01, WJ-32); 1 is blocked by lead-side GCal event deletion (WJ-21).

Reclassified out of blocked (v110 correction): WJ-26, WJ-41, WJ-42, WJ-43, WJ-44, WJ-45, WJ-48 → live (Studio integration deployed at v110, STUDIO_BASE_URL → -rebuild, 8 endpoints verified); WJ-46, WJ-47 → live-sim (drivable via the -rebuild API to inject the approved / won state, then verify the pipeline card reflects it after a poll/refresh).