# Story 1.22: Integrate or Document Compliance Validation

**Status:** Complete
**Priority:** Low
**Depends on:** None

---

## Context / Background

The GPT-5.2 audit noted that "enterprise" modules appear more aspirational than integrated. Investigation confirms that `compliance.py` validation functions are exported but never called in any runtime path.

**Current state in `packages/fapilog-audit/src/fapilog_audit/compliance.py`:**

```python
def validate_compliance_policy(policy: CompliancePolicy) -> ValidationResult:
    """Validate a CompliancePolicy against baseline enterprise rules."""
    # 70 lines of validation logic
    ...

def validate_data_handling(*, level: ComplianceLevel, settings: DataHandlingSettings) -> ValidationResult:
    """Validate data handling settings against a compliance level."""
    # 60 lines of validation logic
    ...
```

**Usage analysis:**

| Function | Exported | Called in Runtime |
|----------|----------|-------------------|
| `validate_compliance_policy` | Yes (`fapilog_audit/__init__.py`) | **No** |
| `validate_data_handling` | Yes (`fapilog_audit/__init__.py`) | **No** |

**Problem:**

- 185 lines of validation code that's never executed
- Maintenance burden without runtime value
- Confusing for users who expect it to be wired in
- `encrypt_audit_logs` validation requires `True` but encryption isn't implemented (related: Story 4.29)

---

## Scope (In / Out)

### In Scope

- Option A: Integrate compliance validation into `AuditTrail.start()` or `AuditSink.start()`
- Option B: Document as opt-in utility for users to call explicitly
- Update docstrings to clarify usage expectations
- Fix validation rules that reference unimplemented features

### Out of Scope

- Implementing actual encryption (Story 4.29 covers config accuracy)
- Adding new compliance frameworks
- Changing CompliancePolicy structure
- Integration with core fapilog Settings (compliance is now in separate package)

---

## Acceptance Criteria

### AC1: Decision Documented

**Description:** A clear decision is made and documented on integration vs opt-in.

**Validation:**

```markdown
# In docs/architecture/compliance.md or similar
## Compliance Validation

The compliance validation utilities are [integrated/opt-in]...
```

### AC2: If Integrated - Validation Called at Startup

**Description:** `validate_compliance_policy` is called during `AuditTrail.start()` when a policy is provided.

**Validation:**

```python
# In packages/fapilog-audit/src/fapilog_audit/audit.py AuditTrail.start()
from fapilog_audit.compliance import validate_compliance_policy

async def start(self) -> None:
    """Start audit trail processing with policy validation."""
    if self.policy.enabled:
        result = validate_compliance_policy(self.policy)
        if not result.ok:
            import warnings
            for issue in result.issues:
                warnings.warn(
                    f"Compliance: {issue.field} - {issue.message}",
                    UserWarning,
                    stacklevel=2,
                )
    # ... existing start logic ...
```

### AC3: If Opt-In - Exports Clarified

**Description:** Functions remain available but documentation clarifies they're utilities.

**Validation:**

```python
# Docstring updated
def validate_compliance_policy(policy: CompliancePolicy) -> ValidationResult:
    """
    Validate a CompliancePolicy against baseline enterprise rules.

    Note: This is an opt-in utility function. It is NOT automatically
    called during startup. Call it explicitly if you need compliance
    validation for your policies.

    Example:
        from fapilog_audit import validate_compliance_policy, CompliancePolicy, ComplianceLevel

        policy = CompliancePolicy(level=ComplianceLevel.HIPAA, ...)
        result = validate_compliance_policy(policy)
        if not result.ok:
            print(result.issues)
    """
```

### AC4: Validation Rules Updated

**Description:** Validation rules don't require unimplemented features.

**Validation:**

```python
# After Story 4.29, encrypt_audit_logs defaults to False
# Validation should warn, not error, if encryption is disabled
# Or skip encryption check entirely until implemented
```

---

## Implementation Notes

### Option A: Integration (Recommended)

**Pros:**

- Catches misconfigurations early
- Provides value for enterprise users
- Justifies the code's existence

**Cons:**

- May break existing configs that don't meet baseline
- Need to handle encrypt_audit_logs=False gracefully

**Implementation:**

```python
# packages/fapilog-audit/src/fapilog_audit/audit.py - in AuditTrail.start()

from .compliance import validate_compliance_policy

async def start(self) -> None:
    """Start audit trail processing with optional policy validation."""
    # Validate compliance policy if enabled
    if self.policy.enabled:
        comp_result = validate_compliance_policy(self.policy)
        # Use warnings for non-critical issues
        if not comp_result.ok:
            import warnings
            for issue in comp_result.issues:
                warnings.warn(
                    f"Compliance: {issue.field} - {issue.message}",
                    UserWarning,
                    stacklevel=2,
                )

    # Existing start logic...
    if self._processing_task is None or self._processing_task.done():
        self._processing_task = asyncio.create_task(self._process_events())
```

### Option B: Opt-In Documentation

**Pros:**

- No breaking changes
- Simpler implementation

**Cons:**

- Code remains unused
- Users may not discover it

**Implementation:**

- Update docstrings with usage examples
- Add to user guide as "Enterprise Utilities"
- Consider removing from `__all__` to reduce API surface

### File Changes

```text
packages/fapilog-audit/src/fapilog_audit/audit.py (MODIFIED - if integrating)
packages/fapilog-audit/src/fapilog_audit/compliance.py (MODIFIED - update docstrings/rules)
packages/fapilog-audit/docs/enterprise.md (NEW or MODIFIED)
```

---

## Tasks

### Phase 1: Decision

- [ ] Review with stakeholders: integrate vs opt-in
- [ ] Document decision rationale

### Phase 2: Implementation

If integrating:

- [ ] Add compliance validation to `AuditTrail.start()`
- [ ] Handle encrypt_audit_logs=False gracefully (warning, not error)
- [ ] Test with various compliance levels

If opt-in:

- [ ] Update function docstrings with examples
- [ ] Add to fapilog-audit documentation
- [ ] Consider removing from `__all__`

### Phase 3: Documentation

- [ ] Document compliance validation in user guide
- [ ] Update CHANGELOG

---

## Tests

### If Integrating

- `packages/fapilog-audit/tests/test_compliance_validation.py`
  - Test validation called when AuditTrail starts
  - Test warnings for non-critical issues
  - Test errors for critical issues

### If Opt-In

- Existing `packages/fapilog-audit/tests/test_compliance.py` tests sufficient
- Add doctest examples to functions

---

## Definition of Done

### Code Complete

- [ ] Decision made and documented
- [ ] Implementation complete per decision
- [ ] Validation rules don't require unimplemented features

### Quality Assurance

- [ ] All tests pass
- [ ] `ruff check` passes
- [ ] `mypy` passes

### Documentation

- [ ] User guide updated
- [ ] CHANGELOG updated

---

## Risks / Rollback

### Risks

1. **Risk:** Integration breaks existing configurations
   - **Mitigation:** Use warnings for soft requirements; only error on critical

2. **Risk:** Validation rules are too strict
   - **Mitigation:** Start with warnings; tighten over time

### Rollback Plan

If issues occur:

1. Remove validation call from AuditTrail.start()
2. Revert to opt-in approach
3. Document as utility only

---

## Related Stories

- **Related:** Story 4.29 - Audit encryption config accuracy
- **Related:** Story 3.4a - Compliance plugins framework

---

## Code Review

**Date:** 2026-01-18
**Reviewer:** Claude
**Verdict:** OK to PR

### Summary

Reviewed integration of compliance validation into `AuditTrail.start()`. Validation is now automatically called when policy is enabled, emitting warnings for compliance issues. Removed `encrypt_audit_logs` validation since encryption is not yet implemented.

### AC Verification

| Criterion | Evidence |
|-----------|----------|
| AC1: Decision Documented | `docs/architecture/compliance.md:10` - "Decision: Integrated Validation" |
| AC2: Validation Called at Startup | `audit.py:254-268` - calls `validate_compliance_policy` when `policy.enabled` |
| AC3: Docstrings Clarified | `compliance.py:51-86` - explains auto-call + manual usage example |
| AC4: Validation Rules Updated | `compliance.py:105-107, 122-123` - removed `encrypt_audit_logs` checks |

### Quality Gates

- [x] ruff check passed
- [x] ruff format passed
- [x] mypy passed
- [x] diff-cover 100%
- [x] No weak assertions
- [x] No dead code

---

## Change Log

| Date       | Change        | Author |
|------------|---------------|--------|
| 2026-01-18 | Code review passed | Claude |
| 2026-01-16 | Initial draft | Claude |
