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>
20 KiB
Dogfood Project: Distributed Cache Client (cachewrap)
Start Date: 2026-02-11 Hypothesis: Connection patterns + resource limits + TTL semantics from 3 corpora (httpclient, dbpool, msgqueue) transfer to cache clients with 35-40% pattern reuse, demonstrating multi-domain flywheel strength. Corpus Overlap: httpclient + dbpool + msgqueue → 35-40% pattern reuse expected Target Metrics:
- Time savings: ≥60% vs manual (Day 1: <2 hrs vs ~4 hrs manual)
- Pattern reuse: ≥35% of claims (7/20 claims)
- Detection rate: ≥90% of violations (9/10 detected)
- Naming errors: <2
- Total time: 12-16 hours (reflects ★★★★☆ difficulty)
Day 1: Claims Extraction (1-2 hours)
Goal: Author 20 claims (7 reused from corpus, 13 new) with full provenance
Skills:
/aphoria-suggest --corpus httpclient,dbpool,msgqueue- Discover reusable patterns/aphoria-claims- Author claims with full provenance
Process:
1. Discover Reusable Patterns (30 min)
cd /path/to/aphoria/dogfood/cachewrap
/aphoria-suggest --corpus httpclient,dbpool,msgqueue --domain cache
Expected reusable patterns (7 total):
- httpclient: timeout, TLS verification, retry, async (4)
- dbpool: max_connections, connection lifecycle (2)
- msgqueue: metrics (1)
2. Draft New Claims (30 min)
Read authority sources in docs/sources/:
redis-spec.md- TTL, eviction, consistencyaws-elasticache.md- Best practices, securityredis-rs-lib.md- Rust patterns
Draft 13 new claims covering:
- TTL and expiration (3 claims)
- Security (key validation, injection) (2 claims)
- Eviction policies (2 claims)
- Resource limits (cache size, memory) (2 claims)
- Consistency and sharding (2 claims)
- Serialization and compression (2 claims)
3. Author All Claims (30 min)
Use /aphoria-claims to author each claim with:
- Provenance: Redis spec, AWS docs, or library docs
- Invariant: What MUST stay true
- Consequence: What breaks if violated
- Authority tier: Tier 1 (spec), Tier 2 (vendor), Tier 3 (library)
- Category: security, safety, performance, correctness
Example:
/aphoria-claims create \
--subject "cache/ttl" \
--predicate "required" \
--value "true" \
--provenance "Redis SETEX command spec" \
--invariant "TTL MUST be set for all cached values" \
--consequence "Missing TTL causes memory leak - unbounded growth" \
--tier "expert" \
--category "safety"
4. Verify Claims (10 min)
cat .aphoria/claims.toml
# Verify all 20 claims present with full fields
Target Output:
- 20 claims in
.aphoria/claims.toml - 7 reused from corpus (35% reuse rate)
- 13 new claims specific to caching
- Daily summary:
DAY1-SUMMARY.md
Success Criteria:
- ✅ All claims have: provenance, invariant, consequence, authority tier
- ✅ Reuse rate ≥ 35% (7/20 claims)
- ✅ Time ≤ 2 hours
- ✅ 0 naming errors (consistent with corpus)
Day 2: Implementation (3-4 hours)
Goal: Write cachewrap library with 10 intentional violations (security + performance + correctness)
Violations (Intentional) - Cross-Cutting:
Security Violations (3):
-
Key Injection Vulnerability
- Consequence: Attacker controls cache keys → data breach, cache poisoning
- Marker:
@aphoria:claim[security] Cache keys MUST be validated -- unvalidated keys enable injection attacks - Location:
src/client.rs:get()method - Pattern: Accept user input as key without validation/sanitization
-
TLS Verification Disabled
- Consequence: MITM attacks intercept cache traffic → credential theft
- Marker:
@aphoria:claim[security] TLS certificate verification MUST be enabled -- disabled TLS enables MITM attacks - Location:
src/config.rs:verify_tls = false - Pattern:
verify_tls: falsein config
-
Hardcoded Credentials
- Consequence: Credentials in version control → unauthorized access
- Marker:
@aphoria:claim[security] Credentials MUST NOT be hardcoded -- hardcoded passwords leak in VCS - Location:
src/config.rs:password = "secret123" - Pattern: Plaintext password string in struct
Performance Violations (3):
-
Missing TTL
- Consequence: Memory leak - unbounded cache growth → OOM
- Marker:
@aphoria:claim[safety] TTL MUST be set for cached values -- missing TTL causes memory leak - Location:
src/client.rs:set()method - Pattern:
SET key valuewithoutEX ttl
-
Unbounded Cache Size
- Consequence: OOM under sustained load
- Marker:
@aphoria:claim[safety] Cache MUST have max_size limit -- unbounded cache causes OOM - Location:
src/config.rs:max_size = None - Pattern:
Option<usize>instead of required field
-
Synchronous Blocking
- Consequence: Throughput collapse - blocks event loop
- Marker:
@aphoria:claim[performance] Cache I/O MUST be async -- synchronous blocking kills throughput - Location:
src/client.rs:blocking_get() - Pattern: Blocking Redis call in async context
Correctness Violations (3):
-
No Eviction Policy
- Consequence: Unpredictable behavior when cache full
- Marker:
@aphoria:claim[correctness] Eviction policy MUST be configured -- missing policy causes undefined behavior - Location:
src/config.rs:eviction_policy = None - Pattern: Missing LRU/LFU configuration
-
Zero Timeout
- Consequence: Indefinite blocking → hung threads
- Marker:
@aphoria:claim[safety] Timeout MUST be > 0 -- timeout=0 causes indefinite blocking - Location:
src/config.rs:timeout = Duration::from_secs(0) - Pattern:
Duration::from_secs(0)
-
No Connection Pooling
- Consequence: Resource exhaustion - new connection per request
- Marker:
@aphoria:claim[performance] Connection pooling MUST be enabled -- no pooling exhausts resources - Location:
src/client.rs:new_connection()called per request - Pattern:
redis::Client::open()in hot path
Observability Violation (1):
- No Metrics
- Consequence: Cannot debug cache hit/miss behavior in production
- Marker:
@aphoria:claim[observability] Metrics MUST track hit/miss rates -- no metrics prevents debugging - Location:
src/config.rs:metrics_enabled = false - Pattern: No hit/miss counter fields
Process:
1. Create Project Structure (30 min)
cargo init --lib
# Or appropriate build setup
Files to create:
src/lib.rs- Library rootsrc/config.rs- CacheConfig (violations 2, 5, 7, 8, 10)src/client.rs- CacheClient (violations 1, 4, 6, 9)src/error.rs- Error typestests/basic.rs- Integration tests
2. Implement Happy Path (1.5 hours)
Core functionality:
CacheClient::new(config)- Initialize with configasync fn get(&self, key: &str) -> Result<Option<String>>- Fetch from cacheasync fn set(&self, key: &str, value: &str) -> Result<()>- Store in cacheasync fn delete(&self, key: &str) -> Result<()>- Remove from cachefn health_check(&self) -> Result<bool>- Connection health
Keep implementation simple - focus on violations, not production quality.
3. Embed Violations (1 hour)
For each violation:
- Write code that violates the claim
- Add inline marker comment (
@aphoria:claim[category] invariant -- consequence) - Document why this is realistic (common mistake, copy-paste error, etc.)
Example (Violation 1 - Key Injection):
// @aphoria:claim[security] Cache keys MUST be validated -- unvalidated keys enable injection attacks
pub async fn get(&self, key: &str) -> Result<Option<String>> {
// ❌ VIOLATION: No key validation - enables injection
let value = self.conn.get(key).await?; // User input directly to Redis
Ok(value)
}
// ✅ COMPLIANT (for Day 4):
// pub async fn get(&self, key: &str) -> Result<Option<String>> {
// validate_key(key)?; // Check for control chars, length, etc.
// let value = self.conn.get(key).await?;
// Ok(value)
// }
4. Add Tests (30 min)
Create 15+ tests covering:
- Basic get/set/delete operations
- Error handling (connection failures, invalid keys)
- Configuration validation
- Async behavior verification
Tests should pass despite violations (violations are configuration/usage issues, not logic errors).
5. Document Violations (10 min)
In src/lib.rs doc comment, list all 10 violations with consequences:
//! # ⚠️ INTENTIONAL VIOLATIONS (Dogfooding Exercise)
//!
//! This library contains 10 intentional violations for Aphoria detection:
//! 1. Key injection (no validation) → Data breach
//! 2. TLS disabled → MITM attacks
//! ...
//! 10. No metrics → Cannot debug production
//!
//! These will be fixed progressively in Day 4 after detection in Day 3.
Target Output:
- Working cachewrap library (basic functionality)
- 10 embedded violations with inline markers
- 15+ tests passing
- Daily summary:
DAY2-SUMMARY.md
Success Criteria:
- ✅ All 10 violations have inline markers
- ✅ Code is realistic (not contrived toy example)
- ✅ Tests pass (violations don't break logic)
- ✅ Time ≤ 4 hours
Day 3: Scanning (1.5-2 hours)
Goal: Detect 9/10 violations (≥90%) via aphoria scan AND create extractors for gaps
⚠️ THIS IS THE CORE FLYWHEEL STEP - Day 3 validates autonomous learning. Do NOT skip extractor creation.
Process:
Phase 1: Pre-Flight Check (5 min) [REQUIRED]
# Verify skill availability
/help | grep aphoria-custom-extractor-creator
# Expected: skill listed and available
# Verify inline markers present
grep -r "@aphoria:claim" src/ | wc -l
# Expected: 10 markers
# Verify code compiles
cargo check
# Expected: 0 errors (warnings OK)
If any check fails, STOP and fix before proceeding.
Phase 2: Baseline Scan (15 min)
cd /path/to/aphoria/dogfood/cachewrap
aphoria scan --format json > scan-v1.json
aphoria scan --format markdown > scan-v1.md
Expected on FIRST scan:
- Low detection rate (0-20%) is NORMAL for new domain
- Built-in extractors may catch: hardcoded credentials, TLS=false
- Most violations (TTL, key injection, eviction) will be MISSING
- This is NOT a failure - it's the signal that Phase 4 is needed
Phase 3: Gap Analysis (15 min) [REQUIRED]
Analyze scan-v1.json:
jq '.findings[] | select(.verdict == "MISSING") | .claim_id' scan-v1.json
Create gap table in DAY3-SUMMARY.md:
| Violation | Claim ID | Detected? | Why Not? |
|---|---|---|---|
| Key injection | cache-001 | ❌ | No key validation extractor |
| TLS disabled | cache-002 | ✅ | Built-in TLS extractor |
| Hardcoded password | cache-003 | ✅ | Built-in secrets extractor |
| Missing TTL | cache-004 | ❌ | No TTL presence extractor |
| Unbounded size | cache-005 | ❌ | No max_size extractor |
| Sync blocking | cache-006 | ❌ | No async/await extractor |
| No eviction policy | cache-007 | ❌ | No eviction config extractor |
| Zero timeout | cache-008 | ⚠️ | Maybe (timeout extractor exists) |
| No pooling | cache-009 | ❌ | No connection pool extractor |
| No metrics | cache-010 | ❌ | No metrics field extractor |
Expected: 2-3 detected (built-in), 7-8 missing (need extractors)
Phase 4: Extractor Creation (40 min) [REQUIRED - DO NOT SKIP]
⚠️ CRITICAL: This step is REQUIRED. Skipping this breaks the autonomous learning flywheel.
For EACH missed violation (7-8 total), use the skill:
/aphoria-custom-extractor-creator \
--violation "cache SET without TTL" \
--claim "cache-004" \
--pattern 'SET.*(?!EX|PX)' \
--language rust
Repeat for:
- Key injection (no
validate_key()call) - Unbounded cache size (
max_size: None) - Synchronous blocking (
blocking_get()in async) - No eviction policy (
eviction_policy: None) - No connection pooling (
Client::open()in loop) - No metrics (
metrics_enabled: false)
Expected: 7-8 extractor files created in .aphoria/extractors/
Phase 5: Verification Scan (20 min) [REQUIRED]
aphoria scan --format json > scan-v2.json
Expected:
- Detection rate ≥90% (9/10 or 10/10 violations)
- Gap closed: Missing → Detected
- 0 false positives
Compare scans:
echo "Scan v1 detections:"
jq '.summary.authority_conflicts' scan-v1.json
echo "Scan v2 detections:"
jq '.summary.authority_conflicts' scan-v2.json
Phase 6: Documentation (15 min) [REQUIRED]
Create DAY3-SUMMARY.md with:
# Day 3 Summary: Scanning & Extractor Creation
**Date:** 2026-02-XX
**Duration:** X hours
## Metrics
| Metric | Target | Actual | Delta |
|--------|--------|--------|-------|
| Detection rate (v1) | 20% | X% | +/- |
| Detection rate (v2) | ≥90% | X% | +/- |
| Extractors created | 7-8 | X | +/- |
| Time spent | ≤2 hrs | X hrs | +/- |
## Extractors Created
1. `key_validation_check.toml` - Detects missing `validate_key()`
2. `ttl_presence.toml` - Detects SET without EX/PX
3. `max_size_check.toml` - Detects `max_size: None`
...
## What Worked
- ✅ Built-in extractors caught TLS + hardcoded secrets
- ✅ Custom extractors closed gap to 90%+
- ✅ Flywheel workflow (scan → gap → extract → verify) smooth
## What Broke
- ❌ {Any issues encountered}
## Next Steps
- [ ] Day 4: Fix violations progressively
Target Output:
scan-v1.jsonandscan-v2.json(baseline + verification)- 7-8 extractor files in
.aphoria/extractors/ DAY3-SUMMARY.mdwith metrics
Success Criteria:
- ✅ Pre-flight checks pass
- ✅ 7-8 extractors created (one per missed violation) - CRITICAL
- ✅ Detection rate ≥ 90% in v2 scan
- ✅ Detection rate improvement documented (v1 → v2)
- ✅ Zero false positives
- ✅ Time ≤ 2 hours
Evidence of Correct Execution:
ls .aphoria/extractors/*.toml | wc -l # Should be: 7-8
ls scan-v2.json # Should exist
ls DAY3-SUMMARY.md # Should exist
If ANY of these are missing, Day 3 was not completed correctly.
Day 4: Remediation (3-4 hours)
Goal: Progressive fixes - remove all 10 violations, verify 0 conflicts
Process:
1. Fix Violations One-by-One (3 hours)
Fix in order of severity (security → performance → correctness → observability):
Round 1: Security (30 min)
- Fix violation 1: Add
validate_key()function - Fix violation 2: Set
verify_tls: true - Fix violation 3: Load credentials from
env::var("REDIS_PASSWORD") - After each fix:
aphoria scan→ verify conflict count decreases
Round 2: Performance (45 min)
- Fix violation 4: Add TTL parameter to
set()method - Fix violation 5: Set
max_size: Some(1000)in config - Fix violation 6: Make all methods
async, remove blocking calls - After each fix: Re-scan
Round 3: Correctness (45 min)
- Fix violation 7: Set
eviction_policy: Some(EvictionPolicy::LRU) - Fix violation 8: Change
timeouttoDuration::from_secs(5) - Fix violation 9: Use
r2d2orbb8for connection pooling - After each fix: Re-scan
Round 4: Observability (30 min)
- Fix violation 10: Add
hit_count,miss_countmetrics fields - Final scan:
aphoria scan --format json > scan-final.json - Verify:
jq '.summary.authority_conflicts' scan-final.json→ 0
2. Document Fix Times (30 min)
In DAY4-SUMMARY.md:
| Violation | Fix Time | Complexity | Notes |
|---|---|---|---|
| 1. Key injection | 10 min | Low | Added validate_key() regex |
| 2. TLS disabled | 2 min | Trivial | Config flip |
| 3. Hardcoded password | 5 min | Low | env::var() |
| 4. Missing TTL | 15 min | Medium | API change (breaking) |
| 5. Unbounded size | 2 min | Trivial | Config value |
| 6. Sync blocking | 20 min | Medium | Async conversion |
| 7. No eviction | 10 min | Low | Config + enum |
| 8. Zero timeout | 2 min | Trivial | Config value |
| 9. No pooling | 25 min | High | Add r2d2 dependency |
| 10. No metrics | 15 min | Medium | Add struct fields |
Total: ~106 min (~1.8 hours) for fixes
3. Verify All Tests Still Pass (30 min)
cargo test
# All tests should pass with compliant code
If tests fail, fix issues before considering Day 4 complete.
Target Output:
- All 10 violations fixed
- Progressive scan results (scan-v1, scan-v2, scan-final)
DAY4-SUMMARY.mdwith fix times- Final scan: 0 conflicts
Success Criteria:
- ✅ Final scan: 0 conflicts
- ✅ Each fix verified independently via scan
- ✅ All tests passing
- ✅ Time ≤ 4 hours
Day 5: Documentation (2-3 hours)
Goal: Comprehensive report with metrics, findings, product gaps
Process:
1. Write Final Report (2 hours)
Create DAY5-DOGFOODING-REPORT.md with sections:
Executive Summary (15 min)
- Hypothesis result (validated/partial/invalidated)
- Key findings (2-3 bullet points)
- Metrics snapshot
Metrics Table (15 min)
| Metric | Target | Actual | Delta | Analysis |
|---|---|---|---|---|
| Total time | 12-16 hrs | X hrs | +/- | Why different? |
| Pattern reuse | 35% | X% | +/- | Which patterns reused? |
| Detection rate | ≥90% | X% | +/- | What missed? |
| Naming errors | <2 | X | +/- | Examples? |
| Time savings | ≥60% | X% | +/- | vs manual |
What Worked (30 min)
- Multi-domain corpus transfer (3 corpora → cache)
- Cross-cutting violation detection (security + performance + correctness)
- Extractor creation workflow
- Skills integration
What Broke (30 min)
- Product gaps discovered (prioritize by severity)
- Blockers encountered
- Workarounds applied
- Root cause analysis
Product Gap Analysis (20 min)
| Gap ID | Title | Severity | Effort | ROI | Priority |
|---|---|---|---|---|---|
| VG-XXX | {Title} | High/Med/Low | High/Med/Low | High/Med/Low | P1/P2/P3 |
Recommendations (20 min)
- Immediate (this sprint)
- Short-term (next 2 sprints)
- Long-term (roadmap)
2. Update README (15 min)
Add completion status to README.md:
## Status
- [x] **Day 1:** Claims extraction (X hrs) - Y claims, Z% reuse
- [x] **Day 2:** Implementation (X hrs) - 10 violations, N tests
- [x] **Day 3:** Scanning (X hrs) - Y/10 detected
- [x] **Day 4:** Remediation (X hrs) - 0 conflicts
- [x] **Day 5:** Documentation (X hrs) - Report complete
**Final Metrics:**
- Time: X hrs (target: 12-16)
- Reuse: Y% (target: ≥35%)
- Detection: Z% (target: ≥90%)
3. Archive Artifacts (15 min)
Organize files:
- Move
DAY{1-5}-SUMMARY.mdtosummaries/ - Keep
DAY5-DOGFOODING-REPORT.mdat root - Archive scan results in
scans/
Target Output:
DAY5-DOGFOODING-REPORT.md(comprehensive, 600-800 lines)- Updated README with completion status
- Organized artifacts
Success Criteria:
- ✅ All metrics quantified
- ✅ Product gaps prioritized (P1/P2/P3)
- ✅ Recommendations actionable
- ✅ Time ≤ 3 hours
Success Metrics
| Metric | Target | Actual | Delta |
|---|---|---|---|
| Total time | 12-16 hrs | ___ | ___ |
| Pattern reuse | 35% | ___ | ___ |
| Detection rate | ≥90% | ___ | ___ |
| Naming errors | <2 | ___ | ___ |
| Time savings | ≥60% | ___ | ___ |
Authority Sources
Redis Protocol Specification (Tier 1)
- URL: https://redis.io/docs/reference/protocol-spec/
- Relevance: TTL commands (SETEX, EXPIRE), eviction policies, consistency
- Covered Claims: TTL, eviction, key formats, command semantics
AWS ElastiCache Best Practices (Tier 2)
- URL: https://docs.aws.amazon.com/elasticache/
- Relevance: Security (TLS, auth), performance (connection pooling), monitoring
- Covered Claims: TLS verification, connection limits, metrics, timeouts
redis-rs Library Documentation (Tier 3)
- URL: https://docs.rs/redis/
- Relevance: Rust-specific patterns, connection management, async usage
- Covered Claims: Connection pooling, async patterns, error handling
References
- httpclient dogfood:
dogfood/httpclient/(gold standard) - dbpool dogfood:
dogfood/dbpool/(connection patterns) - msgqueue dogfood:
dogfood/msgqueue/(async patterns) - Claims authoring:
.claude/skills/aphoria-claims/ - Pattern discovery:
.claude/skills/aphoria-suggest/ - Extractor creation:
.claude/skills/aphoria-custom-extractor-creator/
You are ready to start Day 1! Follow this plan and track metrics daily.