# UAT Gap Analysis

**Date:** 2026-02-06
**Status:** Analysis Complete

## Summary

After reviewing the comprehensive UAT plan against the actual code implementation, I've identified several gaps that would cause test failures if we ran the UAT now.

---

## Critical Gaps (P0 - Will Fail)

### Gap 1: Test Fixture Language Detection

**Test Affected:** All test-core-detection.sh tests

**Issue:** The test fixtures I created lack proper project structure files. The Aphoria walker uses project manifests (`Cargo.toml`, `pyproject.toml`, `package.json`, `go.mod`) to detect the project name and language.

**Current Fixtures:**
```
fixtures/python-tls/client.py  # No pyproject.toml or setup.py
fixtures/rust-tls/client.rs    # Has Cargo.toml ✓
fixtures/go-tls/client.go      # No go.mod
```

**Impact:** Path segments may be wrong or minimal, leading to incorrect concept paths.

**Fix Required:**
- Add `pyproject.toml` to Python fixtures
- Add `go.mod` to Go fixtures
- Keep existing `Cargo.toml` for Rust fixtures

### Gap 2: JSON Output Grep Patterns

**Test Affected:** All test scripts that parse JSON output

**Issue:** The test scripts use regex patterns like `'"verdict":\s*"BLOCK"'` but Aphoria's JSON output is formatted differently.

**Actual JSON structure:**
```json
{
  "conflicts": [
    {
      "claim": {...},
      "conflicts": [...],
      "conflict_score": 0.9,
      "verdict": "Block"
    }
  ]
}
```

**Issues:**
- Verdict is capitalized as `"Block"` not `"BLOCK"` in JSON
- The JSON might be pretty-printed or minified differently

**Fix Required:**
- Update grep patterns to match actual output format
- Consider using `jq` for reliable JSON parsing

### Gap 3: SQL Injection Test Fixture

**Test Affected:** Test 1.1.8

**Issue:** The Python fixture uses simple string concatenation:
```python
query = "SELECT * FROM users WHERE username = '" + username + "'"
```

But the SQL injection extractor regex expects specific patterns:
```rust
python_fstring_sql: r#"f["'][^"']*(?:SELECT|INSERT|UPDATE|DELETE|WHERE)[^"']*\{[^}]+\}"#,
python_format_sql: r#"["'][^"']*(?:SELECT|...[^"']*\{[^}]*\}["']\.format"#,
python_percent_sql: r#"["'][^"']*(?:SELECT|...[^"']*%[sd]["']\s*%"#,
```

None of these match the `+` concatenation pattern.

**Impact:** Test 1.1.8 will fail - no SQL injection detected.

**Fix Required:** Update fixture to use a pattern the extractor can detect:
```python
query = f"SELECT * FROM users WHERE username = '{username}'"  # f-string
# OR
query = "SELECT * FROM users WHERE username = '%s'" % username  # % format
```

### Gap 4: Weak Crypto Test Fixture

**Test Affected:** Test 1.1.10

**Issue:** The Python fixture uses:
```python
return hashlib.md5(password.encode()).hexdigest()
```

The extractor regex is:
```rust
python_md5: Regex::new(r"(?:hashlib\.md5|MD5\.new)").expect("valid regex"),
```

This SHOULD match `hashlib.md5` ✓

But the test script greps for `crypto|md5|weak` in the concept path, and the actual path would be:
`code://python/*/crypto/hashing/algorithm` with predicate `algorithm` and value `MD5`.

**Potential Issue:** The grep pattern needs to match the actual JSON output which includes the concept path and claim data.

---

## Moderate Gaps (P1 - May Fail)

### Gap 5: Command Injection Test Fixture

**Test Affected:** Test 1.1.9

**Issue:** The fixture uses:
```python
os.system("echo " + user_input)
subprocess.call(user_input, shell=True)
```

Need to verify the extractor regex matches these patterns. The command_injection extractor has:
```rust
python_os_system: Regex::new(r"os\.system\s*\([^)]*\+").expect("valid regex"),
python_subprocess_shell: Regex::new(r"subprocess\.(?:call|run|Popen)\s*\([^)]*shell\s*=\s*True").expect("valid regex"),
```

The `os.system("echo " + user_input)` pattern matches `os\.system\s*\([^)]*\+` ✓
The `subprocess.call(user_input, shell=True)` matches `subprocess\.call\s*\([^)]*shell\s*=\s*True` ✓

**Status:** Likely OK but needs verification.

### Gap 6: CORS Test May Not Produce BLOCK

**Test Affected:** Test 1.1.6

**Issue:** The test expects to find a CORS conflict, but:
- The authoritative assertion has `source_class: Clinical` (Tier 1)
- Conflict score calculation depends on tier spread
- May produce FLAG instead of a generic "conflict"

The test script just greps for `cors` which should work, but won't verify verdict level.

**Status:** Test will pass but may not validate BLOCK/FLAG correctly.

### Gap 7: Exit Code Test Fixture Structure

**Test Affected:** test-exit-codes.sh

**Issue:** Same as Gap 1 - fixtures lack proper project structure.

---

## Low Gaps (P2 - Edge Cases)

### Gap 8: Cross-Language Consistency Not Fully Tested

**Test Affected:** Test 1.2.1

**Issue:** The test only checks that all three languages produce BLOCK, but doesn't verify the concept paths are semantically equivalent.

**Better Test:** Verify the tail-path key is the same across languages:
- Python: `tls/cert_verification::enabled`
- Rust: `tls/cert_verification::enabled`
- Go: `tls/cert_verification::enabled`

### Gap 9: False Positive Test Limitations

**Test Affected:** Test 1.3.3

**Issue:** The "clean project" fixture only has a minimal `main.rs`. Real false positive testing needs:
- Legitimate crypto usage (checksums, file hashes)
- Test files with credential fixtures
- Complex code that triggers regex but isn't a vulnerability

---

## UAT Tests That Will Pass

| Test | Expected Result | Confidence |
|------|-----------------|------------|
| 1.1.1 Python TLS | PASS | HIGH - Pattern matches |
| 1.1.2 Rust TLS | PASS | HIGH - Pattern matches |
| 1.1.3 Go TLS | PASS | HIGH - Pattern matches |
| 1.1.4 JWT | PASS | HIGH - Pattern matches |
| 1.1.5 Secrets | PASS (with fixes) | MEDIUM - Need to verify path structure |
| 1.1.6 CORS | PARTIAL | MEDIUM - May not verify verdict |
| 1.1.8 SQL Injection | FAIL | HIGH - Fixture uses wrong pattern |
| 1.1.9 Command Injection | PASS | MEDIUM - Patterns look correct |
| 1.1.10 Weak Crypto | PASS | MEDIUM - Pattern matches |
| 3.4.1-4 Exit Codes | PASS | HIGH - Core functionality works |

---

## Recommended Fixes Before Running UAT

### Priority 1: Fix Test Fixtures (30 mins)

1. Add project manifests to all language fixtures:
```bash
# Python fixtures
echo '[project]\nname = "python-tls"' > fixtures/python-tls/pyproject.toml

# Go fixtures
echo 'module go-tls\ngo 1.21' > fixtures/go-tls/go.mod
```

2. Fix SQL injection fixture:
```python
# Change from:
query = "SELECT * FROM users WHERE username = '" + username + "'"

# To:
query = f"SELECT * FROM users WHERE username = '{username}'"
```

### Priority 2: Fix JSON Parsing (15 mins)

1. Install `jq` as a dependency or use more robust grep patterns:
```bash
# Instead of:
echo "$output" | grep -q '"verdict":\s*"BLOCK"'

# Use:
echo "$output" | jq -e '.conflicts[]? | select(.verdict == "Block")' > /dev/null
```

2. Handle case sensitivity:
```bash
# Make patterns case-insensitive:
echo "$output" | grep -qi '"verdict":\s*"block"'
```

### Priority 3: Add Integration Test Runner (1 hour)

Create a proper test harness that:
1. Builds Aphoria first
2. Creates fixtures with correct structure
3. Runs scans and captures actual output
4. Uses jq for JSON parsing
5. Reports clear pass/fail with diffs

---

## Conclusion

**If we run the UAT now:** ~60% of tests will pass, ~40% will fail due to fixture/parsing issues.

**After fixes:** ~90% of tests should pass, with remaining failures in edge cases that need deeper investigation.

**Recommended approach:**
1. Fix the P0 gaps first (fixtures, JSON parsing)
2. Run the tests to get baseline
3. Fix remaining failures iteratively
4. Add the missing test scripts (drift detection, output formats)
