ClientsFlow · Email-System Overhaul · W4 · EBO

EBO — W4 Speed

DRAFT for owner comments · 2026-07-12. The target speed experience after W4 ships — every click in the Control Panel and on the public booking page feels like Notion/ClickUp: instant acknowledgment, fast settle, no mysterious hangs, no "did my edit actually save?" doubt. Pure latency/caching/plumbing — no new features, no visual redesign (that is W8), no send-gating changes (W1). Assembled from the W4_SPEED handoff + the ANSWERS_ROUND3 rulings (Q3, Q23, and the carried always-warm approval). Scenarios W4-1 … W4-8.

What W4 owns
Raw speed: how fast the board paints, how fast Log Call / stage moves / booking confirms respond, keeping the board cache warm, keeping slow external services (Google Calendar, Notion) off the critical path, and proving it all with numbers the app itself logs.
What W4 only enables (owned elsewhere)
W8 owns the live push board's look and animations — but a push board is only trustworthy on top of W4's cache coherence (a "live" board serving 120s-stale data is worse than a manual refresh). W1 owns which emails send; W2 owns history content; W0 owns the fast_poll cron body — W4 files the board keep-warm request to W0 and verifies it, but never edits that function itself.
You do → click/action/hover You should see → on-screen result Element changes → copy · look · where What changes underneath → data/state Must NOT happen → bug guard 🕓 Touchpoint history → impact on the card's history (or —) 💡 UX critique + suggestion → genuine critique + concrete improvement (owner: keep/omit)
Owner rulings folded in (ANSWERS_ROUND3 > handoff; owner comments > round 3)REQ item 35 (his words): the app today is "pretty wonky and slow"; target feel = Notion/ClickUp — fast, reliable, standardized. REQ item 36: he used Log Call, edited the confirmation email, and "wasn't sure the edit actually saved" — that trust gap is a latency gap. Q3=A: true-push live board (built by W8) — which makes W4's cache-coherence work a prerequisite, not a nice-to-have: a push board must never push into a stale cache. Always-warm containers are pre-approved ("pay for it", round-2 Q9 carried into round 3 unchanged) BUT Q23: total hosting + AI ≤ $30/month — the warm-container spend must fit under that cap.
The speed invariant (the answer key for every scenario below) — extending the booking rule-file's written UX2 invariant to the whole dash: every click gives visible feedback in < 300 ms and a final result in ≤ 2 s (board reads, Log Call, Send-Emails modal, stage moves, booking confirm). Where an external service (Google Calendar, Notion) is slow, the wait is bounded and off the human's critical path — the human never inherits a third party's hang. Canonical state (the deal store) is always written synchronously; only the eventually-consistent Notion mirror is deferred. W4 changes when things happen, never what happens — no copy, no gating, no schema changes.

W4-1 — Opening the Pipeline board: warm open paints in under 2 seconds (happy path / the daily moment)

Who: Mátyás  ·  When: He opens the Pipeline board — dozens of times a day, his one working surface. This is the moment that today feels "wonky and slow". After W4, the normal case is a cached, pre-warmed read.

#You doYou should see Element that changes
copy · look · where
What changes underneathMust NOT happen 🕓 Touchpoint history💡 UX critique + suggestion
1 Mátyás opens the Pipeline board tab (normal day, board recently served or kept warm) The full board — all columns, all cards — is painted and interactive in under 2 seconds from click to usable board Copy: unchanged · Look: unchanged (no redesign — W8's job) · Where: Pipeline tab The board response is served from the warm cache; the payload's own timing fields show a near-zero build (build_ms≈0) — served, not rebuilt Must NOT take 16–20s as historically reported; must NOT show a blank/"Loading…" board for more than 2s on a warm open; must NOT silently rebuild the whole store on every open Critique: "Under 2s" is the invariant, but nothing on screen tells him whether a slow paint was the app or his Wi-Fi — so every slow moment erodes trust in the whole system.
Suggestion: None needed on the UI (no new elements per the style rules); the timing fields the endpoint already returns are the audit trail — QA reads them, the screen stays clean.
2 QA (not Mátyás) re-measures the board build 3× with the cache deliberately bypassed, before and after W4 A logged before/after number for the full board build, using the timing fields the endpoint already returns (build_ms / rows_ms / queue_ms / project_ms) — proving the 2026-07-11 store-read fix (~100s → ~9s full-store scan) actually reached the board path Copy: — · Look: — · Where: QA evidence log, not the UI 3 fresh (cache-bypassed) board builds are timed on prod; the deal-store read portion (rows_ms) is compared against the pre-fix ~10s baseline Must NOT accept rows_ms > 3s for the current deal count without opening a follow-up (the handoff's explicit acceptance bar); must NOT add new instrumentation — the fields already exist, read them Critique: A one-time measurement decays — deals grow, and next quarter nobody knows if the board slid back to 8s.
Suggestion: Since the endpoint already self-reports its timings on every build, have W0's existing health surface keep the latest board build_ms visible there (no new UI in the board itself) — a slow creep becomes a glance, not an archaeology dig. ❓ owner: worth asking W0 for?

W4-2 — Cold open after idle: the keep-warm cron makes the slow path nearly extinct (happy path / always-warm ruling)

Who: Mátyás  ·  When: He opens the board after a longer break (lunch, a call, overnight) — the exact moment that today pays a full synchronous rebuild because the board cache expired and, unlike the Today tab, nothing keeps it warm. Owner pre-approved paying for warmth ("always-warm containers; pay for it"), under the $30/month total cap.

#You doYou should see Element that changes
copy · look · where
What changes underneathMust NOT happen 🕓 Touchpoint history💡 UX critique + suggestion
1 Mátyás opens the board after 30+ minutes away Same experience as W4-1: the board paints in under 2 seconds — because a background keep-warm step has been quietly rebuilding the board cache on a fixed interval, exactly like the Today tab already gets Copy: unchanged · Look: unchanged · Where: Pipeline tab The existing 3-minute background cron gains a warm_board step mirroring the existing warm_today one — implemented by W0 inside its single-writer edit of that cron; W4 files the request and verifies. The cron's heartbeat log shows warm_board: {"status": 200} every run Must NOT have W4 edit the cron function itself (W0-exclusive seam); must NOT leave the board as the only major tab without a warmer; must NOT let the warmer mask a genuinely broken build (a failing warm step must show in the cron heartbeat, not silently vanish) Critique: The warmer runs every 3 minutes but the board cache lives 120s — that leaves a recurring ~60s window each cycle where the cache is expired and a click still pays the cold rebuild. Warm "most of the time" is not the Notion feel.
Suggestion: Close the gap on the cache side: lengthen the board cache's life to ≥ 240s (as the Today tab already has) so the 3-min warmer always lands inside a live window — no extra cron slot, no extra cost. ❓ owner sign-off: proposed threshold, not in the handoff.
2 Worst case: Mátyás hits the board at the exact moment the cache is genuinely cold (warmer missed a beat, fresh deploy) The board still arrives within a documented, measured bound — proposed: ≤ 5 seconds click-to-board — never "however long it happens to take", and never a spinner of unknown duration Copy: unchanged · Look: the normal loading state, briefly · Where: Pipeline tab A cold rebuild runs synchronously but on the already-fixed one-pass store read (W4-1 step 2's measurement is the proof this bound is honest) Must NOT exceed the documented bound without it being treated as a defect; must NOT regress to the per-deal read storm (one network call per deal) that caused the historic 16–20s reads Critique: The handoff mandates "a documented, measured bound" but names no number — someone has to pick one or "bounded" means nothing.
Suggestion: I propose ≤ 5s cold, ≤ 2s warm as the two-tier bar (cold should be rare enough after the warmer that 5s is acceptable). ❓ owner sign-off: these exact numbers.

W4-3 — Your own change is visible immediately — the end of "edit… refresh… still not there" (happy path / trust repair)

Who: Mátyás  ·  When: He logs a call, moves a stage, or edits something — then looks at the board. Today his own change can stay invisible for up to 2 minutes (the cache-invalidation signal only reaches the server copy that handled his edit, not its siblings). This is the root of the "wasn't sure the edit actually saved" complaint, and the Q3=A push board (W8) cannot be built on top of it.

#You doYou should see Element that changes
copy · look · where
What changes underneathMust NOT happen 🕓 Touchpoint history💡 UX critique + suggestion
1 Mátyás makes any change (logs a call, moves a card's stage) and then views the board — same tab, other tab, or a second browser window The board he sees already includes his change — every time, on the first look, with no manual refresh ritual and no "wait two minutes" Copy: the changed card shows its new state · Look: unchanged · Where: Pipeline board The canonical deal store was written synchronously at the click (that already works today); the fix guarantees no server copy keeps serving a pre-edit cached board afterwards Must NOT ever show him a board that is missing an edit he made more than 2 seconds ago; must NOT train him to distrust the board ("better refresh twice to be sure") The logged call / stage move writes its history row exactly as today (owned by W2's rules) — W4 only guarantees the board showing it is never stale. Critique: This bug is invisible in single-server moments and bites exactly when the system is busiest — the worst possible trust profile.
Suggestion: Whatever fix ships, QA must reproduce the stale case first (two concurrent server copies, edit on one, read on the other) and then prove it gone — a fix verified only on one server copy proves nothing.
2 QA measures first, before building: does this app ever actually run more than one concurrent server copy under Mátyás's real single-operator traffic? A recorded verdict with evidence, one of two: (a) yes — multiple copies observed serving within a 2-minute window → the cross-copy invalidation fix is built; (b) no — traffic never triggers a second copy → the item is marked "observed non-issue, revisit if traffic grows" and no distributed-cache machinery is built on spec Copy: — · Look: — · Where: QA evidence log Live evidence (distinguishable server-copy identity in logs, or a controlled burst test) decides build vs. defer — the handoff's explicit measure-first rule Must NOT build a distributed cache-invalidation mechanism blind; must NOT mark the item closed with neither evidence nor fix Critique: Round 3's Q3=A (true-push board) changes this item's stakes: even if today's traffic never spawns a second server copy, W8's push channel plus warm containers may — deferring on today's evidence could plant a bug in W8's foundation.
Suggestion: If verdict is (b), don't just defer — hand W8 a written constraint ("push board must carry the data in the push, or bust the cache version on every push") so the non-fix is a documented dependency, not a landmine. ❓ owner: agree measure-first stands, with this W8 rider?

W4-4 — Log Call responds instantly; the Notion mirror catches up in the background (happy path / the item-36 complaint)

Who: Mátyás  ·  When: He clicks Log Call on a card (the exact flow from his own complaint: created a Meet invite, edited the confirmation email, "wasn't sure the edit actually saved"). Today the click blocks on a full synchronous Notion page rebuild before responding. After W4, the click frees him immediately and the mirror write moves off his critical path.

#You doYou should see Element that changes
copy · look · where
What changes underneathMust NOT happen 🕓 Touchpoint history💡 UX critique + suggestion
1 Mátyás clicks Log Call (with his edits to the confirmation email in place) and confirms The button acknowledges in < 300 ms, the panel completes and frees him in ≤ 2 s — the response no longer waits for the Notion CRM page rebuild. Everything he entered is saved the moment the click lands Copy: unchanged (no new toasts, no ceremony) · Look: unchanged, just fast · Where: the card's Log-Call panel The canonical deal-store write and the calendar/Meet work happen exactly as today; only the Notion mirror rebuild is handed to the existing background worker pool instead of blocking the response — the pattern the codebase already uses elsewhere, applied consistently Must NOT hold the click hostage to Notion's response time; must NOT change what gets written — same call touchpoint, same edited email body driving the calendar description (the shipped Ferenc-Zemen behavior), just asynchronous mirroring The call touchpoint row appears exactly as today, with the edited copy — unchanged content, owned by W2. QA probe: the row is present and correct even though the click returned before the Notion mirror finished. Critique: Making the click faster fixes the latency half of his complaint; the "did it save?" feeling also has a UI-feedback half — but that half is explicitly W7's (UI Action Discipline), and inventing a confirmation surface here would double-build it.
Suggestion: Keep W4 surgical; note the seam so W7's feedback work lands on the now-fast endpoint. No new UI here.
2 Nothing — a rare failure: the background Notion mirror write fails after the click already returned Mátyás's board and the deal's real state are still correct — the canonical store was written synchronously at the click. Only the Notion CRM page is temporarily stale, and the failure is logged (visible via W0's existing health/alarm surfaces, not a new W4 UI) Copy: — · Look: — · Where: behind the scenes Deal store (canonical) written synchronously; the deferred mirror write failed and logged — matching the codebase's already-documented invariant: "the deal-store write stays synchronous; only the eventually-consistent mirror is deferred" Must NOT lose the logged call itself when only the mirror fails; must NOT report the click as failed when the canonical write succeeded; must NOT invent a new failure UI (existing logging/alarm surfaces only) The touchpoint row exists (canonical); only the Notion page presentation lags until the next successful sync. Critique: "Eventually consistent" needs an eventually — with no bound, a stale Notion page could quietly persist for days.
Suggestion: Proposed bound: the Notion mirror reflects the change within ~10 s normally, and a failed mirror write is retried on the next regular sync pass rather than dropped. ❓ owner sign-off: the 10s expectation (not in the handoff).

W4-5 — Lead books a call: the confirm screen never hangs, even when Google Calendar does (happy path + failure bound / lead-facing)

Who: A lead (public booking page) + Mátyás (downstream)  ·  When: A lead picks a slot and submits. This page historically hung 60–90s when Google Calendar's availability check stalled — the one remaining unbounded external call sits on the critical path of every booking. This is the existing flow, verified — plus the one surgical fix.

#You doYou should see Element that changes
copy · look · where
What changes underneathMust NOT happen 🕓 Touchpoint history💡 UX critique + suggestion
1 The lead picks a slot and submits the booking form (normal day, Google Calendar healthy) Existing flow, verify unchanged: the confirmation screen renders in ≤ 2 s; the calendar invite, Meet link, notification email, and the card's update all complete in the background moments later Copy: unchanged (client-facing Hungarian confirm copy as today) · Look: unchanged · Where: public booking page The already-shipped optimistic path: slot claimed + availability checked synchronously, everything heavy (CRM, Meet, email, board push) finalized on a background thread — the booking rule file's < 2s target, already honored in code Must NOT regress the ≤ 2s confirm while touching this path; must NOT double-book (the claim + pre-filter protection stays exactly as is) The booking lands in the lead's history exactly as today (owned by W2) — booked-call touchpoint + confirmation email record, written by the background finalize. Critique: None — this path is already right; the EBO's job is to prove it stays right after the adjacent fix.
Suggestion: — (no change proposed; verification only).
2 The lead submits while Google Calendar's availability service is slow or hung (the historic 60–90s scenario) The confirmation screen still renders — worst case within ~9 s (the same 8-second wait cap the page's first availability check already uses, plus overhead) — never a 60–90s white-screen hang Copy: the normal confirm screen (the lead never sees the degradation) · Look: unchanged · Where: public booking page The second, authoritative availability check — today the only unbounded Google Calendar call on the critical path — gets the identical 8s wait-cap treatment its sibling pre-filter already has, failing open (proceed + log) on timeout. Only the wait is bounded; the fail-open semantics do not change Must NOT hang past ~9s no matter what Google does; must NOT change the double-book risk posture (on timeout, protection still comes from the slot claim + the pre-filter — the same accepted window that exists today); must NOT fail the booking outright because an availability read timed out Unchanged — the booking's history rows are written by the background finalize whether or not the availability check timed out (the timeout is logged internally, not shown to the lead). Critique: ~9s is 4.5× the 2s invariant — acceptable only because it's a rare degraded mode, but a lead staring at 9s of nothing may resubmit.
Suggestion: The slot-claim already makes a duplicate submit harmless (idempotent), which is the real protection; any visible "still working…" affordance is W7 UI-discipline territory, not W4's. ❓ owner sign-off: ~9s as the accepted degraded bound.
3 QA proves the bound: simulate a hung availability check on staging (test calendar), book a ZZ-sentinel slot The confirm screen renders within the ~2–9s window instead of hanging; a test asserting "availability check hangs > 8s → booking still returns within ~9s" is green; test data purged after Copy: — · Look: — · Where: staging + test suite A unit/integration test mocks the availability call to hang and asserts the booking handler returns within ~9s; a live staging probe with a ZZ-sentinel lead confirms it end-to-end Must NOT ship the fix on a green typecheck alone (the hang only shows under a hung dependency — it must be simulated); must NOT leave ZZ test bookings behind ZZ-sentinel rows only, purged after the pass. Critique:
Suggestion: — (pure verification row).

W4-6 — Webhooks (payments, inbound email) never block on the Notion mirror (behind the scenes / consistency sweep)

Who: System (Stripe payment webhook, bank-transfer match, inbound email) + Mátyás (sees the results on the board)  ·  When: Money arrives or a lead replies. No human waits on these HTTP responses, but a slow synchronous Notion write inside a webhook risks provider timeouts and retries — same disease as W4-4, lower severity. One call site must be traced before touched.

#You doYou should see Element that changes
copy · look · where
What changes underneathMust NOT happen 🕓 Touchpoint history💡 UX critique + suggestion
1 Nothing — a payment lands (Stripe webhook or bank-transfer match fires) On the board, the deal shows its payment progress exactly as today; behind the scenes the webhook response returns promptly instead of waiting out a full Notion page rebuild Copy: unchanged · Look: unchanged · Where: the paying deal's card (eventually-consistent Notion page follows) The two payment-path Notion mirror writes move to the same background-worker pattern as W4-4; canonical payment state still written synchronously. All existing payment tests stay green Must NOT change any payment logic, amounts, or stage transitions — timing only; must NOT let a webhook exceed the provider's timeout because of a Notion hang (the retry storm that follows is worse than the slowness) Payment history rows unchanged in content and order (owned by W2/W1) — only the Notion mirroring moment shifts by seconds. Critique: Bundling these two low-priority wraps into the same change as W4-4 inflates the diff and the QA surface for near-zero user-visible gain.
Suggestion: The handoff already allows it: bundle only if the diff stays small, otherwise ship as a fast follow-up after W4-4 proves the pattern. Keep the option, don't force it.
2 QA traces (before any edit) the inbound-reply mirror write: does it run on the already-asynchronous fast-ack path, or synchronously inside the webhook response? A one-line recorded finding with the code trace: either "already off-thread — no fix needed" or "still synchronous — wrap it like W4-4"; only in the second case is the code touched Copy: — · Look: — · Where: implementation notes / QA evidence The inbound email webhook is documented as fast-ack (it spawns background processing immediately) — if the mirror write lives inside that spawned worker, it never blocked anyone and must be left alone Must NOT "fix" a call site that was never on a request thread (churn without benefit, plus merge-collision risk with W1/W2 who also touch inbound); must NOT skip the trace and guess Critique: This row is the handoff's own discipline made visible: measure/trace first, edit second — the cheapest bug is the one you don't introduce.
Suggestion: — (keep as-is; it's the pattern W4-3 step 2 uses too).

W4-7 — The click-feedback invariant holds across the dash (guardrail / the Notion-feel acceptance sweep)

Who: Mátyás  ·  When: Any ordinary working click — moving a card between stages, opening the Send-Emails modal, switching tabs. The booking page has this invariant written down; the dash never did. This scenario writes it down and sweeps the main clicks against it. (Visual redesign, loading-state polish, and double-click guards stay with W8/W7 — this is a pure timing sweep.)

#You doYou should see Element that changes
copy · look · where
What changes underneathMust NOT happen 🕓 Touchpoint history💡 UX critique + suggestion
1 Mátyás drags/moves a card to another stage The card visually moves at once (feedback < 300 ms — the existing optimistic UI) and the move is fully settled server-side in ≤ 2 s; the board never snaps the card back on a healthy save Copy: unchanged · Look: unchanged (existing optimistic move) · Where: board columns Optimistic UI applies the move instantly; the canonical store write settles behind it — existing behavior, now verified against the written invariant Must NOT block the drag on the server round-trip; must NOT leave the UI and store disagreeing after 2s Stage-move history behavior unchanged (owned by existing stage-sync rules). Critique: "< 300 ms feedback" is the handoff's number; for already-optimistic paths like this drag the real bar is one frame (< 100 ms) — 300 ms of nothing after a drag-drop feels broken even though it passes.
Suggestion: Two-tier reading: optimistic paths (drag, button-press states) ≈ instant (< 100 ms); request-bound paths ≤ 300 ms to first feedback. ❓ owner sign-off: adopt the two-tier bar.
2 Mátyás opens the Send-Emails modal on a card The modal opens with feedback < 300 ms and is fully usable in ≤ 2 s (this modal historically took 38 s; that fix already shipped — existing flow, verify unchanged, guarded against regression here) Copy: unchanged · Look: unchanged · Where: Send-Emails modal No new work — the shipped fix is re-timed as part of this sweep so a regression can't ride in silently under W1/W2's concurrent edits to the same surfaces Must NOT regress toward the historic 38s open while W1/W2 rework the modal's contents; must NOT re-fix what is already fixed (verification only) Critique:
Suggestion: — (regression guard row; no change proposed).

W4-8 — Speed never busts the budget: always-warm under the $30/month cap (guardrail / Q23)

Who: Mátyás (pays the bill)  ·  When: After W4's warm-container/keep-warm changes have run in production for a billing-visible period. Owner pre-approved paying for warmth — but round 3's Q23 caps total hosting + AI at $30/month. Speed that silently breaches the cap is a defect, not a win.

#You doYou should see Element that changes
copy · look · where
What changes underneathMust NOT happen 🕓 Touchpoint history💡 UX critique + suggestion
1 QA checks the Modal spend after the keep-warm + warm-container settings have been live (projected to a full month) A recorded number: projected monthly hosting spend with W4's changes, and total hosting + AI ≤ $30/month. If the projection breaches the cap, the warm sizing is dialed back (shorter warm window / fewer warm containers) until it fits — the ≤ 2s warm-open target is then re-verified at the cheaper setting Copy: — · Look: — · Where: QA evidence + W0's billing-guard surface The keep-warm step costs ~one extra internal request per 3-min cron tick (near-zero); the always-warm container floor is the real line item — its projected cost is read from Modal's own usage/billing view, not estimated Must NOT ship warm-container sizing without a cost projection; must NOT let W4 spend eat the AI budget's share of the $30 (the cap is TOTAL, and the ongoing spend alarm itself is W0's — W4 only proves its own contribution fits) Critique: "Pay for it" (round 2) and "≤ $30 total" (round 3) can genuinely collide if AI usage grows — and W4 would be the silent culprit nobody suspects.
Suggestion: Record the chosen warm sizing + its measured monthly cost in one line in the W4 close-out notes, so any future budget alarm can be traced to (or cleared of) this decision in seconds.
🕓 Touchpoint-history note for W4:
W4 is a timing workstream — it never authors, edits, or reorders a touchpoint. Every history row in the scenarios above (the logged call in W4-4, the booking rows in W4-5, payment rows in W4-6) is written with identical content and order to today, under W2's ownership; the only thing W4 moves is the moment the Notion mirror catches up (from "inside the click" to "seconds after the click"). The standing invariant is explicit: the canonical deal store is written synchronously at the click — a background mirror failure can never lose a touchpoint, only delay its Notion presentation. QA for every deferred-write row therefore has two halves: the click is fast, AND the history row still lands, correct and complete.
💡 UX themes across all W4 scenarios:
(1) The human never inherits a dependency's hang — every external wait (Google Calendar, Notion) is either off the critical path or hard-bounded; "however long it takes" is banned. (2) Fast must also be honest — the click frees immediately, but the canonical write happens synchronously first; W4 never trades correctness for perceived speed. (3) Measure before building — the two architectural fixes (cross-copy cache coherence, inbound mirror wrap) each start with recorded evidence, not assumption. (4) No new UI — W4 adds zero visible elements; feedback polish is W7's, visuals are W8's; W4's fingerprints are only in the timings. (5) Thresholds are named numbers — warm ≤ 2s, cold ≤ 5s, feedback < 300 ms (optimistic paths ≈ instant), booking degraded ≤ ~9s, mirror catch-up ~10s — every one measurable in a QA pass, the proposed ones flagged for sign-off below. (6) Speed fits the budget — the $30/month total cap outranks any latency win.

Work-item → scenario-step mapping

Each build work item from the W4_SPEED handoff, and the scenario steps that prove it works when clicked through / probed on staging then prod.

Work itemWhat it deliversProven by (scenario · step)
WI-1 · Board build re-measured (handoff W4-1)Live before/after timing of the full board build using the endpoint's own timing fields; confirms the 2026-07-11 store-read fix reached the board path; follow-up opened if the store-read portion still > 3s.W4-1·1 · W4-1·2 · W4-2·2
WI-2 · Board keep-warm (handoff W4-2, W0 implements)A warm_board step in the existing 3-min cron (filed to W0, single-writer seam respected); cron heartbeat shows warm_board: 200; cold opens become rare.W4-2·1 (heartbeat + warm-open timing)
WI-3 · Bounded booking availability check (handoff W4-3)The last unbounded Google Calendar call on the booking critical path gets the existing 8s wait-cap, fail-open semantics unchanged; the 60–90s hang class is extinct.W4-5·1 · W4-5·2 · W4-5·3
WI-4 · Log-Call mirror write off-thread (handoff W4-4)Log Call responds in ≤ 2s; Notion mirror deferred to the existing background worker; canonical write stays synchronous; existing Log-Call tests green.W4-4·1 · W4-4·2 · (visibility) W4-3·1
WI-5 · Billing mirror writes off-thread (handoff W4-5)Both payment-path Notion writes wrapped the same way (bundled only if the diff stays small, else fast follow-up); billing tests green.W4-6·1
WI-6 · Inbound mirror call traced first (handoff W4-6)A recorded one-line finding with the code trace — "already off-thread" or "wrap it" — before any edit to the inbound path.W4-6·2
WI-7 · Cache-coherence: measure, then fix or defer (handoff W4-7)Evidence-based verdict on multi-copy staleness; fix built only on evidence (or explicitly deferred with a written W8 push-board rider); either way the "own change invisible" experience ends.W4-3·1 · W4-3·2
WI-8 · Dash click-invariant sweep (mission-level)The booking-only < 300 ms / ≤ 2s invariant written down for the dash and swept: stage moves, Send-Emails modal open (regression-guarded), board opens.W4-7·1 · W4-7·2 · W4-1·1
WI-9 · Cost fit under the $30 cap (Q23 rider)Projected monthly hosting spend recorded for the chosen warm sizing; total hosting + AI ≤ $30/month or the sizing is dialed back and speed re-verified.W4-8·1
❓ Thresholds & decisions I set myself (the handoff names no number) — please comment (keep / change) in this round:
❓ D1 Cold-open bound (W4-2·2): warm open ≤ 2s (handoff invariant), genuinely-cold open ≤ 5s click-to-board. Keep 5s, or tighter?
❓ D2 Board cache lifetime vs warmer interval (W4-2·1): the 3-min warmer leaves ~60s expired windows against the current 120s cache; I propose lengthening the board cache to ≥ 240s (matching Today's) so the warmer always lands inside a live window. OK?
❓ D3 Notion mirror catch-up window (W4-4·2): the deferred mirror reflects the change within ~10s normally; failed writes retry on the next sync pass, never dropped. OK?
❓ D4 Booking degraded bound (W4-5·2): when Google Calendar hangs, the confirm screen may take up to ~9s (8s cap + overhead) — accepted rare worst case, protection posture unchanged. Accept?
❓ D5 Two-tier feedback bar (W4-7·1): optimistic paths (drag, button-press states) ≈ instant (< 100 ms); request-bound paths < 300 ms to first feedback; everything settles ≤ 2s. Adopt the two tiers, or keep the single 300 ms bar?
❓ D6 Cache-coherence verdict (b) rider (W4-3·2): if measurement shows a second server copy never occurs today, W4 defers the distributed fix BUT hands W8 a written push-board constraint (push carries the data / busts the cache) instead of leaving it unstated. Confirm measure-first + rider?
❓ D7 Board build-time visibility (W4-1·2 💡): ask W0 to surface the latest board build time on the existing health view (no new board UI) so slow-creep is caught at a glance. Worth filing to W0?
Sign-off — acceptance oracle. By signing, Sarudi Mátyás locks scenarios W4-1 … W4-8, the speed invariant, and the named thresholds above as the acceptance answer key for W4 Speed, and records his keep/change verdict on the ❓ decisions D1–D7. No W4 code is built or deployed before this signature.
Sarudi Mátyás  ✔ Draft · 2026-07-12 · awaiting sign-off