diff --git a/.claude/agents/codebase-agent.md b/.claude/agents/codebase-agent.md
index 5dd34c2..a83312b 100644
--- a/.claude/agents/codebase-agent.md
+++ b/.claude/agents/codebase-agent.md
@@ -255,6 +255,50 @@ Testing strategies:
- All tests pass
```
+## Self-Review Protocol
+
+Before presenting work, perform a self-review by switching perspective to act as a reviewer:
+
+### Self-Review Checklist
+
+1. **Edge Cases Considered?**
+ - Null/empty inputs
+ - Boundary conditions
+ - Error states
+
+2. **Security Issues Addressed?**
+ - Input validation at boundaries
+ - Sanitization applied
+ - No hardcoded secrets
+
+3. **Error Handling Complete?**
+ - Exceptions caught appropriately
+ - User-friendly error messages
+ - Rollback on failure
+
+4. **Assumptions Clearly Stated?**
+ - Document non-obvious decisions
+ - Note limitations
+
+### Self-Review Process
+
+```text
+1. Complete implementation
+2. Switch perspective: "As a reviewer, what would I flag?"
+3. Check each item in checklist above
+4. Fix any issues found
+5. If significant fix made, note: "Self-review: Fixed [issue]"
+6. Maximum 2 self-review iterations to prevent infinite loops
+```
+
+### Example Self-Review Note
+
+```markdown
+Self-review: Fixed edge case for null input in validate_slug()
+- Original code would throw NullPointerException
+- Added early return for null/empty values
+```
+
## Error Handling
When errors occur:
diff --git a/.github/scripts/auto-fix.sh b/.github/scripts/auto-fix.sh
new file mode 100755
index 0000000..af3b0cb
--- /dev/null
+++ b/.github/scripts/auto-fix.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Auto-fix script for Autonomous Quality Enforcement (AQE) pattern
+# This script automatically fixes common issues
+
+set -e
+
+echo "=== Running AQE Auto-Fix ==="
+
+# Fix markdown linting issues
+if command -v markdownlint &> /dev/null; then
+ echo "Running markdownlint --fix..."
+ markdownlint docs/**/*.md README.md CLAUDE.md CONTRIBUTING.md --fix 2>/dev/null || true
+ echo "✅ Markdown auto-fix complete"
+else
+ echo "⚠️ markdownlint not installed, skipping markdown fixes"
+fi
+
+# Fix trailing whitespace
+echo "Removing trailing whitespace..."
+find docs -name "*.md" -exec sed -i 's/[[:space:]]*$//' {} \; 2>/dev/null || true
+echo "✅ Trailing whitespace removed"
+
+# Ensure files end with newline
+echo "Ensuring files end with newline..."
+find docs -name "*.md" -exec sh -c 'tail -c1 "$1" | read -r _ || echo >> "$1"' _ {} \; 2>/dev/null || true
+echo "✅ Newlines added"
+
+echo ""
+echo "=== AQE Auto-Fix Complete ✅ ==="
+echo "Run check.sh to verify all issues are resolved"
diff --git a/.github/scripts/check.sh b/.github/scripts/check.sh
new file mode 100755
index 0000000..7e7069b
--- /dev/null
+++ b/.github/scripts/check.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Validation script for Autonomous Quality Enforcement (AQE) pattern
+# This script runs all quality checks and returns non-zero on failure
+
+set -e
+
+echo "=== Running AQE Validation Checks ==="
+
+# Check if markdownlint is available
+if command -v markdownlint &> /dev/null; then
+ echo "Running markdownlint..."
+ markdownlint docs/**/*.md README.md CLAUDE.md CONTRIBUTING.md 2>/dev/null || {
+ echo "❌ Markdown linting failed"
+ exit 1
+ }
+ echo "✅ Markdown linting passed"
+else
+ echo "⚠️ markdownlint not installed, skipping markdown checks"
+fi
+
+# Validate documentation structure
+echo "Checking documentation structure..."
+test -d docs/patterns || { echo "❌ docs/patterns/ missing"; exit 1; }
+test -f docs/README.md || { echo "❌ docs/README.md missing"; exit 1; }
+test -d docs/adr || { echo "❌ docs/adr/ missing"; exit 1; }
+echo "✅ Documentation structure valid"
+
+# Check for required CLAUDE.md
+test -f CLAUDE.md || { echo "❌ CLAUDE.md missing"; exit 1; }
+echo "✅ CLAUDE.md exists"
+
+# Check for required agent configuration
+test -f .claude/agents/codebase-agent.md || { echo "❌ .claude/agents/codebase-agent.md missing"; exit 1; }
+echo "✅ Codebase agent configuration exists"
+
+# Check for context files
+test -d .claude/context || { echo "❌ .claude/context/ missing"; exit 1; }
+echo "✅ Context directory exists"
+
+echo ""
+echo "=== All AQE Validation Checks Passed ✅ ==="
diff --git a/.github/scripts/e2e-tests/run-all-e2e-tests.sh b/.github/scripts/e2e-tests/run-all-e2e-tests.sh
new file mode 100755
index 0000000..5d56083
--- /dev/null
+++ b/.github/scripts/e2e-tests/run-all-e2e-tests.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+# Run all E2E pattern tests and report results
+
+set -e
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+FAILED=0
+PASSED=0
+RESULTS=""
+
+echo "=========================================="
+echo " Pattern Validation E2E Test Suite"
+echo "=========================================="
+echo ""
+
+run_test() {
+ local test_name=$1
+ local test_script=$2
+
+ echo "Running: $test_name"
+ echo "---"
+
+ if bash "$SCRIPT_DIR/$test_script"; then
+ PASSED=$((PASSED + 1))
+ RESULTS="$RESULTS\n✅ $test_name"
+ else
+ FAILED=$((FAILED + 1))
+ RESULTS="$RESULTS\n❌ $test_name"
+ fi
+ echo ""
+}
+
+# Run all pattern tests
+run_test "Pattern 1: AQE" "test-pattern-1-aqe.sh"
+run_test "Pattern 2: CBA" "test-pattern-2-cba.sh"
+run_test "Pattern 3: Dependabot" "test-pattern-3-dependabot.sh"
+run_test "Pattern 4: GHA" "test-pattern-4-gha.sh"
+run_test "Pattern 5: Issue-to-PR" "test-pattern-5-issue-to-pr.sh"
+run_test "Pattern 6: Multi-Agent" "test-pattern-6-multi-agent.sh"
+run_test "Pattern 7: PR Review" "test-pattern-7-pr-review.sh"
+run_test "Pattern 8: Security" "test-pattern-8-security.sh"
+run_test "Pattern 9: Self-Review" "test-pattern-9-self-review.sh"
+run_test "Pattern 10: Stale" "test-pattern-10-stale.sh"
+run_test "Pattern 11: Testing" "test-pattern-11-testing.sh"
+
+# Summary
+echo "=========================================="
+echo " Test Results Summary"
+echo "=========================================="
+echo -e "$RESULTS"
+echo ""
+echo "Passed: $PASSED / $((PASSED + FAILED))"
+echo "Failed: $FAILED / $((PASSED + FAILED))"
+echo ""
+
+if [[ $FAILED -gt 0 ]]; then
+ echo "❌ SOME TESTS FAILED"
+ exit 1
+else
+ echo "✅ ALL TESTS PASSED"
+ exit 0
+fi
diff --git a/.github/scripts/e2e-tests/test-pattern-1-aqe.sh b/.github/scripts/e2e-tests/test-pattern-1-aqe.sh
new file mode 100755
index 0000000..41e2877
--- /dev/null
+++ b/.github/scripts/e2e-tests/test-pattern-1-aqe.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+# E2E Test: Pattern 1 - Autonomous Quality Enforcement (AQE)
+# Tests that check.sh and auto-fix.sh work correctly
+
+set -e
+
+echo "=== E2E Test: Pattern 1 - AQE ==="
+
+# Test 1: Verify check.sh exists and is executable
+echo "Test 1: Verify check.sh exists..."
+if [[ -x ".github/scripts/check.sh" ]]; then
+ echo "✅ check.sh exists and is executable"
+else
+ echo "❌ check.sh missing or not executable"
+ exit 1
+fi
+
+# Test 2: Verify auto-fix.sh exists and is executable
+echo "Test 2: Verify auto-fix.sh exists..."
+if [[ -x ".github/scripts/auto-fix.sh" ]]; then
+ echo "✅ auto-fix.sh exists and is executable"
+else
+ echo "❌ auto-fix.sh missing or not executable"
+ exit 1
+fi
+
+# Test 3: Verify validate.yml workflow exists
+echo "Test 3: Verify validate.yml workflow exists..."
+if [[ -f ".github/workflows/validate.yml" ]]; then
+ echo "✅ validate.yml workflow exists"
+else
+ echo "❌ validate.yml workflow missing"
+ exit 1
+fi
+
+# Test 4: Run check.sh and verify it executes
+echo "Test 4: Run check.sh..."
+if .github/scripts/check.sh; then
+ echo "✅ check.sh executed successfully"
+else
+ echo "❌ check.sh failed"
+ exit 1
+fi
+
+# Test 5: Verify CLAUDE.md has AQE process rule
+echo "Test 5: Verify AQE process rule in CLAUDE.md..."
+if grep -q "Autonomous Quality Enforcement" CLAUDE.md; then
+ echo "✅ AQE process rule found in CLAUDE.md"
+else
+ echo "❌ AQE process rule missing from CLAUDE.md"
+ exit 1
+fi
+
+echo ""
+echo "=== Pattern 1 (AQE): ALL TESTS PASSED ✅ ==="
diff --git a/.github/scripts/e2e-tests/test-pattern-10-stale.sh b/.github/scripts/e2e-tests/test-pattern-10-stale.sh
new file mode 100755
index 0000000..dc43d42
--- /dev/null
+++ b/.github/scripts/e2e-tests/test-pattern-10-stale.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+# E2E Test: Pattern 10 - Stale Issue Management
+# Tests that stale workflow is properly configured
+
+set -e
+
+echo "=== E2E Test: Pattern 10 - Stale Issue Management ==="
+
+WORKFLOW=".github/workflows/stale.yml"
+
+# Test 1: Verify workflow exists
+echo "Test 1: Verify stale.yml exists..."
+if [[ -f "$WORKFLOW" ]]; then
+ echo "✅ stale.yml exists"
+else
+ echo "❌ stale.yml missing"
+ exit 1
+fi
+
+# Test 2: Verify uses actions/stale
+echo "Test 2: Verify uses actions/stale..."
+if grep -q "actions/stale" "$WORKFLOW"; then
+ echo "✅ Uses actions/stale"
+else
+ echo "❌ Does not use actions/stale"
+ exit 1
+fi
+
+# Test 3: Verify schedule trigger configured
+echo "Test 3: Verify schedule trigger..."
+if grep -q "schedule" "$WORKFLOW"; then
+ echo "✅ Schedule trigger configured"
+else
+ echo "❌ Schedule trigger not configured"
+ exit 1
+fi
+
+# Test 4: Verify days-before-stale configured
+echo "Test 4: Verify stale timing configured..."
+if grep -q "days-before-stale" "$WORKFLOW"; then
+ echo "✅ Stale timing configured"
+else
+ echo "❌ Stale timing not configured"
+ exit 1
+fi
+
+# Test 5: Verify exempt labels configured
+echo "Test 5: Verify exempt labels..."
+if grep -q "exempt" "$WORKFLOW"; then
+ echo "✅ Exempt labels configured"
+else
+ echo "❌ Exempt labels not configured"
+ exit 1
+fi
+
+# Test 6: Verify stale message configured
+echo "Test 6: Verify stale message..."
+if grep -q "stale-issue-message\|stale-pr-message" "$WORKFLOW"; then
+ echo "✅ Stale message configured"
+else
+ echo "❌ Stale message not configured"
+ exit 1
+fi
+
+echo ""
+echo "=== Pattern 10 (Stale): ALL TESTS PASSED ✅ ==="
diff --git a/.github/scripts/e2e-tests/test-pattern-11-testing.sh b/.github/scripts/e2e-tests/test-pattern-11-testing.sh
new file mode 100755
index 0000000..54a61e2
--- /dev/null
+++ b/.github/scripts/e2e-tests/test-pattern-11-testing.sh
@@ -0,0 +1,73 @@
+#!/bin/bash
+# E2E Test: Pattern 11 - Testing Patterns
+# Tests that test pyramid structure exists and tests pass
+
+set -e
+
+echo "=== E2E Test: Pattern 11 - Testing Patterns ==="
+
+# Test 1: Verify tests directory exists
+echo "Test 1: Verify tests directory exists..."
+if [[ -d "tests" ]]; then
+ echo "✅ tests directory exists"
+else
+ echo "❌ tests directory missing"
+ exit 1
+fi
+
+# Test 2: Verify unit tests directory exists
+echo "Test 2: Verify unit tests directory..."
+if [[ -d "tests/unit" ]]; then
+ echo "✅ tests/unit exists"
+else
+ echo "❌ tests/unit missing"
+ exit 1
+fi
+
+# Test 3: Verify integration tests directory exists
+echo "Test 3: Verify integration tests directory..."
+if [[ -d "tests/integration" ]]; then
+ echo "✅ tests/integration exists"
+else
+ echo "❌ tests/integration missing"
+ exit 1
+fi
+
+# Test 4: Verify e2e tests directory exists
+echo "Test 4: Verify e2e tests directory..."
+if [[ -d "tests/e2e" ]]; then
+ echo "✅ tests/e2e exists"
+else
+ echo "❌ tests/e2e missing"
+ exit 1
+fi
+
+# Test 5: Verify pytest.ini exists
+echo "Test 5: Verify pytest.ini exists..."
+if [[ -f "pytest.ini" ]]; then
+ echo "✅ pytest.ini exists"
+else
+ echo "❌ pytest.ini missing"
+ exit 1
+fi
+
+# Test 6: Verify conftest.py exists
+echo "Test 6: Verify conftest.py exists..."
+if [[ -f "tests/conftest.py" ]]; then
+ echo "✅ conftest.py exists"
+else
+ echo "❌ conftest.py missing"
+ exit 1
+fi
+
+# Test 7: Run all tests
+echo "Test 7: Run full test suite..."
+if python -m pytest tests/ -v --tb=short 2>&1; then
+ echo "✅ All tests passed"
+else
+ echo "❌ Some tests failed"
+ exit 1
+fi
+
+echo ""
+echo "=== Pattern 11 (Testing): ALL TESTS PASSED ✅ ==="
diff --git a/.github/scripts/e2e-tests/test-pattern-2-cba.sh b/.github/scripts/e2e-tests/test-pattern-2-cba.sh
new file mode 100755
index 0000000..8ed7d3c
--- /dev/null
+++ b/.github/scripts/e2e-tests/test-pattern-2-cba.sh
@@ -0,0 +1,73 @@
+#!/bin/bash
+# E2E Test: Pattern 2 - Codebase Agent (CBA)
+# Tests that CBA configuration files exist and are complete
+
+set -e
+
+echo "=== E2E Test: Pattern 2 - CBA ==="
+
+# Test 1: Verify codebase-agent.md exists
+echo "Test 1: Verify codebase-agent.md exists..."
+if [[ -f ".claude/agents/codebase-agent.md" ]]; then
+ echo "✅ codebase-agent.md exists"
+else
+ echo "❌ codebase-agent.md missing"
+ exit 1
+fi
+
+# Test 2: Verify autonomy levels are documented
+echo "Test 2: Verify autonomy levels documented..."
+if grep -qi "autonomy" .claude/agents/codebase-agent.md; then
+ echo "✅ Autonomy levels documented"
+else
+ echo "❌ Autonomy levels not documented"
+ exit 1
+fi
+
+# Test 3: Verify context directory exists
+echo "Test 3: Verify context directory exists..."
+if [[ -d ".claude/context" ]]; then
+ echo "✅ Context directory exists"
+else
+ echo "❌ Context directory missing"
+ exit 1
+fi
+
+# Test 4: Verify architecture.md exists
+echo "Test 4: Verify architecture.md exists..."
+if [[ -f ".claude/context/architecture.md" ]]; then
+ echo "✅ architecture.md exists"
+else
+ echo "❌ architecture.md missing"
+ exit 1
+fi
+
+# Test 5: Verify security-standards.md exists
+echo "Test 5: Verify security-standards.md exists..."
+if [[ -f ".claude/context/security-standards.md" ]]; then
+ echo "✅ security-standards.md exists"
+else
+ echo "❌ security-standards.md missing"
+ exit 1
+fi
+
+# Test 6: Verify testing-patterns.md exists
+echo "Test 6: Verify testing-patterns.md exists..."
+if [[ -f ".claude/context/testing-patterns.md" ]]; then
+ echo "✅ testing-patterns.md exists"
+else
+ echo "❌ testing-patterns.md missing"
+ exit 1
+fi
+
+# Test 7: Verify self-review protocol exists
+echo "Test 7: Verify self-review protocol..."
+if grep -qi "self-review" .claude/agents/codebase-agent.md; then
+ echo "✅ Self-review protocol documented"
+else
+ echo "❌ Self-review protocol not documented"
+ exit 1
+fi
+
+echo ""
+echo "=== Pattern 2 (CBA): ALL TESTS PASSED ✅ ==="
diff --git a/.github/scripts/e2e-tests/test-pattern-3-dependabot.sh b/.github/scripts/e2e-tests/test-pattern-3-dependabot.sh
new file mode 100755
index 0000000..d1755f3
--- /dev/null
+++ b/.github/scripts/e2e-tests/test-pattern-3-dependabot.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+# E2E Test: Pattern 3 - Dependabot Auto-Merge
+# Tests that Dependabot configuration and auto-merge workflow exist
+
+set -e
+
+echo "=== E2E Test: Pattern 3 - Dependabot Auto-Merge ==="
+
+# Test 1: Verify dependabot.yml exists
+echo "Test 1: Verify dependabot.yml exists..."
+if [[ -f ".github/dependabot.yml" ]]; then
+ echo "✅ dependabot.yml exists"
+else
+ echo "❌ dependabot.yml missing"
+ exit 1
+fi
+
+# Test 2: Verify dependabot-auto-merge.yml workflow exists
+echo "Test 2: Verify dependabot-auto-merge.yml exists..."
+if [[ -f ".github/workflows/dependabot-auto-merge.yml" ]]; then
+ echo "✅ dependabot-auto-merge.yml exists"
+else
+ echo "❌ dependabot-auto-merge.yml missing"
+ exit 1
+fi
+
+# Test 3: Verify dependabot.yml has package-ecosystem
+echo "Test 3: Verify package-ecosystem configured..."
+if grep -q "package-ecosystem" .github/dependabot.yml; then
+ echo "✅ package-ecosystem configured"
+else
+ echo "❌ package-ecosystem not configured"
+ exit 1
+fi
+
+# Test 4: Verify auto-merge workflow checks for dependabot
+echo "Test 4: Verify auto-merge checks for dependabot..."
+if grep -qi "dependabot" .github/workflows/dependabot-auto-merge.yml; then
+ echo "✅ Auto-merge workflow checks for dependabot"
+else
+ echo "❌ Auto-merge workflow doesn't check for dependabot"
+ exit 1
+fi
+
+# Test 5: Verify auto-merge uses dependabot metadata
+echo "Test 5: Verify dependabot metadata action used..."
+if grep -q "dependabot/fetch-metadata" .github/workflows/dependabot-auto-merge.yml; then
+ echo "✅ dependabot/fetch-metadata action used"
+else
+ echo "❌ dependabot/fetch-metadata action not found"
+ exit 1
+fi
+
+echo ""
+echo "=== Pattern 3 (Dependabot): ALL TESTS PASSED ✅ ==="
diff --git a/.github/scripts/e2e-tests/test-pattern-4-gha.sh b/.github/scripts/e2e-tests/test-pattern-4-gha.sh
new file mode 100755
index 0000000..8a64759
--- /dev/null
+++ b/.github/scripts/e2e-tests/test-pattern-4-gha.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+# E2E Test: Pattern 4 - GitHub Actions Automation Patterns
+# Tests that all 4 sub-pattern workflows exist
+
+set -e
+
+echo "=== E2E Test: Pattern 4 - GHA Automation Patterns ==="
+
+WORKFLOWS_DIR=".github/workflows"
+FAILED=0
+
+# Test 1: Issue-to-PR workflow
+echo "Test 1: Verify issue-to-pr.yml exists..."
+if [[ -f "$WORKFLOWS_DIR/issue-to-pr.yml" ]]; then
+ echo "✅ issue-to-pr.yml exists"
+else
+ echo "❌ issue-to-pr.yml missing"
+ FAILED=1
+fi
+
+# Test 2: PR Auto-Review workflow
+echo "Test 2: Verify pr-review.yml exists..."
+if [[ -f "$WORKFLOWS_DIR/pr-review.yml" ]]; then
+ echo "✅ pr-review.yml exists"
+else
+ echo "❌ pr-review.yml missing"
+ FAILED=1
+fi
+
+# Test 3: Dependabot Auto-Merge workflow
+echo "Test 3: Verify dependabot-auto-merge.yml exists..."
+if [[ -f "$WORKFLOWS_DIR/dependabot-auto-merge.yml" ]]; then
+ echo "✅ dependabot-auto-merge.yml exists"
+else
+ echo "❌ dependabot-auto-merge.yml missing"
+ FAILED=1
+fi
+
+# Test 4: Stale Issue Management workflow
+echo "Test 4: Verify stale.yml exists..."
+if [[ -f "$WORKFLOWS_DIR/stale.yml" ]]; then
+ echo "✅ stale.yml exists"
+else
+ echo "❌ stale.yml missing"
+ FAILED=1
+fi
+
+# Summary
+if [[ $FAILED -eq 1 ]]; then
+ echo ""
+ echo "=== Pattern 4 (GHA): SOME TESTS FAILED ❌ ==="
+ exit 1
+fi
+
+echo ""
+echo "=== Pattern 4 (GHA): ALL TESTS PASSED ✅ ==="
diff --git a/.github/scripts/e2e-tests/test-pattern-5-issue-to-pr.sh b/.github/scripts/e2e-tests/test-pattern-5-issue-to-pr.sh
new file mode 100755
index 0000000..edce49b
--- /dev/null
+++ b/.github/scripts/e2e-tests/test-pattern-5-issue-to-pr.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+# E2E Test: Pattern 5 - Issue-to-PR Automation
+# Tests that issue-to-pr workflow is properly configured
+
+set -e
+
+echo "=== E2E Test: Pattern 5 - Issue-to-PR Automation ==="
+
+WORKFLOW=".github/workflows/issue-to-pr.yml"
+
+# Test 1: Verify workflow exists
+echo "Test 1: Verify issue-to-pr.yml exists..."
+if [[ -f "$WORKFLOW" ]]; then
+ echo "✅ issue-to-pr.yml exists"
+else
+ echo "❌ issue-to-pr.yml missing"
+ exit 1
+fi
+
+# Test 2: Verify workflow triggers on issue labeled
+echo "Test 2: Verify triggers on issue labeled..."
+if grep -q "issues:" "$WORKFLOW" && grep -q "labeled" "$WORKFLOW"; then
+ echo "✅ Triggers on issue labeled"
+else
+ echo "❌ Does not trigger on issue labeled"
+ exit 1
+fi
+
+# Test 3: Verify workflow checks for ready-for-pr label
+echo "Test 3: Verify checks for ready-for-pr label..."
+if grep -q "ready-for-pr" "$WORKFLOW"; then
+ echo "✅ Checks for ready-for-pr label"
+else
+ echo "❌ Does not check for ready-for-pr label"
+ exit 1
+fi
+
+# Test 4: Verify workflow has issue clarity analysis
+echo "Test 4: Verify issue clarity analysis..."
+if grep -qi "clarity\|acceptance criteria\|requirements" "$WORKFLOW"; then
+ echo "✅ Issue clarity analysis present"
+else
+ echo "❌ Issue clarity analysis missing"
+ exit 1
+fi
+
+# Test 5: Verify workflow can create PRs
+echo "Test 5: Verify PR creation capability..."
+if grep -q "gh pr create" "$WORKFLOW"; then
+ echo "✅ PR creation configured"
+else
+ echo "❌ PR creation not configured"
+ exit 1
+fi
+
+# Test 6: Verify workflow can post clarification comments
+echo "Test 6: Verify clarification comment capability..."
+if grep -q "gh issue comment" "$WORKFLOW"; then
+ echo "✅ Clarification comments configured"
+else
+ echo "❌ Clarification comments not configured"
+ exit 1
+fi
+
+echo ""
+echo "=== Pattern 5 (Issue-to-PR): ALL TESTS PASSED ✅ ==="
diff --git a/.github/scripts/e2e-tests/test-pattern-6-multi-agent.sh b/.github/scripts/e2e-tests/test-pattern-6-multi-agent.sh
new file mode 100755
index 0000000..b2cf529
--- /dev/null
+++ b/.github/scripts/e2e-tests/test-pattern-6-multi-agent.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+# E2E Test: Pattern 6 - Multi-Agent Code Review
+# Tests that multi-agent code review documentation exists
+
+set -e
+
+echo "=== E2E Test: Pattern 6 - Multi-Agent Code Review ==="
+
+DOC="docs/patterns/multi-agent-code-review.md"
+
+# Test 1: Verify documentation exists
+echo "Test 1: Verify multi-agent-code-review.md exists..."
+if [[ -f "$DOC" ]]; then
+ echo "✅ multi-agent-code-review.md exists"
+else
+ echo "❌ multi-agent-code-review.md missing"
+ exit 1
+fi
+
+# Test 2: Verify Architecture Advisor documented
+echo "Test 2: Verify Architecture Advisor documented..."
+if grep -qi "architecture" "$DOC"; then
+ echo "✅ Architecture Advisor documented"
+else
+ echo "❌ Architecture Advisor not documented"
+ exit 1
+fi
+
+# Test 3: Verify Simplification Advisor documented
+echo "Test 3: Verify Simplification Advisor documented..."
+if grep -qi "simplification" "$DOC"; then
+ echo "✅ Simplification Advisor documented"
+else
+ echo "❌ Simplification Advisor not documented"
+ exit 1
+fi
+
+# Test 4: Verify Security Advisor documented
+echo "Test 4: Verify Security Advisor documented..."
+if grep -qi "security" "$DOC"; then
+ echo "✅ Security Advisor documented"
+else
+ echo "❌ Security Advisor not documented"
+ exit 1
+fi
+
+# Test 5: Verify confidence thresholds documented
+echo "Test 5: Verify confidence thresholds documented..."
+if grep -qE "(80%|90%|confidence)" "$DOC"; then
+ echo "✅ Confidence thresholds documented"
+else
+ echo "❌ Confidence thresholds not documented"
+ exit 1
+fi
+
+# Test 6: Verify finding categories documented (CRITICAL, WARNING, INFO)
+echo "Test 6: Verify finding categories documented..."
+if grep -q "CRITICAL" "$DOC" && grep -q "WARNING" "$DOC"; then
+ echo "✅ Finding categories documented"
+else
+ echo "❌ Finding categories not documented"
+ exit 1
+fi
+
+echo ""
+echo "=== Pattern 6 (Multi-Agent): ALL TESTS PASSED ✅ ==="
diff --git a/.github/scripts/e2e-tests/test-pattern-7-pr-review.sh b/.github/scripts/e2e-tests/test-pattern-7-pr-review.sh
new file mode 100755
index 0000000..88b59fd
--- /dev/null
+++ b/.github/scripts/e2e-tests/test-pattern-7-pr-review.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+# E2E Test: Pattern 7 - PR Auto-Review
+# Tests that PR auto-review workflow is properly configured
+
+set -e
+
+echo "=== E2E Test: Pattern 7 - PR Auto-Review ==="
+
+WORKFLOW=".github/workflows/pr-review.yml"
+
+# Test 1: Verify workflow exists
+echo "Test 1: Verify pr-review.yml exists..."
+if [[ -f "$WORKFLOW" ]]; then
+ echo "✅ pr-review.yml exists"
+else
+ echo "❌ pr-review.yml missing"
+ exit 1
+fi
+
+# Test 2: Verify workflow triggers on pull_request
+echo "Test 2: Verify triggers on pull_request..."
+if grep -q "pull_request" "$WORKFLOW"; then
+ echo "✅ Triggers on pull_request"
+else
+ echo "❌ Does not trigger on pull_request"
+ exit 1
+fi
+
+# Test 3: Verify workflow skips draft PRs
+echo "Test 3: Verify skips draft PRs..."
+if grep -qi "draft" "$WORKFLOW"; then
+ echo "✅ Draft PR handling configured"
+else
+ echo "❌ Draft PR handling not configured"
+ exit 1
+fi
+
+# Test 4: Verify workflow checks for skip-review label
+echo "Test 4: Verify skip-review label support..."
+if grep -q "skip-review" "$WORKFLOW"; then
+ echo "✅ skip-review label supported"
+else
+ echo "❌ skip-review label not supported"
+ exit 1
+fi
+
+# Test 5: Verify security checks configured
+echo "Test 5: Verify security checks..."
+if grep -qi "secret\|password\|key\|security" "$WORKFLOW"; then
+ echo "✅ Security checks configured"
+else
+ echo "❌ Security checks not configured"
+ exit 1
+fi
+
+# Test 6: Verify workflow can post comments
+echo "Test 6: Verify comment posting capability..."
+if grep -q "gh pr comment\|issue comment\|comment" "$WORKFLOW"; then
+ echo "✅ Comment posting configured"
+else
+ echo "❌ Comment posting not configured"
+ exit 1
+fi
+
+echo ""
+echo "=== Pattern 7 (PR Auto-Review): ALL TESTS PASSED ✅ ==="
diff --git a/.github/scripts/e2e-tests/test-pattern-8-security.sh b/.github/scripts/e2e-tests/test-pattern-8-security.sh
new file mode 100755
index 0000000..98a00f7
--- /dev/null
+++ b/.github/scripts/e2e-tests/test-pattern-8-security.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+# E2E Test: Pattern 8 - Security Patterns
+# Tests that security module exists and tests pass
+
+set -e
+
+echo "=== E2E Test: Pattern 8 - Security Patterns ==="
+
+# Test 1: Verify security module exists
+echo "Test 1: Verify security.py exists..."
+if [[ -f "src/core/security.py" ]]; then
+ echo "✅ security.py exists"
+else
+ echo "❌ security.py missing"
+ exit 1
+fi
+
+# Test 2: Verify sanitize_string function exists
+echo "Test 2: Verify sanitize_string function..."
+if grep -q "def sanitize_string" src/core/security.py; then
+ echo "✅ sanitize_string function exists"
+else
+ echo "❌ sanitize_string function missing"
+ exit 1
+fi
+
+# Test 3: Verify validate_slug function exists
+echo "Test 3: Verify validate_slug function..."
+if grep -q "def validate_slug" src/core/security.py; then
+ echo "✅ validate_slug function exists"
+else
+ echo "❌ validate_slug function missing"
+ exit 1
+fi
+
+# Test 4: Verify sanitize_path function exists
+echo "Test 4: Verify sanitize_path function..."
+if grep -q "def sanitize_path" src/core/security.py; then
+ echo "✅ sanitize_path function exists"
+else
+ echo "❌ sanitize_path function missing"
+ exit 1
+fi
+
+# Test 5: Verify security tests exist
+echo "Test 5: Verify security tests exist..."
+if [[ -f "tests/unit/test_security.py" ]]; then
+ echo "✅ test_security.py exists"
+else
+ echo "❌ test_security.py missing"
+ exit 1
+fi
+
+# Test 6: Run security unit tests
+echo "Test 6: Run security unit tests..."
+if python -m pytest tests/unit/test_security.py -v --tb=short 2>&1; then
+ echo "✅ Security tests passed"
+else
+ echo "❌ Security tests failed"
+ exit 1
+fi
+
+echo ""
+echo "=== Pattern 8 (Security): ALL TESTS PASSED ✅ ==="
diff --git a/.github/scripts/e2e-tests/test-pattern-9-self-review.sh b/.github/scripts/e2e-tests/test-pattern-9-self-review.sh
new file mode 100755
index 0000000..0f88b4d
--- /dev/null
+++ b/.github/scripts/e2e-tests/test-pattern-9-self-review.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+# E2E Test: Pattern 9 - Self-Review Reflection
+# Tests that self-review protocol is documented in CBA
+
+set -e
+
+echo "=== E2E Test: Pattern 9 - Self-Review Reflection ==="
+
+CBA_CONFIG=".claude/agents/codebase-agent.md"
+
+# Test 1: Verify CBA config exists
+echo "Test 1: Verify codebase-agent.md exists..."
+if [[ -f "$CBA_CONFIG" ]]; then
+ echo "✅ codebase-agent.md exists"
+else
+ echo "❌ codebase-agent.md missing"
+ exit 1
+fi
+
+# Test 2: Verify self-review section exists
+echo "Test 2: Verify self-review section..."
+if grep -qi "self-review" "$CBA_CONFIG"; then
+ echo "✅ Self-review section exists"
+else
+ echo "❌ Self-review section missing"
+ exit 1
+fi
+
+# Test 3: Verify edge cases checklist item
+echo "Test 3: Verify edge cases in checklist..."
+if grep -qi "edge case" "$CBA_CONFIG"; then
+ echo "✅ Edge cases in checklist"
+else
+ echo "❌ Edge cases not in checklist"
+ exit 1
+fi
+
+# Test 4: Verify security checklist item
+echo "Test 4: Verify security in checklist..."
+if grep -qi "security" "$CBA_CONFIG"; then
+ echo "✅ Security in checklist"
+else
+ echo "❌ Security not in checklist"
+ exit 1
+fi
+
+# Test 5: Verify error handling checklist item
+echo "Test 5: Verify error handling in checklist..."
+if grep -qi "error handling" "$CBA_CONFIG"; then
+ echo "✅ Error handling in checklist"
+else
+ echo "❌ Error handling not in checklist"
+ exit 1
+fi
+
+# Test 6: Verify iteration limit documented
+echo "Test 6: Verify iteration limit..."
+if grep -qE "(iteration|maximum|max)" "$CBA_CONFIG"; then
+ echo "✅ Iteration limit documented"
+else
+ echo "❌ Iteration limit not documented"
+ exit 1
+fi
+
+echo ""
+echo "=== Pattern 9 (Self-Review): ALL TESTS PASSED ✅ ==="
diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml
new file mode 100644
index 0000000..2243e4f
--- /dev/null
+++ b/.github/workflows/dependabot-auto-merge.yml
@@ -0,0 +1,37 @@
+name: Dependabot Auto-Merge
+
+on:
+ pull_request:
+ types: [opened, synchronize, reopened, labeled]
+
+permissions:
+ contents: write
+ pull-requests: write
+
+jobs:
+ auto-merge:
+ runs-on: ubuntu-latest
+ if: github.actor == 'dependabot[bot]'
+
+ steps:
+ - name: Dependabot metadata
+ id: metadata
+ uses: dependabot/fetch-metadata@v2
+ with:
+ github-token: "${{ secrets.GITHUB_TOKEN }}"
+
+ - name: Auto-merge patch updates
+ if: steps.metadata.outputs.update-type == 'version-update:semver-patch'
+ run: |
+ echo "Auto-merging patch update: ${{ github.event.pull_request.title }}"
+ gh pr merge --auto --squash "${{ github.event.pull_request.html_url }}"
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Comment on minor/major updates
+ if: steps.metadata.outputs.update-type != 'version-update:semver-patch'
+ run: |
+ echo "Minor/major update detected - requires human review"
+ gh pr comment "${{ github.event.pull_request.html_url }}" --body "⚠️ This is a **${{ steps.metadata.outputs.update-type }}** update and requires human review before merging."
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/e2e-pattern-tests.yml b/.github/workflows/e2e-pattern-tests.yml
new file mode 100644
index 0000000..fc66a65
--- /dev/null
+++ b/.github/workflows/e2e-pattern-tests.yml
@@ -0,0 +1,185 @@
+name: E2E Pattern Tests
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+ workflow_dispatch:
+
+jobs:
+ pattern-1-aqe:
+ name: Pattern 1 - AQE
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Run AQE tests
+ run: |
+ chmod +x .github/scripts/e2e-tests/test-pattern-1-aqe.sh
+ .github/scripts/e2e-tests/test-pattern-1-aqe.sh
+
+ pattern-2-cba:
+ name: Pattern 2 - CBA
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Run CBA tests
+ run: |
+ chmod +x .github/scripts/e2e-tests/test-pattern-2-cba.sh
+ .github/scripts/e2e-tests/test-pattern-2-cba.sh
+
+ pattern-3-dependabot:
+ name: Pattern 3 - Dependabot
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Run Dependabot tests
+ run: |
+ chmod +x .github/scripts/e2e-tests/test-pattern-3-dependabot.sh
+ .github/scripts/e2e-tests/test-pattern-3-dependabot.sh
+
+ pattern-4-gha:
+ name: Pattern 4 - GHA
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Run GHA tests
+ run: |
+ chmod +x .github/scripts/e2e-tests/test-pattern-4-gha.sh
+ .github/scripts/e2e-tests/test-pattern-4-gha.sh
+
+ pattern-5-issue-to-pr:
+ name: Pattern 5 - Issue-to-PR
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Run Issue-to-PR tests
+ run: |
+ chmod +x .github/scripts/e2e-tests/test-pattern-5-issue-to-pr.sh
+ .github/scripts/e2e-tests/test-pattern-5-issue-to-pr.sh
+
+ pattern-6-multi-agent:
+ name: Pattern 6 - Multi-Agent
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Run Multi-Agent tests
+ run: |
+ chmod +x .github/scripts/e2e-tests/test-pattern-6-multi-agent.sh
+ .github/scripts/e2e-tests/test-pattern-6-multi-agent.sh
+
+ pattern-7-pr-review:
+ name: Pattern 7 - PR Review
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Run PR Review tests
+ run: |
+ chmod +x .github/scripts/e2e-tests/test-pattern-7-pr-review.sh
+ .github/scripts/e2e-tests/test-pattern-7-pr-review.sh
+
+ pattern-8-security:
+ name: Pattern 8 - Security
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Setup Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.11'
+ - name: Install dependencies
+ run: pip install pytest
+ - name: Run Security tests
+ run: |
+ chmod +x .github/scripts/e2e-tests/test-pattern-8-security.sh
+ .github/scripts/e2e-tests/test-pattern-8-security.sh
+
+ pattern-9-self-review:
+ name: Pattern 9 - Self-Review
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Run Self-Review tests
+ run: |
+ chmod +x .github/scripts/e2e-tests/test-pattern-9-self-review.sh
+ .github/scripts/e2e-tests/test-pattern-9-self-review.sh
+
+ pattern-10-stale:
+ name: Pattern 10 - Stale
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Run Stale tests
+ run: |
+ chmod +x .github/scripts/e2e-tests/test-pattern-10-stale.sh
+ .github/scripts/e2e-tests/test-pattern-10-stale.sh
+
+ pattern-11-testing:
+ name: Pattern 11 - Testing
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Setup Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.11'
+ - name: Install dependencies
+ run: pip install pytest
+ - name: Run Testing tests
+ run: |
+ chmod +x .github/scripts/e2e-tests/test-pattern-11-testing.sh
+ .github/scripts/e2e-tests/test-pattern-11-testing.sh
+
+ summary:
+ name: E2E Test Summary
+ runs-on: ubuntu-latest
+ needs:
+ - pattern-1-aqe
+ - pattern-2-cba
+ - pattern-3-dependabot
+ - pattern-4-gha
+ - pattern-5-issue-to-pr
+ - pattern-6-multi-agent
+ - pattern-7-pr-review
+ - pattern-8-security
+ - pattern-9-self-review
+ - pattern-10-stale
+ - pattern-11-testing
+ if: always()
+ steps:
+ - name: Check results
+ run: |
+ echo "=========================================="
+ echo " E2E Pattern Test Results"
+ echo "=========================================="
+ echo ""
+ echo "Pattern 1 (AQE): ${{ needs.pattern-1-aqe.result }}"
+ echo "Pattern 2 (CBA): ${{ needs.pattern-2-cba.result }}"
+ echo "Pattern 3 (Dependabot): ${{ needs.pattern-3-dependabot.result }}"
+ echo "Pattern 4 (GHA): ${{ needs.pattern-4-gha.result }}"
+ echo "Pattern 5 (Issue-to-PR): ${{ needs.pattern-5-issue-to-pr.result }}"
+ echo "Pattern 6 (Multi-Agent): ${{ needs.pattern-6-multi-agent.result }}"
+ echo "Pattern 7 (PR Review): ${{ needs.pattern-7-pr-review.result }}"
+ echo "Pattern 8 (Security): ${{ needs.pattern-8-security.result }}"
+ echo "Pattern 9 (Self-Review): ${{ needs.pattern-9-self-review.result }}"
+ echo "Pattern 10 (Stale): ${{ needs.pattern-10-stale.result }}"
+ echo "Pattern 11 (Testing): ${{ needs.pattern-11-testing.result }}"
+ echo ""
+
+ # Check if any failed
+ if [[ "${{ needs.pattern-1-aqe.result }}" == "failure" ]] || \
+ [[ "${{ needs.pattern-2-cba.result }}" == "failure" ]] || \
+ [[ "${{ needs.pattern-3-dependabot.result }}" == "failure" ]] || \
+ [[ "${{ needs.pattern-4-gha.result }}" == "failure" ]] || \
+ [[ "${{ needs.pattern-5-issue-to-pr.result }}" == "failure" ]] || \
+ [[ "${{ needs.pattern-6-multi-agent.result }}" == "failure" ]] || \
+ [[ "${{ needs.pattern-7-pr-review.result }}" == "failure" ]] || \
+ [[ "${{ needs.pattern-8-security.result }}" == "failure" ]] || \
+ [[ "${{ needs.pattern-9-self-review.result }}" == "failure" ]] || \
+ [[ "${{ needs.pattern-10-stale.result }}" == "failure" ]] || \
+ [[ "${{ needs.pattern-11-testing.result }}" == "failure" ]]; then
+ echo "❌ SOME PATTERN TESTS FAILED"
+ exit 1
+ else
+ echo "✅ ALL PATTERN TESTS PASSED"
+ fi
diff --git a/.github/workflows/issue-to-pr.yml b/.github/workflows/issue-to-pr.yml
new file mode 100644
index 0000000..443db21
--- /dev/null
+++ b/.github/workflows/issue-to-pr.yml
@@ -0,0 +1,96 @@
+name: Issue to PR
+
+on:
+ issues:
+ types: [labeled]
+
+permissions:
+ contents: write
+ pull-requests: write
+ issues: write
+
+jobs:
+ analyze-and-create-pr:
+ runs-on: ubuntu-latest
+ if: github.event.label.name == 'ready-for-pr'
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Analyze issue clarity
+ id: analyze
+ env:
+ ISSUE_BODY: ${{ github.event.issue.body }}
+ run: |
+ # Check for acceptance criteria indicators
+ if echo "$ISSUE_BODY" | grep -qiE "(acceptance criteria|requirements|should|must|expected)"; then
+ echo "clear=true" >> $GITHUB_OUTPUT
+ echo "Issue has clear requirements"
+ else
+ echo "clear=false" >> $GITHUB_OUTPUT
+ echo "Issue may need clarification"
+ fi
+
+ - name: Request clarification for vague issues
+ if: steps.analyze.outputs.clear == 'false'
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ ISSUE_NUMBER: ${{ github.event.issue.number }}
+ run: |
+ gh issue comment "$ISSUE_NUMBER" --body "This issue was labeled ready-for-pr but may need more detail.
+
+ Please provide:
+ - Clear acceptance criteria
+ - Expected behavior
+ - Any specific implementation requirements
+
+ Once updated, remove and re-add the ready-for-pr label."
+
+ - name: Create implementation branch
+ if: steps.analyze.outputs.clear == 'true'
+ env:
+ ISSUE_TITLE: ${{ github.event.issue.title }}
+ ISSUE_NUMBER: ${{ github.event.issue.number }}
+ run: |
+ BRANCH_NAME="issue-${ISSUE_NUMBER}-$(echo "$ISSUE_TITLE" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | head -c 40)"
+ git checkout -b "$BRANCH_NAME"
+ echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV
+
+ - name: Create draft PR
+ if: steps.analyze.outputs.clear == 'true'
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ ISSUE_TITLE: ${{ github.event.issue.title }}
+ ISSUE_NUMBER: ${{ github.event.issue.number }}
+ run: |
+ # Create a placeholder commit
+ cat > IMPLEMENTATION.md << EOF
+ # Implementation for Issue #${ISSUE_NUMBER}
+
+ Issue: ${ISSUE_TITLE}
+
+ ## Changes
+ - [ ] Implementation pending
+ EOF
+
+ git config user.name "github-actions[bot]"
+ git config user.email "github-actions[bot]@users.noreply.github.com"
+ git add IMPLEMENTATION.md
+ git commit -m "feat: Start implementation for #${ISSUE_NUMBER}"
+ git push -u origin "$BRANCH_NAME"
+
+ gh pr create \
+ --draft \
+ --title "feat: ${ISSUE_TITLE}" \
+ --body "## Summary
+ Implements #${ISSUE_NUMBER}
+
+ ## Changes
+ - Implementation in progress
+
+ ## Test Plan
+ - [ ] Tests added
+ - [ ] Manual verification complete
+
+ ---
+ Created automatically from issue #${ISSUE_NUMBER}"
diff --git a/.github/workflows/pr-review.yml b/.github/workflows/pr-review.yml
new file mode 100644
index 0000000..0bc49c9
--- /dev/null
+++ b/.github/workflows/pr-review.yml
@@ -0,0 +1,113 @@
+name: PR Auto-Review
+
+on:
+ pull_request:
+ types: [opened, synchronize, ready_for_review]
+
+permissions:
+ contents: read
+ pull-requests: write
+
+jobs:
+ auto-review:
+ runs-on: ubuntu-latest
+ # Skip draft PRs and PRs with skip-review label
+ if: |
+ github.event.pull_request.draft == false &&
+ !contains(github.event.pull_request.labels.*.name, 'skip-review')
+
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Get changed files
+ id: changed
+ run: |
+ CHANGED_FILES=$(gh pr view ${{ github.event.pull_request.number }} --json files -q '.files[].path' | tr '\n' ' ')
+ echo "files=$CHANGED_FILES" >> $GITHUB_OUTPUT
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Security review
+ id: security
+ run: |
+ FINDINGS=""
+
+ # Check for hardcoded secrets patterns
+ if git diff origin/main...HEAD | grep -iE "(password|secret|api_key|token)\s*=\s*['\"][^'\"]+['\"]"; then
+ FINDINGS="${FINDINGS}🔴 **CRITICAL**: Potential hardcoded secrets detected\n"
+ fi
+
+ # Check for .env file additions
+ if echo "${{ steps.changed.outputs.files }}" | grep -qE "\.env$"; then
+ FINDINGS="${FINDINGS}🔴 **CRITICAL**: .env file should not be committed\n"
+ fi
+
+ # Check for TODO/FIXME in security-sensitive areas
+ if git diff origin/main...HEAD | grep -iE "(security|auth|password)" | grep -iE "(todo|fixme|hack)"; then
+ FINDINGS="${FINDINGS}🟡 **WARNING**: TODO/FIXME in security-sensitive code\n"
+ fi
+
+ if [ -n "$FINDINGS" ]; then
+ echo "has_findings=true" >> $GITHUB_OUTPUT
+ echo -e "findings=$FINDINGS" >> $GITHUB_OUTPUT
+ else
+ echo "has_findings=false" >> $GITHUB_OUTPUT
+ fi
+
+ - name: Code quality review
+ id: quality
+ run: |
+ FINDINGS=""
+
+ # Check for large files
+ LARGE_FILES=$(git diff --stat origin/main...HEAD | grep -E "\+[0-9]{3,}" | head -5)
+ if [ -n "$LARGE_FILES" ]; then
+ FINDINGS="${FINDINGS}🟡 **WARNING**: Large changes detected - consider breaking into smaller PRs\n"
+ fi
+
+ # Check for missing tests in code changes
+ CODE_CHANGED=$(echo "${{ steps.changed.outputs.files }}" | grep -E "\.(py|js|ts)$" | grep -v test || true)
+ TEST_CHANGED=$(echo "${{ steps.changed.outputs.files }}" | grep -E "test" || true)
+ if [ -n "$CODE_CHANGED" ] && [ -z "$TEST_CHANGED" ]; then
+ FINDINGS="${FINDINGS}🟡 **WARNING**: Code changes without corresponding tests\n"
+ fi
+
+ if [ -n "$FINDINGS" ]; then
+ echo "has_findings=true" >> $GITHUB_OUTPUT
+ echo -e "findings=$FINDINGS" >> $GITHUB_OUTPUT
+ else
+ echo "has_findings=false" >> $GITHUB_OUTPUT
+ fi
+
+ - name: Post review comment
+ if: steps.security.outputs.has_findings == 'true' || steps.quality.outputs.has_findings == 'true'
+ run: |
+ COMMENT="## 🤖 Automated PR Review\n\n"
+
+ if [ "${{ steps.security.outputs.has_findings }}" == "true" ]; then
+ COMMENT="${COMMENT}### Security Findings\n${{ steps.security.outputs.findings }}\n"
+ fi
+
+ if [ "${{ steps.quality.outputs.has_findings }}" == "true" ]; then
+ COMMENT="${COMMENT}### Code Quality\n${{ steps.quality.outputs.findings }}\n"
+ fi
+
+ COMMENT="${COMMENT}\n---\n*This is an automated review. Please address any 🔴 CRITICAL issues before merging.*"
+
+ echo -e "$COMMENT" | gh pr comment ${{ github.event.pull_request.number }} --body-file -
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Post success comment
+ if: steps.security.outputs.has_findings == 'false' && steps.quality.outputs.has_findings == 'false'
+ run: |
+ gh pr comment ${{ github.event.pull_request.number }} --body "## 🤖 Automated PR Review
+
+ ✅ No security or code quality issues detected.
+
+ ---
+ *This is an automated review.*"
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
new file mode 100644
index 0000000..05f42e4
--- /dev/null
+++ b/.github/workflows/stale.yml
@@ -0,0 +1,63 @@
+name: Stale Issue Management
+
+on:
+ schedule:
+ # Run daily at midnight UTC
+ - cron: '0 0 * * *'
+ workflow_dispatch:
+
+permissions:
+ issues: write
+ pull-requests: write
+
+jobs:
+ stale:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/stale@v9
+ with:
+ # Issue configuration
+ days-before-stale: 30
+ days-before-close: 7
+ stale-issue-label: 'stale'
+ stale-issue-message: |
+ This issue has been automatically marked as stale because it has not had recent activity.
+
+ It will be closed in 7 days if no further activity occurs.
+
+ If this issue is still relevant:
+ - Add a comment to keep it open
+ - Add a `pinned` label to prevent automatic closure
+
+ close-issue-message: |
+ This issue has been automatically closed due to inactivity.
+
+ If this is still a valid issue, please feel free to reopen it with updated information.
+
+ # PR configuration
+ days-before-pr-stale: 14
+ days-before-pr-close: 7
+ stale-pr-label: 'stale'
+ stale-pr-message: |
+ This pull request has been automatically marked as stale because it has not had recent activity.
+
+ It will be closed in 7 days if no further activity occurs.
+
+ close-pr-message: |
+ This pull request has been automatically closed due to inactivity.
+
+ If you'd like to continue working on this, please reopen or create a new PR.
+
+ # Exempt labels
+ exempt-issue-labels: 'pinned,security,bug,help-wanted'
+ exempt-pr-labels: 'pinned,security'
+
+ # Don't stale issues/PRs with assignees
+ exempt-all-assignees: true
+
+ # Remove stale label when activity occurs
+ remove-stale-when-updated: true
+
+ # Rate limiting
+ operations-per-run: 100
diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml
new file mode 100644
index 0000000..f47629a
--- /dev/null
+++ b/.github/workflows/validate.yml
@@ -0,0 +1,54 @@
+name: Validate
+
+on:
+ push:
+ branches: [main, 'validation/*']
+ pull_request:
+ branches: [main]
+ workflow_dispatch:
+
+jobs:
+ aqe-validation:
+ name: AQE Quality Checks
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup Node.js (for markdownlint)
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+
+ - name: Install markdownlint
+ run: npm install -g markdownlint-cli
+
+ - name: Run validation checks
+ run: |
+ chmod +x .github/scripts/check.sh
+ .github/scripts/check.sh
+
+ - name: Markdown linting
+ run: markdownlint docs/**/*.md README.md CLAUDE.md CONTRIBUTING.md
+
+ documentation-structure:
+ name: Documentation Structure
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Check documentation structure
+ run: |
+ # Verify patterns documentation exists
+ test -d docs/patterns || { echo "Error: docs/patterns/ missing"; exit 1; }
+ test -f docs/README.md || { echo "Error: docs/README.md missing"; exit 1; }
+ test -d docs/adr || { echo "Error: docs/adr/ missing"; exit 1; }
+ echo "All required documentation files present"
+
+ - name: Check required files
+ run: |
+ test -f CLAUDE.md || { echo "Error: CLAUDE.md missing"; exit 1; }
+ test -f .claude/agents/codebase-agent.md || { echo "Error: codebase-agent.md missing"; exit 1; }
+ test -d .claude/context || { echo "Error: .claude/context/ missing"; exit 1; }
+ echo "All required configuration files present"
diff --git a/.markdownlint.json b/.markdownlint.json
index 25ba725..0d94d87 100644
--- a/.markdownlint.json
+++ b/.markdownlint.json
@@ -1,8 +1,11 @@
{
"default": true,
"MD013": false,
+ "MD032": false,
"MD033": false,
+ "MD034": false,
"MD041": false,
"MD046": false,
- "MD051": false
+ "MD051": false,
+ "MD060": false
}
diff --git a/CLAUDE.md b/CLAUDE.md
index ec489ad..862f0c4 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -122,6 +122,20 @@ ruff check docs/examples/
markdownlint docs/**/*.md README.md CLAUDE.md --fix
```
+### Autonomous Quality Enforcement (AQE) Process Rule
+
+**ALWAYS run validation before showing work**:
+
+```bash
+# Run validation checks
+.github/scripts/check.sh
+
+# Auto-fix common issues
+.github/scripts/auto-fix.sh
+```
+
+This ensures all quality gates pass before presenting work to the user.
+
---
## Documentation Guidelines
diff --git a/pytest.ini b/pytest.ini
new file mode 100644
index 0000000..2afe20e
--- /dev/null
+++ b/pytest.ini
@@ -0,0 +1,28 @@
+[pytest]
+testpaths = tests
+python_files = test_*.py
+python_classes = Test*
+python_functions = test_*
+
+# Markers
+markers =
+ e2e: End-to-end tests (require external services)
+ unit: Unit tests (fast, isolated)
+ integration: Integration tests (may use test database)
+
+# Default options
+addopts =
+ -v
+ --tb=short
+ --strict-markers
+
+# Coverage settings (when using pytest-cov)
+# Uncomment below when pytest-cov is installed:
+# addopts =
+# -v
+# --tb=short
+# --strict-markers
+# --cov=src
+# --cov-report=html
+# --cov-report=term-missing
+# --cov-fail-under=80
diff --git a/src/__init__.py b/src/__init__.py
new file mode 100644
index 0000000..801496d
--- /dev/null
+++ b/src/__init__.py
@@ -0,0 +1 @@
+"""Source package for pattern validation examples."""
diff --git a/src/core/__init__.py b/src/core/__init__.py
new file mode 100644
index 0000000..5a6df1a
--- /dev/null
+++ b/src/core/__init__.py
@@ -0,0 +1,5 @@
+"""Core utilities package."""
+
+from .security import sanitize_string, validate_slug, sanitize_path
+
+__all__ = ["sanitize_string", "validate_slug", "sanitize_path"]
diff --git a/src/core/security.py b/src/core/security.py
new file mode 100644
index 0000000..49b0118
--- /dev/null
+++ b/src/core/security.py
@@ -0,0 +1,162 @@
+"""Security utilities for input validation and sanitization.
+
+This module provides security functions as documented in the security-patterns.md.
+All input validation and sanitization happens at the API boundary.
+"""
+
+import re
+import os
+from typing import Optional
+
+
+def sanitize_string(value: Optional[str], max_length: int = 200) -> str:
+ """
+ Sanitize a string by removing dangerous characters.
+
+ Args:
+ value: The input string to sanitize
+ max_length: Maximum allowed length (default 200)
+
+ Returns:
+ Sanitized string with:
+ - Control characters removed
+ - HTML tags removed
+ - Whitespace trimmed
+ - Length enforced
+
+ Example:
+ >>> sanitize_string(" HelloWorld ")
+ 'HelloWorld'
+ """
+ if value is None:
+ return ""
+
+ # Convert to string if needed
+ result = str(value)
+
+ # Remove control characters (ASCII 0-31, except tab/newline)
+ result = re.sub(r'[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]', '', result)
+
+ # Remove HTML tags to prevent XSS
+ result = re.sub(r'<[^>]+>', '', result)
+
+ # Trim whitespace
+ result = result.strip()
+
+ # Enforce max length
+ if len(result) > max_length:
+ result = result[:max_length]
+
+ return result
+
+
+def validate_slug(value: str) -> str:
+ """
+ Validate a URL-safe slug.
+
+ Args:
+ value: The slug to validate
+
+ Returns:
+ The validated slug (unchanged if valid)
+
+ Raises:
+ ValueError: If the slug is invalid
+
+ Valid slugs:
+ - Lowercase letters, numbers, and hyphens only
+ - Cannot start or end with hyphen
+ - Cannot have consecutive hyphens
+ - Cannot be empty
+
+ Example:
+ >>> validate_slug("valid-slug-123")
+ 'valid-slug-123'
+ >>> validate_slug("Invalid!")
+ ValueError: Slug contains invalid characters
+ """
+ if not value:
+ raise ValueError("Slug cannot be empty")
+
+ if value.startswith('-'):
+ raise ValueError("Slug cannot start with hyphen")
+
+ if value.endswith('-'):
+ raise ValueError("Slug cannot end with hyphen")
+
+ if '--' in value:
+ raise ValueError("Slug cannot contain consecutive hyphens")
+
+ if value != value.lower():
+ raise ValueError("Slug must be lowercase")
+
+ # Check for valid characters (lowercase, numbers, hyphens)
+ if not re.match(r'^[a-z0-9-]+$', value):
+ raise ValueError("Slug contains invalid characters (only lowercase letters, numbers, and hyphens allowed)")
+
+ return value
+
+
+def sanitize_path(path: str) -> str:
+ """
+ Sanitize a file path to prevent path traversal attacks.
+
+ Args:
+ path: The file path to sanitize
+
+ Returns:
+ Sanitized path with:
+ - Path traversal sequences removed
+ - Null bytes removed
+ - Multiple slashes normalized
+
+ Example:
+ >>> sanitize_path("../../../etc/passwd")
+ 'etc/passwd'
+ >>> sanitize_path("docs//file.md")
+ 'docs/file.md'
+ """
+ if not path:
+ return ""
+
+ # Remove null bytes
+ result = path.replace('\x00', '')
+
+ # Normalize path separators
+ result = result.replace('\\', '/')
+
+ # Remove path traversal sequences
+ while '..' in result:
+ result = result.replace('..', '')
+
+ # Normalize multiple slashes
+ while '//' in result:
+ result = result.replace('//', '/')
+
+ # Remove leading slash to ensure relative path
+ result = result.lstrip('/')
+
+ return result
+
+
+def validate_environment_secret(name: str) -> Optional[str]:
+ """
+ Safely retrieve a secret from environment variables.
+
+ Args:
+ name: The environment variable name
+
+ Returns:
+ The secret value, or None if not set
+
+ Note:
+ This function demonstrates the secrets management pattern:
+ - Secrets should ONLY come from environment variables
+ - Never hardcode secrets in source code
+ - Use .env files (in .gitignore) for local development
+
+ Example:
+ >>> validate_environment_secret("API_KEY")
+ 'secret-value-from-env'
+ """
+ return os.environ.get(name)
diff --git a/tests/conftest.py b/tests/conftest.py
new file mode 100644
index 0000000..f9f54b3
--- /dev/null
+++ b/tests/conftest.py
@@ -0,0 +1,41 @@
+"""Shared fixtures for testing."""
+
+import pytest
+
+
+@pytest.fixture
+def sample_string():
+ """Sample string for testing sanitization."""
+ return "Test String"
+
+
+@pytest.fixture
+def dangerous_string():
+ """String with dangerous characters for security testing."""
+ return ""
+
+
+@pytest.fixture
+def path_traversal_string():
+ """String attempting path traversal."""
+ return "../../../etc/passwd"
+
+
+@pytest.fixture
+def valid_slug():
+ """Valid URL-safe slug."""
+ return "valid-slug-123"
+
+
+@pytest.fixture
+def invalid_slugs():
+ """List of invalid slugs for testing."""
+ return [
+ "", # empty
+ "-test", # starts with hyphen
+ "test-", # ends with hyphen
+ "test--name", # consecutive hyphens
+ "Test", # uppercase
+ "test name", # space
+ "test@name", # special char
+ ]
diff --git a/tests/e2e/__init__.py b/tests/e2e/__init__.py
new file mode 100644
index 0000000..8b96df1
--- /dev/null
+++ b/tests/e2e/__init__.py
@@ -0,0 +1 @@
+"""End-to-end tests for complete workflows."""
diff --git a/tests/e2e/test_cba_workflow.py b/tests/e2e/test_cba_workflow.py
new file mode 100644
index 0000000..df8ad78
--- /dev/null
+++ b/tests/e2e/test_cba_workflow.py
@@ -0,0 +1,55 @@
+"""End-to-end tests for Codebase Agent workflow.
+
+These tests demonstrate the complete CBA workflow pattern.
+They are marked as e2e and require GitHub API credentials to run.
+"""
+
+import pytest
+
+
+@pytest.mark.e2e
+class TestCBAWorkflow:
+ """E2E tests for Codebase Agent automation."""
+
+ @pytest.mark.skip(reason="Requires GitHub API credentials")
+ def test_issue_to_pr_workflow(self):
+ """
+ Test complete issue-to-PR workflow.
+
+ Workflow:
+ 1. Create GitHub issue with clear acceptance criteria
+ 2. Apply 'ready-for-pr' label
+ 3. Wait for workflow to create draft PR
+ 4. Verify PR is linked to issue
+ 5. Verify PR has proper description
+ 6. Clean up (close PR, delete branch)
+ """
+ pass
+
+ @pytest.mark.skip(reason="Requires GitHub API credentials")
+ def test_pr_auto_review_workflow(self):
+ """
+ Test PR auto-review workflow.
+
+ Workflow:
+ 1. Create PR with test changes
+ 2. Wait for auto-review workflow
+ 3. Verify review comment posted
+ 4. Verify security issues flagged
+ 5. Clean up
+ """
+ pass
+
+ @pytest.mark.skip(reason="Requires GitHub API credentials")
+ def test_dependabot_auto_merge_workflow(self):
+ """
+ Test Dependabot auto-merge workflow.
+
+ Workflow:
+ 1. Simulate Dependabot patch PR
+ 2. Wait for auto-merge workflow
+ 3. Verify PR is auto-merged
+ 4. Simulate minor update PR
+ 5. Verify human review required
+ """
+ pass
diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py
new file mode 100644
index 0000000..88865b8
--- /dev/null
+++ b/tests/integration/__init__.py
@@ -0,0 +1 @@
+"""Integration tests for API endpoints."""
diff --git a/tests/integration/test_validation_api.py b/tests/integration/test_validation_api.py
new file mode 100644
index 0000000..e28316e
--- /dev/null
+++ b/tests/integration/test_validation_api.py
@@ -0,0 +1,45 @@
+"""Integration tests demonstrating API boundary validation."""
+
+import pytest
+
+# Note: This is an example test structure for documentation purposes.
+# A real implementation would use FastAPI TestClient.
+
+
+class TestAPIValidation:
+ """Tests for API input validation at boundary."""
+
+ def test_valid_input_accepted(self):
+ """Valid input should be accepted and processed."""
+ # Example: POST /api/v1/items with valid data
+ # Response should be 201 Created
+ valid_data = {"name": "Test Item", "slug": "test-item"}
+ # client.post("/api/v1/items", json=valid_data)
+ # assert response.status_code == 201
+ assert valid_data["name"] == "Test Item"
+
+ def test_invalid_slug_rejected(self):
+ """Invalid slug should return 422 Unprocessable Entity."""
+ # Example: POST /api/v1/items with invalid slug
+ invalid_data = {"name": "Test", "slug": "Invalid Slug!"}
+ # response = client.post("/api/v1/items", json=invalid_data)
+ # assert response.status_code == 422
+ assert "!" in invalid_data["slug"]
+
+ def test_missing_required_field_rejected(self):
+ """Missing required field should return 422."""
+ # Example: POST /api/v1/items without name
+ incomplete_data = {"slug": "test"}
+ # response = client.post("/api/v1/items", json=incomplete_data)
+ # assert response.status_code == 422
+ assert "name" not in incomplete_data
+
+ def test_xss_attempt_sanitized(self):
+ """XSS attempt in input should be sanitized."""
+ # Example: POST /api/v1/items with XSS payload
+ xss_data = {"name": "", "slug": "test"}
+ # response = client.post("/api/v1/items", json=xss_data)
+ # data = response.json()
+ # assert "Hello"
+
+ # Act
+ result = sanitize_string(input_str)
+
+ # Assert
+ assert "