<reasoning_content>
*   Extend `JobQueue` class with `process_job(job_id: str, Processor: Callable) -> bool`.
    *   `JobQueue` already has `add_job(job_id, data)`.
    *   `process_job` steps:
        1. Get `data` from `add_job`.
        2. Call `processor(data)`.
        3. Handle exceptions: retry up to 4 times (1 initial + 3 retries).
        4. Track retries per job.
        5. Exponential backoff: 1s, 2s, 4s.
        6. *Crucial*: Do NOT `time.sleep()`. Record delays in the data object.
        7. Return `True` on success, `False` on all failure.
    *   Constraint: Standard library only, no explanations, code only.

    *   `JobQueue` needs a way to store jobs (dictionary).
    *   `add_job(job_id, data)`: Stores `data` in a dict mapping `job_id` to the data.
    *   `process_job(job_id, processor)`:
        *   Retrieve data.
        *   Loop up to 4 times.
        *   Try `processor(data)`.
        *   If success, return `True`.
        *   If exception, check retry count.
        *   Calculate delay: $2^{(retry\_count - 1)}$ where retries starts at 1?
            *   Initial call (attempt 0): No delay.
            *   Retry 1 (attempt 1): Delay 1s.
            *   Retry 2 (attempt 2): Delay 2s.
            *   Retry 3 (attempt 3): Delay 4s.
        *   Update `data` with retry count and `last_delay`.
        *   If reached 4 attempts, return `False`.

    *   The prompt implies `JobQueue` exists. I should provide a base version for context or assume it exists. Since I need to "Extend" it, I'll write the class 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]):
            self.jobs[job_id] = data

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

            data = self.jobs[job_id]
            # Ensure retry tracking exists in the data object
            if "retry_count" not in data:
                data["retry_count"] = 0

            for attempt in range(4):
                try:
                    processor(data)
                    return True
                except Exception:
                    if attempt < 3:
                        # Delays are 1, 2, 4 for retries 1, 2, 3
                        # attempt 0 fails -> next is retry 1 (delay 1)
                        # attempt 1 fails -> next is retry 2 (delay 2)
                        # attempt 2 fails -> next is retry 3 (delay 4)
                        delay = 2**attempt
                        data["retry_count"] = attempt + 1
                        data["last_delay"] = delay
                    else:
                        # All 4 attempts failed
                        return False
            return False
    ```

    *   "Make up to 4 total attempts (initial + 3 retries)."
    *   "Track the retry count per job."
    *   "Use exponential backoff (delays of 1s, 2s, 4s)."
    *   "Do NOT actually sleep — record the delays as data."

    Refining the loop:
    Attempt 0: `processor(data)`. Fail. `retry_count` becomes 1. `last_delay` becomes $2^0 = 1$.
    Attempt 1: `processor(data)`. Fail. `retry_count` becomes 2. `last_delay` becomes $2^1 = 2$.
    Attempt 2: `processor(data)`. Fail. `retry_count` becomes 3. `last_delay` becomes $2^2 = 4$.
    Attempt 3: `processor(data)`. Fail. Max attempts reached. Return False.

    Wait, let's re-read "retry count per job". Should it be inside the data dict? Yes, that's the standard way to "record the delays as data".

    *   `from typing import Callable, Dict, Any`
    *   `class JobQueue:`
    *   `def add_job(...)`
    *   `def process_job(...)`

    Let's double check the logic.
    If `attempt` is 0: fails. `retry_count` = 1, `last_delay` = 1.
    If `attempt` is 1: fails. `retry_count` = 2, `last_delay` = 2.
    If `attempt` is 2: fails. `retry_count` = 3, `last_delay` = 4.
    If `attempt` is 3: fails. Return False.

    This fits the requirement.

    ```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[[Dict[str, Any]], Any]) -> bool:
            if job_id not in self.jobs:
                return False

            data = self.jobs[job_id]
            if "retry_count" not in data:
                data["retry_count"] = 0

            for attempt in range(4):
                try:
                    processor(data)
                    return True
                except Exception:
                    if attempt < 3:
                        # Exponential backoff: 2^0=1, 2^1=2, 2^2=4
                        delay = 2 ** attempt
                        data["retry_count"] = attempt + 1
                        data["last_delay"] = delay
                    else:
                        return False
            return False
    ```

    Wait, the prompt says "Return False if all 4 attempts raise." My loop handles that.
    "Do NOT actually sleep". Check.
    "Track the retry count per job". Check.
    "Return True on the first successful attempt". Check.

    One detail: The prompt says "Extend the JobQueue class". I should provide the class definition.

    One more check on the logic:
    Total attempts: 4.
    Attempt 1 (Index 0): `processor(data)`. If Exception: `retry_count`=1, `delay`=1.
    Attempt 2 (Index 1): `processor(data)`. If Exception: `retry_count`=2, `delay`=2.
    Attempt 3 (Index 2): `processor(data)`. If Exception: `retry_count`=3, `delay`=4.
    Attempt 4 (Index 3): `processor(data)`. If Exception: Return False.

    This is exactly what I wrote.

    Actually, the instruction says "Record the delays as data". I should ensure the data dict is actually modified in place (which it is, because dicts are mutable).

    One minor check: `processor` signature. `processor(data)`.

    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]):
            self.jobs[job_id] = data

        def process_job(self, job_id: str, processor: Callable[[Dict[str, Any]], Any]) -> bool:
            if job_id not in self.jobs:
                return False
            
            data = self.jobs[job_id]
            if "retry_count" not in data:
                data["retry_count"] = 0
            
            for attempt in range(4):
                try:
                    processor(data)
                    return True
                except Exception:
                    if attempt < 3:
                        data["retry_count"] = attempt + 1
                        data["last_delay"] = 2 ** attempt
                    else:
                        return False
            return False
    ```

    Wait, the prompt says "retry count per job". Does it mean the global count of retries or the count for this specific process attempt? "Track the retry count per job" usually refers to the state of the job itself. Since `data` is the payload of the job, putting it there is correct.

    Double check "record the delays as data". I added `last_delay`.

    Is there any ambiguity on "delays of 1s, 2s, 4s"?
    Attempt 1 fails -> Delay 1.
    Attempt 2 fails -> Delay 2.
    Attempt 3 fails -> Delay 4.
    Attempt 4 fails -> Done.
    This is correct.

    Wait, what if `retry_count` is already > 0 because of a previous partial success? The prompt doesn't specify if `process_job` should resume or start fresh. Usually, it starts fresh or assumes the `data` object holds the state. My code starts fresh on the loop but respects existing `retry_count` keys if they exist. If I want to be safe, I should probably initialize it inside the method if it's missing.

    Let's refine the `retry_count` initialization to ensure it doesn't carry over incorrectly if the user wants a fresh start, but the prompt says "Track the retry count per job", implying persistence.

    I'll stick to the logic where it starts at 0 unless already set. Actually, to be safe and clean, I'll just initialize it.

    Wait, "record the delays as data". I'll make sure it's in the dict.

    Final check on requirements:
    - Extend JobQueue: Yes.
    - `process_job` signature correct: Yes.
    - `processor(data)` call: Yes.
    - Exception handling + 4 attempts: Yes.
    - Exponential backoff: Yes.
    - No sleep: Yes.
    - Record delays: Yes.
    - True/False return: Yes.
    - Standard library: Yes.
    - Python code only: Yes.
</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]):
        self.jobs[job_id] = data

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

        data = self.jobs[job_id]
        if "retry_count" not in data:
            data["retry_count"] = 0

        for attempt in range(4):
            try:
                processor(data)
                return True
            except Exception:
                if attempt < 3:
                    # Exponential backoff: 2^0=1, 2^1=2, 2^2=4
                    delay = 2 ** attempt
                    data["retry_count"] = attempt + 1
                    data["last_delay"] = delay
                else:
                    return False
        return False
```
</content>