Skip to content

[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-use users get compact guidance.
      • Fast lane: deep-link with schema-valid payload users skip onboarding and go straight to Paste & Log.
    • 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: isAwaitingReturn expires after 24h, showStepsAgain preference after 30d.
    • Help remains available on demand: How logging works entry 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 again on 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)

  1. Entry: landing CTA, manual dashboard entry, or deep-link open.
  2. Bootstrap: guest/auth context initialized.
  3. Lane Select: decide guided vs fast based on entry source and payload readiness.
  4. Guided Lane: quickstart panel -> handoff resume card -> paste & log.
  5. Fast Lane: direct paste & log.
  6. First Success: meal write confirmed and totals updated.
  7. Optional Guidance: Trigger B optimization prompt (post-adoption only).
  8. Promotion Path: sign up/log in flow with sync behavior branch.
  9. 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 version and 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 PendingMealCard in 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: LandingPage CTA 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 clipboard
  • secondary 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 result
  • secondary 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 again still available.

Core Screen C: Paste & Log + Success Confirmation (Both lanes)

  • Where: PendingMealCard and 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 example and Copy 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)
  • firstLogStartedAt
  • promptCopiedAt
  • handoffResumed
  • pasteAttemptCount before first success
  • firstLogSucceededAt
  • 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 (guided vs fast) 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 all fallback).
  • 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 again is 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 again on 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.md
    • docs/product/vision.md
    • docs/project_management/index.md
    • docs/project_management/logs/features/2026-01-17_design_first_log_ux.md
    • frontend/src/pages/LandingPage.tsx
    • frontend/src/pages/Dashboard.tsx
    • frontend/src/features/dashboard/components/PendingMealCard.tsx
    • frontend/src/features/dashboard/components/PromotionBanner.tsx (or equivalent)
    • frontend/src/features/dashboard/__tests__/MealLoggingIntegration.test.tsx
    • frontend/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 importGuestHistory contract.

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 works is 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 fast lane 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 again placement 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 again scenario: 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 works entry 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 again affordance 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 (closed vs pending execution mismatch).
  • Step 6: Finalize architecture doc updates in docs/architecture/ux_definitions.md for 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 lint
    • task 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-5w8 to in_progress so 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:
    • entryLane resolver (guided/fast) with deterministic deep-link eligibility and fallback reasons.
    • handoffResume local persistence with 24h return TTL + 30d steps preference TTL.
    • firstLogProgress local 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 useMealStaging to:
    • 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 Dashboard UI 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.md
    • docs/product/vision.md
  • 2026-02-14 (Verify): Passed:
    • task check:types
    • task test:frontend
    • task lint
    • task 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 JSON is 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 JSON controls 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 JSON as 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:types
    • task test:frontend
    • task 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 Prompt button shrinks and reveals links for ChatGPT, Gemini, and Grok next 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.
  • 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.

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.