# Aphoria Configuration for cachewrap Dogfood Project # Purpose: Validate multi-domain flywheel (httpclient + dbpool + msgqueue → cache) [project] name = "cachewrap-dogfood" version = "0.1.0" [scan] # Include all Rust source files include = ["src/**/*.rs"] # Exclude test files and build artifacts from scanning exclude = ["tests/**/*.rs", "target/**"] [episteme] # CRITICAL: Use persistent mode (not ephemeral) for pattern learning # This enables the flywheel - pattern aggregation across scans mode = "persistent" # Corpus database location (matches API's STEMEDB_CORPUS_DB_DIR) corpus_db = "/home/jml/.aphoria/corpus-db" [corpus] # Enable pattern aggregation (flywheel mechanism) aggregation_enabled = true # Include corpus sources for pattern reuse sources = [ "httpclient", # Async patterns: timeout, TLS, retry "dbpool", # Connection patterns: max_connections, lifecycle "msgqueue", # Messaging patterns: backpressure, metrics ] # Include all corpus types include_rfc = true # RFC normative statements include_owasp = true # OWASP cheat sheets (security claims) include_vendor = true # Vendor docs (Redis, AWS ElastiCache) use_community = true # Community-learned patterns # Cache directory for downloaded sources cache_dir = "/home/jml/.aphoria/cache" # ============================================================================ # EXTRACTORS CONFIGURATION # ============================================================================ # By default, all 42 built-in extractors run (security patterns: TLS, secrets, # injection, timeouts, etc.). Custom extractors will be created on Day 3 via # /aphoria-custom-extractor-creator skill. # # Built-in extractors that may detect violations: # - hardcoded_secrets: Detects violation 3 (plaintext password) # - tls_config: Detects violation 2 (verify_tls = false) # - timeout_config: May detect violation 8 (timeout = 0) # # Custom extractors needed (created on Day 3): # - key_validation: Violation 1 (no validate_key call) # - ttl_presence: Violation 4 (SET without EX/PX) # - max_size_check: Violation 5 (max_size = None) # - async_check: Violation 6 (blocking calls in async) # - eviction_policy_check: Violation 7 (eviction_policy = None) # - connection_pool_check: Violation 9 (no pooling) # - metrics_check: Violation 10 (metrics_enabled = false) # ============================================================================ [extractors] [extractors.inline_markers] # Enable @aphoria:claim comments enabled = true sync_to_pending = true # ============================================================================ # CUSTOM DECLARATIVE EXTRACTORS (Day 3) # ============================================================================ # Extractor 1: Detect missing key validation [[extractors.declarative]] name = "cache_key_validation_missing" description = "Detects get() method accepting raw &str keys without validation (enables injection attacks)" languages = ["rust"] pattern = 'pub\s+async\s+fn\s+get\s*\(&self,\s*key:\s*&str\)' claim.subject = "cache/key_validation" claim.predicate = "required" claim.value = false confidence = 0.9 # Extractor 2: Detect TLS verification disabled [[extractors.declarative]] name = "tls_verification_disabled" description = "Detects verify_tls: false in cache config (enables MITM attacks)" languages = ["rust"] pattern = 'verify_tls:\s*false' claim.subject = "cache/tls/certificate_validation" claim.predicate = "required" claim.value = false confidence = 0.95 # Extractor 3: Detect hardcoded passwords [[extractors.declarative]] name = "hardcoded_password" description = "Detects hardcoded password strings in cache config" languages = ["rust"] pattern = 'password:\s*"[^"]+"\.to_string\(\)' claim.subject = "cache/credentials/password" claim.predicate = "hardcoded" claim.value = true confidence = 0.9 # Extractor 4: Detect missing TTL [[extractors.declarative]] name = "ttl_missing" description = "Detects SET commands without TTL (causes memory leak)" languages = ["rust"] pattern = 'conn\.set::<[^>]+>\([^)]+\)\.await\?;' claim.subject = "cache/ttl" claim.predicate = "required" claim.value = false confidence = 0.85 # Extractor 5: Detect unbounded max_size [[extractors.declarative]] name = "max_size_unbounded" description = "Detects max_size: None (unbounded cache allows OOM)" languages = ["rust"] pattern = 'max_size:\s*None' claim.subject = "cache/max_size" claim.predicate = "bounded" claim.value = false confidence = 0.95 # Extractor 6: Detect blocking in async [[extractors.declarative]] name = "async_blocking" description = "Detects blocking get_connection() in async functions" languages = ["rust"] pattern = 'self\.client\.get_connection\(\)' claim.subject = "cache/async/blocking_forbidden" claim.predicate = "required" claim.value = false confidence = 0.9 # Extractor 7: Detect missing eviction policy [[extractors.declarative]] name = "eviction_policy_missing" description = "Detects eviction_policy: None (undefined behavior when cache full)" languages = ["rust"] pattern = 'eviction_policy:\s*None' claim.subject = "cache/eviction_policy" claim.predicate = "required" claim.value = false confidence = 0.95 # Extractor 8: Detect zero timeout [[extractors.declarative]] name = "timeout_zero" description = "Detects Duration::from_secs(0) timeout (indefinite blocking)" languages = ["rust"] pattern = 'timeout:\s*Duration::from_secs\(0\)' claim.subject = "cache/timeout" claim.predicate = "max_value" claim.value_from_match = false claim.value = 0.0 confidence = 1.0 # Extractor 9: Detect missing connection pooling [[extractors.declarative]] name = "connection_pool_missing" description = "Detects get_multiplexed_async_connection() per request (resource exhaustion)" languages = ["rust"] pattern = 'let\s+mut\s+conn\s*=\s*self\.client\.get_multiplexed_async_connection\(\)\.await' claim.subject = "cache/connection/max_connections" claim.predicate = "bounded" claim.value = false confidence = 0.85 # Extractor 10: Detect metrics disabled [[extractors.declarative]] name = "metrics_disabled" description = "Detects metrics_enabled: false (prevents production debugging)" languages = ["rust"] pattern = 'metrics_enabled:\s*false' claim.subject = "cache/metrics/enabled" claim.predicate = "required" claim.value = false confidence = 0.95 # Thresholds for conflict severity verdicts [thresholds] block_threshold = 0.7 # Conflict score >= 0.7 → BLOCK (critical violations) flag_threshold = 0.5 # Conflict score >= 0.5 → FLAG (warnings)