# Directive: fp_ai_reasoning_trace

**Type**: FP Auxiliary
**Level**: 3 (Medium Priority)
**Parent Directive**: None
**Priority**: LOW - Internal debugging and explainability aid

---

## Purpose

The `fp_ai_reasoning_trace` directive inserts structured trace comments into generated code that document the AI's reasoning process, directive applications, and design decisions. This directive provides **AI explainability** that helps users understand why code was generated in a specific way.

AI reasoning traces provide **transparency and debugging support**, enabling:
- **Explainability**: Document why the AI made specific decisions
- **Directive Traceability**: Show which directives were applied and why
- **Debugging Aid**: Help users understand generated code structure
- **Educational Value**: Teach FP patterns by explaining transformations
- **Audit Trail**: Track AI decision-making for compliance and review

This directive acts as a **documentation layer** that makes AI reasoning visible to human developers.

---

## When to Apply

This directive applies when:
- **Generating new functions** - Add trace comments explaining design choices
- **Refactoring code** - Document which directives triggered changes
- **Complex transformations** - Explain multi-step FP conversions
- **Optimization decisions** - Document why optimizations were applied/skipped
- **Error handling patterns** - Explain monad/Result type choices
- **Called by project directives**:
  - `project_file_write` - Add reasoning traces to generated code
  - Works with all FP directives - Documents directive applications
  - `project_compliance_check` - Log reasoning for compliance decisions

---

## Workflow

### Trunk: insert_trace_annotations

Analyzes generated or refactored code to insert reasoning trace comments documenting AI decisions.

**Steps**:
1. **Identify code sections** - Find functions, transformations, patterns
2. **Query reasoning context** - Retrieve which directives were applied
3. **Check for existing traces** - Detect outdated or missing traces
4. **Generate trace comments** - Create structured reasoning annotations
5. **Insert traces** - Add comments at appropriate locations
6. **Validate formatting** - Ensure traces are readable and consistent

### Branches

**Branch 1: If missing_trace**
- **Then**: `add_reasoning_comment`
- **Details**: Function or code section lacks reasoning trace
  - Identify transformation or pattern applied
  - Query directive application history
  - Generate structured trace comment
  - Insert at function or section start
- **Result**: Returns code with reasoning trace

**Branch 2: If outdated_trace**
- **Then**: `refresh_context`
- **Details**: Existing trace is stale or incomplete
  - Code was refactored but trace not updated
  - Directive application changed
  - Regenerate trace from current context
  - Replace old trace with updated version
- **Result**: Returns code with refreshed trace

**Branch 3: If trace_complete**
- **Then**: `mark_as_traced`
- **Details**: Code already has complete reasoning trace
  - Trace documents all relevant decisions
  - Format is correct and readable
  - No updates needed
- **Result**: Code passes trace check

**Fallback**: `skip_trace`
- **Details**: Trace not applicable or beneficial
  - Trivial function (no reasoning needed)
  - Generated by user (not AI)
  - Trace would add noise
- **Result**: Skip trace insertion

---

## Examples

### ✅ Compliant Code

**Function with Reasoning Trace (Passes):**
```python
def process_users(users: list[dict]) -> list[dict]:
    """
    Process user list to extract adults with valid emails.

    # AIMFP_REASONING_TRACE
    # Applied directives: fp_list_operations, fp_data_filtering
    # Transformation: Imperative loop → filter + map pipeline
    # Reasoning: Replaced mutable accumulator with declarative operations
    # Pure predicates: is_adult, has_valid_email (extracted for reusability)
    # Performance: O(n) single pass with lazy evaluation potential
    """
    return [
        format_user(user)
        for user in users
        if is_adult(user) and has_valid_email(user)
    ]

# Pure helper predicates
def is_adult(user: dict) -> bool:
    """Check if user is 18 or older (pure)."""
    return user.get('age', 0) >= 18

def has_valid_email(user: dict) -> bool:
    """Check if user has valid email format (pure)."""
    email = user.get('email', '')
    return '@' in email and '.' in email.split('@')[1]

def format_user(user: dict) -> dict:
    """Format user data (pure, returns new dict)."""
    return {
        'name': user['name'],
        'email': user['email'],
        'status': 'verified'
    }
```

**Why Compliant**:
- Clear reasoning trace documents transformation
- Shows which directives were applied
- Explains why list comprehension was chosen
- Documents complexity and performance characteristics
- Educational for users learning FP patterns

---

**Complex Refactoring with Trace (Passes):**
```python
def calculate_invoice_total(invoice: dict) -> Result[float, str]:
    """
    Calculate total invoice amount with tax.

    # AIMFP_REASONING_TRACE
    # Applied directives: fp_result_types, fp_error_pipeline, fp_purity
    # Transformation: Exception-based → Result monad error handling
    # Reasoning:
    #   1. Original code used try/except (imperative error handling)
    #   2. Converted to Result type for functional error composition
    #   3. Validation errors return Err() instead of raising exceptions
    #   4. Success path returns Ok() with computed value
    # Error handling: Composable, no exceptions, explicit error types
    # Dependencies: All helper functions are pure (validate_invoice, compute_subtotal)
    """
    # Validate invoice structure
    validation = validate_invoice(invoice)
    if isinstance(validation, Err):
        return validation  # Early return with validation error

    # Compute subtotal from line items
    subtotal_result = compute_subtotal(invoice['items'])
    if isinstance(subtotal_result, Err):
        return subtotal_result  # Propagate calculation error

    # Apply tax rate
    subtotal = subtotal_result.value
    tax_rate = invoice.get('tax_rate', 0.0)
    total = subtotal * (1 + tax_rate)

    return Ok(total)

def validate_invoice(invoice: dict) -> Result[None, str]:
    """
    Validate invoice structure (pure).

    # AIMFP_REASONING_TRACE
    # Applied directives: fp_result_types, fp_purity
    # Reasoning: Validation function returns Result instead of raising
    # Pure: No side effects, deterministic output
    """
    if not invoice:
        return Err("Invoice is empty")
    if 'items' not in invoice or not invoice['items']:
        return Err("Invoice has no items")
    return Ok(None)

def compute_subtotal(items: list[dict]) -> Result[float, str]:
    """
    Compute subtotal from line items (pure).

    # AIMFP_REASONING_TRACE
    # Applied directives: fp_map_reduce, fp_purity
    # Transformation: Mutable accumulator → reduce with pure combiner
    # Reasoning: Eliminated loop with mutable total variable
    """
    try:
        return Ok(sum(item['price'] * item['quantity'] for item in items))
    except (KeyError, TypeError) as e:
        return Err(f"Invalid item format: {e}")
```

**Why Compliant**:
- Multi-level reasoning traces (main function + helpers)
- Documents multi-directive application
- Explains transformation rationale
- Shows error handling strategy
- Traces dependency purity

---

**Optimization Decision Trace (Passes):**
```python
def fibonacci(n: int) -> int:
    """
    Calculate nth Fibonacci number with memoization.

    # AIMFP_REASONING_TRACE
    # Applied directives: fp_purity, fp_memoization, fp_cost_analysis
    # Original complexity: O(2^n) - exponential (naive recursion)
    # Optimized complexity: O(n) - linear (with memoization)
    # Reasoning:
    #   1. fp_cost_analysis detected exponential time complexity
    #   2. Function is pure (deterministic, no side effects)
    #   3. fp_memoization applied @lru_cache for automatic caching
    #   4. Cache is safe: pure function, immutable inputs
    # Performance: 1000x speedup for n > 30
    # Trade-off: O(n) space for cache vs. O(n) stack depth
    """
    @lru_cache(maxsize=None)
    def fib(n: int) -> int:
        if n <= 1:
            return n
        return fib(n - 1) + fib(n - 2)

    return fib(n)
```

**Why Compliant**:
- Documents optimization decision
- Shows before/after complexity analysis
- Explains why memoization was safe to apply
- Documents trade-offs
- Educational value for optimization patterns

---

### ❌ Non-Compliant Code

**Missing Reasoning Trace (Violation):**
```python
# ❌ VIOLATION: No reasoning trace
def process_data(data: list[int]) -> list[int]:
    """Process data."""
    return [x * 2 for x in data if x > 0]

# Problem:
# - No explanation of transformation applied
# - No documentation of which directives were used
# - User doesn't know why comprehension was chosen
# - Educational opportunity missed
```

**Why Non-Compliant**:
- Missing AIMFP_REASONING_TRACE comment
- No directive documentation
- No transformation explanation
- Lacks educational context

**Refactored (Compliant):**
```python
# ✅ REFACTORED: With reasoning trace
def process_data(data: list[int]) -> list[int]:
    """
    Process data: filter positive values and double them.

    # AIMFP_REASONING_TRACE
    # Applied directives: fp_list_operations, fp_data_filtering
    # Transformation: Imperative loop → filter + map comprehension
    # Reasoning: Replaced for-loop with declarative comprehension
    # Pure operations: No mutations, returns new list
    # Pattern: filter (x > 0) then map (x * 2)
    """
    return [x * 2 for x in data if x > 0]
```

---

**Incomplete Trace (Violation):**
```python
# ❌ VIOLATION: Trace too vague
def calculate_total(items: list[dict]) -> float:
    """
    Calculate total.

    # AIMFP_REASONING_TRACE
    # Applied directives: fp_purity
    # Reasoning: Made function pure
    """
    return sum(item['price'] for item in items)

# Problem:
# - Trace too generic (doesn't explain specific transformation)
# - Doesn't mention fp_map_reduce or list operations
# - No complexity or performance notes
# - Doesn't explain why sum() was chosen
```

**Why Non-Compliant**:
- Trace lacks specificity
- Missing relevant directives
- No transformation details
- Not educational

**Refactored (Compliant):**
```python
# ✅ REFACTORED: Detailed trace
def calculate_total(items: list[dict]) -> float:
    """
    Calculate total from item prices.

    # AIMFP_REASONING_TRACE
    # Applied directives: fp_map_reduce, fp_list_operations, fp_purity
    # Transformation: Mutable accumulator loop → built-in sum()
    # Reasoning:
    #   1. Original code used total = 0; for item in items: total += item['price']
    #   2. fp_map_reduce detected simple summation pattern
    #   3. Converted to sum() built-in (more efficient than reduce)
    # Pure: Deterministic, no side effects, no mutations
    # Complexity: O(n) single pass
    """
    return sum(item['price'] for item in items)
```

---

**Outdated Trace (Violation):**
```python
# ❌ VIOLATION: Trace doesn't match current code
def divide(a: float, b: float) -> Result[float, str]:
    """
    Divide two numbers.

    # AIMFP_REASONING_TRACE
    # Applied directives: fp_purity
    # Reasoning: Made function pure by removing print statements
    # Pure: No side effects
    """
    if b == 0:
        return Err("Division by zero")
    return Ok(a / b)

# Problem:
# - Trace mentions removing print statements (not in current code)
# - Doesn't mention fp_result_types directive application
# - Doesn't explain exception → Result transformation
# - Trace is stale from previous version
```

**Why Non-Compliant**:
- Outdated trace (mentions irrelevant changes)
- Missing current directive (fp_result_types)
- Doesn't explain current transformation
- Misleading to users

**Refactored (Compliant):**
```python
# ✅ REFACTORED: Current trace
def divide(a: float, b: float) -> Result[float, str]:
    """
    Divide two numbers safely.

    # AIMFP_REASONING_TRACE
    # Applied directives: fp_result_types, fp_purity
    # Transformation: Exception-based → Result type error handling
    # Reasoning:
    #   1. Original code raised ZeroDivisionError exception
    #   2. fp_result_types converted to Result monad pattern
    #   3. Error case returns Err() with message
    #   4. Success case returns Ok() with result
    # Pure: Deterministic, no exceptions, no side effects
    # Error handling: Composable with flatMap/bind
    """
    if b == 0:
        return Err("Division by zero")
    return Ok(a / b)
```

---

## Edge Cases

### Edge Case 1: Trace Verbosity Balance

**Issue**: Too much trace detail creates noise, too little is not helpful

**Handling**:
```python
# ❌ Too verbose (noise)
def add(a: int, b: int) -> int:
    """
    Add two integers.

    # AIMFP_REASONING_TRACE
    # Applied directives: fp_purity
    # Transformation: None (already pure)
    # Reasoning: Function takes two integers and returns their sum.
    #            This is a pure operation because addition is deterministic.
    #            No side effects occur during execution.
    #            No mutations are performed on inputs.
    #            No external state is accessed.
    #            No I/O operations are performed.
    # Pure: Yes, deterministic output for given inputs
    # Complexity: O(1) constant time
    # Space: O(1) constant space
    """
    return a + b

# Problem: Trace is excessive for trivial function

# ✅ Appropriate (concise for simple function)
def add(a: int, b: int) -> int:
    """
    Add two integers.

    # AIMFP_REASONING_TRACE
    # Pure arithmetic operation - no trace needed
    """
    return a + b

# ✅ Better: Skip trace for trivial functions
def add(a: int, b: int) -> int:
    """Add two integers (pure)."""
    return a + b
```

**Directive Action**: Skip traces for trivial functions (1-2 lines, no transformations).

---

### Edge Case 2: Multi-Directive Application

**Issue**: Function was refactored by multiple directives in sequence

**Handling**:
```python
def process_orders(orders: list[dict]) -> Result[list[dict], str]:
    """
    Process orders: validate, filter paid, enrich with totals.

    # AIMFP_REASONING_TRACE
    # Applied directives (in order):
    #   1. fp_purity - Eliminated global config access, passed as parameter
    #   2. fp_list_operations - Replaced imperative loop with comprehension
    #   3. fp_data_filtering - Extracted pure predicates (is_paid, is_valid)
    #   4. fp_result_types - Converted exception handling to Result type
    #   5. fp_error_pipeline - Chained validation and transformation
    #
    # Transformation sequence:
    #   1. Original: Imperative loop with global state and try/except
    #   2. Step 1: Isolated state (config passed as param)
    #   3. Step 2: Converted loop to list comprehension
    #   4. Step 3: Extracted predicates to named functions
    #   5. Step 4: Replaced exceptions with Result returns
    #   6. Final: Composable, pure, error-safe pipeline
    #
    # Pure: All helper functions are pure, no mutations
    # Error handling: Result type with early return on validation failure
    """
    # Validation
    if not orders:
        return Err("No orders to process")

    # Filter and transform
    paid_orders = [
        enrich_order(order)
        for order in orders
        if is_valid(order) and is_paid(order)
    ]

    return Ok(paid_orders)
```

**Directive Action**: Document sequential directive applications with transformation steps.

---

### Edge Case 3: Performance Trade-offs

**Issue**: Optimization directive applied/skipped based on trade-off analysis

**Handling**:
```python
def find_user(users: list[dict], user_id: int) -> Option[dict]:
    """
    Find user by ID in user list.

    # AIMFP_REASONING_TRACE
    # Applied directives: fp_optionals, fp_purity
    # Optimization decision: fp_memoization NOT applied
    # Reasoning:
    #   1. Function is pure (candidate for memoization)
    #   2. fp_cost_analysis estimated O(n) linear search
    #   3. fp_memoization considered but rejected
    # Why memoization was skipped:
    #   - user_id input space is large (unbounded cache)
    #   - users list is mutable input (unsafe cache key)
    #   - Function called with different user lists (cache thrashing)
    #   - Better optimization: use dict lookup at call site
    # Trade-off: Accepted O(n) search for cache safety
    """
    for user in users:
        if user['id'] == user_id:
            return Some(user)
    return Nothing()
```

**Directive Action**: Document why optimizations were NOT applied (equally important).

---

## Related Directives

- **Depends On**:
  - All FP directives - This directive documents their applications
- **Triggers**: None (passive documentation directive)
- **Called By**:
  - `project_file_write` - Add traces when writing generated code
  - All FP directives - Document their reasoning in traces
- **Escalates To**: None

---

## Helper Functions

Query `get_helpers_for_directive()` to discover this directive's available helpers.
See system prompt for usage.
---

## Database Operations

This directive updates the following tables:

- **`functions`**: Sets `has_reasoning_trace = 1` when trace added
- **`notes`**: Logs reasoning trace with `note_type = 'reasoning_trace'`
- **`notes`**: Stores full trace content for future reference

---

## Testing

How to verify this directive is working:

1. **Generate new function** → Directive adds reasoning trace
   ```python
   # Expected: AIMFP_REASONING_TRACE comment in docstring
   def new_func(...):
       """
       ...
       # AIMFP_REASONING_TRACE
       # Applied directives: ...
       """
   ```

2. **Refactor existing function** → Directive updates trace
   ```python
   # Before: No trace or outdated trace
   # After: Current trace reflecting recent transformation
   ```

3. **Check database** → Verify trace logged
   **Use helper functions** for all project.db operations. Query available helpers.

**IMPORTANT**: Never use direct SQL for project.db - always use helpers or call project directives (like project_file_write).

---

## Common Mistakes

- ❌ **Too verbose traces** - Overwhelming detail for simple functions
- ❌ **Too vague traces** - "Made pure" without explaining how
- ❌ **Outdated traces** - Not updated when code changes
- ❌ **Missing directive list** - Not documenting which directives applied
- ❌ **No transformation explanation** - Not showing before/after patterns

---

## Roadblocks and Resolutions

### Roadblock 1: trace_missing
**Issue**: Generated code lacks reasoning trace
**Resolution**: Insert AIMFP_REASONING_TRACE comment documenting transformation

### Roadblock 2: outdated_trace
**Issue**: Trace references old code or transformations
**Resolution**: Regenerate trace from current directive application context

### Roadblock 3: trace_too_verbose
**Issue**: Trace adds excessive noise to code
**Resolution**: Simplify trace for trivial functions or skip if not beneficial

### Roadblock 4: multi_directive_trace
**Issue**: Multiple directives applied, trace could be complex
**Resolution**: Document directives in application order with transformation steps

---

## References

None
---

*Part of AIMFP v1.0 - FP Auxiliary directive for AI reasoning transparency and explainability*
