<reasoning_content>
*   Target: Extend a `JobQueue` class.
    *   Method to add: `process_job(job_id: str, Processor: Callable) -> bool`.
    *   Behavior:
        1.  Find `data` from `add_job(job_id, data)`.
        2.  Call `processor(data)`.
        3.  Exception Handling: Retry up to 4 times total (Initial + 3 retries).
        4.  Backoff: Exponential backoff (1s, 2s, 4s) between retries.
        5.  No Sleep: Record delays in the data dictionary instead of actually calling `time.sleep()`.
        6.  Return value: `True` on success, `False` on final failure.
        7.  Constraints: Standard library only. No external packages. Python code only.

    *   I need a base `JobQueue` class to define the structure.
    *   `jobs` attribute: A dictionary mapping `job_id` to `data`.
    *   `add_job` method: Stores the dictionary.
    *   `process_job` method: Implements the logic.

    *   *Iteration:* Loop 4 times.
    *   *Logic inside loop:*
        *   Try `processor(data)`.
        *   If success: `return True`.
        *   If exception:
            *   If it's the last attempt (index 3), return `False`.
            *   Else, calculate backoff (2^attempt).
            *   Update the `data` dictionary with the delay.
            *   Continue loop.

    *   *Backoff Calculation:*
        *   Attempt 0 (Initial): If fail, wait 1s.
        *   Attempt 1 (Retry 1): If fail, wait 2s.
        *   Attempt 2 (Retry 2): If fail, wait 4s.
        *   Attempt 3 (Retry 3): If fail, return False.
        *   Wait sequence: [1, 2, 4].

    *   *Tracking*: "Track the retry count per job". Does this mean a separate counter or adding it to the data dict? The prompt says "record the delays as data". I'll include `retry_count` and `last_delay` in the data dict to be safe, or just the delays as requested.

    *   *Wait, the prompt says "record the delays as data"*: Does it mean the current delay? Yes.

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

        def process_job(self, job_id: str, Processor: Callable[[dict], None]) -> bool:
            if job_id not in self.jobs:
                return False

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

            for attempt in range(max_attempts):
                try:
                    Processor(data)
                    return True
                except Exception:
                    if attempt < max_attempts - 1:
                        delay = backoff_schedule[attempt]
                        data["last_delay"] = delay
                        data["retry_count"] = attempt + 1
                    else:
                        return False
            return False
    ```

    *   "Call `processor(data)` where `data` is the dict passed to `add_job`". Done.
    *   "On any exception ... retry. Make up to 4 total attempts". Done.
    *   "Track the retry count per job". I'll make sure `retry_count` is in the dict.
    *   "Use exponential backoff (delays of 1s, 2s, 4s)". Done.
    *   "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.
    *   "Use only the standard library". Done.
    *   "Write only the Python code, no explanations". Done.

    Wait, let me check the backoff sequence again.
    Attempt 0 (Initial): Fail.
    Retry 1: Delay 1s.
    Retry 2: Delay 2s.
    Retry 3: Delay 4s.
    Fail 4.
    Actually, the prompt says "delays of 1s, 2s, 4s".
    Attempt 0 fails -> Delay 1.
    Attempt 1 fails -> Delay 2.
    Attempt 2 fails -> Delay 4.
    Attempt 3 fails -> No more retries.

    Is the logic `range(4)`?
    i=0: try. fail. delay=backoff[0]=1.
    i=1: try. fail. delay=backoff[1]=2.
    i=2: try. fail. delay=backoff[2]=4.
    i=3: try. fail. return False.

    Yes, that matches.

    One small thing: "Track the retry count per job". Since `data` is modified in place inside `self.jobs`, this persists.

    Let's refine the `JobQueue` definition slightly to make it robust.

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

        def process_job(self, job_id: str, Processor: Callable[[dict], None]) -> bool:
            if job_id not in self.jobs:
                return False

            data = self.jobs[job_id]
            delays = [1, 2, 4]
            
            for i in range(4):
                try:
                    Processor(data)
                    return True
                except Exception:
                    if i < 3:
                        data["retry_count"] = i + 1
                        data["last_delay"] = delays[i]
                    else:
                        return False
            return False
    ```

    Wait, the prompt says "Record the delays as data". I'll just make sure the `retry_count` and `last_delay` are added.

    Actually, I'll keep it clean.

    One detail: "Call `processor(data)` where `data` is the dict passed to `add_job`".
    If the processor modifies `data`, that's fine.

    Final check on "Track the retry count per job".
    If the user calls `process_job` multiple times for the same ID, the `retry_count` should probably reset or continue? Usually, these things are processed once. I'll just let the dictionary store it.

    One edge case: If `job_id` doesn't exist. The prompt doesn't specify, but returning False is standard.

    Python code only. No explanations.

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

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

    Wait, `attempt` 0 is the initial attempt.
    If attempt 0 fails, we want to record the delay for the *next* retry?
    "Use exponential backoff (delays of 1s, 2s, 4s)".
    If attempt 0 fails, delay 1s.
    If attempt 1 fails, delay 2s.
    If attempt 2 fails, delay 4s.
    If attempt 3 fails, return False.

    My code:
    i=0: `attempt < 3` is true. `data["retry_count"] = 1`, `data["last_delay"] = 1`.
    i=1: `attempt < 3` is true. `data["retry_count"] = 2`, `data["last_delay"] = 2`.
    i=2: `attempt < 3` is true. `data["retry_count"] = 3`, `data["last_delay"] = 4`.
    i=3: `attempt < 3` is false. `return False`.

    Wait, the prompt says "Make up to 4 total attempts (initial + 3 retries)".
    If the 3rd retry (which is the 4th attempt total) fails, return False.
    My code handles this correctly.

    One final check: `Processor` type hint. `Callable[[dict], None]` or `Callable[[dict], Any]`. `Any` is safer.

    Wait, "Do NOT actually sleep — record the delays as data". 
    Should I also record the total elapsed time? No, just delays as requested.

    I will structure the code clearly.

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

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

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

            for i in range(4):
                try:
                    Processor(data)
                    return True
                except Exception:
                    if i < 3:
                        data["retry_count"] = i + 1
                        data["last_delay"] = delays[i]
                    else:
                        return False
            return False
    ```
    Actually, `attempt` index logic:
    Attempt 1 (index 0): Fail. `retry_count`=1, `last_delay`=1.
    Attempt 2 (index 1): Fail. `retry_count`=2, ` last_delay`=2.
    Attempt 3 (index 2): Fail. `retry_count`=3, ` last_delay`=4.
    Attempt 4 (index 3): Fail. Return False.

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

    def process_job(self, job_id: str, Processor: Callable[[dict], Any]) -> bool:
        if job_id not in self.jobs:
            return False
        
        data = self.jobs[job_id]
        backoff_delays = [1, 2, 4]
        
        for attempt_idx in range(4):
            try:
                Processor(data)
                return True
            except Exception:
                if attempt_idx < 3:
                    data["retry_count"] = attempt_idx + 1
                    data["last_delay"] = backoff_delays[attempt_idx]
                else:
                    return False
        return False
```
</content>