<reasoning_content>
*   Class `JobQueue` needs to be extended.
    *   Method: `process_job(job_id: str, processor: Callable) -> bool`.
    *   Functionality:
        1.  Call `processor(data)` where `data` is the value associated with `job_id` in the internal storage.
        2.  On exception: Retry up to 4 total attempts (1 original + 3 retries).
        3.  Track retry count per job.
        4.  Exponential backoff (1s, 2s, 4s).
        5.  Do *not* sleep; record delays in `data`.
        6.  Return `True` on success, `False` if all 4 fail.
    *   Constraint: Use only standard library. Only Python code.

    *   `self.jobs = {}` (to store `job_id: data`).
    *   `self.retry_counts = {}` (to track how many times a job has been retried? Or maybe just the attempts).
    *   Wait, the prompt says "record the delays as data". This implies `data` is modified.
    *   Wait, "record the delays as data" sounds like the delay values should be appended to the `data` dictionary.

    *   `add_job(job_id: str, data: dict)`: Stores `data`.
    *   `process_job(job_id: str, processor: Callable) -> bool`:
        *   Retrieve `data` for `job_id`.
        *   `attempts = 0`
        *   `max_attempts = 4`
        *   Loop:
            *   `attempts += 1`
            *   Try: `processor(data)`
            *   If success, return `True`.
            *   If exception:
                *   If `attempts < max_attempts`:
                    *   Calculate backoff: `2**(attempts - 1)`. Wait, delays are 1s, 2s, 4s.
                    *   Attempt 1 fails -> backoff 1s.
                    *   Attempt 2 fails -> backoff 2s.
                    *   Attempt 3 fails -> backoff 4s.
                    *   Attempt 4 fails -> return `False`.
                    *   Recording delay: `data['delays'].append(delay)`? Or just `data['delay'] = delay`? The prompt says "record the delays as data". I'll use a list `data['delays']` if it exists, otherwise create it, or just append to a key `delays`. Let's assume `data['delays']` is a list.

    *   1st attempt: Fail.
    *   Delay for 2nd attempt: 1s.
    *   2nd attempt: Fail.
    *   Delay for 3rd attempt: 2s.
    *   3rd attempt: Fail.
    *   Delay for 4th attempt: 4s.
    *   4th attempt: Fail.
    *   Total attempts = 4.

    *   `JobQueue` needs to store jobs.
    *   `add_job` implementation.
    *   `process_job` implementation.

    *   The prompt says: "record the delays as data".
    *   If I use `data['delays'].append(delay)`, I need to make sure `data['delays']` is initialized.
    *   "Return False if all 4 attempts raise."

    ```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[str, Any]):
            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]
            max_attempts = 4
            
            for attempt in range(1, max_attempts + 1):
                try:
                    processor(data)
                    return True
                except Exception:
                    if attempt < max_attempts:
                        delay = 2**(attempt - 1)
                        if 'delays' not in data:
                            data['delays'] = []
                        data['delays'].append(delay)
                    else:
                        return False
            return False
    ```

    *   "Track the retry count per job." - The loop variable `attempt` tracks it locally, but maybe it means persistent state? Usually, `process_job` is called once to handle the whole retry logic.
    *   "Do NOT actually sleep — record the delays as data." - Done.
    *   "Return True on the first successful attempt. Return False if all 4 attempts raise." - Done.

    Wait, the prompt says "Track the retry count per job". This could mean an instance variable `self.retries = {}`. But the `process_job` function handles the retries within itself (a loop). If `process_job` is called *one time* for a specific `job_id`, it does the 4 attempts. If it's called multiple times, that's different. The prompt says: "On any exception... retry... Make up to 4 total attempts". This implies the retries happen inside `process_job`.

    Let's re-read: "Extend the JobQueue class with a retry method... Add `process_job(...)`".
    The retry logic is *inside* `process_job`.

    Backoff calculation:
    Attempt 1 fails -> delay 1 (2^0).
    Attempt 2 fails -> delay 2 (2^1).
    Attempt 3 fails -> delay 4 (2^2).
    Attempt 4 fails -> Exit.

    Correct.

    ```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[str, Any]) -> 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
            
            while attempts < max_attempts:
                try:
                    processor(data)
                    return True
                except Exception:
                    attempts += 1
                    if attempts < max_attempts:
                        delay = 2 ** (attempts - 1)
                        if 'delays' not in data:
                            data['delays'] = []
                        data['delays'].append(delay)
                    else:
                        return False
            return False
    ```

    One edge case: If `processor` modifies `data` in a way that causes the next attempt to fail or succeed differently, that's standard.

    Double check: "Track the retry count per job".
    If I am doing all retries within one call of `process_job`, I am tracking it via `attempts`.
    If the prompt meant `process_job` should be called once per attempt, the signature and requirements would be different. The wording "Make up to 4 total attempts" inside `process_job`'s behavior description suggests the loop is inside.

    Final check on constraints:
    - Standard library only? Yes.
    - Write only Python code? Yes.
    - No explanations? Yes.
    - Exponential backoff (1, 2, 4)? Yes.
    - Return True/False correctly? Yes.

    One detail: `data['delays']` should be initialized if it's the first time an exception occurs.

    ```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[str, Any]) -> 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]
            max_attempts = 4
            
            for attempt in range(1, max_attempts + 1):
                try:
                    processor(data)
                    return True
                except Exception:
                    if attempt < max_attempts:
                        delay = 2 ** (attempt - 1)
                        if 'delays' not in data:
                            data['delays'] = []
                        data['delays'].append(delay)
                    else:
                        return False
            return False
    ```
    Wait, the requirement "Track the retry count per job" might imply that the class should know how many times a job has been retried across multiple `process_job` calls. But the instructions say "On any exception... retry... Make up to 4 total attempts". This phrasing is a bit ambiguous, but in the context of a single `process_job` call, a loop is the most logical interpretation.

    Actually, if `process_job` is called, and it fails 4 times, it returns False. If I call `process_job` *again* later, should it start from 0 or continue? "Make up to 4 total attempts" usually implies the lifecycle of the job processing attempt. Given the instruction "On any exception... retry", it implies the retry happens immediately within the function.

    One more thing: "record the delays as data".
    `data['delays'] = [1, 2, 4]`?
    If the first attempt fails, delay is 1.
    If the second attempt fails, delay is 2.
    If the third attempt fails, delay is 4.
    Total 4 attempts.

    If `attempt` is 1 (first try):
    Exception occurs.
    `attempt < 4` is true.
    `delay = 2**(1-1) = 1`.
    `data['delays'] = [1]`.
    Next loop `attempt` is 2.
    Exception occurs.
    `attempt < 4` is true.
    `delay = 2**(2-1) = 2`.
    `data['delays'] = [1, 2]`.
    Next loop `attempt` is 3.
    Exception occurs.
    `attempt < 4` is true.
    `delay = 2**(3-1) = 4`.
    `data['delays'] = [1, 2, 4]`.
    Next loop `attempt` is 4.
    Exception occurs.
    `attempt < 4` is false.
    Return `False`.

    This matches perfectly.

    Final code structure:

    ```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[str, Any]) -> 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]
            max_attempts = 4
            
            for attempt in range(1, max_attempts + 1):
                try:
                    processor(data)
                    return True
                except Exception:
                    if attempt < max_attempts:
                        delay = 2 ** (attempt - 1)
                        if 'delays' not in data:
                            data['delays'] = []
                        data['delays'].append(delay)
                    else:
                        return False
            return False
    ```

    Wait, should I include the `add_job` method in the output? The prompt says "Extend the JobQueue class... Add `process_job`...". Usually, this means I provide the whole class or the extended parts. I'll provide the complete class to ensure it's valid code.

    Also, `Callable` needs to be imported from `typing`. `Dict` and `Any` too.
</reasoning_content>

<content>
```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[str, Any]) -> 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]
        max_attempts = 4
        
        for attempt in range(1, max_attempts + 1):
            try:
                processor(data)
                return True
            except Exception:
                if attempt < max_attempts:
                    delay = 2 ** (attempt - 1)
                    if 'delays' not in data:
                        data['delays'] = []
                    data['delays'].append(delay)
                else:
                    return False
        return False
```
</content>