<reasoning_content>
*   Class: `JobQueue`.
    *   Method to add: `process_job(job_id: str, processor: Callable) -> bool`.
    *   Core logic:
        1.  Retrieve `data` associated with `job_id` (from `add_job`).
        2.  Call `processor(data)`.
        3.  If exception occurs, retry up to 3 times (total 4 attempts).
        4.  Exponential backoff: 1s, 2s, 4s.
        5.  *Constraint*: Do NOT sleep. Record delays in `data` instead.
        6.  Return `True` on success, `False` if all 4 fail.
    *   Requirements: Standard library only, no external packages, no explanations.

    *   `jobs`: A dictionary mapping `job_id` to `data`.

    *   `add_job(self, job_id: str, data: dict)`: To populate the internal state.
    *   `process_job(self, job_id: str, processor: Callable) -> bool`.

    *   Need to store `data` for each `job_id`.
    *   `self.jobs = {}`

    ```python
    def process_job(self, job_id: str, processor: Callable) -> bool:
        data = self.jobs.get(job_id)
        if data is None:
             return False # or raise Error, but usually return False if job doesn't exist

        backoffs = [1, 2, 4]
        for attempt in range(4): # 0, 1, 2, 3
            try:
                processor(data)
                return True
            except Exception:
                if attempt < 3: # If we haven't exhausted all retries
                    delay = backoffs[attempt]
                    data['delay'] = delay # Requirement: "record the delays as data"
                    # Wait, the requirement says "record the delays as data".
                    # Does it mean record the *current* delay or a list?
                    # "record the delays as data" implies adding to the dict.
                    # Let's assume: data['delay'] = delay
                else:
                    return False
    ```

    *   "On any exception from the processor, retry."
    *   "Make up to 4 total attempts (initial + 3 retries)."
    *   "Track the retry count per job." -> The prompt says "Track the retry count per job", but also says "record the delays as data". I should probably add a `retry_count` key to the data dict too.
    *   "Use exponential backoff (delays of 1s, 2s, 4s)."
    *   "Do NOT actually sleep — record the delays as data."

    Let's refine the loop:
    ```python
    for attempt in range(4):
        try:
            processor(data)
            return True
        except Exception:
            if attempt < 3:
                # attempt 0 failed -> retry 1 (delay 1)
                # attempt 1 failed -> retry 2 (delay 2)
                # attempt 2 failed -> retry 3 (delay 4)
                # attempt 3 failed -> fail
                delay = 2**attempt # 1, 2, 4
                data['retry_count'] = attempt + 1
                data['delay'] = delay
            else:
                return False
    ```
    Wait, `2**0 = 1`, `2**1 = 2`, `2**2 = 4`. That works.

    Wait, if I record `retry_count` and `delay` in the dict, I should probably initialize `retry_count` if not present? Or just write it when an exception happens.
    The prompt says "Track the retry count per job".

    Let's re-read: "Track the retry count per job. Use exponential backoff... record the delays as data."

    Implementation:
    ```python
    from typing import Callable, Dict, Any

    class JobQueue:
        def __init__(self):
            self.jobs: Dict[str, Dict[str, Any]] = {}

        def add_job(self, job_id: str, data: dict) -> None:
            self.jobs[job_id] = data

        def process_job(self, job_id: str, processor: Callable) -> bool:
            if job_id not in self.jobs:
                return False

            data = self.jobs[job_id]
            attempts = 0
            max_attempts = 4
            backoffs = [1, 2, 4]

            while attempts < max_attempts:
                try:
                    processor(data)
                    return True
                except Exception:
                    attempts += 1
                    if attempts < max_attempts:
                        delay = backoffs[attempts - 1]
                        data['retry_count'] = attempts
                        data['delay'] = delay
                    else:
                        return False
            return False
    ```

    - `add_job(job_id, data)`: Done.
    - `process_job(job_id, processor)`: Done.
    - Max 4 attempts: Done.
    - Track retry count: Done (`data['retry_count']`).
    - Exponential backoff (1, 2, 4): Done.
    - Do NOT sleep, record delays in data: Done (`data['delay']`).
    - Return True on success, False on total failure: Done.

    Wait, if `processor(data)` is called, and it succeeds on the *first* attempt, I shouldn't have added any `retry_count` or `delay` to the data.
    If it fails on attempt 1:
    - `attempts` becomes 1.
    - `attempts < 4` is True.
    - `delay = backoffs[0]` which is 1.
    - `data['retry_count'] = 1`.
    - `data['delay'] = 1`.
    - Next loop: `attempts` is 1. `processor(data)` called.
    - If it fails again: `attempts` becomes 2. `delay = backoffs[1]` which is 2. `data['retry_count'] = 2`. `data['delay'] = 2`.

    This looks correct.

    - `from typing import Callable, Dict, Any`
    - Class structure.
    - Only Python code.

    One small detail: "Track the retry count per job". This could mean a property of the `JobQueue` instance or the `data` dict. Given the context of "record the delays as data", putting it in the `data` dict is the most consistent approach.

    Also, `processor` takes `data`.

    Final code structure check:
    ```python
    from typing import Callable, Dict, Any

    class JobQueue:
        def __init__(self):
            self.jobs: Dict[str, dict] = {}

        def add_job(self, job_id: str, data: dict) -> None:
            self.jobs[job_id] = data

        def process_job(self, job_id: str, processor: Callable) -> bool:
            if job_id not in self.jobs:
                return False

            data = self.jobs[job_id]
            backoffs = [1, 2, 4]
            
            for attempt in range(4):
                try:
                    processor(data)
                    return True
                except Exception:
                    if attempt < 3:
                        # attempt is 0-indexed: 0, 1, 2
                        # failures at attempt 0, 1, 2 trigger retries
                        data['retry_count'] = attempt + 1
                        data['delay'] = backoffs[attempt]
                    else:
                        return False
            return False
    ```

    If attempt 0 fails: `data['retry_count'] = 1`, `data['delay'] = 1`. Correct.
    If attempt 1 fails: `data['retry_count'] = 2`, `data['delay'] = 2`. Correct.
    If attempt 2 fails: `data['retry_count'] = 3`, `data['delay'] = 4`. Correct.
    If attempt 3 fails: Returns `False`. Correct.

    Wait, the prompt says: "Track the retry count per job". 
    If I use the `data` dict to store it, I am following the instruction "record the delays as data".
    I'll stick to this.

    Final check on types and imports.
    `Callable` needs `from typing import Callable`.

    One minor thought: Should I use `job_id` to track retry count in a separate dict? 
    "Track the retry count per job. ... record the delays as data." 
    If I record `delay` in `data`, it makes sense to record `retry_count` in `data`.

    Let's make sure I don't include any explanations.
</reasoning_content>

<content>
```python
from typing import Callable, Dict, Any

class JobQueue:
    def __init__(self):
        self.jobs: Dict[str, dict] = {}

    def add_job(self, job_id: str, data: dict) -> None:
        self.jobs[job_id] = data

    def process_job(self, job_id: str, processor: Callable) -> bool:
        if job_id not in self.jobs:
            return False

        data = self.jobs[job_id]
        backoffs = [1, 2, 4]
        max_attempts = 4

        for attempt in range(max_attempts):
            try:
                processor(data)
                return True
            except Exception:
                if attempt < max_attempts - 1:
                    data['retry_count'] = attempt + 1
                    data['delay'] = backoffs[attempt]
                else:
                    return False
        return False
```
</content>