# TICKET-PMAT-5021: Hook Integration with Gate Executor

**Status**: GREEN
**Priority**: P0
**Complexity**: 5
**Estimated Time**: 2 hours
**Dependencies**: TICKET-PMAT-5005 (pre-commit hooks), TICKET-PMAT-5020 (gate executor)
**Sprint**: Sprint 18 - Quality Gate Automation

## Objective

Integrate the quality gate executor (PMAT-5020) with existing pre-commit hooks (PMAT-5005) to automatically run quality checks before commits. This ensures all commits meet quality standards without manual intervention.

## Success Criteria

- [ ] Update pre-commit hooks to call gate executor
- [ ] Generate hooks with configurable gates
- [ ] Support bypass mechanisms (--no-verify)
- [ ] Fast execution (<30s for most projects)
- [ ] Clear error messages when gates fail
- [ ] All quality gates pass (complexity <10, coverage >80%, no SATD)

## Test Strategy

### Unit Tests
- [ ] `test_generate_hook_with_gates` - Hook script includes gate execution
- [ ] `test_hook_config_serialization` - Config to/from YAML
- [ ] `test_hook_bypass_documentation` - Help text for --no-verify
- [ ] `test_hook_error_formatting` - Clear failure messages

### Property Tests
- [ ] Property: Hook always returns correct exit code
- [ ] Property: Failed gates prevent commit
- [ ] Property: --no-verify always bypasses

### Integration Tests
- [ ] `integration_hook_execution` - Run hook on test project
- [ ] `integration_gate_failure` - Verify commit blocked on failure

## Quality Gates

- [ ] Cyclomatic complexity <10 for all functions
- [ ] Cognitive complexity <15 for all functions
- [ ] Line coverage >80%
- [ ] Branch coverage >80%
- [ ] 0 SATD violations
- [ ] 0 clippy warnings
- [ ] All tests pass

## Implementation Plan

### Phase 1: Enhanced Hook Configuration

```rust
// server/src/scaffold/hooks.rs (extend existing)

use crate::quality::GateConfig;

/// Enhanced hook configuration with quality gates
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnhancedHookConfig {
    /// Base configuration
    pub base: HookConfig,
    /// Quality gate configuration
    pub gates: GateConfig,
    /// Enable fast mode (skip slow gates)
    pub fast_mode: bool,
}

impl Default for EnhancedHookConfig {
    fn default() -> Self {
        Self {
            base: HookConfig {
                project_type: TemplateType::Agent { based_on: AgentFramework::Pforge },
                quality_gates: QualityGateConfig::extreme_tdd(),
            },
            gates: GateConfig {
                run_clippy: true,
                clippy_strict: true,
                run_tests: true,
                test_timeout: 30, // Faster for hooks
                check_coverage: false, // Skip in fast mode
                min_coverage: 80.0,
                check_complexity: false, // Skip in fast mode
                max_complexity: 10,
            },
            fast_mode: true,
        }
    }
}
```

### Phase 2: Enhanced Hook Generation

```rust
/// Generate pre-commit hook with quality gate executor
///
/// # Complexity
/// - Time: O(1)
/// - Cyclomatic: 4
pub fn generate_pre_commit_hook_with_gates(config: &EnhancedHookConfig) -> Result<String> {
    let gate_checks = if config.fast_mode {
        r#"
# Fast mode: Run clippy and tests only
cargo clippy --all-targets --all-features -- -D warnings || exit 1
cargo test --all-features || exit 1
"#
    } else {
        r#"
# Full mode: Run all quality gates via pmat
if command -v pmat &> /dev/null; then
    pmat quality-gates --config .pmat-gates.toml || exit 1
else
    echo "Warning: pmat not found, running basic checks..."
    cargo clippy --all-targets --all-features -- -D warnings || exit 1
    cargo test --all-features || exit 1
fi
"#
    };

    let hook = format!(
        r#"#!/bin/bash
# Pre-commit hook with quality gate executor
# Generated by PMAT ScaffoldEngine
#
# To bypass: git commit --no-verify

set -e

echo "Running pre-commit quality gates..."

{}

echo "✓ All quality gates passed!"
exit 0
"#,
        gate_checks
    );

    Ok(hook)
}
```

### Phase 3: Gate Configuration File

```rust
/// Generate .pmat-gates.toml configuration file
///
/// # Complexity
/// - Time: O(1)
/// - Cyclomatic: 2
pub fn generate_gate_config(gates: &GateConfig) -> Result<String> {
    let toml = format!(
        r#"# PMAT Quality Gate Configuration
# Generated by PMAT ScaffoldEngine

[gates]
run_clippy = {}
clippy_strict = {}
run_tests = {}
test_timeout = {}
check_coverage = {}
min_coverage = {}
check_complexity = {}
max_complexity = {}
"#,
        gates.run_clippy,
        gates.clippy_strict,
        gates.run_tests,
        gates.test_timeout,
        gates.check_coverage,
        gates.min_coverage,
        gates.check_complexity,
        gates.max_complexity
    );

    Ok(toml)
}

/// Install gate configuration file
///
/// # Complexity
/// - Time: O(1)
/// - Cyclomatic: 2
pub fn install_gate_config(project_dir: &Path, config: &GateConfig) -> Result<()> {
    let config_path = project_dir.join(".pmat-gates.toml");
    let toml = generate_gate_config(config)?;
    std::fs::write(&config_path, toml)
        .map_err(ScaffoldError::IoError)?;
    Ok(())
}
```

### Phase 4: Enhanced Scaffold Integration

```rust
// server/src/scaffold/mod.rs (update existing scaffold function)

impl ScaffoldEngine {
    pub fn scaffold(&self, config: ScaffoldConfig) -> Result<PathBuf> {
        // ... existing code ...

        // Install enhanced hooks with quality gates
        let hook_config = EnhancedHookConfig::default();
        self.install_enhanced_hooks(&project_dir, &hook_config)?;

        Ok(project_dir)
    }

    /// Install hooks with quality gate integration
    ///
    /// # Complexity
    /// - Time: O(1)
    /// - Cyclomatic: 3
    fn install_enhanced_hooks(
        &self,
        project_dir: &Path,
        config: &EnhancedHookConfig,
    ) -> Result<()> {
        // Generate and install pre-commit hook
        let pre_commit = generate_pre_commit_hook_with_gates(config)?;
        install_pre_commit_hook(project_dir, &pre_commit)?;

        // Install gate configuration file
        install_gate_config(project_dir, &config.gates)?;

        // Install post-commit hook (already exists from PMAT-5013)
        install_post_commit_hook(project_dir)?;

        Ok(())
    }
}
```

### Phase 5: Tests

```rust
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_generate_hook_with_gates_fast_mode() {
        let config = EnhancedHookConfig {
            base: HookConfig {
                project_type: TemplateType::Agent { based_on: AgentFramework::Pforge },
                quality_gates: QualityGateConfig::default(),
            },
            gates: GateConfig::default(),
            fast_mode: true,
        };

        let hook = generate_pre_commit_hook_with_gates(&config).unwrap();

        assert!(hook.contains("#!/bin/bash"));
        assert!(hook.contains("cargo clippy"));
        assert!(hook.contains("cargo test"));
        assert!(!hook.contains("pmat quality-gates"));
    }

    #[test]
    fn test_generate_hook_with_gates_full_mode() {
        let mut config = EnhancedHookConfig::default();
        config.fast_mode = false;

        let hook = generate_pre_commit_hook_with_gates(&config).unwrap();

        assert!(hook.contains("pmat quality-gates"));
        assert!(hook.contains("--config .pmat-gates.toml"));
    }

    #[test]
    fn test_hook_bypass_documentation() {
        let config = EnhancedHookConfig::default();
        let hook = generate_pre_commit_hook_with_gates(&config).unwrap();

        assert!(hook.contains("--no-verify"));
    }

    #[test]
    fn test_generate_gate_config() {
        let gates = GateConfig {
            run_clippy: true,
            clippy_strict: true,
            run_tests: true,
            test_timeout: 300,
            check_coverage: true,
            min_coverage: 80.0,
            check_complexity: true,
            max_complexity: 10,
        };

        let toml = generate_gate_config(&gates).unwrap();

        assert!(toml.contains("run_clippy = true"));
        assert!(toml.contains("min_coverage = 80"));
        assert!(toml.contains("max_complexity = 10"));
    }

    #[test]
    fn test_install_gate_config() {
        use tempfile::TempDir;

        let temp_dir = TempDir::new().unwrap();
        let gates = GateConfig::default();

        install_gate_config(temp_dir.path(), &gates).unwrap();

        let config_path = temp_dir.path().join(".pmat-gates.toml");
        assert!(config_path.exists());

        let content = std::fs::read_to_string(&config_path).unwrap();
        assert!(content.contains("run_clippy"));
    }

    #[test]
    #[ignore] // Requires git repo
    fn integration_hook_execution() {
        use tempfile::TempDir;
        use std::process::Command;

        let temp_dir = TempDir::new().unwrap();
        let git_dir = temp_dir.path().join(".git/hooks");
        std::fs::create_dir_all(&git_dir).unwrap();

        let config = EnhancedHookConfig::default();
        let hook = generate_pre_commit_hook_with_gates(&config).unwrap();
        install_pre_commit_hook(temp_dir.path(), &hook).unwrap();

        // Try to run the hook (may fail but should execute)
        let result = Command::new("bash")
            .arg(git_dir.join("pre-commit"))
            .current_dir(temp_dir.path())
            .status();

        assert!(result.is_ok());
    }
}
```

## Complexity Analysis

Functions with complexity:
- `generate_pre_commit_hook_with_gates`: CC=4
- `generate_gate_config`: CC=2
- `install_gate_config`: CC=2
- `install_enhanced_hooks`: CC=3

All functions under CC=10 threshold ✓

## Verification Commands

```bash
# Run tests
cargo test --lib scaffold::hooks

# Generate project with hooks
cargo run --bin pmat -- scaffold agent my-test-agent

# Test hook execution
cd my-test-agent && git add . && git commit -m "test"
```

## Files to Create/Modify

### Modified Files
- `server/src/scaffold/hooks.rs` - Add enhanced hook generation
- `server/src/scaffold/mod.rs` - Update scaffold() to use enhanced hooks

## Risk Assessment

**Low Risk:**
- Builds on existing tested hooks
- Backward compatible (fast mode as default)
- Clear bypass mechanism

**Mitigation:**
- Fast mode ensures hooks complete quickly
- Fallback to basic checks if pmat not found
- Clear documentation on --no-verify

## Notes

This ticket connects the quality gate executor (PMAT-5020) with the scaffolding system (Sprint 16), creating an end-to-end quality enforcement pipeline:

1. **Scaffold project** → Generate hooks with gate executor
2. **Developer commits** → Pre-commit hook runs gates
3. **Gates pass** → Commit proceeds
4. **Gates fail** → Commit blocked with clear error message
5. **Post-commit** → Roadmap auto-updated (PMAT-5013)

**Fast mode ensures:**
- Clippy + tests run in <30s
- Coverage/complexity skipped (run in CI)
- Developer productivity maintained

**TDD Cycle Duration**: Estimated 2 hours for RED → GREEN → REFACTOR
