<reasoning_content>
*   Extend a `JobQueue` class.
    *   Method: `process_job(job_id: str, processor: Callable) -> bool`.
    *   `processor(data)` is called with `data` stored during `add_job(job_id, data)`.
    *   Retry logic: Up to 4 total attempts (1 initial + 3 retries).
    *   Retry condition: Any exception from `processor`.
    *   Backoff: Exponential (1s, 2s, 4s).
    *   Requirement: Do *not* sleep. Instead, record the delays in `data`.
    *   Return: `True` on success, `False` if all attempts fail.
    *   Constraints: Standard library only, no external packages, code only, no explanations.

    *   Need a way to store jobs: `self.jobs = {}`.
    *   `add_job(job_id: str, data: dict)`: Stores `data` in `self.jobs[job_id]`.
    *   `process_job(job_id: str, processor: Callable) -> bool`:
        *   Retrieve `data` from `self.jobs[job_id]`.
        *   Loop `attempts` from 0 to 3 (total 4).
        *   In the loop:
            *   Try: `processor(data)`. If success, return `True`.
            *   Except:
                *   If `attempts == 3` (last attempt), break and return `False`.
                *   Calculate delay: `2 ** attempts` (1, 2, 4).
                *   Record delay: `data['delay'] = delay`. Wait, "record the delays as data" usually implies adding a key to the dictionary. Let's use a key like `'retry_delay'`.
                *   Continue loop.

    *   How to store delays? "record the delays as data". If multiple retries happen, should I append them or overwrite? Usually, in these types of coding challenges, it means updating the dict so the processor/caller can see it. I'll use `data['delay'] = delay`.

    ```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[[Dict[str, Any]], Any]) -> bool:
            if job_id not in self.jobs:
                return False
            
            data = self.jobs[job_id]
            max_attempts = 4
            
            for attempt in range(max_attempts):
                try:
                    processor(data)
                    return True
                except Exception:
                    if attempt < max_attempts - 1:
                        # Exponential backoff: 1, 2, 4
                        delay = 2 ** attempt
                        data['delay'] = delay
                    else:
                        return False
            return False
    ```

    *   "Make up to 4 total attempts (initial + 3 retries)." -> Loop range(4) covers 0, 1, 2, 3. Correct.
    *   "Track the retry count per job." -> The instructions say "Track the retry count per job" BUT then says "record the delays as data". Usually, "track" might mean internal state, but "record as data" is the action. I'll add a `retry_count` to `data` just in case, or just stick to the delay instruction which is more explicit. Let's look at the delay instruction again: "record the delays as data".
    *   Wait, "Track the retry count per job" - does it mean `data['retry_count']`? I'll add both to be safe, as the prompt asks for both.
    *   "Use exponential backoff (delays of 1s, 2s, 4s)."
        *   Attempt 0 fails -> delay 1s (2^0) -> record delay -> Attempt 1.
        *   Attempt 1 fails -> delay 2s (2^1) -> record delay -> Attempt 2.
        *   Attempt 2 fails -> delay 4s (2^2) -> record delay -> Attempt 3.
        *   Attempt 3 fails -> return False.

    *   Let's refine the `data` updates:
        `data['retry_count'] = attempt + 1`? No, retry count usually starts after first failure.
        If 1st attempt fails: retry 1.
        If 2nd attempt fails: retry 2.
        If 3rd attempt fails: retry 3.

    Actually, looking at the prompt: "Track the retry count per job. Use exponential backoff (delays of 1s, 2s, 4s). Do NOT actually sleep — record the delays as data."
    
    Let's implement exactly that.

    ```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[[Dict[str, Any]], Any]) -> 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)
                        data['retry_count'] = attempts
                        data['delay'] = delay
                    else:
                        return False
            return False
    ```

    Let's re-verify the math.
    Attempt 1 (index 0): Fails. `attempts` becomes 1. `attempts < 4` is True. `delay = 2 ** 0 = 1`. `data['retry_count'] = 1`, `data['delay'] = 1`.
    Attempt 2 (index 1): Fails. `attempts` becomes 2. `attempts < 4` is True. `delay = 2 ** 1 = 2`. `data['retry_count'] = 2`, `data['delay'] = 2`.
    Attempt 3 (index 2): Fails. `attempts` becomes 3. `attempts < 4` is True. `delay = 2 ** 2 = 4`. `data['retry_count'] = 3`, `data['delay'] = 4`.
    Attempt 4 (index 3): Fails. `attempts` becomes 4. `attempts < 4` is False. Returns `False`.

    This matches the requirements.

    *   Only standard library.
    *   No external packages.
    *   Only Python code.
    *   No explanations.

    One detail: the prompt says "Track the retry count per job." This could mean an internal attribute `self.retries = {job_id: count}` or part of the `data`. Given the next sentence says "record the delays as data", it's highly probable they want the metadata inside the dictionary provided to `add_job`.

    Wait, the `processor` signature is `processor(data)`. `data` is the dictionary.

    Final check on "4 total attempts (initial + 3 retries)":
    Attempt 1: Initial
    Attempt 2: Retry 1
    Attempt 3: Retry 2
    Attempt 4: Retry 3
    Total = 4. Matches.

    Wait, the requirement "Track the retry count per job" might imply `self.retries = {}`. But "record the delays as data" is very specific about where the delay goes. I'll put both in `data`.

    ```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[[Dict[str, Any]], Any]) -> bool:
            if job_id not in self.jobs:
                return False
            
            data = self.jobs[job_id]
            for attempt in range(4):
                try:
                    processor(data)
                    return True
                except Exception:
                    if attempt < 3:
                        delay = 2 ** attempt
                        data['retry_count'] = attempt + 1
                        data['delay'] = delay
                    else:
                        return False
            return False
    ```
    Wait, if `attempt` is 0, `2**0` is 1. If `attempt` is 1, `2**1` is 2. If `attempt` is 2, `2**2` is 4.
    If `attempt` is 0 (initial), it failed. `attempt < 3` is true. `delay = 1`. `retry_count = 1`.
    If `attempt` is 1 (1st retry), it failed. `attempt < 3` is true. `delay = 2`. `retry_count = 2`.
    If `attempt` is 2 (2nd retry), it failed. `attempt < 3` is true. `delay = 4`. `retry_count = 3`.
    If `attempt` is 3 (3rd retry), it failed. `attempt < 3` is false. Returns `False`.
    This looks perfect.

    Wait, `retry_count` logic:
    Initial attempt fails -> `retry_count` = 1 (meaning 1st retry is prepared).
    Actually, `retry_count` usually means how many retries *have happened*. 
    If initial fails, it is retry #1.
    If 1st retry fails, it is retry #2.
    If 2nd retry fails, it is retry #3.
    
    Let's refine the variable names and logic slightly to be extremely clean.

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

    class JobQueue:
        def __init__(self):
            self.jobs = {}

        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]
            for attempt in range(4):
                try:
                    processor(data)
                    return True
                except Exception:
                    if attempt < 3:
                        delay = 2 ** attempt
                        data['retry_count'] = attempt + 1
                        data['delay'] = delay
                    else:
                        return False
            return False
    ```

    Wait, one more look: "Track the retry count per job". 
    If I use `data['retry_count']`, it is technically tracking it *within the job's data*.
    If the user wanted `self.retry_counts = {}`, they usually specify "in the class" or "as an attribute". Given the instruction "record the delays as data", keeping metadata in `data` is consistent.

    One final check on the delay: 1, 2, 4.
    `attempt 0` fails -> `2**0` = 1. Correct.
    `attempt 1` fails -> `2**1` = 2. Correct.
    `attempt 2` fails -> `2**2` = 4. Correct.
    `attempt 3` fails -> loop terminates. Correct.

    Is `Callable` imported? Yes, from `typing`.

    Wait, the instructions say: "Extend the JobQueue class". It doesn't provide the base class, so I must provide the whole class including the `add_job` method mentioned in the requirements.

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

    One small edge case: `processor(data)` might modify `data`. That's fine.
    One small edge case: `data` is a dict. If `add_job` is called with a dict, `self.jobs[job_id]` stores a reference to that dict. Modifying `data` inside `process_job` modifies the original dict. This is standard behavior.

    Final check of the requirements:
    1. Call `processor(data)`. Checked.
    2. Retry 4 total attempts. Checked.
    3. Track retry count and use exponential backoff (1, 2, 4). Checked.
    4. Do NOT sleep, record delays in data. Checked.
    5. Return True on success, False on all fails. Checked.
    6. Standard library only. Checked.
    7. Only code, no explanation. Checked.
</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[[Dict[str, Any]], Any]) -> bool:
        if job_id not in self.jobs:
            return False
        
        data = self.jobs[job_id]
        max_attempts = 4
        
        for attempt in range(max_attempts):
            try:
                processor(data)
                return True
            except Exception:
                if attempt < max_attempts - 1:
                    # Exponential backoff: 2^0=1, 2^1=2, 2^2=4
                    delay = 2 ** attempt
                    data['retry_count'] = attempt + 1
                    data['delay'] = delay
                else:
                    return False
        return False
```
</content>