> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qode.world/llms.txt
> Use this file to discover all available pages before exploring further.

# Interview Process States, Events

> Define how interview events, and system logic determine the interview lifecycle, status transitions, and assessment generation.

## Overview

This document defines the **canonical interview flow** and its associated **event model**. It standardizes how the system tracks interview progress, transitions states, and determines terminal outcomes.

<Info>
  All events in this document are **append-only**, immutable, and ordered by timestamp.
</Info>

## Event Payload & Realtime Interview Status

This section defines the **canonical event payload schema** and the **realtime interview status model**

***

## Event Payload Schema

Every interview-related event MUST conform to the following payload structure.

```json theme={null}
{
  "interviewId": "uniqueId",
  "currentStatus": "INTERVIEW_COMPLETED", // Old status of the interview (SCHEDULED, STARTED, NO_SHOW, CANDIDATE_DROP_OFF, INTERVIEW_COMPLETED, REPORT_GENERATED)
  "jobId": "NON_STEM",
  "candidateEmailId": "joenewsman@gmail.com",
  "timestamp": "2025-12-09T14:46:59Z",
  "roleTitle": "Role Title (from Turing)",
  "eventName": "Event Name (from Qode)",
  "eventValue": "Event Value (from Qode)",
  "realtimeStatus": "INTERVIEW_COMPLETED", // New status of the interview (INTERVIEW_SCHEDULED, INTERVIEW_CREATED, INTERVIEW_GETTING_READY, INTERVIEW_STARTED, INTERVIEW_LOCKED, INTERVIEW_COMPLETED, etc.)
  "isTerminal": true
}
```

***

## Field Definitions

### Core Identifiers

* **`interviewId`**
  Unique identifier for the interview (shared across all attempts). And create another `interviewId` if send the same payload again.

* **`jobId`**
  Interview type: STEM, NON-STEM, SWE, DOCKER, DS

* **`candidateEmailId`**
  Candidate email address used for identification and notifications.

### Event Metadata

* **`eventName`**
  Canonical event name emitted by Qode
  (example: `create_attempt`, `candidate_ready`, `attempt_end`, `abandon`).

* **`eventValue`**
  Optional contextual data for the event
  (example: failure reason, button clicked, system signal).

* **`timestamp`**
  UTC timestamp indicating when the event occurred.

### Realtime State Fields

* **`currentStatus`**
  Old interview status that we don't use anymore in new event flow.
  In the future, we will use `realtimeStatus`.

* **`realtimeStatus`**
  The new **realtime interview status**, derived from the event stream.

* **`isTerminal`**
  Boolean indicating whether the interview can progress further.

#### All Realtime Status Values

| Realtime Status                | Meaning                                  | Terminal |
| ------------------------------ | ---------------------------------------- | -------- |
| `INTERVIEW_SCHEDULED`          | Interview scheduled but not yet accessed | No       |
| `INTERVIEW_CREATED`            | Interview is   created                   | No       |
| `INTERVIEW_GETTING_READY`      | Device checks and warm-up in progress    | No       |
| `INTERVIEW_STARTED`            | Interview actively running with Tracy    | No       |
| `INTERVIEW_LOCKED`             | Interview locked from further actions    | No       |
| `INTERVIEW_COMPLETED`          | Interview finalized and report ready     | Yes      |
| `INTERVIEW_TECH_FAILURE`       | Terminated due to technical failure      | Yes      |
| `INTERVIEW_ABANDONED`          | Candidate disengaged                     | Yes      |
| `INTERVIEW_TIMEOUT`            | Interview expired                        | Yes      |
| `INTERVIEW_CONNECTION_FAILURE` | Network-related termination              | Yes      |

***

## Canonical Event Model

Each row represents a **canonical event** emitted during the interview lifecycle.

| event                   | description                                                                  | frequency                                                                                                                      | semantic\_meaning                                  | real\_time\_status        | is\_terminal | terminal\_reason | what\_comes\_next           | example\_utc\_timestamp |
| ----------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------- | ------------------------- | ------------ | ---------------- | --------------------------- | ----------------------- |
| `create_interview_link` | Return an unique interview\_id                                               | Once                                                                                                                           | Turing sends an API request to create an interview | INTERVIEW\_SCHEDULED      | FALSE        | NONE             | link\_opened                |                         |
|                         |                                                                              |                                                                                                                                |                                                    |                           |              |                  |                             |                         |
| `link_opened`           | Candidate opens interview link and loading the preparing page.               | Once per attempt                                                                                                               | Candidate signals intent to start                  | INTERVIEW\_CREATED        | FALSE        | NONE             | create\_attempt             | 2025-01-14T10:00:05Z    |
| `create_attempt`        | One interview\_id can have multiple attempts                                 | Once per attempt                                                                                                               | System starts a fresh attemp                       | INTERVIEW\_CREATED        | FALSE        | NONE             | start\_device\_check        | 2025-01-14T10:00:12Z    |
| `tracy_joined`          | AI interviewer joins room                                                    | Once per attempt                                                                                                               | Interview context initialized                      | INTERVIEW\_CREATED        | FALSE        | NONE             | independent step in backend | 2025-01-14T10:00:14Z    |
|                         |                                                                              |                                                                                                                                |                                                    |                           |              |                  |                             |                         |
| `has_camera_device`     | Can get candidate's camera device                                            | Send everytime it triggers with UPDATED\_CAMERA\_DEVICE                                                                        | Camera hardware is updated                         | INTERVIEW\_GETTING\_READY | FALSE        | NONE             | device\_check\_passed       | 2025-01-14T10:00:18Z    |
| `has_mic_device`        | Can get candidate's microphone device                                        | Send everytime it triggers with UPDATED\_MICROPHONE\_DEVICE                                                                    | Microphone hardware is updated                     | INTERVIEW\_GETTING\_READY | FALSE        | NONE             | device\_check\_passed       | 2025-01-14T10:00:21Z    |
| `device_check_passed`   | Have camera and microphone permission                                        | Send everytime it triggers when have both camera and mic granted permission                                                    | System confirms technical eligibility              | INTERVIEW\_GETTING\_READY | FALSE        | NONE             | candidate\_ready            | 2025-01-14T10:00:23Z    |
|                         |                                                                              |                                                                                                                                |                                                    |                           |              |                  |                             |                         |
| `candidate_ready`       | Candidate clicks Start Button and can join the meeting room. Log from Tracy. | Send everytime it triggers, candidate can reload and rejoin again                                                              | Candidate explicitly consents to proceed           | INTERVIEW\_GETTING\_READY | FALSE        | NONE             | face\_detected              | 2025-01-14T10:01:10Z    |
| `face_detected`         | Face detected with Tracy present                                             | Send everytime it triggers with enum \[CANDIDATE\_FACE\_IN\_BOX, CANDIDATE\_NO\_FACE\_DETECTED, CANDIDATE\_FACE\_OUTSIDE\_BOX] | Candidate visually present                         | INTERVIEW\_GETTING\_READY | FALSE        | NONE             | speech\_detected            | 2025-01-14T10:01:12Z    |
| `speech_detected`       | Speech detected during warm-up                                               | Once per attempt \[END\_WARM\_UP, ERROR\_IN\_WARM\_UP]                                                                         | Microphone usable for interview                    | INTERVIEW\_GETTING\_READY | FALSE        | NONE             | first\_question             | 2025-01-14T10:01:20Z    |
|                         |                                                                              |                                                                                                                                |                                                    |                           |              |                  |                             |                         |
| `first_question`        | First interview question delivered after warm-up with token start\_interview | Once per attempt when Tracy generates start\_interview                                                                         | Interview content begins                           | INTERVIEW\_STARTED        | FALSE        | NONE             | attempt\_end                | 2025-01-14T10:01:21Z    |
| `attempt_end`           | end\_interview has been generated                                            | Once per attempt when Tracy generates end\_interview                                                                           | Tracy speaks outro and the attempt has concluded   | INTERVIEW\_LOCKED         | FALSE        | NONE             | report\_generated           | 2025-01-14T10:28:40Z    |
| `tracy_left`            | When Tracy left the room                                                     | Once per attempt when Tracy left                                                                                               |                                                    | INTERVIEW\_LOCKED         | FALSE        | NONE             | report\_generated           | 2025-01-14T10:28:45Z    |
|                         |                                                                              |                                                                                                                                |                                                    |                           |              |                  |                             |                         |
| `report_generated`      | Interview marked completed                                                   | Once per attempt                                                                                                               | Successful terminal outcome                        | INTERVIEW\_COMPLETED      | TRUE         | SUCCESS          |                             | 2025-01-14T10:30:00Z    |

***

## Interview Attempt – Event-Driven Swimlane (Happy Path)

<WhimsicalEmbed url="https://whimsical.com/turing-Wq5fT1LbqS4syf5NdKr9AB" />

> **View the interactive flow:**\
> [Interview Event Swimlane Diagram (Whimsical)](https://whimsical.com/turing-Wq5fT1LbqS4syf5NdKr9AB)

An interview attempt progresses through **six ordered phases**, from link access to terminal completion.

1. **Interview Link Exists**
2. **Audio and Video Permissions Screen**
3. **Candidate Clicks Start**
4. **Interview with Tracy**
5. **Interview Ends**
6. **Completed**

Each phase emits **canonical events** that may:

* Update the authoritative interview state
* Trigger downstream processing
* Transition the attempt into a terminal outcome

<Info>
  All interview behavior is driven by events. States are derived from the event stream and are never written directly.
</Info>

***

### Happy Path (Successful Completion)

The happy path represents a **fully completed interview** where the candidate reaches the natural end of the session.

**Key characteristics**

* Tracy completes the interview flow
* `<end_token>` is generated
* The attempt ends normally
* Scoring and finalization proceed

**Canonical events**

* `attempt_end` → Tracy speaks outro and generates `<end_token>`
* `report_generated`

***

## Completed State Rules

Once a `report_generated` event is emitted:

* The interview attempt is **completed**
* All artifacts (transcript, scores, report) are ready
* The interview link **cannot be reused** to create a new attempt

***

## Interview Attempt – Failure & Exit Paths (Non-Happy Path)

This section defines **all failure and early-exit paths** for an interview attempt. These paths represent **terminal conditions** where the interview **cannot continue** and **can be retried** using the same link.

<Info>
  Failure and exit events are authoritative. Once emitted, the interview attempt immediately transitions to a terminal state.
</Info>

***

## Failure & Exit Flow Overview

An interview attempt may terminate from **any active phase**, including:

* Device check failed
* Candidate drops mid-interview
* Interview times out
* Connection failure

Each path emits a **single canonical failure or exit event**, followed by interview finalization when applicable.

***

### Failure & Exit Paths

#### 1. Device Validation Failure

Occurs during device checks when required hardware or permissions are not met.

**Flow**

* Device checks in progress
* Event emitted: `device_check_failed`

***

### 2. Candidate Abandonment

Occurs when the candidate clicks `End Interview` during interview before `attemp_end`.

**Flow**

* Any active step
* Event emitted: `abandon`
* Interview terminates immediately

***

### 3. Interview Expiration (Timeout)

Occurs when the interview exceeds the allowed time window.

**Flow**

* Any active step
* Event emitted: `expire`
* Interview terminates

<Warning>
  - Timeouts are 10 minutes when the meeting is created if candidate doesn't join the room.
</Warning>

***

### 4. Connection Failure

Occurs when the interview session drops due to network issues.

**Flow**

* Any active step
* Event emitted: `connection_failure`
* Interview terminates

<Info>
  Connection failures are classified separately from abandonment for analytics accuracy. If candidate left during the interview without clicking `End Interview`, Tracy will wait 5 minutes before leaving the interview.
</Info>

***

### Canonical Failure & Exit Events

| Event                 | Description                                                                                                              | Semantic Meaning                                | Emitted By      | Client Visible | Authoritative State |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------- | --------------- | -------------- | ------------------- |
| `device_check_failed` | Device validation failed                                                                                                 | Attempt cannot proceed technically              | System          | Yes            | TERMINAL            |
| `abandon`             | Candidate clicks `End Interview` during interview before `attemp_end`                                                    | Candidate purposely wants to end the interview. | System-detected | Yes            | TERMINAL            |
| `expire`              | Candidate doesn't click `Start Interview` button after 10 minues.                                                        | System-enforced timeout                         | System          | Yes            | TERMINAL            |
| `connection_failure`  | Connection failure due to network (candidate left without clicking `End Interview`) and doesn't rejoin within 5 minutes. | Interview interrupted by connectivity loss      | System          | Yes            | TERMINAL            |

***

### Terminal State Rules

Once a failure or exit event is emitted:

* The interview attempt is **irreversibly terminal**
* The interview link **can be reused** to create a new attempt

***

## Retry & New Attempt Creation

This section defines how the system handles **retries** after an interview attempt reaches a terminal outcome.

Retries are **event-driven** and always result in the creation of a **new interview attempt**.

<Info>
  An interview attempt is immutable. Retrying never reopens or modifies a previous attempt.
</Info>

***

## When a Retry Is Allowed

A retry is allowed **only** when the previous attempt ended in a **terminal but retry-eligible state**.

### Retry-Eligible Terminal Outcomes

| Status                         | Retry Allowed | Rationale                                 |
| ------------------------------ | ------------- | ----------------------------------------- |
| `INTERVIEW_TECH_FAILURE`       | Yes           | Candidate was blocked by technical issues |
| `INTERVIEW_CONNECTION_FAILURE` | Yes           | Interview interrupted by network loss     |
| `INTERVIEW_TIMEOUT`            | Yes           | Interview expired before completion       |
| `INTERVIEW_ABANDONED`          | Yes           | Candidate disengaged                      |

### Non-Retryable Terminal Outcomes

| Terminal Reason       | Retry Allowed | Rationale                        |
| --------------------- | ------------- | -------------------------------- |
| `INTERVIEW_COMPLETED` | No            | Interview successfully completed |

<Warning>
  A completed interview can never be retried using the same interview link.
</Warning>

***
