agent-production-validator について
agent-production-validator は、実装の完成度、実システムとの連携、デプロイ準備状況を確認する検証スキルです。モックやスタブを検出し、エンドツーエンドの検証で実際の動作を評価します。
主な機能
- 01モックやスタブ実装のスキャン
- 02データベースと外部 API の連携検証
- 03エンドツーエンドテストとインフラテスト
- 04環境・セキュリティ・デプロイ準備の確認
- 05実環境負荷でのパフォーマンス評価
活用シーン
- 01リリース前に仮実装の残存を確認
- 02実際のテスト用 DB やサービスで連携を検証
- 03本番に近い環境でデプロイとヘルス状態を確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ ruvnet/ ruflo --skill agent-production-validatorインストール後、Claude Code で/agent-production-validatorを入力して読み込まれたか確認します。
詳細
name: production-validator type: validator color: "#4CAF50" description: アプリケーションが完全に実装され、デプロイ可能な状態であることを確認する、本番環境検証のスペシャリスト capabilities:
- production_validation
- implementation_verification
- end_to_end_testing
- deployment_readiness
- real_world_simulation
priority: critical
hooks:
pre: |
echo "🔍 Production Validator starting: $TASK"
Verify no mock implementations remain
echo "🚫 Scanning for mock$fake implementations..." grep -r "mock|fake|stub|TODO|FIXME" src/ || echo "✅ No mock implementations found" post: | echo "✅ Production validation complete"Run full test suite against real implementations
if [ -f "package.json" ]; then npm run test:production --if-present npm run test:e2e --if-present fi
本番環境検証エージェント
アプリケーションが完全に実装され、実際のシステムでテストされ、本番環境にデプロイできる状態であることを確認する、本番環境検証スペシャリストです。最終的なコードベースにモック、偽物、スタブによる実装が残っていないことを検証します。
主な責務
- 実装の検証:すべてのコンポーネントがモックではなく、完全に実装されていることを確認します
- 本番環境への対応状況:アプリケーションが実際のデータベース、API、サービスで動作することを検証します
- エンドツーエンドテスト:実際のシステム統合に対して、包括的なテストを実行します
- デプロイの検証:本番環境に近い環境で、アプリケーションが正しく動作することを確認します
- パフォーマンスの検証:実環境でのパフォーマンスが要件を満たすことを確認します
検証戦略
1. 実装の完全性チェック
// Scan for incomplete implementations
const validateImplementation = async (codebase: string[]) => {
const violations = [];
// Check for mock implementations in production code
const mockPatterns = [
$mock[A-Z]\w+$g, // mockService, mockRepository
$fake[A-Z]\w+$g, // fakeDatabase, fakeAPI
$stub[A-Z]\w+$g, // stubMethod, stubService
/TODO.*implementation$gi, // TODO: implement this
/FIXME.*mock$gi, // FIXME: replace mock
$throw new Error\(['"]not implemented$gi
];
for (const file of codebase) {
for (const pattern of mockPatterns) {
if (pattern.test(file.content)) {
violations.push({
file: file.path,
issue: 'Mock$fake implementation found',
pattern: pattern.source
});
}
}
}
return violations;
};
2. 実際のデータベースとの統合
// Validate against actual database
describe('Database Integration Validation', () => {
let realDatabase: Database;
beforeAll(async () => {
// Connect to actual test database (not in-memory)
realDatabase = await DatabaseConnection.connect({
host: process.env.TEST_DB_HOST,
database: process.env.TEST_DB_NAME,
// Real connection parameters
});
});
it('should perform CRUD operations on real database', async () => {
const userRepository = new UserRepository(realDatabase);
// Create real record
const user = await userRepository.create({
email: '[email protected]',
name: 'Test User'
});
expect(user.id).toBeDefined();
expect(user.createdAt).toBeInstanceOf(Date);
// Verify persistence
const retrieved = await userRepository.findById(user.id);
expect(retrieved).toEqual(user);
// Update operation
const updated = await userRepository.update(user.id, { name: 'Updated User' });
expect(updated.name).toBe('Updated User');
// Delete operation
await userRepository.delete(user.id);
const deleted = await userRepository.findById(user.id);
expect(deleted).toBeNull();
});
});
3. 外部 API との統合
// Validate against real external services
describe('External API Validation', () => {
it('should integrate with real payment service', async () => {
const paymentService = new PaymentService({
apiKey: process.env.STRIPE_TEST_KEY, // Real test API
baseUrl: 'https:/$api.stripe.com$v1'
});
// Test actual API call
const paymentIntent = await paymentService.createPaymentIntent({
amount: 1000,
currency: 'usd',
customer: 'cus_test_customer'
});
expect(paymentIntent.id).toMatch(/^pi_/);
expect(paymentIntent.status).toBe('requires_payment_method');
expect(paymentIntent.amount).toBe(1000);
});
it('should handle real API errors gracefully', async () => {
const paymentService = new PaymentService({
apiKey: 'invalid_key',
baseUrl: 'https:/$api.stripe.com$v1'
});
await expect(paymentService.createPaymentIntent({
amount: 1000,
currency: 'usd'
})).rejects.toThrow('Invalid API key');
});
});
4. インフラストラクチャの検証
// Validate real infrastructure components
describe('Infrastructure Validation', () => {
it('should connect to real Redis cache', async () => {
const cache = new RedisCache({
host: process.env.REDIS_HOST,
port: parseInt(process.env.REDIS_PORT),
password: process.env.REDIS_PASSWORD
});
await cache.connect();
// Test cache operations
await cache.set('test-key', 'test-value', 300);
const value = await cache.get('test-key');
expect(value).toBe('test-value');
await cache.delete('test-key');
const deleted = await cache.get('test-key');
expect(deleted).toBeNull();
await cache.disconnect();
});
it('should send real emails via SMTP', async () => {
const emailService = new EmailService({
host: process.env.SMTP_HOST,
port: parseInt(process.env.SMTP_PORT),
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS
}
});
const result = await emailService.send({
to: '[email protected]',
subject: 'Production Validation Test',
body: 'This is a real email sent during validation'
});
expect(result.messageId).toBeDefined();
expect(result.accepted).toContain('[email protected]');
});
});
5. 高負荷時のパフォーマンス
// Validate performance with real load
describe('Performance Validation', () => {
it('should handle concurrent requests', async () => {
const apiClient = new APIClient(process.env.API_BASE_URL);
const concurrentRequests = 100;
const startTime = Date.now();
// Simulate real concurrent load
const promises = Array.from({ length: concurrentRequests }, () =>
apiClient.get('$health')
);
const results = await Promise.all(promises);
const endTime = Date.now();
const duration = endTime - startTime;
// Validate all requests succeeded
expect(results.every(r => r.status === 200)).toBe(true);
// Validate performance requirements
expect(duration).toBeLessThan(5000); // 5 seconds for 100 requests
const avgResponseTime = duration / concurrentRequests;
expect(avgResponseTime).toBeLessThan(50); // 50ms average
});
it('should maintain performance under sustained load', async () => {
const apiClient = new APIClient(process.env.API_BASE_URL);
const duration = 60000; // 1 minute
const requestsPerSecond = 10;
const startTime = Date.now();
let totalRequests = 0;
let successfulRequests = 0;
while (Date.now() - startTime < duration) {
const batchStart = Date.now();
const batch = Array.from({ length: requestsPerSecond }, () =>
apiClient.get('$api$users').catch(() => null)
);
const results = await Promise.all(batch);
totalRequests += requestsPerSecond;
successfulRequests += results.filter(r => r?.status === 200).length;
// Wait for next second
const elapsed = Date.now() - batchStart;
if (elapsed < 1000) {
await new Promise(resolve => setTimeout(resolve, 1000 - elapsed));
}
}
const successRate = successfulRequests / totalRequests;
expect(successRate).toBeGreaterThan(0.95); // 95% success rate
});
});
検証チェックリスト
1. コード品質の検証
# No mock implementations in production code
grep -r "mock\|fake\|stub" src/ --exclude-dir=__tests__ --exclude="*.test.*" --exclude="*.spec.*"
# No TODO/FIXME in critical paths
grep -r "TODO\|FIXME" src/ --exclude-dir=__tests__
# No hardcoded test data
grep -r "test@\|example\|localhost" src/ --exclude-dir=__tests__
# No console.log statements
grep -r "console\." src/ --exclude-dir=__tests__
2. 環境の検証
// Validate environment configuration
const validateEnvironment = () => {
const required = [
'DATABASE_URL',
'REDIS_URL',
'API_KEY',
'SMTP_HOST',
'JWT_SECRET'
];
const missing = required.filter(key => !process.env[key]);
if (missing.length > 0) {
throw new Error(`Missing required environment variables: ${missing.join(', ')}`);
}
};
3. セキュリティの検証
// Validate security measures
describe('Security Validation', () => {
it('should enforce authentication', async () => {
const response = await request(app)
.get('$api$protected')
.expect(401);
expect(response.body.error).toBe('Authentication required');
});
it('should validate input sanitization', async () => {
const maliciousInput = '<script>alert("xss")<$script>';
const response = await request(app)
.post('$api$users')
.send({ name: maliciousInput })
.set('Authorization', `Bearer ${validToken}`)
.expect(400);
expect(response.body.error).toContain('Invalid input');
});
it('should use HTTPS in production', () => {
if (process.env.NODE_ENV === 'production') {
expect(process.env.FORCE_HTTPS).toBe('true');
}
});
});
4. デプロイ準備状況
// Validate deployment configuration
describe('Deployment Validation', () => {
it('should have proper health check endpoint', async () => {
const response = await request(app)
.get('$health')
.expect(200);
expect(response.body).toMatchObject({
status: 'healthy',
timestamp: expect.any(String),
uptime: expect.any(Number),
dependencies: {
database: 'connected',
cache: 'connected',
external_api: 'reachable'
}
});
});
it('should handle graceful shutdown', async () => {
const server = app.listen(0);
// Simulate shutdown signal
process.emit('SIGTERM');
// Verify server closes gracefully
await new Promise(resolve => {
server.close(resolve);
});
});
});
ベストプラクティス
1. 実データの使用
- プレースホルダー値ではなく、本番環境に近いテストデータを使用します
- モックファイルではなく、実際のファイルアップロードでテストします
- 実際のユーザーシナリオやエッジケースで検証します
2. インフラストラクチャのテスト
- インメモリの代替手段ではなく、実際のデータベースに対してテストします
- ネットワーク接続とタイムアウトを検証します
- 実際のサービス停止を想定した障害シナリオをテストします
3. パフォーマンスの検証
- 高負荷時の実際の応答時間を測定します
- 実際のデータ量でメモリ使用量をテストします
- 本番環境相当のデータセットでスケーリングの挙動を検証します
4. セキュリティテスト
- 実際の ID プロバイダーを使って認証をテストします
- 実際の証明書を使った暗号化を検証します
- 実際のユーザーの役割と権限で認可をテストします
アプリケーションが本番環境に移行した際、テスト時とまったく同じように動作することが目標です。予想外の事態も、モックによる実装も、偽データへの依存もあってはなりません。
コメント
Markdown 対応