[2026-01-17] Design: First Log Experience UX
Task Metadata
Date: 2026-01-17
Status: Plan Approved
- Beads Issue: 2512_genai_food_tracking-5w8 (in progress)
Objective
Goal: Design and operationalize a first-log journey that helps a first-time user understand the Sidecar model and successfully complete cross-app AI logging (copy prompt -> switch to AI app -> describe/photo food -> return to ChatKcal) with near-zero confusion, then introduces account creation only after value is demonstrated.
- Trigger: Phase 2 roadmap still lists "First-Log Experience Design" as incomplete while related Guest Mode capabilities are already shipped.
- Problem Statement: The current plan defines intent but under-specifies Sidecar teaching moments, cross-app handoff UX, prompt timing, and simple validation criteria.
- Primary Outcome: A complete design package that implementation can execute without product ambiguity.
- Constraints:
- Must preserve shipped Guest Mode architecture and promotion sync behavior.
- No backend schema changes in this design phase.
- Must work for both manual entry and deep-link (
/track?meal_json=...) entry paths. - Must explicitly support first-time users who have never logged via a separate AI app before.
- Success Target (Design Phase):
- Canonical state model documented end-to-end.
- Sidecar model explained in product copy without jargon overload.
- First-time users receive explicit step guidance during cross-app handoff.
- Registration prompt strategy defined with explicit trigger thresholds.
- Lightweight validation signals are defined without introducing new analytics infrastructure.
- Acceptance criteria are testable in unit/integration/E2E suites.
Technical Strategy
Tighten the journey into a v3 two-lane model: a short guided lane for first-time manual users and a fast lane for users who already have a deep-link payload. Keep mandatory onboarding to 3 surfaces max before first value.
- Key Decisions:
- Guest-first remains canonical: users can log immediately without auth gate.
- Two explicit lanes (v3):
- Guided lane:
landing/manual first-useusers get compact guidance. - Fast lane:
deep-link with schema-valid payloadusers skip onboarding and go straight toPaste & Log.
- Guided lane:
- 3 mandatory surfaces max in guided lane before first success.
- Surface counting is explicit: a surface is a route, blocking modal, or primary persistent onboarding module.
- Teach only what is needed now: each surface answers one question (
what is this,what do I do next,did it work). - Handoff guidance must be resumable: if users leave for AI app and return later, they resume from the last step.
- Resumability contract includes TTL:
isAwaitingReturnexpires after 24h,showStepsAgainpreference after 30d. - Help remains available on demand:
How logging worksentry point is always accessible after first-run. - Value-before-identity with deterministic triggers: registration ask uses a defined post-success matrix.
- Two promotion modes stay distinct:
- New account: silent promotion.
- Existing account: explicit merge/discard confirmation.
- Fast-lane eligibility is strict and deterministic: invalid/partial/oversized/unknown-version deep links always fall back to guided lane.
- Fallback preserves user effort: when fallback occurs, prefill ingest text when safely extractable.
- Single source of truth for prompt timing: trigger conditions stay centralized and intentionally simple.
- Trigger B is post-adoption optimization only: it is not part of core first-log education.
- Minimal ingest recovery is in scope: inline format error copy +
Show example+Copy prompt againon the paste surface. - Clipboard failures have fallback UX: if clipboard write is blocked, render selectable prompt text with
Select all. - Instrumentation stays lightweight: no large analytics rework is required for this phase.
Proposed UX State Model (v3, Two-Lane)
- Entry: landing CTA, manual dashboard entry, or deep-link open.
- Bootstrap: guest/auth context initialized.
- Lane Select: decide
guidedvsfastbased on entry source and payload readiness. - Guided Lane: quickstart panel -> handoff resume card -> paste & log.
- Fast Lane: direct paste & log.
- First Success: meal write confirmed and totals updated.
- Optional Guidance: Trigger B optimization prompt (post-adoption only).
- Promotion Path: sign up/log in flow with sync behavior branch.
- Post-Promotion Confirmation: clear ownership/sync outcome.
Fast-Lane Eligibility Contract (Deterministic)
Fast lane is allowed only when all checks pass:
- Entry source is
deep_link. - Payload includes
versionand version is supported by the current parser. - Payload size is below bounded threshold (
MAX_DEEP_LINK_BYTES) to protect UI responsiveness. - Payload is parseable offline (no network lookup required).
- Payload contains minimum fields required to render
PendingMealCardin non-error state. - Required: meal identity + aggregate totals + at least one ingredient/item entry.
Fallback behavior when any check fails:
- Route to guided lane.
- Preserve paste context by pre-filling raw payload text where possible.
- Never show fast-lane-only assumptions (no hidden skipped guidance).
Handoff Persistence Contract (TTL + Restore Rules)
- Storage: browser local storage key
handoffState(single JSON object). - TTLs:
isAwaitingReturn: 24 hours.showStepsAgain: 30 days.- Restore semantics:
- If return TTL is valid: restore handoff card and next action.
- If return TTL expired: show neutral ingest prompt (
Ready to paste your AI result?) instead of stale step index. - If user already logged a meal in this session/day: do not auto-reenter guided lane.
Screen Plan v3 (3 Core + Optional Helpers)
Core Screen A: Quickstart Panel (Guided lane only)
- Where:
LandingPageCTA region and mirrored compact version on Dashboard for first-run manual entry. - Content:
headline: "Use any AI chat app. Track meals here."body: "ChatKcal does not analyze photos itself. Copy the prompt to your clipboard, run it in your AI app, then paste the result here."cta:Copy prompt to clipboardsecondary cta:See steps- Value provided: immediate clarity on the model and next action.
- Exit condition: prompt copied or user opens steps helper.
Core Screen B: Handoff Resume Card (Guided lane only)
- Where: sticky inline card at top of dashboard after
Copy Prompt. - Content:
- step list (
Open AI app,Paste + add photo/text,Return and paste) support: "We keep this tab ready for 24 hours."cta:I have my resultsecondary cta:Copy prompt again- Value provided: reduces app-switch anxiety and makes return path explicit.
- Exit condition: user enters paste surface or dismisses with
Show steps againstill available.
Core Screen C: Paste & Log + Success Confirmation (Both lanes)
- Where:
PendingMealCardand post-log success toast/banner. - Content:
- paste card title/helper +
Log Meal - inline invalid-format guidance:
That does not look like a ChatKcal log. Paste the full result from your AI app. - collapsed helper actions:
Show exampleandCopy prompt again - success title/body +
Log Another - Value provided: explicit completion and immediate reinforcement of repeatable loop.
- Exit condition: first meal logged.
Optional Helper D: On-Demand "How Logging Works"
- Where: persistent help entry in dashboard header/menu.
- Value provided: recovery path for confused users without forcing repeated onboarding.
Optional Helper E: Trigger B Optimization Prompt
- Where: post-log inline prompt after demonstrated sustained use.
- Value provided: advanced efficiency tips, not core onboarding.
Optional Helper F: Returning User Merge Modal
- Where: auth promotion branch when cloud history exists.
- Value provided: prevents accidental data handling decisions.
\"Throw Rocks\" UX Stress Cases
- Guided-lane user leaves for AI app for 10+ minutes and returns (resume state must persist).
- Deep-link user arrives with valid payload (must stay in fast lane; no guided interruption).
- Deep-link user arrives with invalid/partial payload (must fall back to guided lane and preserve prefill context).
- User starts guided lane, dismisses helper, then requests
Show steps again. - User switches from deep-link to manual flow midstream without losing paste context.
- Clipboard write blocked by browser policy (fallback selectable prompt still lets user continue).
- User pastes invalid/truncated AI output once (inline recovery keeps them on the same surface).
- Mobile app switch suspends tab process and user returns via refresh (state restore still coherent).
- AI app returns multiple meals in one paste (UI explicitly states one meal per paste if parser is single-meal).
- User dismisses Trigger B prompt; it must not reappear in the same phase.
Simple Prompt Trigger Contract (Design Decision)
Use one follow-up trigger for optimization tips only:
- Trigger B (Habit + Time Signal): user has more than 5 total meals and logs on at least a second unique day.
- Display behavior: show once per user (no repeated nags in the same period).
- Suppression Rules: never interrupt an in-flight meal submission flow.
Registration Ask Trigger Matrix (Deterministic)
- Stage 1 (first value): after first successful log, show non-blocking banner with dismiss.
- Copy direction:
Save your logs across devices. Create account. - Stage 2 (sustained intent): after second unique log day OR 3 total logged meals, show stronger (still non-modal) banner.
- Modal escalation: only when user initiates a cloud-only action (for example history sync/export).
- Global suppression: never block ingest/submit path with registration modal before first success.
Instrumentation Scope (Lightweight)
- Full queryable funnel instrumentation is out of scope for this phase.
- Store local deterministic signals for QA/debug (no new analytics backend required):
laneAssigned(guided|fast)firstLogStartedAtpromptCopiedAthandoffResumedpasteAttemptCountbefore first successfirstLogSucceededAt- Rollout decision is based on QA and simple before/after behavior checks, not a new analytics dashboard project.
Testing Strategy
- Must Test:
- Lane classification correctness (
guidedvsfast) for landing/manual/deep-link entries. - Invalid/partial deep-link payload falls back to guided lane and preserves prefill when possible.
- Guided lane completes first log with only Core A -> B -> C mandatory surfaces.
- Fast lane reaches Core C directly for valid deep-link payloads.
- Handoff resume card persists across tab/app switch and returns user to next required action.
- TTL semantics: 24h handoff restore and neutral reset after expiry.
- Clipboard blocked path still supports prompt transfer (
Select allfallback). - Invalid paste shows inline recovery (
Show example,Copy prompt again) without route change. - Mobile suspend/restore keeps state coherent after app switch + refresh.
Show steps againis always reachable post-dismissal.- Registration ask appears only per trigger matrix and never blocks first submit.
- Returning authenticated user with existing cloud history (merge/discard branch).
- Trigger B appears once and only after threshold is met.
- Should Test:
- Mobile-first readability and tap targets for core surfaces.
- Paste surface alone contains enough guidance for users who skip Screen A.
- Offline/online boundary behavior during promotion.
- Skip (This Design Log):
- Backend mutation implementation details already covered in Guest Mode backend logs.
- Full parser redesign and large ingestion error-state taxonomy.
Risk Analysis
- High Risk: Prompt fatigue
- Over-aggressive registration prompts may reduce repeat logging.
- Mitigation: simple trigger matrix + suppression rules + QA-based threshold tuning.
- High Risk: Sidecar model confusion
- New users may assume ChatKcal performs AI analysis directly and not understand the cross-app step.
- Mitigation: first-use explanatory copy + guided handoff steps + contextual reminders.
- High Risk: Cross-app abandonment
- Users may drop after switching to external AI app if return path is unclear.
- Mitigation: clear return cues, resumable state, and post-return helper copy.
- High Risk: Data ownership confusion
- Users may not understand whether entries are local or cloud-synced.
- Mitigation: explicit session badge/copy at promotion and post-promotion confirmation.
- Medium Risk: Merge anxiety for returning users
- Ambiguous merge/discard copy can cause accidental overwrite behavior.
- Mitigation: confirmation modal with concise consequence text and safe default.
- Medium Risk: Clipboard failures in restricted environments
- Browser privacy policies or enterprise controls may block clipboard writes.
- Mitigation: always provide selectable prompt fallback and explicit recovery hint.
- Medium Risk: Invalid/truncated paste on first attempt
- First-time users often paste partial AI output.
- Mitigation: inline format guidance +
Show example+Copy prompt againon Core C. - Medium Risk: Measurement blind spots
- Without full analytics, outcome signal can be weaker.
- Mitigation: keep trigger logic deterministic and verify with targeted QA + lightweight counters.
- Security Implications:
- No new auth model introduced in this phase.
- Ensure no guest payload appears in logs/analytics without redaction.
-
Files to Modify (Design + Delivery Plan):
docs/architecture/ux_definitions.mddocs/product/vision.mddocs/project_management/index.mddocs/project_management/logs/features/2026-01-17_design_first_log_ux.mdfrontend/src/pages/LandingPage.tsxfrontend/src/pages/Dashboard.tsxfrontend/src/features/dashboard/components/PendingMealCard.tsxfrontend/src/features/dashboard/components/PromotionBanner.tsx(or equivalent)frontend/src/features/dashboard/__tests__/MealLoggingIntegration.test.tsxfrontend/tests/guest-mode.spec.js
-
Operational Dependencies:
- Guest Mode auth-state and local storage behavior must remain unchanged.
- Promotion sync backend behavior must remain consistent with
importGuestHistorycontract.
1. Two-Lane State Contract (v3)
- File:
docs/architecture/ux_definitions.md - Intent: Formalize guided and fast lanes with explicit transitions.
state: entry | bootstrap | lane_select | guided_quickstart | guided_handoff | ingest | first_success | optional_tip | promotion | promoted
transition(entry -> bootstrap): session starts
transition(bootstrap -> lane_select): entry context + payload readiness evaluated
transition(lane_select -> guided_quickstart): manual/landing + no ready payload
transition(lane_select -> ingest): deep-link with ready payload
transition(guided_quickstart -> guided_handoff): prompt copied or steps opened
transition(guided_handoff -> ingest): user returns with result or chooses paste now
transition(ingest -> first_success): meal persisted
transition(first_success -> optional_tip): Trigger B true
2. Lane Resolver Logic
- File:
frontend/src/features/dashboard/utils/entryLane.ts - Intent: Keep lane assignment deterministic and easy to test.
export type FirstLogLane = "guided" | "fast";
export type LaneDecision = {
lane: FirstLogLane;
prefillText: string | null;
reason:
| "valid_deep_link_payload"
| "not_deep_link_entry"
| "invalid_payload_version"
| "payload_too_large"
| "payload_missing_required_fields"
| "payload_not_parseable_offline";
};
type DeepLinkValidation = {
isEligibleForFastLane: boolean;
reason: LaneDecision["reason"];
prefillText: string | null;
};
export const resolveFirstLogLane = ({
entrySource,
payload,
}: {
entrySource: "landing" | "manual" | "deep_link";
payload: unknown;
}): LaneDecision => {
if (entrySource !== "deep_link") {
return { lane: "guided", prefillText: null, reason: "not_deep_link_entry" };
}
const validation: DeepLinkValidation = validateDeepLinkPayload(payload);
if (validation.isEligibleForFastLane) {
return { lane: "fast", prefillText: null, reason: "valid_deep_link_payload" };
}
return {
lane: "guided",
prefillText: validation.prefillText,
reason: validation.reason,
};
};
3. Handoff Resume Contract
- File:
frontend/src/features/dashboard/utils/handoffResume.ts - Intent: Guarantee users can return after context switching without restarting.
export type HandoffState = {
promptCopiedAt: number | null;
isAwaitingReturn: boolean;
awaitingReturnExpiresAt: number | null; // now + 24h
lastStepSeen: "quickstart" | "handoff" | "ingest" | null;
showStepsAgain: boolean;
showStepsAgainExpiresAt: number | null; // now + 30d
firstLogSucceededAt: number | null;
};
4. Trigger B Optimization Prompt Logic
- File:
frontend/src/features/dashboard/utils/sidecarPromptTrigger.ts - Intent: Keep Trigger B scoped to post-adoption optimization only.
export const shouldShowSidecarPrompt = ({
justLoggedMeal,
promptAlreadyShown,
totalMeals,
uniqueLogDays,
}: {
justLoggedMeal: boolean;
promptAlreadyShown: boolean;
totalMeals: number;
uniqueLogDays: number;
}): boolean => {
if (!justLoggedMeal || promptAlreadyShown) return false;
return totalMeals > 5 && uniqueLogDays >= 2;
};
5. Teaching Copy Contract (Core vs Optional)
- File:
frontend/src/features/dashboard/content/sidecarOnboardingCopy.ts - Intent: Keep mandatory vs optional content explicit.
export const sidecarOnboardingCopy = {
core: {
quickstart: {
headline: "Use any AI chat app. Track meals here.",
body: "ChatKcal does not analyze photos itself. Use your AI app, then paste the result here.",
cta: "Copy prompt to clipboard",
},
handoff: {
steps: [
"Open AI app",
"Paste prompt + add photo/text",
"Return and paste result",
],
cta: "I have my result",
tertiaryCta: "Copy prompt again",
secondaryCta: "Show steps again",
},
ingestRecovery: {
invalidFormat:
"That does not look like a ChatKcal log. Paste the full result from your AI app.",
showExample: "Show example",
copyPromptAgain: "Copy prompt again",
},
success: {
title: "Meal logged",
body: "Repeat: copy -> AI -> paste.",
cta: "Log Another",
},
},
optional: {
triggerBTips: {
title: "You’re building consistency",
body: "Want to make logging faster? Save your prompt setup.",
},
mergeModal: {
title: "Choose how to handle this device's guest logs",
},
},
};
6. Registration Ask Trigger Logic
- File:
frontend/src/features/dashboard/utils/registrationPrompt.ts - Intent: Prevent pre-aha pressure and keep registration asks deterministic.
export type RegistrationAskStage = "none" | "stage_1_banner" | "stage_2_banner";
export const getRegistrationAskStage = ({
firstLogSucceeded,
uniqueLogDays,
totalMeals,
isIngestInFlight,
userInitiatedCloudOnlyAction,
}: {
firstLogSucceeded: boolean;
uniqueLogDays: number;
totalMeals: number;
isIngestInFlight: boolean;
userInitiatedCloudOnlyAction: boolean;
}): RegistrationAskStage => {
if (isIngestInFlight) return "none";
if (!firstLogSucceeded) return "none";
if (userInitiatedCloudOnlyAction) return "stage_2_banner";
if (uniqueLogDays >= 2 || totalMeals >= 3) return "stage_2_banner";
return "stage_1_banner";
};
Critique & Gaps
- Critical 1: Status drift across systems.
- Beads issue is closed, but roadmap and log still indicate pending execution.
- Impact: Delivery ownership ambiguity and false completion signals.
- High 1: Lane misclassification risk.
- Pre-hardening, invalid/partial deep-link payloads could accidentally enter fast lane.
- Impact: User lands in a broken "quick" path without sufficient guidance.
- High 2: Resumability promise is underspecified.
- Pre-hardening, we promised "come back anytime" without persistence TTL and restoration rules.
- Impact: Broken trust if users return and lose progress context.
- High 3: Registration trigger ambiguity.
- Pre-hardening, "after value" was stated but not translated into deterministic UI trigger rules.
- Impact: inconsistent implementation and accidental early conversion pressure.
- Medium 1: Optional help discoverability risk.
- If
How logging worksis too hidden, dismissed users may not recover. - Impact: avoidable abandonment on second attempt.
- Medium 2: Content density on mobile.
- Quickstart/handoff instructions can still feel heavy on small screens.
- Impact: scanning friction at the highest-risk moment.
- Medium 3: Trigger B relevance drift.
- Tips prompt may feel random if copy does not connect to observed behavior.
- Impact: perceived nag rather than useful optimization.
- Medium 4: Clipboard environment variability.
- Some browsers/devices can block clipboard API writes.
- Impact: users cannot continue despite understanding the flow.
- Medium 5: Surface counting drift.
- "3 surfaces max" can drift unless surface definition is explicit.
- Impact: onboarding bloat can re-enter through new blockers.
Gap Analysis
- Lane Gap (closed in this revision): strict eligibility rules for
fastlane with fallback to guided lane. - Resumability Gap (closed in this revision): handoff TTL and restoration behavior across refresh/tab close.
- Registration Gap (closed in this revision): deterministic banner/modal triggers.
- Recovery Gap (closed in this revision): permanent
Show steps againplacement and paste-surface first-aid actions. - Surface Gap (closed in this revision): explicit definition of what counts as a mandatory surface.
- Measurement Gap: Keep validation lightweight but ensure lane-specific outcomes are verifiable.
- Delivery Gap: Keep rollout gated behind flag with a rollback path.
- Process Gap: Issue state and roadmap state are out of sync.
1. Acceptance Criteria Hardening
Define pass/fail criteria before implementation:
- User can log first meal without auth prompt blocking submission.
- Fast lane eligibility is schema-gated (supported version, bounded size, required fields, offline-parseable).
- Invalid/partial deep-link payload never enters fast lane; guided fallback can prefill available raw content.
- Guided lane requires only Core A -> Core B -> Core C before first success (max 3 mandatory surfaces).
- Fast lane skips Core A/B and goes directly to Core C for valid deep-link payloads.
- Handoff resume state restores correctly after app/tab switch, honors TTL, and exposes
Show steps again. - First-time user can complete guided lane without out-of-product support.
- Paste surface provides minimal recovery on invalid format without leaving the surface.
- Registration prompt behavior follows deterministic trigger matrix and never blocks first-success path.
- Follow-up optimization prompt appears only when Trigger B condition is met.
- Returning-user merge modal shows explicit consequence copy and safe default action.
- Prompt display state is persisted so users are not repeatedly nagged.
2. Lightweight Success Checks (Plan-Level)
Use simple validation checks based on existing data model:
- Guided lane scenario: first log completion succeeds with all 3 core surfaces.
- Fast-lane contract scenario: invalid payload cannot produce fast lane.
- Fast lane scenario: valid deep-link reaches paste/log without guided interruption.
- Resume scenario: user returns after delay and sees correct next step context.
- Resume expiry scenario: expired state resolves to neutral ingest prompt.
Show steps againscenario: helper can be reopened after dismissing guidance.- Invalid paste scenario: inline recovery appears and user can retry immediately.
- Users meeting Trigger B see optimization prompt once.
- Users not meeting Trigger B do not see optimization prompt.
- Prompt suppression remains intact during in-flight submission.
3. Regression Safeguards
- Add deterministic E2E scenario matrix for guided lane, fast lane, and resume states.
- Add "throw rocks" scenarios focused on lane switching and delayed return behavior.
- Add UTF-8 copy regression check for onboarding copy strings to prevent mojibake artifacts.
- Require snapshot/assertion for registration prompt suppression during in-flight submit states.
- Gate rollout behind feature flag for quick disable if prompt friction rises unexpectedly.
4. Must/Should/Could Scope Lock
- Must:
- Fast-lane eligibility contract + deterministic guided fallback.
- Handoff TTL + restoration semantics.
- Minimal paste recovery affordances on Core C.
- Registration ask trigger matrix with non-blocking first-success behavior.
- Should:
- Clipboard fallback UX for blocked environments.
How logging worksentry from paste surface, not only header/menu.- Mobile compact variants for Core A/B with expandable detail.
- Could:
- Optional local preference for AI app label personalization.
Done, do not show againaffordance after confirmed first success.
Execution Plan
Approval Gate Passed
User approved the revised Approach + Execution Plan on 2026-02-14; implementation may proceed.
- Step 1: Re-audit existing first-log log quality and identify structural gaps.
- Step 2: Upgrade Context/Approach/Impact with explicit state model, trigger matrix, and risk controls.
- Step 3: Expand Senior Critique into severity-ranked findings with closure actions.
- Step 4: Define measurable acceptance criteria with simplified trigger rules and lightweight validation.
- Step 5: Align issue state with roadmap state (
closedvs pending execution mismatch). - Step 6: Finalize architecture doc updates in
docs/architecture/ux_definitions.mdfor the revised state machine. - Step 7: Finalize implementation task split (lane resolver, core A/B/C surfaces, resumable handoff state, optional helpers, E2E lane matrix).
- Step 8: Execute UI + test changes for lane resolver, guided/fast surfaces, resumable handoff, and prompt triggers.
- Verify:
task linttask test- Guided lane, fast lane, and Trigger B scenarios verified in deterministic test runs.
Execution Notes
Infrastructure & Structural Hardening
- 2026-02-11: Initial design direction was partially documented in architecture and vision docs.
- 2026-02-13: Log upgraded from high-level narrative to execution-ready plan with explicit contracts and measurable outcomes.
- 2026-02-14: User approved the revised plan; implementation phase started.
- 2026-02-14 (Process): Re-opened beads issue
2512_genai_food_tracking-5w8toin_progressso tracker status matches roadmap execution state. - Added a formal Sidecar-aware two-lane model (guided/fast), resumable handoff contract, and lightweight validation checks to remove implementation ambiguity.
- Added deterministic fast-lane eligibility schema, guided fallback prefill behavior, registration trigger matrix, and paste-surface first-aid recovery requirements.
Implementation & Verification
- 2026-02-14 (Execute): Implemented first-log flow primitives:
entryLaneresolver (guided/fast) with deterministic deep-link eligibility and fallback reasons.handoffResumelocal persistence with 24h return TTL + 30d steps preference TTL.firstLogProgresslocal counters for first-success, unique log days, registration dismissal, and Trigger B suppression.- deterministic registration stage and Trigger B utility logic.
- 2026-02-14 (Execute): Updated
useMealStagingto:- classify deep-link entry lane before staging;
- support raw paste input + submit flow;
- preserve fallback text on invalid deep links;
- expose ingest error states for inline UI recovery.
- 2026-02-14 (Execute): Updated
DashboardUI to add:- Guided quickstart card + resumable handoff card;
- paste-surface recovery (
Show example,Copy prompt again); - clipboard fallback (
Select all) when write is blocked; - non-blocking registration stage banners and one-time Trigger B prompt.
- 2026-02-14 (Execute): Updated docs:
docs/architecture/ux_definitions.mddocs/product/vision.md
- 2026-02-14 (Verify): Passed:
task check:typestask test:frontendtask linttask test:e2e(against existing tmux dev server)task test(full logic + visual suite)
- 2026-02-14 (Review Failure): User validation reported major UX regression: first-time flow rendered three stacked control sections with duplicate prompt/paste actions, causing excessive vertical space and violating the "minimal app" goal.
- 2026-02-14 (User Feedback Decision): Prefer legacy clipboard-first ingest control over text-area staging. Rationale: one tap on
Paste Meal JSONis fewer actions and cleaner than click + paste + secondary submit. - 2026-02-14 (Root Cause):
- onboarding quickstart/handoff surfaces were added as additive UI blocks rather than replacing default action surfaces in first-time state;
- default
Copy Prompt/Paste Meal JSONcontrols and new paste-prep module remained visible concurrently; - gating was not strict to
first-time + zero meals + no pending meal, so the left column became overloaded.
- 2026-02-14 (Correction Required):
- collapse first-time UX into a single primary action surface;
- retain legacy
Paste Meal JSONas the primary ingest path in first-time minimal mode; - remove always-visible text-area + secondary "prepare" action from default first-time UI;
- re-run user validation before returning this log to
Ready for Review.
- 2026-02-14 (Rework Applied):
- removed always-visible "Paste and prepare meal" text-area module from Dashboard;
- replaced quickstart card with compact helper copy in first-time zero-meal state;
- wired handoff CTA to direct clipboard ingest (
Paste Meal JSON) to keep one-tap flow.
- 2026-02-14 (Rework Verify): Passed:
task check:typestask test:frontendtask test:e2e
- 2026-02-14 (New User Clarity Gap): User reported the first-time state still lacked a clear introduction/tutorial; the only visible guidance was a poorly worded single-line hint (
Use any AI app: tap the prompt button...), which did not sufficiently explain the Sidecar model or the cross-app workflow. - 2026-02-14 (Design Improvement Implemented): Replaced the weak one-line hint with a compact tutorial-style quickstart card that:
- explicitly explains the Sidecar model (AI app estimates, ChatKcal stores);
- enumerates the core workflow steps (copy prompt -> switch apps -> paste/photo/describe -> copy JSON -> paste meal JSON).
- 2026-02-14 (Post-Copy App Links): Implemented an inline "quick switch" row that appears after
Copy Prompt:Copy Promptbutton shrinks and reveals links forChatGPT,Gemini, andGroknext to it.- This reduces friction in the handoff moment and matches the intended mental model ("copy here, switch there").
- 2026-02-14 (Regression Found + Fixed): Playwright E2E
getByText('Copy Prompt')assertions became ambiguous because the tutorial copy now contains the phrase "Copy Prompt" as step text.- Fixed by updating the test selector to target the button explicitly (
getByRole('button', { name: 'Copy Prompt' })). - Re-verified with
task test:e2e.
- Fixed by updating the test selector to target the button explicitly (
- 2026-02-14 (Proposed Design Pivot): User proposed a simpler, clearer onboarding model than the current first-log plan:
- Add an explicit first-run gate: ask
First time user?and, on confirmation, run an animated tutorial sequence that explains the Sidecar model and the exact workflow. - Allow retriggering the tutorial later via a subtle affordance (ex:
How do I log again?). - After the tutorial, emphasize the primary action (
Copy Prompt) with a small attention animation (ex: subtle shake) when the user has zero meals logged. Note: This is materially different from the current work-log’s guided/handoff surface plan and should be treated as a new approved approach before further implementation changes.
- Add an explicit first-run gate: ask
Architecture Refinement (Optional)
- Clarified that "guest-first" is not just onboarding copy; it is a Sidecar onboarding contract that must survive deep-link, manual logging, and promotion paths with lane-specific behavior.
- Converted promotion behavior into explicitly separate branches for new vs returning users, with consequence-aware copy requirements.
- Reduced mandatory education to 3 core surfaces and moved extra guidance into optional, on-demand helpers.
Operational Rationale (Optional)
- This phased design is appropriate because underlying Guest Mode infrastructure is already delivered, so remaining risk is Sidecar comprehension, cross-app completion, and conversion optimization.
- Alternatives considered:
- Auth-first onboarding: rejected due to delayed time-to-value and higher pre-aha abandonment risk.
- No prompt model: rejected because it weakens promotion and retention mechanics.
Deviation from Plan (Optional)
- Deviation: Fast-lane validation keeps legacy payloads (missing
version) eligible for fast lane. - Reason: Existing live deep links do not consistently include
version; strict rejection would regress current link behavior. - Impact: Forward compatibility is preserved while still rejecting explicit unsupported versions.
Remaining scope: simplify first-time UI into one minimal surface, remove duplicated controls, then re-run user acceptance testing before rollout tuning.
User Approval & Key Learnings
Key Learnings
- A first-log flow cannot be considered "designed" until prompt timing, user guidance moments, and validation contracts are explicit.
- Fast lane must be a strict schema contract; permissive lane assignment silently creates broken first runs.
- Sidecar products need explicit first-use teaching; users should not have to infer cross-app behavior.
- Resumability promises require TTL semantics and restoration rules or user trust erodes quickly.
- Guest-first UX succeeds only when data ownership is obvious at each promotion boundary.
- Process-state consistency (log, roadmap, issue tracker) is critical to avoid false closure.
User review failed due onboarding density regression; implementation rework is required before review handoff.
Context Memory (AI-Only)
Summary for Future Context
Initial First-Log UX implementation passed automated checks but failed user review due UI density: onboarding was additive (quickstart + existing actions + paste-prep) rather than minimal first-time replacement. Next iteration must enforce strict first-time gating and a single compact action surface before returning to Ready for Review.