## PRD: Ralph Wiggum Loop Execution

**Project Title:** Ralph Wiggum Loop Execution
**Version:** 1.0
**Date:** 2023-10-27

## 1. Introduction

The "Ralph Wiggum Loop Execution" project aims to provide a simple, configurable, and repeatable execution engine for basic, atomic "Wiggumisms." Inspired by Ralph Wiggum's often circular and repetitive statements, this system will allow users to define a simple action or phrase and execute it in a loop for a specified number of iterations. Each execution will be logged, and a summary of the loop's activity will be provided upon completion. This foundational component is designed to be extensible, allowing for more complex Wiggumisms and potentially parallel execution in future iterations.

## 2. Goals

*   Provide a core loop execution mechanism.
*   Allow configuration of the Wiggumism to be executed and the number of iterations.
*   Log each iteration's activity.
*   Offer a clear execution summary.
*   Establish a robust, testable, and documented codebase.

## 3. Atomic Stories

### Core Implementation Stories (14 stories)

### GPM-001: Establish Initial Project Structure
**Goal:** Create the foundational directory and file structure for the project.
**Acceptance Criteria:**
- A `src/` directory exists for source code.
- A `tests/` directory exists for unit and integration tests.
- A `config/` directory exists for configuration files.
**Files:** `src/`, `tests/`, `config/` (directories)
**Spawns:** First source file, first test file.

### GPM-002: Define `IWiggumism` Interface
**Goal:** Create a conceptual interface (using `typing.Protocol`) for what constitutes a "Wiggumism" that can be executed.
**Acceptance Criteria:**
- A `src/wiggum_core/interfaces.py` file is created.
- It contains a `Protocol` named `IWiggumism` with an abstract `execute` method that takes `iteration_num: int` and returns `str`.
**Files:** `src/wiggum_core/interfaces.py`
**Spawns:** Concrete `SimpleWiggumism` implementation.

### GPM-003: Create Core Loop Module
**Goal:** Create the main module that will house the core loop execution logic.
**Acceptance Criteria:**
- A `src/wiggum_core/loop_executor.py` file is created.
- The file is initially empty or contains a basic docstring.
**Files:** `src/wiggum_core/loop_executor.py`
**Spawns:** Function signature for the loop executor.

### GPM-004: Implement `execute_wiggum_loop` Function Signature
**Goal:** Define the basic function signature for the primary loop execution function.
**Acceptance Criteria:**
- `execute_wiggum_loop` function exists in `loop_executor.py`.
- It accepts an `IWiggumism` object and an integer `loop_count`.
- It currently returns `None`.
**Files:** `src/wiggum_core/loop_executor.py`
**Spawns:** Internal loop logic.

### GPM-005: Implement Basic Loop Counter
**Goal:** Add a basic `for` loop structure to iterate `loop_count` times within `execute_wiggum_loop`.
**Acceptance Criteria:**
- The `execute_wiggum_loop` function contains a `for` loop.
- The loop iterates from `0` to `loop_count - 1`.
- A temporary `pass` statement or print statement indicates the loop body.
**Files:** `src/wiggum_core/loop_executor.py`
**Spawns:** Execution of the Wiggumism inside the loop.

### GPM-006: Execute `IWiggumism` within the Loop
**Goal:** Call the `execute` method of the provided `IWiggumism` object inside each iteration of the loop, passing the current iteration number.
**Acceptance Criteria:**
- Inside the `for` loop in `execute_wiggum_loop`, `wiggumism.execute(i)` is called, where `i` is the current iteration number.
- The function still returns `None`.
**Files:** `src/wiggum_core/loop_executor.py`
**Spawns:** Logging of each execution.

### GPM-007: Implement `SimpleWiggumism` Concrete Class
**Goal:** Create a concrete implementation of `IWiggumism` that simply holds a string and returns a formatted version of it when `execute` is called.
**Acceptance Criteria:**
- A `src/wiggum_core/wiggumisms.py` file is created.
- It contains a class `SimpleWiggumism` that implements `IWiggumism`.
- Its `__init__` takes a `message` string.
- Its `execute` method returns `f"{self.message} (Iteration {iteration_num})"` to standard output.
**Files:** `src/wiggum_core/wiggumisms.py`
**Spawns:** Testing `SimpleWiggumism`.

### GPM-008: Add Basic Logging for Each Iteration
**Goal:** Introduce basic logging (using Python's `logging` module) to record each iteration's output.
**Acceptance Criteria:**
- `logging` module is imported in `loop_executor.py`.
- A logger instance is configured (e.g., basic config for console output).
- The string returned by `wiggumism.execute()` is logged at `INFO` level.
**Files:** `src/wiggum_core/loop_executor.py`
**Spawns:** Refactoring logging configuration.

### GPM-009: Parameterize `loop_count` for `execute_wiggum_loop`
**Goal:** Ensure `loop_count` is properly received and used by `execute_wiggum_loop`.
**Acceptance Criteria:**
- The `execute_wiggum_loop` function correctly uses the `loop_count` parameter to control iterations.
- No hardcoded loop count remains.
**Files:** `src/wiggum_core/loop_executor.py`
**Spawns:** Testing loop count.

### GPM-010: Define `WiggumLoopResult` Data Structure
**Goal:** Create a data class to encapsulate the results and summary of a loop execution.
**Acceptance Criteria:**
- A `src/wiggum_core/results.py` file is created.
- It contains a `dataclass` named `WiggumLoopResult`.
- `WiggumLoopResult` includes fields like `total_iterations_executed` (int), `start_time` (datetime), and `end_time` (datetime).
**Files:** `src/wiggum_core/results.py`
**Spawns:** Returning `WiggumLoopResult` from loop executor.

### GPM-011: Return `WiggumLoopResult` from `execute_wiggum_loop`
**Goal:** Modify `execute_wiggum_loop` to create and return a `WiggumLoopResult` object upon completion.
**Acceptance Criteria:**
- `execute_wiggum_loop` now returns `WiggumLoopResult`.
- The `total_iterations_executed` field is correctly populated with `loop_count`.
- `start_time` and `end_time` are captured using `datetime.now()` and assigned.
**Files:** `src/wiggum_core/loop_executor.py`
**Spawns:** Testing `WiggumLoopResult` integrity.

### GPM-012: Add `iteration_outputs` to `WiggumLoopResult`
**Goal:** Enhance `WiggumLoopResult` to store the output string from each Wiggumism execution.
**Acceptance Criteria:**
- `WiggumLoopResult` in `src/wiggum_core/results.py` gains a new field: `iteration_outputs: List[str]`.
- Each string in the list represents the exact output from `wiggumism.execute()`.
**Files:** `src/wiggum_core/results.py`
**Spawns:** Populating `iteration_outputs` in the loop.

### GPM-013: Populate `iteration_outputs` in `execute_wiggum_loop`
**Goal:** Modify `execute_wiggum_loop` to collect the output string from each iteration and store it in `WiggumLoopResult`.
**Acceptance Criteria:**
- Inside the loop, the string returned by `wiggumism.execute()` is stored in a list.
- This list is then assigned to `WiggumLoopResult.iteration_outputs`.
**Files:** `src/wiggum_core/loop_executor.py`
**Spawns:** Verification of collected iteration outputs.

### GPM-014: Add `wiggumism_name` to `WiggumLoopResult`
**Goal:** Include the name or type of the executed Wiggumism in the `WiggumLoopResult` for better reporting.
**Acceptance Criteria:**
- `WiggumLoopResult` gains a `wiggumism_name: str` field.
- This field is populated with the `__class__.__name__` of the `IWiggumism` instance passed to `execute_wiggum_loop`.
**Files:** `src/wiggum_core/loop_executor.py`, `src/wiggum_core/results.py`
**Spawns:** CLI display of Wiggumism name.

### Test/Verification Stories (6 stories)

### GPM-015: Unit Test for `SimpleWiggumism` Execution
**Goal:** Verify that `SimpleWiggumism` correctly formats and returns its message when executed.
**Acceptance Criteria:**
- A `tests/unit/test_wiggumisms.py` file is created.
- It contains a test function that instantiates `SimpleWiggumism`.
- It asserts that the `execute` method returns the expected formatted string for a given iteration number.
**Files:** `tests/unit/test_wiggumisms.py`
**Spawns:** More complex Wiggumism tests.

### GPM-016: Unit Test for `execute_wiggum_loop` - Basic Count
**Goal:** Verify that `execute_wiggum_loop` runs for the specified number of iterations.
**Acceptance Criteria:**
- A `tests/unit/test_loop_executor.py` file is created.
- It contains a test function that calls `execute_wiggum_loop` with a mock `IWiggumism`.
- It asserts that the mock `IWiggumism.execute` method was called `loop_count` times.
**Files:** `tests/unit/test_loop_executor.py`
**Spawns:** Testing `WiggumLoopResult` values.

### GPM-017: Unit Test for `WiggumLoopResult` Integrity
**Goal:** Verify that the `WiggumLoopResult` returned by `execute_wiggum_loop` contains correct data.
**Acceptance Criteria:**
- A test function in `tests/unit/test_loop_executor.py` calls `execute_wiggum_loop`.
- It asserts that `total_iterations_executed` matches the input `loop_count`.
- It asserts that `start_time` is before `end_time`.
- It asserts that `wiggumism_name` is correctly populated.
**Files:** `tests/unit/test_loop_executor.py`
**Spawns:** Testing `iteration_outputs`.

### GPM-018: Unit Test for `WiggumLoopResult` `iteration_outputs`
**Goal:** Verify that the `iteration_outputs` list in `WiggumLoopResult` is correctly populated.
**Acceptance Criteria:**
- A test function in `tests/unit/test_loop_executor.py` calls `execute_wiggum_loop`.
- It asserts that the `iteration_outputs` list has `loop_count` entries.
- It asserts that the content of the entries matches the expected format from `SimpleWiggumism`.
**Files:** `tests/unit/test_loop_executor.py`
**Spawns:** Integration tests for the full system.

### GPM-019: Integration Test: Full Loop Execution with Logging
**Goal:** Verify that the entire loop execution process, including logging, works as expected.
**Acceptance Criteria:**
- A `tests/integration/test_full_execution.py` file is created.
- It calls `execute_wiggum_loop` with `SimpleWiggumism`.
- It captures log output (e.g., using `caplog` if pytest, or `logging.handlers.MemoryHandler`).
- It asserts that log messages for each iteration are present and correctly formatted.
**Files:** `tests/integration/test_full_execution.py`
**Spawns:** CLI integration test.

### GPM-020: Unit Test: Edge Case for Loop Count (Zero)
**Goal:** Verify that `execute_wiggum_loop` handles a `loop_count` of 0 gracefully.
**Acceptance Criteria:**
- A test function in `tests/unit/test_loop_executor.py` calls `execute_wiggum_loop` with `loop_count=0`.
- It asserts that `total_iterations_executed` is 0.
- It asserts that `iteration_outputs` is an empty list.
- It asserts that the mock `IWiggumism.execute` method was *not* called.
**Files:** `tests/unit/test_loop_executor.py`
**Spawns:** Negative testing for invalid loop counts.

### Documentation/Configuration Stories (4 stories)

### GPM-021: Create `README.md` with Project Overview
**Goal:** Provide a basic `README.md` file explaining the project's purpose and how to get started.
**Acceptance Criteria:**
- A `README.md` file is created at the project root.
- It contains a title, a brief description of the Ralph Wiggum Loop, and basic setup instructions.
**Files:** `README.md`
**Spawns:** Detailed usage instructions in README.

### GPM-022: Add Basic Docstrings to Core Modules
**Goal:** Add docstrings to the `IWiggumism` interface, `SimpleWiggumism` class, `WiggumLoopResult` dataclass, and `execute_wiggum_loop` function.
**Acceptance Criteria:**
- `src/wiggum_core/interfaces.py`, `src/wiggum_core/wiggumisms.py`, `src/wiggum_core/results.py`, and `src/wiggum_core/loop_executor.py` have appropriate class/function-level docstrings.
- Docstrings explain the purpose, parameters, and return values.
**Files:** `src/wiggum_core/interfaces.py`, `src/wiggum_core/wiggumisms.py`, `src/wiggum_core/results.py`, `src/wiggum_core/loop_executor.py`
**Spawns:** More detailed docstrings and Sphinx documentation.

### GPM-023: Create `default.ini` for Configuration
**Goal:** Establish a default configuration file for loop parameters.
**Acceptance Criteria:**
- A `config/default.ini` file is created.
- It contains a `[loop]` section with `default_wiggumism_message` and `default_loop_count` keys.
- Values are set to reasonable defaults (e.g., "I'm a unit!", 3).
**Files:** `config/default.ini`
**Spawns:** Configuration loading logic.

### GPM-024: Implement Configuration Loading for Loop Parameters
**Goal:** Add functionality to load default loop parameters from `default.ini`.
**Acceptance Criteria:**
- A `src/wiggum_core/config.py` file is created.
- It contains a function `load_config` that uses `configparser` to read `default.ini`.
- `load_config` returns a dictionary or object containing the loaded parameters.
**Files:** `src/wiggum_core/config.py`
**Spawns:** Integration of config into CLI.

### Integration Stories (7 stories)

### GPM-025: Create `cli.py` for Command-Line Interface
**Goal:** Set up the entry point for command-line execution.
**Acceptance Criteria:**
- A `src/cli.py` file is created.
- It contains a `main` function.
- It imports `argparse` but does not yet define arguments.
**Files:** `src/cli.py`
**Spawns:** Argument parsing for Wiggumism message.

### GPM-026: Implement `argparse` for Wiggumism Message
**Goal:** Add a command-line argument to specify the Wiggumism message.
**Acceptance Criteria:**
- `src/cli.py` uses `argparse` to define a `--message` argument (string).
- The `main` function can parse this argument.
- A default message is used if `--message` is not provided.
**Files:** `src/cli.py`
**Spawns:** Argument parsing for loop count.

### GPM-027: Implement `argparse` for Loop Count
**Goal:** Add a command-line argument to specify the number of loop iterations.
**Acceptance Criteria:**
- `src/cli.py` uses `argparse` to define a `--count` argument (integer).
- The `main` function can parse this argument.
- A default count is used if `--count` is not provided.
**Files:** `src/cli.py`
**Spawns:** Calling the loop executor from CLI.

### GPM-028: Call `execute_wiggum_loop` from `cli.py`
**Goal:** Integrate the core loop execution into the CLI.
**Acceptance Criteria:**
- `src/cli.py` imports `execute_wiggum_loop` and `SimpleWiggumism`.
- The `main` function instantiates `SimpleWiggumism` with the parsed message and calls `execute_wiggum_loop` with the parsed count.
**Files:** `src/cli.py`
**Spawns:** Displaying results in CLI.

### GPM-029: Display `WiggumLoopResult` Summary in CLI
**Goal:** Print a user-friendly summary of the loop execution results to the console.
**Acceptance Criteria:**
- The `main` function in `src/cli.py` receives the `WiggumLoopResult`.
- It prints `wiggumism_name`, `total_iterations_executed`, and the `start_time`/`end_time` in a readable format.
**Files:** `src/cli.py`
**Spawns:** Displaying iteration details.

### GPM-030: Integrate Config Loading into `cli.py`
**Goal:** Allow CLI arguments to override, but fall back to, configuration file defaults.
**Acceptance Criteria:**
- `src/cli.py` imports `load_config` from `src/wiggum_core/config.py`.
- Default values for `--message` and `--count` in `argparse` are loaded from the config.
- CLI arguments still take precedence over config defaults.
**Files:** `src/cli.py`
**Spawns:** Robust error handling in CLI.

### GPM-031: Implement Basic Error Handling in CLI
**Goal:** Add basic error handling for invalid input types (e.g., non-integer `loop_count`).
**Acceptance Criteria:**
- `src/cli.py` wraps the argument parsing and loop execution in a `try-except` block.
- It catches `ValueError` for incorrect types and prints a user-friendly error message before exiting with a non-zero status.
**Files:** `src/cli.py`
**Spawns:** More specific error types.

### Optimization Stories (4 stories)

### GPM-032: Refactor Logging to Use a Dedicated Logger Instance
**Goal:** Improve logging by using a named logger instance and centralizing basic logging configuration.
**Acceptance Criteria:**
- A `src/wiggum_core/logger_config.py` file is created with a function to set up basic logging (e.g., formatter, handler).
- `src/wiggum_core/loop_executor.py` obtains a named logger instance (`logging.getLogger(__name__)`) and uses it.
- `src/cli.py` also calls the logger configuration.
**Files:** `src/wiggum_core/loop_executor.py`, `src/wiggum_core/logger_config.py`, `src/cli.py`
**Spawns:** Advanced logging features (e.g., file output).

### GPM-033: Add Optional Iteration Delay
**Goal:** Introduce an optional delay between loop iterations to simulate processing time or for demonstration.
**Acceptance Criteria:**
- `execute_wiggum_loop` accepts an optional `delay_seconds: float` parameter (default 0).
- If `delay_seconds > 0`, `time.sleep(delay_seconds)` is called at the end of each iteration.
- `src/cli.py` adds an optional `--delay` argument (float) which is passed to the loop executor and configured via `default.ini`.
**Files:** `src/wiggum_core/loop_executor.py`, `src/cli.py`, `config/default.ini`
**Spawns:** Performance profiling.

### GPM-034: Ensure `WiggumLoopResult` Immutability
**Goal:** Make the `WiggumLoopResult` dataclass immutable to prevent accidental modification after creation.
**Acceptance Criteria:**
- `WiggumLoopResult` in `src/wiggum_core/results.py` is defined with `frozen=True`.
- All fields are correctly initialized during creation and cannot be changed afterward.
**Files:** `src/wiggum_core/results.py`
**Spawns:** Defensive programming for Wiggumism state.

### GPM-035: Implement `reset` Method for `IWiggumism`
**Goal:** Introduce a `reset` method to the `IWiggumism` interface, allowing Wiggumisms with internal state to be reset between loop runs or before a new loop.
**Acceptance Criteria:**
- `IWiggumism` in `src/wiggum_core/interfaces.py` gains an abstract `reset()` method.
- `SimpleWiggumism` in `src/wiggum_core/wiggumisms.py` implements `reset()` as a no-op (since it has no state).
**Files:** `src/wiggum_core/interfaces.py`, `src/wiggum_core/wiggumisms.py`
**Spawns:** Wiggumisms with internal state that utilize `reset()`.