# S05 UAT — End-to-end trust and workflow polish ## Goal Verify that one real job can be entered from `/jobs`, `/dashboard`, and `/reminders`, then carried through the same trusted workspace loop: - saved package material is visible and reusable - linked Gmail threads stay current without thread re-import - follow-up drafting is grounded in saved package + correspondence - no recruiter email is sent unless the human explicitly chooses the send action in a safe environment ## Safety Guardrails 1. **Do not click `Send and log email`** unless outbound mail is intentionally routed to a safe sink, stub mailbox, or other non-production target. 2. If safe outbound handling is not confirmed, stop after reviewing the follow-up draft and the manual-send boundary copy. 3. Do not capture or share screenshots containing sensitive recruiter or correspondence content. 4. Use one job that already has all or most of the following: - a saved tailored CV and/or other saved package material - at least one imported Gmail thread linked to the job - a workflow action from the overview surfaces - follow-up context that should produce a draft ## Preconditions - API is running on the expected backend origin with working CORS for the frontend. - UI is running and can load real API-backed job data. - Gmail integration is authenticated for the current user. - The selected job belongs to the current user and has real recruiter/thread context. - If the final send step will be tested, outbound mail is pointed at a safe sink/stub. ## Shared Expected Signals For The Same Job Across `/jobs`, `/dashboard`, and `/reminders`, the same job should: - show the same general next action - open the same job workspace - land on the same tab or equivalent workflow destination - preserve the same saved package, correspondence, and follow-up state Inside the job workspace, expect to see: - package save-state chips - a signal that saved package material feeds follow-up drafting - linked-thread continuity state in Correspondence - explicit manual-send boundary copy in Follow up --- ## Test Case 1 — `/jobs` routes into the trusted workspace ### Steps 1. Open `/jobs`. 2. Find a job row with a workflow chip, readiness signal, or next-action control. 3. Open that job using the primary workflow action. ### Expected - The dialog/workspace opens for the selected job. - The opened tab matches the job’s workflow need rather than a generic default. - The selected company and role match the job row you opened. --- ## Test Case 2 — saved package material is visible and reusable ### Steps 1. In the opened job workspace, go to **Tailored CV**. 2. Review the save-state chips for: - Tailored CV - Cover letter - Application answer - Recruiter message 3. Review the “Saved working material” panel. 4. If the job already has saved package data, confirm those fields show as saved. ### Expected - The page shows save-state chips instead of leaving package trust implicit. - The workspace explicitly indicates that saved package material feeds follow-up drafting. - Saved material reflects the job’s current stored state, not just the latest generated draft. - Resetting or revisiting the tab preserves the saved package state. ### Edge checks - If one package field is unsaved, only that field should look incomplete; generic notes alone should not make the job appear package-ready. - If the application answer exists, it should come back from saved state rather than disappearing or duplicating. --- ## Test Case 3 — correspondence shows linked-thread continuity in the workspace ### Steps 1. Open the **Correspondence** tab for the same job. 2. Confirm the Gmail connection state is visible. 3. Confirm the linked-thread panel/state is visible in the main workspace. 4. Review the linked-thread count. 5. Click **Refresh linked threads**. ### Expected - The workspace shows Gmail connection status without needing the import modal to explain trust. - If linked Gmail threads already exist, the workspace shows the linked-thread count. - After refresh, the UI reports whether new messages were imported or whether linked threads were already current. - The user is not forced through a full thread re-import flow for a thread that is already linked. ### Edge checks - If no new Gmail messages exist, the refresh should say the linked threads are current rather than failing silently. - If the job has no linked threads, the UI should say so clearly instead of implying a broken refresh. --- ## Test Case 4 — new linked correspondence appears without thread re-import ### Steps 1. Use a job whose recruiter thread has changed since the last import, or create that condition safely before the test. 2. With the same job open in **Correspondence**, trigger **Refresh linked threads**. 3. Review the correspondence timeline/list after refresh. ### Expected - The new inbound or user-sent Gmail message appears in the same job’s correspondence. - The refresh uses the already-linked Gmail thread. - The user does not need to search for and re-import the whole thread manually. ### Edge checks - Duplicate refreshes should not keep importing the same message repeatedly. - Imported message order and thread continuity should still look sensible in the correspondence list. --- ## Test Case 5 — grounded follow-up drafting stays separate from send ### Steps 1. Open the **Follow up** tab for the same job. 2. Review the follow-up context panel. 3. Confirm it references package/correspondence grounding such as thread subject, last activity, or other grounding signals. 4. Click **Regenerate draft** if needed. 5. Review the manual-send boundary panel. 6. Edit the subject/body if desired. 7. **Stop before clicking `Send and log email`** unless outbound mail is confirmed safe. ### Expected - The draft context clearly reflects saved package material and imported correspondence. - Regenerating the draft changes/reloads draft content only; it does not send email. - The manual-send boundary copy clearly states that generation/regeneration never sends recruiter email. - The only outbound action remains the explicit send button. ### Edge checks - If the recruiter email field is blank, drafting should still work; only the manual send step should be blocked or require completion. - Draft review/editing should remain possible without side effects in correspondence. --- ## Test Case 6 — `/dashboard` opens the same job with the same semantics ### Steps 1. Close the workspace. 2. Open `/dashboard`. 3. Find the same job in an attention, readiness, or reminder card. 4. Open the job from the dashboard action. ### Expected - The same job workspace opens. - The opened tab/action meaning matches the job’s workflow need. - Saved package state, linked-thread continuity state, and follow-up context are the same as when the job was opened from `/jobs`. ### Edge checks - The dashboard should not route the same job to a conflicting tab/action compared with `/jobs`. --- ## Test Case 7 — `/reminders` opens the same job with the same semantics ### Steps 1. Close the workspace. 2. Open `/reminders`. 3. Find the same job in its reminder grouping. 4. Open the job from the reminder action. ### Expected - The same job workspace opens. - The same job lands in the same workflow area or equivalent action destination as the other entry points. - Package state, correspondence continuity, and follow-up trust state remain unchanged. ### Edge checks - Reminder grouping should reflect the same workflow classification seen elsewhere, not a conflicting heuristic. --- ## Test Case 8 — optional safe-sink send verification > Run this only if outbound email is confirmed safe. ### Steps 1. Confirm the environment is using a stub mailbox, sink, or other non-production target. 2. In **Follow up**, click `Send and log email`. 3. Re-open **Correspondence** and/or refresh the job state. ### Expected - The outbound action occurs only after the explicit click. - The job history/correspondence reflects the sent follow-up appropriately. - No autonomous send happened before this explicit action. ### Edge checks - If the send endpoint is intentionally stubbed, the UI should still make the boundary clear and report the stubbed result consistently. --- ## Pass Criteria S05 passes UAT when all of the following are true for the same job: - `/jobs`, `/dashboard`, and `/reminders` all open the same job workspace coherently. - Saved package material is visible as reusable workflow state. - Linked-thread continuity is visible in the correspondence workspace. - Refreshing linked threads updates correspondence without requiring re-import of an already-linked thread. - Follow-up drafting is clearly grounded in package + correspondence context. - Draft generation/regeneration never sends email on its own. - No recruiter email is sent unless the human explicitly chooses the send action in a safe environment. ## Failure Clues - Different surfaces route the same job to conflicting next actions. - Generic notes make the job appear package-ready when saved package material is actually missing. - Linked-thread freshness is hidden, ambiguous, or only discoverable through import-only UI. - Refreshing linked threads requires a new full-thread import. - Regenerating a follow-up draft appears coupled to sending. - Workspace state changes depending on whether the job was opened from jobs, dashboard, or reminders.