Skip to main content

Integration Checker Agent

The integration checker agent verifies that phases work together as a system, not just individually.

Purpose

Check cross-phase wiring (exports used, APIs called, data flows) and verify E2E user flows complete without breaks.
Critical mindset: Individual phases can pass while the system fails. A component can exist without being imported. An API can exist without being called. Focus on connections, not existence.

When Invoked

Spawned by milestone auditor during /gsd:audit-milestone.

Core Principle

Existence ≠ Integration Integration verification checks connections:
  1. Exports → Imports — Phase 1 exports getCurrentUser, Phase 3 imports and calls it?
  2. APIs → Consumers/api/users route exists, something fetches from it?
  3. Forms → Handlers — Form submits to API, API processes, result displays?
  4. Data → Display — Database has data, UI renders it?
A “complete” codebase with broken wiring is a broken product.

What It Does

1. Build Export/Import Map

For each phase, extract what it provides and what it should consume. From SUMMARYs, extract:
# Key exports from each phase
for summary in .planning/phases/*/*-SUMMARY.md; do
  echo "=== $summary ==="
  grep -A 10 "Key Files\|Exports\|Provides" "$summary" 2>/dev/null
done
Build provides/consumes map:
Phase 1 (Auth):
  provides: getCurrentUser, AuthProvider, useAuth, /api/auth/*
  consumes: nothing (foundation)

Phase 2 (API):
  provides: /api/users/*, /api/data/*, UserType, DataType
  consumes: getCurrentUser (for protected routes)

Phase 3 (Dashboard):
  provides: Dashboard, UserCard, DataList
  consumes: /api/users/*, /api/data/*, useAuth

2. Verify Export Usage

For each phase’s exports, verify they’re imported and used. Check imports:
check_export_used() {
  local export_name="$1"
  local source_phase="$2"
  local search_path="${3:-src/}"

  # Find imports
  local imports=$(grep -r "import.*$export_name" "$search_path" \
    --include="*.ts" --include="*.tsx" 2>/dev/null | \
    grep -v "$source_phase" | wc -l)

  # Find usage (not just import)
  local uses=$(grep -r "$export_name" "$search_path" \
    --include="*.ts" --include="*.tsx" 2>/dev/null | \
    grep -v "import" | grep -v "$source_phase" | wc -l)

  if [ "$imports" -gt 0 ] && [ "$uses" -gt 0 ]; then
    echo "CONNECTED ($imports imports, $uses uses)"
  elif [ "$imports" -gt 0 ]; then
    echo "IMPORTED_NOT_USED ($imports imports, 0 uses)"
  else
    echo "ORPHANED (0 imports)"
  fi
}

3. Verify API Coverage

Check that API routes have consumers. Find all API routes:
# Next.js App Router
find src/app/api -name "route.ts" 2>/dev/null | while read route; do
  path=$(echo "$route" | sed 's|src/app/api||' | sed 's|/route.ts||')
  echo "/api$path"
done
Check each route has consumers:
check_api_consumed() {
  local route="$1"
  local search_path="${2:-src/}"

  # Search for fetch/axios calls to this route
  local fetches=$(grep -r "fetch.*['\"]$route\|axios.*['\"]$route" "$search_path" \
    --include="*.ts" --include="*.tsx" 2>/dev/null | wc -l)

  if [ "$total" -gt 0 ]; then
    echo "CONSUMED ($total calls)"
  else
    echo "ORPHANED (no calls found)"
  fi
}

4. Verify Auth Protection

Check that routes requiring auth actually check auth. Find protected route indicators:
# Routes that should be protected (dashboard, settings, user data)
protected_patterns="dashboard|settings|profile|account|user"

# Find components/pages matching these patterns
grep -r -l "$protected_patterns" src/ --include="*.tsx" 2>/dev/null
Check auth usage in protected areas:
check_auth_protection() {
  local file="$1"

  # Check for auth hooks/context usage
  local has_auth=$(grep -E "useAuth|useSession|getCurrentUser|isAuthenticated" "$file" 2>/dev/null)

  # Check for redirect on no auth
  local has_redirect=$(grep -E "redirect.*login|router.push.*login|navigate.*login" "$file" 2>/dev/null)

  if [ -n "$has_auth" ] || [ -n "$has_redirect" ]; then
    echo "PROTECTED"
  else
    echo "UNPROTECTED"
  fi
}

5. Verify E2E Flows

Derive flows from milestone goals and trace through codebase.
verify_auth_flow() {
  echo "=== Auth Flow ==="

  # Step 1: Login form exists
  local login_form=$(grep -r -l "login\|Login" src/ --include="*.tsx" 2>/dev/null | head -1)
  [ -n "$login_form" ] && echo "✓ Login form: $login_form" || echo "✗ Login form: MISSING"

  # Step 2: Form submits to API
  if [ -n "$login_form" ]; then
    local submits=$(grep -E "fetch.*auth|axios.*auth|/api/auth" "$login_form" 2>/dev/null)
    [ -n "$submits" ] && echo "✓ Submits to API" || echo "✗ Form doesn't submit to API"
  fi

  # Step 3: API route exists
  local api_route=$(find src -path "*api/auth*" -name "*.ts" 2>/dev/null | head -1)
  [ -n "$api_route" ] && echo "✓ API route: $api_route" || echo "✗ API route: MISSING"

  # Step 4: Redirect after success
  if [ -n "$login_form" ]; then
    local redirect=$(grep -E "redirect|router.push|navigate" "$login_form" 2>/dev/null)
    [ -n "$redirect" ] && echo "✓ Redirects after login" || echo "✗ No redirect after login"
  fi
}
verify_data_flow() {
  local component="$1"
  local api_route="$2"
  local data_var="$3"

  echo "=== Data Flow: $component$api_route ==="

  # Step 1: Component exists
  local comp_file=$(find src -name "*$component*" -name "*.tsx" 2>/dev/null | head -1)
  [ -n "$comp_file" ] && echo "✓ Component: $comp_file" || echo "✗ Component: MISSING"

  if [ -n "$comp_file" ]; then
    # Step 2: Fetches data
    local fetches=$(grep -E "fetch|axios|useSWR|useQuery" "$comp_file" 2>/dev/null)
    [ -n "$fetches" ] && echo "✓ Has fetch call" || echo "✗ No fetch call"

    # Step 3: Has state for data
    local has_state=$(grep -E "useState|useQuery|useSWR" "$comp_file" 2>/dev/null)
    [ -n "$has_state" ] && echo "✓ Has state" || echo "✗ No state for data"

    # Step 4: Renders data
    local renders=$(grep -E "\{.*$data_var.*\}|\{$data_var\." "$comp_file" 2>/dev/null)
    [ -n "$renders" ] && echo "✓ Renders data" || echo "✗ Doesn't render data"
  fi

  # Step 5: API route exists and returns data
  local route_file=$(find src -path "*$api_route*" -name "*.ts" 2>/dev/null | head -1)
  [ -n "$route_file" ] && echo "✓ API route: $route_file" || echo "✗ API route: MISSING"

  if [ -n "$route_file" ]; then
    local returns_data=$(grep -E "return.*json|res.json" "$route_file" 2>/dev/null)
    [ -n "$returns_data" ] && echo "✓ API returns data" || echo "✗ API doesn't return data"
  fi
}

6. Compile Integration Report

Structure findings for milestone auditor. Wiring status:
wiring:
  connected:
    - export: "getCurrentUser"
      from: "Phase 1 (Auth)"
      used_by: ["Phase 3 (Dashboard)", "Phase 4 (Settings)"]

  orphaned:
    - export: "formatUserData"
      from: "Phase 2 (Utils)"
      reason: "Exported but never imported"

  missing:
    - expected: "Auth check in Dashboard"
      from: "Phase 1"
      to: "Phase 3"
      reason: "Dashboard doesn't call useAuth or check session"
Flow status:
flows:
  complete:
    - name: "User signup"
      steps: ["Form", "API", "DB", "Redirect"]

  broken:
    - name: "View dashboard"
      broken_at: "Data fetch"
      reason: "Dashboard component doesn't fetch user data"
      steps_complete: ["Route", "Component render"]
      steps_missing: ["Fetch", "State", "Display"]

What It Produces

Integration Report

## Integration Check Complete

### Wiring Summary

**Connected:** {N} exports properly used
**Orphaned:** {N} exports created but unused
**Missing:** {N} expected connections not found

### API Coverage

**Consumed:** {N} routes have callers
**Orphaned:** {N} routes with no callers

### Auth Protection

**Protected:** {N} sensitive areas check auth
**Unprotected:** {N} sensitive areas missing auth

### E2E Flows

**Complete:** {N} flows work end-to-end
**Broken:** {N} flows have breaks

### Detailed Findings

#### Orphaned Exports

{List each with from/reason}

#### Missing Connections

{List each with from/to/expected/reason}

#### Broken Flows

{List each with name/broken_at/reason/missing_steps}

#### Unprotected Routes

{List each with path/reason}

#### Requirements Integration Map

| Requirement | Integration Path | Status | Issue |
|-------------|-----------------|--------|-------|
| {REQ-ID} | {Phase X export → Phase Y import → consumer} | WIRED / PARTIAL / UNWIRED | {specific issue or "—"} |

**Requirements with no cross-phase wiring:**
{List REQ-IDs that exist in a single phase with no integration touchpoints}

Critical Rules

Check connections, not existence. Files existing is phase-level. Files connecting is integration-level.Trace full paths. Component → API → DB → Response → Display. Break at any point = broken flow.Check both directions. Export exists AND import exists AND import is used AND used correctly.Be specific about breaks. “Dashboard doesn’t work” is useless. “Dashboard.tsx line 45 fetches /api/users but doesn’t await response” is actionable.Return structured data. The milestone auditor aggregates your findings. Use consistent format.

Verifier

Verifies individual phases (integration checker verifies between phases)

Executor

Creates the integrations that checker verifies