Completes Task #3 of httpclient dogfooding with 100% detection rate (7/7 violations). ## New Extractors - **OptionBoundsExtractor**: Detects Option<T> fields set to None (unbounded) - **OptionValueExtractor**: Extracts values from Some(n) for threshold checks Both extractors use context-aware pattern matching to understand Rust Option<T> semantics, which declarative extractors cannot handle. ## Implementation **Files Created**: - applications/aphoria/src/extractors/option_bounds.rs (257 lines) - applications/aphoria/src/extractors/option_value.rs (277 lines) - applications/aphoria/docs/examples/extractors/programmatic-option-semantics.md **Files Modified**: - applications/aphoria/src/extractors/mod.rs - Added module declarations - applications/aphoria/src/extractors/registry.rs - Registered extractors - applications/aphoria/dogfood/httpclient/.aphoria/claims.toml - Added 4 claims - applications/aphoria/dogfood/httpclient/TASK-1-SUMMARY.md - Task #3 completion ## Results | Metric | Value | |--------|-------| | Detection Rate | 100% (7/7 violations) | | Improvement | +29 percentage points (from 71%) | | New Violations | 2 (max_redirects, max_retries unbounded) | | Unit Tests | 13 (all passing) | ## Two-Claim Strategy For each bounded Option<T> field: 1. **configured** claim - Detects None (unbounded) 2. **max_value** claim - Validates Some(n) threshold Example: - `max_redirects: None` → CONFLICT (not configured) - `max_redirects: Some(20)` → CONFLICT (exceeds 10) - `max_redirects: Some(5)` → PASS ## Enterprise Quality ✓ Proper error handling (no unwrap/expect) ✓ Comprehensive tests (6+7 unit tests) ✓ Full documentation with examples ✓ Reusable for 10+ similar patterns ✓ Screening patterns for performance ## Cachewrap Dogfood Also includes complete cachewrap dogfood exercise: - 10 claims for Redis cache wrapper - Day 1-5 summaries - Full retrospective and evaluation - Declarative extractors for all patterns Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
418 lines
14 KiB
TOML
418 lines
14 KiB
TOML
[[claim]]
|
|
id = "httpclient-connect-timeout-001"
|
|
concept_path = "httpclient/connect_timeout"
|
|
predicate = "max_value"
|
|
value = 10.0
|
|
comparison = "equals"
|
|
provenance = "Mozilla HTTP docs + Requests library (10s connect timeout)"
|
|
invariant = "TCP connection timeout MUST NOT exceed 10 seconds"
|
|
consequence = "Unresponsive endpoints block connection establishment"
|
|
authority_tier = "expert"
|
|
evidence = ["Mozilla HTTP guidelines, Requests library default"]
|
|
category = "safety"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-request-timeout-001"
|
|
concept_path = "httpclient/request_timeout"
|
|
predicate = "max_value"
|
|
value = 30.0
|
|
comparison = "equals"
|
|
provenance = "Mozilla HTTP docs (30s recommended), aligned with dbpool timeout pattern"
|
|
invariant = "HTTP request timeout MUST NOT exceed 30 seconds"
|
|
consequence = "Slow external services block thread pool, cascade failures"
|
|
authority_tier = "expert"
|
|
evidence = ["Mozilla HTTP guidelines, RFC 7230"]
|
|
category = "safety"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-read-timeout-001"
|
|
concept_path = "httpclient/read_timeout"
|
|
predicate = "max_value"
|
|
value = 30.0
|
|
comparison = "equals"
|
|
provenance = "Mozilla HTTP docs (15-30s for response body reading)"
|
|
invariant = "Response body read timeout MUST NOT exceed 30 seconds"
|
|
consequence = "Slow streaming responses block thread pool"
|
|
authority_tier = "expert"
|
|
evidence = ["Mozilla HTTP guidelines"]
|
|
category = "safety"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-idle-timeout-001"
|
|
concept_path = "httpclient/idle_timeout"
|
|
predicate = "required"
|
|
value = true
|
|
comparison = "equals"
|
|
provenance = "RFC 7230 Section 6.3 (persistent connections), reused from dbpool/idle_timeout pattern"
|
|
invariant = "Idle connection timeout MUST be configured"
|
|
consequence = "Stale connections accumulate, waste resources"
|
|
authority_tier = "expert"
|
|
evidence = ["RFC 7230 Section 6.3, dbpool pattern alignment"]
|
|
category = "safety"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-idle-timeout-default-001"
|
|
concept_path = "httpclient/idle_timeout"
|
|
predicate = "default_value"
|
|
value = 60.0
|
|
comparison = "equals"
|
|
provenance = "Mozilla HTTP docs + RFC 7230 (60s aligns with server keep-alive)"
|
|
invariant = "Idle timeout default SHOULD be 60 seconds"
|
|
consequence = "Too short closes connections prematurely, too long wastes resources"
|
|
authority_tier = "community"
|
|
evidence = ["Mozilla HTTP guidelines, RFC 7230"]
|
|
category = "constants"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-tls-cert-validation-001"
|
|
concept_path = "httpclient/tls/certificate_validation"
|
|
predicate = "required"
|
|
value = true
|
|
comparison = "equals"
|
|
provenance = "OWASP A07:2021 + Mozilla Security Guidelines, reused from dbpool pattern"
|
|
invariant = "HTTPS connections MUST validate server certificates"
|
|
consequence = "Man-in-the-middle attacks, credential exposure"
|
|
authority_tier = "expert"
|
|
evidence = ["OWASP A07:2021, Mozilla HTTPS guidelines, Requests library default"]
|
|
category = "security"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-tls-enabled-001"
|
|
concept_path = "httpclient/tls/enabled"
|
|
predicate = "recommended"
|
|
value = true
|
|
comparison = "equals"
|
|
provenance = "Security best practice, reused from dbpool pattern"
|
|
invariant = "HTTPS SHOULD be enabled by default for all connections"
|
|
consequence = "Unencrypted traffic exposes sensitive data (credentials, PII)"
|
|
authority_tier = "community"
|
|
evidence = ["Mozilla Security Guidelines, OWASP"]
|
|
category = "security"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-tls-min-version-001"
|
|
concept_path = "httpclient/tls/min_version"
|
|
predicate = "min_value"
|
|
value = 1.2
|
|
comparison = "equals"
|
|
provenance = "OWASP + Mozilla Security Guidelines (TLS 1.2 minimum as of 2023)"
|
|
invariant = "TLS version MUST be >= 1.2 (TLS 1.0/1.1 deprecated)"
|
|
consequence = "Vulnerable to protocol downgrade attacks (BEAST, POODLE)"
|
|
authority_tier = "expert"
|
|
evidence = ["OWASP TLS cheat sheet, Mozilla guidelines"]
|
|
category = "security"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-tls-ciphers-001"
|
|
concept_path = "httpclient/tls/cipher_suites"
|
|
predicate = "recommended"
|
|
value = "modern_only"
|
|
comparison = "equals"
|
|
provenance = "Mozilla Security Guidelines (ECDHE, AES-GCM preferred)"
|
|
invariant = "TLS cipher suites SHOULD use modern ciphers only"
|
|
consequence = "Weak ciphers (RC4, 3DES, MD5) enable decryption attacks"
|
|
authority_tier = "community"
|
|
evidence = ["Mozilla Security Guidelines"]
|
|
category = "security"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-max-redirects-001"
|
|
concept_path = "httpclient/max_redirects"
|
|
predicate = "max_value"
|
|
value = 10.0
|
|
comparison = "equals"
|
|
provenance = "RFC 7231 Section 6.4 (10 redirects recommended), pattern from dbpool/max_connections"
|
|
invariant = "HTTP redirect limit MUST NOT exceed 10"
|
|
consequence = "Infinite redirect loops exhaust client resources"
|
|
authority_tier = "expert"
|
|
evidence = ["RFC 7231 Section 6.4"]
|
|
category = "safety"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-redirect-loop-001"
|
|
concept_path = "httpclient/redirects/loop_detection"
|
|
predicate = "required"
|
|
value = true
|
|
comparison = "equals"
|
|
provenance = "Requests library pattern (TooManyRedirects exception)"
|
|
invariant = "Redirect loop detection MUST be implemented"
|
|
consequence = "Without detection, infinite loops exhaust resources"
|
|
authority_tier = "expert"
|
|
evidence = ["Requests library implementation, RFC 7231"]
|
|
category = "safety"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-retry-max-001"
|
|
concept_path = "httpclient/retry/max_attempts"
|
|
predicate = "max_value"
|
|
value = 3.0
|
|
comparison = "equals"
|
|
provenance = "Requests library default + Mozilla guidelines (3 retries max)"
|
|
invariant = "Retry attempts MUST NOT exceed 3"
|
|
consequence = "Unlimited retries cause retry storms, amplify cascading failures"
|
|
authority_tier = "expert"
|
|
evidence = ["Requests library default, Mozilla HTTP guidelines"]
|
|
category = "safety"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-retry-backoff-001"
|
|
concept_path = "httpclient/retry/backoff"
|
|
predicate = "required"
|
|
value = "exponential"
|
|
comparison = "equals"
|
|
provenance = "Requests library pattern (exponential backoff 1s, 2s, 4s)"
|
|
invariant = "Retry backoff MUST use exponential strategy"
|
|
consequence = "Fixed-interval retries amplify load spikes during outages"
|
|
authority_tier = "expert"
|
|
evidence = ["Requests library urllib3.util.retry"]
|
|
category = "safety"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-retry-idempotent-001"
|
|
concept_path = "httpclient/retry/idempotent_only"
|
|
predicate = "required"
|
|
value = true
|
|
comparison = "equals"
|
|
provenance = "Mozilla HTTP docs + Requests library (only retry GET/PUT/DELETE)"
|
|
invariant = "Retries MUST only apply to idempotent methods"
|
|
consequence = "Retrying POST requests may cause duplicate operations (charges, bookings)"
|
|
authority_tier = "expert"
|
|
evidence = ["Mozilla HTTP guidelines, Requests library default"]
|
|
category = "safety"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-retry-post-excluded-001"
|
|
concept_path = "httpclient/retry/post_excluded"
|
|
predicate = "required"
|
|
value = true
|
|
comparison = "equals"
|
|
provenance = "Requests library default (never retry POST by default)"
|
|
invariant = "POST requests MUST be excluded from automatic retries"
|
|
consequence = "Retrying POST can cause duplicate charges, bookings, state mutations"
|
|
authority_tier = "expert"
|
|
evidence = ["Requests library implementation"]
|
|
category = "safety"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-metrics-enabled-001"
|
|
concept_path = "httpclient/metrics/enabled"
|
|
predicate = "recommended"
|
|
value = true
|
|
comparison = "equals"
|
|
provenance = "Observability best practice, reused from dbpool pattern"
|
|
invariant = "Metrics collection SHOULD be enabled for production HTTP clients"
|
|
consequence = "Cannot monitor client health, debug production issues, or detect cascades"
|
|
authority_tier = "community"
|
|
evidence = ["Prometheus best practices, SRE handbook, dbpool pattern"]
|
|
category = "observability"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-metrics-exposed-001"
|
|
concept_path = "httpclient/metrics/exposed"
|
|
predicate = "required"
|
|
value = "request_count,active_connections,latency_p99,error_rate"
|
|
comparison = "equals"
|
|
provenance = "RED method (Rate, Errors, Duration), adapted from dbpool/metrics/exposed"
|
|
invariant = "Core HTTP metrics MUST be exposed: request_count, active_connections, latency_p99, error_rate"
|
|
consequence = "Incomplete observability prevents production debugging and SLO tracking"
|
|
authority_tier = "community"
|
|
evidence = ["RED method (Prometheus), dbpool pattern alignment"]
|
|
category = "observability"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-pool-size-001"
|
|
concept_path = "httpclient/pool_size"
|
|
predicate = "recommended_range"
|
|
value = "50-100"
|
|
comparison = "equals"
|
|
provenance = "Mozilla HTTP docs (50-100 connections per host for production)"
|
|
invariant = "Connection pool size SHOULD be 50-100 per host in production"
|
|
consequence = "Too few limits throughput, too many causes resource exhaustion"
|
|
authority_tier = "community"
|
|
evidence = ["Mozilla HTTP guidelines"]
|
|
category = "constants"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-pool-default-size-001"
|
|
concept_path = "httpclient/pool/default_size"
|
|
predicate = "default_value"
|
|
value = 10.0
|
|
comparison = "equals"
|
|
provenance = "Requests library default (10 connections via urllib3)"
|
|
invariant = "Default pool size SHOULD be 10 connections per host"
|
|
consequence = "Default works for most cases, high-concurrency apps need tuning"
|
|
authority_tier = "community"
|
|
evidence = ["Requests library urllib3.poolmanager default"]
|
|
category = "constants"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-connection-pooling-001"
|
|
concept_path = "httpclient/sessions/connection_pooling"
|
|
predicate = "recommended"
|
|
value = true
|
|
comparison = "equals"
|
|
provenance = "Requests library best practice (use Session() for connection reuse)"
|
|
invariant = "Connection pooling SHOULD be enabled for multi-request scenarios"
|
|
consequence = "Without pooling, every request pays TCP + TLS handshake cost"
|
|
authority_tier = "community"
|
|
evidence = ["Requests library Session documentation"]
|
|
category = "architecture"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-user-agent-001"
|
|
concept_path = "httpclient/headers/user_agent"
|
|
predicate = "required"
|
|
value = true
|
|
comparison = "equals"
|
|
provenance = "Mozilla HTTP docs (always send User-Agent header)"
|
|
invariant = "User-Agent header MUST be sent with all requests"
|
|
consequence = "Servers may block or rate-limit requests without User-Agent"
|
|
authority_tier = "community"
|
|
evidence = ["Mozilla HTTP guidelines"]
|
|
category = "architecture"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-error-handling-001"
|
|
concept_path = "httpclient/error_handling/request_failure"
|
|
predicate = "must"
|
|
value = "return_error_not_panic"
|
|
comparison = "equals"
|
|
provenance = "Robustness pattern, reused from dbpool/error_handling/connection_failure"
|
|
invariant = "HTTP request failures MUST return Result, NEVER panic"
|
|
consequence = "Unhandled panics crash the application"
|
|
authority_tier = "expert"
|
|
evidence = ["Rust error handling best practices, dbpool pattern"]
|
|
category = "safety"
|
|
status = "active"
|
|
created_by = "aphoria-suggest"
|
|
created_at = "2026-02-10T04:09:22Z"
|
|
|
|
# Programmatic extractor claims for Option<T> semantics
|
|
|
|
[[claim]]
|
|
id = "httpclient-max-redirects-configured"
|
|
concept_path = "httpclient/max_redirects"
|
|
predicate = "configured"
|
|
value = true
|
|
comparison = "equals"
|
|
provenance = "RFC 7231 Section 6.4 (redirect limit required)"
|
|
invariant = "Redirect limit MUST be configured (not unbounded)"
|
|
consequence = "Unbounded redirects allow infinite loops, exhaust resources"
|
|
authority_tier = "expert"
|
|
evidence = ["RFC 7231 Section 6.4"]
|
|
category = "safety"
|
|
status = "active"
|
|
created_by = "task-3-programmatic-extractors"
|
|
created_at = "2026-02-11T00:00:00Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-max-redirects-threshold"
|
|
concept_path = "httpclient/max_redirects"
|
|
predicate = "max_value"
|
|
value = 10.0
|
|
comparison = "equals"
|
|
provenance = "RFC 7231 Section 6.4 (10 redirects recommended)"
|
|
invariant = "Redirect limit MUST NOT exceed 10"
|
|
consequence = "Excessive redirects waste bandwidth, delay responses"
|
|
authority_tier = "expert"
|
|
evidence = ["RFC 7231 Section 6.4"]
|
|
category = "safety"
|
|
status = "active"
|
|
created_by = "task-3-programmatic-extractors"
|
|
created_at = "2026-02-11T00:00:00Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-max-retries-configured"
|
|
concept_path = "httpclient/retry/max_attempts"
|
|
predicate = "configured"
|
|
value = true
|
|
comparison = "equals"
|
|
provenance = "Mozilla HTTP guidelines (retry limit required)"
|
|
invariant = "Retry limit MUST be configured (not unbounded)"
|
|
consequence = "Unbounded retries cause retry storms, amplify failures"
|
|
authority_tier = "expert"
|
|
evidence = ["Mozilla HTTP guidelines", "Requests library default"]
|
|
category = "safety"
|
|
status = "active"
|
|
created_by = "task-3-programmatic-extractors"
|
|
created_at = "2026-02-11T00:00:00Z"
|
|
|
|
[[claim]]
|
|
id = "httpclient-max-retries-threshold"
|
|
concept_path = "httpclient/retry/max_attempts"
|
|
predicate = "max_value"
|
|
value = 3.0
|
|
comparison = "equals"
|
|
provenance = "Requests library default + Mozilla guidelines"
|
|
invariant = "Retry attempts MUST NOT exceed 3"
|
|
consequence = "Excessive retries amplify cascading failures"
|
|
authority_tier = "expert"
|
|
evidence = ["Requests library default", "Mozilla HTTP guidelines"]
|
|
category = "safety"
|
|
status = "active"
|
|
created_by = "task-3-programmatic-extractors"
|
|
created_at = "2026-02-11T00:00:00Z"
|