# Phase 7 UAT: The Shield **Status:** Ready for Testing **Target Date:** 2026-02-03 **Confidence:** High (7A, 7B complete; 7C core complete) ## Summary Phase 7 (The Shield) defends against spam, Sybil attacks, and knowledge poisoning. This UAT validates the trust-at-scale infrastructure for opening Episteme to millions of agents. **Scope:** - 7A Admission Control: PoW-based spam protection, trust tiers, graduated quotas - 7B EigenTrust: Sybil-resistant global trust propagation - 7C Content Defense: Quality scoring, MinHash/LSH similarity, quarantine store, admin API - 7D Circuit Breakers: Per-agent banning with Closed/Open/HalfOpen state machine ## Test Coverage (Verified) | Area | Tests | Status | |------|-------|--------| | Circuit Breakers (7D) | 25 | PASS | | Trust Graph Store (7B) | 23 | PASS | | Trust Rank Store | 22 | PASS | | PoW types (7A) | 19 | PASS | | Domain Trust Store (7B) | 18 | PASS | | Admission Store (7A) | 16 | PASS | | Content Defense (quality) (7C) | 13 | PASS | | Similarity Index (MinHash/LSH) (7C) | 12 | PASS | | Quarantine Store (7C) | 9 | PASS | | Trust Tier types (7A) | 8 | PASS | | API Admission integration | 6 | PASS | | Content Defense Layer (7C) | 5 | PASS | | **Total Phase 7** | **176** | **ALL PASS** | ## Realistic Usage Scenarios ### Scenario 1: New Agent Onboarding **Goal:** Verify graduated difficulty protects against spam bots while not blocking legitimate agents. ```bash # 1. New agent with no history should require PoW curl -X GET http://localhost:18180/v1/admission/status \ -H "X-Agent-Id: 0000000000000000000000000000000000000000000000000000000000000001" # Expected: 200 with pow_required: true, difficulty: 16 # 2. Submit first assertions with PoW proof # Agent must solve: BLAKE3(nonce || agent_id || timestamp) has 16 leading zero bits # This takes ~16 seconds on average # 3. After 10 assertions, difficulty drops to 1 bit (trivial) # 4. After 50 assertions OR trust > 0.6, PoW exempt ``` **Acceptance Criteria:** - [ ] New agents see `pow_required: true`, `difficulty: 16` - [ ] HTTP 428 returned when PoW missing/invalid - [ ] Difficulty graduates: 16 bits (1-10) → 1 bit (11-50) → 0 (51+) - [ ] Trusted agents (>0.6) are exempt regardless of assertion count ### Scenario 2: Trust Tier Quotas **Goal:** Verify rate limiting scales with trust level. | Tier | Trust Range | Quota Multiplier | Hourly Limit | |------|-------------|------------------|--------------| | Untrusted | 0.0-0.3 | 0.1x | 1,000/hr | | Limited | 0.3-0.5 | 0.5x | 5,000/hr | | Verified | 0.5-0.7 | 1.0x | 10,000/hr | | Trusted | 0.7-0.9 | 2.0x | 20,000/hr | | Authority | 0.9-1.0 | 10.0x | 100,000/hr | **Acceptance Criteria:** - [ ] Quota headers present in responses (`X-RateLimit-*`) - [ ] Untrusted agents limited to 0.1x base quota - [ ] Authority agents get 10x quota - [ ] HTTP 429 returned when quota exceeded ### Scenario 3: EigenTrust Sybil Resistance **Goal:** Verify isolated trust rings get near-zero global trust. ``` Legitimate Network: Sybil Ring: Seed ─────> A X ──> Y │ │ │ │ v v v v B ──────> C Z <── W ``` **Acceptance Criteria:** - [ ] Seed-connected agents (A, B, C) accumulate positive global trust - [ ] Isolated ring (X, Y, Z, W) converges to near-zero trust - [ ] Power iteration converges in <100 iterations (ε = 1e-4) - [ ] Domain-specific trust factors applied correctly ### Scenario 4: Content Quality Filtering **Goal:** Verify spam/noise detection without blocking legitimate content. | Content Type | Expected Quality | Should Quarantine? | |--------------|------------------|-------------------| | Normal assertion: "Aspirin:treats:Headache" | >0.6 | No | | Low entropy: "aaaa:bbbb:cccc" | <0.4 | Yes | | Structured data with JSON | >0.7 (bonus) | No | | Untrusted agent + high confidence | <0.5 (penalty) | Yes | **Acceptance Criteria:** - [ ] Shannon entropy check flags random noise (< 1.5 bits/char) - [ ] Minimum subject/predicate length enforced (default 3 chars) - [ ] Structured data (JSON, URLs, dates) gets +0.1 bonus - [ ] Untrusted + high confidence gets -0.5 penalty - [ ] Quality < 0.4 triggers quarantine ### Scenario 5: Quarantine Admin Workflow **Goal:** Verify suspicious content can be reviewed and processed. ```bash # 1. List pending quarantine events curl http://localhost:18180/v1/admin/quarantine?limit=20 # 2. Review specific event curl http://localhost:18180/v1/admin/quarantine/{hash} # 3. Approve or reject curl -X POST http://localhost:18180/v1/admin/quarantine/{hash}/approve curl -X POST http://localhost:18180/v1/admin/quarantine/{hash}/reject ``` **Acceptance Criteria:** - [ ] `GET /v1/admin/quarantine` lists pending events with reasons - [ ] `GET /v1/admin/quarantine/{hash}` returns full assertion bytes - [ ] `POST .../approve` moves assertion to main index - [ ] `POST .../reject` marks as reviewed but keeps quarantined - [ ] Quarantine reasons clearly indicate why flagged ## Integration Points to Verify 1. **Ingestion Pipeline Integration** - Content defense layer called before indexing - Quarantine bypasses normal index path - Bloom filter restored on restart 2. **Trust Store Interplay** - EigenTrust feeds into TrustTier calculation - Domain trust factors into Authority lens weights - Trust decay applies to computed scores 3. **API Middleware Chain** - AdmissionLayer checks PoW before rate limiting - MeterLayer applies tier-based quotas - Headers reflect current trust state ### Scenario 6: Near-Duplicate Detection (MinHash/LSH) **Goal:** Verify similar content is flagged without blocking unique assertions. | Content Pair | Jaccard Similarity | Expected | |--------------|-------------------|----------| | "Aspirin:treats:Headache" vs same | 1.0 | Duplicate | | "Aspirin:treats:Headache" vs "Aspirin:treats:Migraine" | ~0.7 | Unique | | "Aspirin treats headaches" vs "Aspirin:treats:Headache" | ~0.85 | Unique | | "Asprin:treats:Headach" (typos) vs "Aspirin:treats:Headache" | ~0.92 | Duplicate | **Acceptance Criteria:** - [ ] Bloom filter provides fast "definitely not seen" path - [ ] MinHash signatures (k=128) computed correctly - [ ] LSH bands (16 bands × 8 rows) enable efficient lookup - [ ] Jaccard threshold of 0.9 correctly identifies near-duplicates - [ ] Unique content with similar structure passes through ### Scenario 7: Circuit Breaker State Machine (7D) **Goal:** Verify misbehaving agents are temporarily banned with recovery path. ``` State Flow: CLOSED (normal) --[5 failures]--> OPEN (banned) OPEN --[30 sec timeout]--> HALF_OPEN (testing) HALF_OPEN --[1 success]--> CLOSED HALF_OPEN --[1 failure]--> OPEN ``` **Acceptance Criteria:** - [ ] New agents start with no circuit record (allowed) - [ ] 5 failures within window trips circuit to OPEN - [ ] OPEN agents receive HTTP 503 with `Retry-After` header - [ ] After 30 sec, OPEN transitions to HALF_OPEN - [ ] Single success in HALF_OPEN closes circuit - [ ] Single failure in HALF_OPEN re-trips to OPEN - [ ] Admin can manually reset circuits ## Known Limitations 1. **Performance Untested:** - EigenTrust computation on large graphs (>10k agents) - Bloom filter memory at scale (currently sized for 1M items) - Quarantine store scan performance with many pending items - Circuit breaker store with many tripped agents ## Commands to Run ```bash # Full test suite cargo test --workspace # Phase 7 specific tests (176 total) cargo test -p stemedb-storage -- circuit_breaker # 7D: 25 tests cargo test -p stemedb-storage -- trust_graph # 7B: 23 tests cargo test -p stemedb-storage -- trust_rank # Trust: 22 tests cargo test -p stemedb-core -- pow # 7A: 19 tests cargo test -p stemedb-storage -- domain_trust # 7B: 18 tests cargo test -p stemedb-storage -- admission # 7A: 16 tests cargo test -p stemedb-storage -- content_defense # 7C: 13 tests cargo test -p stemedb-storage -- similarity_index # 7C: 12 tests cargo test -p stemedb-storage -- quarantine # 7C: 9 tests cargo test -p stemedb-core -- trust_tier # 7A: 8 tests cargo test -p stemedb-api --test admission_integration # API: 6 tests cargo test -p stemedb-ingest -- content_defense # 7C: 5 tests # Clippy must pass cargo clippy --workspace -- -D warnings # Go SDK cd sdk/go/steme && go test -v ``` ## Success Criteria **Phase 7 UAT passes when:** 1. All 176 Phase 7 tests pass 2. All 7 usage scenarios verified manually 3. Clippy clean with no warnings 4. Go SDK tests pass 5. API endpoints return correct responses 6. Quarantine workflow complete end-to-end 7. Circuit breaker state transitions verified 8. Near-duplicate detection at 0.9 Jaccard threshold works ## Related Documentation - [Admission Control API](./admission-control.md) - [Phase 6 UAT](./phase6-uat.md) - [Roadmap Phase 7](../../roadmap.md#phase-7-the-shield-trust-at-scale)