claw-code/.guardrails/docs/standards/TEST_PRODUCTION_SEPARATION.md

15 KiB

Test/Production Separation Standards

MANDATORY: All testing infrastructure must be fully isolated from production.

Related: AGENT_GUARDRAILS.md | CODE_REVIEW.md


Overview

This document establishes mandatory standards for separating test and production environments. All testing code, data, services, and infrastructure must be completely isolated from production to prevent data corruption, unintended changes, and security incidents.

BLOCKING VIOLATION: Any violation of these standards is a blocking error requiring immediate resolution.


CORE MANDATORY RULES

The Three Laws of Test/Production Separation

1. PRODUCTION CODE IS CREATED FIRST
   - Production code MUST exist before any test code
   - Tests MUST NOT create production resources
   - Test code exists ONLY to validate production code

2. ALL TESTING INFRASTRUCTURE IS SEPARATE
   - Separate database instances (not just schemas)
   - Separate service instances
   - Separate user accounts
   - Separate network configurations

3. WHEN IN DOUBT, ASK THE USER
   - If test/production boundary is unclear → ASK
   - If environment separation is ambiguous → ASK
   - Never assume or guess deployment target

Mandatory Pre-Code Checklist

Before creating ANY code, verify:

Check Requirement Verify
PRODUCTION FIRST Production code created before test code [ ]
DATABASE ISOLATION Test DB is separate instance from prod DB [ ]
SERVICE ISOLATION Test services are separate from prod [ ]
USER SEPARATION Test users are separate from prod users [ ]
CLEAR LABELING Test code is clearly labeled or removed [ ]
UNCERTAINTY CHECK If unclear, have you asked the user? [ ]

ENVIRONMENT SEPARATION REQUIREMENTS

Database Separation

Environment Database Instance Access Rules Connection Config
Production prod-db.example.com:5432 Production users only DATABASE_URL=prod://...
Testing test-db.example.com:5432 Test users only DATABASE_URL=test://...
Development dev-db.example.com:5432 Developers only DATABASE_URL=dev://...

MANDATORY RULE:

NEVER:
  ✓ Use production database for tests
  ✓ Use test database for production
  ✓ Share connections between environments
  ✓ Use same credentials across environments

ALWAYS:
  ✓ Separate database instances for each environment
  ✓ Separate credentials for each environment
  ✓ Separate connection strings in config
  ✓ Validate database instance before queries

Service Separation

PRODUCTION SERVICES:
  API: api.production.com
  Auth: auth.production.com
  Storage: storage.production.com

TEST SERVICES:
  API: api.test.example.com
  Auth: auth.test.example.com
  Storage: storage.test.example.com

DEVELOPMENT SERVICES:
  API: api.dev.example.com
  Auth: auth.dev.example.com
  Storage: storage.dev.example.com

MANDATORY RULE:

NEVER:
  ✓ Use production services for tests
  ✓ Write test code that depends on prod endpoints
  ✓ Route test traffic through production infrastructure

ALWAYS:
  ✓ Configure separate service endpoints per environment
  ✓ Validate service endpoint before requests
  ✓ Use environment-specific configuration files
  ✓ Route test traffic to test environment

User Account Separation

PRODUCTION USERS (real data):
  user_001, user_002, user_003...
  - Real data with privacy requirements
  - Protected by compliance policies

TEST USERS (synthetic data):
  test_user_001, test_user_002, qatest_003...
  - Synthetic/fake data only
  - Clearly identified in database
  - Never mixed with production users

ADMINISTRATIVE USERS:
  prod_admin → Production admin only
  test_admin → Test environment only
  dev_admin  → Development only

MANDATORY RULE:

NEVER:
  ✓ Create test users in production database
  ✓ Create real users in test database
  ✓ Share user accounts across environments
  ✓ Use production credentials in test code

ALWAYS:
  ✓ Separate user accounts per environment
  ✓ Clearly label test users with prefixes (test_*, qa_*)
  ✓ Separate authentication systems per environment
  ✓ Use different passwords/tokens per environment

CODE CREATION SEQUENCE

Mandatory Order of Operations

STEP 1: CREATE PRODUCTION CODE FIRST
   ↓
   - Implement the feature/functionality
   - Deploy to production environment
   - Verify production code works
   ↓
STEP 2: CREATE TEST INFRASTRUCTURE
   ↓
   - Set up separate test database
   - Set up separate test services
   - Set up test user accounts
   ↓
STEP 3: CREATE TEST CODE
   ↓
   - Write tests for production code
   - Configure test to use test environment
   - Verify tests execute in isolation
   ↓
STEP 4: CLEANUP TEST CODE (optional)
   ↓
   - Remove test code OR
   - Label test code clearly
   - Document test infrastructure

Anti-Pattern: Creating Test Code First

WRONG (FORBIDDEN):

[Create test code]
  → [Create test users in production DB]
  → [Run tests on production data]
  → [CORRUPTS PRODUCTION DATABASE]

CORRECT:

[Create production code]
  → [Deploy to production]
  → [Set up separate test environment]
  → [Create test code]
  → [Run tests in isolation]

TEST CODE LABELING REQUIREMENTS

When to Label vs Remove

Scenario Action Rationale
Unit tests in test files Keep Standard test infrastructure
Integration tests Keep in test/ directory Standard pattern
Test code mixed with production REMOVE Code pollution
Debug code in production REMOVE Security risk
Mock implementations Keep in mocks/ directory Standard pattern

Labeling Standards

If test code must coexist with production code, use these labels:

// JavaScript/TypeScript
// @test-only - DO NOT USE IN PRODUCTION
const testHelper = () => { ... };
# Python
# @test-only: DO NOT USE IN PRODUCTION
def test_helper():
    pass
// Rust
// @test-only: DO NOT USE IN PRODUCTION
#[cfg(test)]
fn test_helper() {
}
// Go
// @test-only: DO NOT USE IN PRODUCTION
// +build test

func testHelper() {
}

Alternative: File-based separation

prod/
  handler.py      ← Production code
  service.js      ← Production code
test/
  handler_test.py ← Test code
  service_test.js ← Test code

UNCERTAINTY HANDLING PROTOCOL

Mandatory Ask Triggers

ALWAYS ask the end user if ANY of these apply:

UNCERTAINTY TRIGGERS (ALWAYS ASK):

[ ] Not sure if database is test or production
[ ] Environment configuration unclear
[ ] Service endpoints not clearly differentiated
[ ] User account naming convention unclear
[ ] Test code location ambiguous
[ ] Whether to label or remove test code
[ ] Database connection strings not environment-specific
[ ] Configuration files not clearly labeled by environment

Ask Template

When uncertain, use this template:

UNCERTAINTY QUESTION:

"I need clarification on test/production separation:

CONTEXT: [describe what you're doing]
UNCERTAINTY: [what you're unclear about]
CURRENT ASSUMPTION: [what you would assume]
QUESTION: [what you need answered]

OPTIONS:
1. Option A: [description]
2. Option B: [description]
3. Other: [please specify]

Please confirm which option is correct."

Example Scenarios

Scenario 1: Database Uncertainty

"UNCERTAINTY QUESTION:

I see database connection: DATABASE_URL=postgres://user:pass@db:5432/app

CONTEXT: Creating test infrastructure
UNCERTAINTY: Is this test database or production database?
CURRENT ASSUMPTION: This is test database based on local host
QUESTION: Should I use this database for tests, or is there a separate test DB?

OPTIONS:
1. Use this database for tests (it's already isolated)
2. Create separate test database (need separate instance)
3. Other: please specify"

Scenario 2: Test Code Placement

"UNCERTAINTY QUESTION:

I need to create test code for user authentication validation.

CONTEXT: Adding authentication feature + tests
UNCERTAINTY: Where should test code be placed?
CURRENT ASSUMPTION: Create test/auth_test.py file
QUESTION: Is this correct, or should tests be in a different location?

OPTIONS:
1. Create test/auth_test.py (standard)
2. Add test code inline in auth.py (with @test-only labels)
3. Other: please specify"

VERIFICATION CHECKLISTS

Pre-Commit Verification

Before committing ANY changes:

[ ] Production code exists and is committed first
[ ] Test database is separate instance (not just schema)
[ ] Test services are separate endpoints
[ ] Test users have test_ or qa_ prefixes
[ ] Connection strings use different hosts per environment
[ ] No test code in production files
[ ] Test code labeled with @test-only if inline
[ ] Configuration files clearly labeled by environment
[ ] Asked user if any uncertainty existed
[ ] No hardcoded production credentials in test code

Pre-Push Verification

Before pushing to remote:

[ ] All pre-commit checks pass
[ ] CI/CD pipeline validates test/production separation
[ ] No production database connections in test code
[ ] No test database connections in production code
[ ] Environment variables are properly set
[ ] Secrets not committed to repository
[ ] Documentation updated with test/production setup
[ ] Code review confirms separation

CI/CD Blocking Checks

These checks must pass or deployment is BLOCKED:

BLOCKING CHECKS (MUST PASS):

✓ No production credentials in test files
✓ No test database connections in production files
✓ Database URLs validate as environment-specific
✓ Service endpoints validate as environment-specific
✓ Test files contain test_ or _test in filename
✓ Production files do NOT contain @test-only code
✓ Environment variables are set correctly
✓ Secrets management validated

IF ANY FAIL: BLOCK DEPLOYMENT

EXAMPLES AND PATTERNS

Good Pattern: Environment-Specific Config

# config/production.yaml
environment: production
database:
  host: prod-db.example.com
  port: 5432
  name: production_db
  user: prod_user
  password: ${PROD_DB_PASSWORD}
services:
  api: api.production.com

---

# config/test.yaml
environment: test
database:
  host: test-db.example.com
  port: 5432
  name: test_db
  user: test_user
  password: ${TEST_DB_PASSWORD}
services:
  api: api.test.example.com

Good Pattern: Environment Loading

# config_loader.py
import os
import yaml

ENV = os.getenv('APP_ENV', 'development')

def load_config():
    config_path = f'config/{ENV}.yaml'
    with open(config_path, 'r') as f:
        return yaml.safe_load(f)

config = load_config()

# Usage
database_url = f"postgresql://{config['database']['user']}:"
                f"{config['database']['password']}@"
                f"{config['database']['host']}:"
                f"{config['database']['port']}/"
                f"{config['database']['name']}"

Anti-Pattern: Hardcoded Production URLs

# BAD - FORBIDDEN
def connect_database():
    # WRONG: Hardcoded production URL
    conn = psycopg2.connect("postgresql://prod_user:pass@prod-db:5432/prod_db")
    return conn

Good Pattern: Environment Variable Loading

# GOOD - CORRECT
def connect_database():
    config = load_config()
    conn = psycopg2.connect(
        host=config['database']['host'],
        port=config['database']['port'],
        database=config['database']['name'],
        user=config['database']['user'],
        password=config['database']['password']
    )
    return conn

BLOCKING VIOLATIONS

Immediate Halt Conditions

STOP IMMEDIATELY if ANY of these are detected:

CRITICAL VIOLATIONS (HALT):

✓ Attempting to create test users in production database
✓ Attempting to write test data in production database
✓ Test code connecting to production database
✓ Production code connecting to test database
✓ Sharing user accounts across environments
✓ sharing service endpoints across environments
✓ Test code in production files without @test-only
✓ Hardcoded production credentials in test files
✓ No environment-specific configuration detected
✓ Uncertainty not resolved and proceeding anyway

Notification Protocol

WHEN VIOLATION DETECTED:

1. HALT IMMEDIATELY
2. Report exact violation
3. Report file and line number
4. Explain why it's dangerous
5. Request user guidance
6. DO NOT proceed without user confirmation

QUICK REFERENCE

+------------------------------------------------------------------+
|         TEST/PRODUCTION SEPARATION QUICK REFERENCE                |
+------------------------------------------------------------------+
| MANDATORY RULES:                                                 |
|   1. Production code CREATED FIRST                               |
|   2. All test infrastructure SEPARATE (DBs, services, users)     |
|   3. If unsure, ASK THE USER                                     |
+------------------------------------------------------------------+
| CHECKLIST:                                                       |
|   [ ] Production code exists first                               |
|   [ ] Test DB is separate instance                               |
|   [ ] Test services are separate endpoints                       |
|   [ ] Test users have test_/qa_ prefixes                         |
|   [ ] Test code labeled or removed                               |
|   [ ] Config files clearly labeled by env                        |
+------------------------------------------------------------------+
| NEVER DO:                                                        |
|   ✗ Create test users in production                             |
|   ✗ Use production DB for tests                                 |
|   ✗ Hardcode prod credentials in test code                      |
|   ✗ Proceed when uncertain                                      |
+------------------------------------------------------------------+
| WHEN UNCERTAIN:                                                  |
|   "I need clarification on test/production separation:"         |
|   → Describe context and uncertainty                            |
|   → Present options                                             |
|   → Wait for user confirmation                                  |
+------------------------------------------------------------------+
| BLOCKING VIOLATIONS:                                             |
|   Test code in prod, prod connections in test code               |
|   → CI/CD blocks deployment if detected                          |
+------------------------------------------------------------------+

Authored by: TheArchitectit Document Owner: Project Maintainers Review Cycle: Monthly Last Review: 2026-01-16 Next Review: 2026-02-16