Skip to main content

05 - Human Validation Workflows - Approval and Review Processes

Code review best practices with AI-generated code, checklists, approval workflows, segregation of duties, risk-based review strategy.

What do you think about this article?

At a Glance

Code review best practices with AI-generated code, checklists, approval workflows, segregation of duties, risk-based review strategy.

Human Validation Workflows for AI Code

Quality engineering automation does not eliminate the need for human intervention. Human validation remains the final and irreplaceable filter to ensure that AI-generated code meets business requirements, respects the team's architectural conventions and does not introduce semantic problems that no automated tool can detect.

In this article we will explore how to structure code review workflows, approval gates and pair programming practices specific to AI-generated code, with operational checklists and risk-based strategies to optimize reviewer time.

What You Will Learn

  • Code review best practices specific to AI-generated code
  • Operational checklists for AI code reviewers
  • Approval gates and segregation of duties in the AI context
  • Risk-based strategies for prioritizing review
  • Pair programming with AI: how and when to use it effectively
  • Metrics for measuring validation process effectiveness

Code Review for AI Code: A Different Approach

Reviewing AI-generated code requires a fundamentally different approach from reviewing human code. With human code, the reviewer knows the author's style, habits and weak points. With AI code, the reviewer must face output that may be technically correct but semantically inadequate, structurally complex without reason, or apparently professional while containing subtle defects.

The Three Dimensions of AI Review

AI code review must cover three dimensions that are often overlooked in traditional review:

  • Functional correctness: does the code actually do what it should? AI often satisfies the prompt literally but not the real intent
  • Architectural adequacy: does the code integrate with the existing architecture? AI does not know the project conventions
  • Completeness: is error handling, logging, validation, testing missing? AI tends to produce partial implementations

# Automated checklist for AI code review
class AICodeReviewChecklist:
    """Structured checklist for AI-generated code review"""

    def __init__(self, diff_content, project_config):
        self.diff = diff_content
        self.config = project_config
        self.findings = []

    def run_checklist(self):
        """Runs all checklist controls"""
        checks = [
            self._check_error_handling(),
            self._check_input_validation(),
            self._check_logging(),
            self._check_naming_conventions(),
            self._check_hardcoded_values(),
            self._check_test_coverage(),
            self._check_documentation(),
            self._check_security_patterns(),
            self._check_architecture_fit(),
            self._check_duplication(),
        ]
        return {
            "total_checks": len(checks),
            "passed": sum(1 for c in checks if c["status"] == "PASS"),
            "failed": sum(1 for c in checks if c["status"] == "FAIL"),
            "warnings": sum(1 for c in checks if c["status"] == "WARN"),
            "details": checks,
            "recommendation": self._overall_recommendation(checks)
        }

    def _check_error_handling(self):
        """Verifies presence and quality of error handling"""
        has_try_except = "try:" in self.diff
        has_specific_exceptions = any(
            exc in self.diff for exc in
            ["ValueError", "TypeError", "KeyError", "IOError"]
        )
        has_bare_except = "except:" in self.diff or "except Exception:" in self.diff

        if has_bare_except and not has_specific_exceptions:
            return {"check": "Error Handling", "status": "FAIL",
                    "message": "Only generic exceptions, specific handlers needed"}
        elif not has_try_except:
            return {"check": "Error Handling", "status": "WARN",
                    "message": "No error handling present"}
        return {"check": "Error Handling", "status": "PASS",
                "message": "Adequate error handling"}

    def _check_hardcoded_values(self):
        """Detects hardcoded values that should be configurable"""
        import re
        patterns = [
            r'https?://[^\s"\']+',  # Hardcoded URL
            r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b',  # IP address
            r'port\s*=\s*\d+',      # Hardcoded port
            r'timeout\s*=\s*\d+',   # Hardcoded timeout
        ]
        issues = []
        for pattern in patterns:
            matches = re.findall(pattern, self.diff)
            issues.extend(matches)

        if issues:
            return {"check": "Hardcoded Values", "status": "FAIL",
                    "message": f"Found {len(issues)} hardcoded values"}
        return {"check": "Hardcoded Values", "status": "PASS",
                "message": "No hardcoded values detected"}

    def _overall_recommendation(self, checks):
        """Final recommendation based on results"""
        fails = sum(1 for c in checks if c["status"] == "FAIL")
        if fails == 0:
            return "APPROVE"
        elif fails <= 2:
            return "REQUEST_CHANGES"
        else:
            return "REJECT"
      

Operational Checklist for Reviewers

A structured checklist is the most effective way to ensure consistency in AI code review. Every reviewer must follow the same sequence of checks, reducing the risk of overlooking critical aspects.

Review Checklist for AI-Generated Code

Area Check Priority
Functionality Does the code satisfy task requirements, not just the prompt? Critical
Security No injection, hardcoded secrets, weak auth? Critical
Error handling Specific exceptions, structured logging, recovery? High
Input validation All inputs validated for type, range, format? High
Architecture Consistent with project conventions and patterns? High
Tests Tests present, meaningful and with adequate coverage? High
Duplication Does not duplicate functionality already existing in codebase? Medium
Naming Variables, functions and classes with clear, consistent names? Medium
Configuration No hardcoded values, externalized configuration? Medium
Documentation Docstrings, comments on complex logic, README updated? Low

Approval Gates and Segregation of Duties

For high-risk AI-generated code, a single reviewer may not be sufficient. Approval gates define how many and which approvers are needed based on the risk level of the code, implementing segregation of duties that reduces the risk of superficial approvals.


# Approval gates configuration for AI code
# .github/CODEOWNERS or equivalent configuration

# Risk-based approval rules
approval_rules:
  # AI code touching security: 2 reviewers + security team
  security_critical:
    paths:
      - "src/auth/**"
      - "src/security/**"
      - "src/crypto/**"
    required_approvals: 2
    required_teams: ["security-team"]
    ai_code_extra_review: true

  # AI code in core areas: 2 reviewers
  core_business:
    paths:
      - "src/services/**"
      - "src/models/**"
      - "src/api/**"
    required_approvals: 2
    required_teams: ["backend-team"]

  # AI code in less critical areas: 1 reviewer
  standard:
    paths:
      - "src/utils/**"
      - "src/components/**"
    required_approvals: 1

  # Infrastructure code: ops team mandatory
  infrastructure:
    paths:
      - "docker/**"
      - "k8s/**"
      - ".github/workflows/**"
    required_approvals: 2
    required_teams: ["ops-team"]
      

Risk-Based Review Strategy

Not all AI code requires the same level of scrutiny. A risk-based strategy assigns the review level based on the potential impact of the code, optimizing reviewer time without compromising quality.

  • Critical risk (security, payments, personal data): thorough review with 2+ approvers and mandatory specific tests
  • High risk (core business logic, public APIs): standard review with 2 approvers
  • Medium risk (utilities, UI components, helpers): light review with 1 approver
  • Low risk (documentation, non-critical configuration): auto-approval with automated checks

Pair Programming with AI

Pair programming with AI is a practice where the developer actively collaborates with the AI assistant, guiding code generation step by step rather than accepting complete outputs. This approach drastically reduces defects because the developer maintains control over architecture and design decisions.

Guidelines for Pair Programming with AI

  • Incremental prompts: ask AI to generate one function at a time, not entire modules
  • Immediate review: examine each output before proceeding to the next
  • Explicit context: provide AI with project conventions, available imports and architecture
  • Test first: write tests first and ask AI to generate the implementation
  • Iterative refactoring: after generation, ask AI to optimize, simplify and improve
  • Manual validation: run code locally and verify behavior before committing

When to Use Pair Programming vs Direct Generation

Pair programming with AI is recommended for complex business logic code, integration with existing systems and security-critical areas. Direct generation is acceptable for boilerplate, simple utility functions and configuration code, always with subsequent review.

Validation Process Effectiveness Metrics

To continuously improve the human validation process, it is necessary to measure its effectiveness. Key metrics include the rate of defects intercepted in review, average review time and the ratio between defects found in review and defects escaped to production.

Validation Process KPIs

Metric Target How to Measure
Review Effectiveness >80% Bugs in review / (bugs in review + bugs in prod)
Review Turnaround Time <4 hours Average time from PR opened to approval
Rejection Rate for AI Code 15-25% Rejected AI PRs / total AI PRs
Rework Rate <30% PRs with change requests / total PRs
Escape Rate <5% Prod bugs from approved AI code

Review Workflow Automation

Many aspects of review can be automated to reduce the burden on human reviewers and ensure that basic checks are always performed. Pre-review automated checks filter obvious problems, allowing reviewers to focus on the semantic and architectural aspects that only a human can evaluate.


# Pre-review automation for PRs with AI code
class PreReviewAutomation:
    """Automated checks before human review"""

    def __init__(self, pull_request):
        self.pr = pull_request

    def run_pre_checks(self):
        """Runs all pre-review checks"""
        results = {
            "quality_gate": self._check_quality_gate(),
            "test_coverage": self._check_coverage_threshold(),
            "security_scan": self._check_security_findings(),
            "complexity": self._check_complexity_threshold(),
            "duplication": self._check_duplication_threshold(),
            "ai_metadata": self._check_ai_code_labeling(),
        }

        all_passed = all(r["passed"] for r in results.values())
        return {
            "ready_for_review": all_passed,
            "blocking_issues": [
                k for k, v in results.items() if not v["passed"]
            ],
            "details": results
        }

    def _check_ai_code_labeling(self):
        """Verifies that AI code is properly labeled"""
        # AI-generated files should have a marker
        ai_files = self._detect_ai_generated_files()
        labeled = [f for f in ai_files if self._has_ai_label(f)]
        return {
            "passed": len(labeled) == len(ai_files),
            "message": f"{len(labeled)}/{len(ai_files)} AI files labeled"
        }
      

Conclusions

Human validation remains fundamental in the quality engineering workflow for AI code. No automated tool can replace contextual understanding, architectural judgment and the intuition of an experienced developer. However, the process must be structured, measurable and supported by automation to scale with the volume of AI-generated code.

In the next article we will explore CI/CD guardrails: how to implement automatic quality gates in the pipeline, configure SonarQube for automatic rejection of code that does not meet thresholds, and integrate policy enforcement with tools like OPA and Kyverno.

The goal is not to slow down development with bureaucracy, but to create an efficient validation process that intercepts problems before they become expensive to fix.

Frequently asked questions

What is the main purpose of human validation in AI code quality engineering?

Human validation remains the final and irreplaceable filter to ensure that AI-generated code meets business requirements, respects architectural conventions, and does not introduce semantic problems.

How does reviewing AI-generated code differ from reviewing human-written code?

Reviewing AI-generated code requires a fundamentally different approach because the reviewer must face output that may be technically correct but semantically inadequate or structurally complex without reason.

What are the three dimensions of AI review that are often overlooked in traditional review?

The three dimensions of AI review are operational, approval gates and segregation of duties, and risk-based strategy.

When is pair programming with AI recommended over direct generation of code?

Pair programming with AI is recommended for complex business logic code, integration with existing systems, and security-critical areas.

Sources and further reading

Commenti

Caricamento commenti...

Sign in to comment

Discuss this article in the community

Join the Telegram group to discuss with other developers, ask questions and share your experiences.

Did you like this article?

Explore other content on the blog or discover my projects