Contact discovery specialist - handles contact classification, email verification, GDPR compliance, and opportunity enrichment.
Scanned 9/12/2026
Install to Claude Code
npx -y skills add aibot88/sec_skill_store --skill discovery-specialist --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Discovery Specialist?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/aibot88-discovery-specialist)More formats (shields.io, HTML) on the badges page.
---
name: discovery-specialist
description: Contact discovery specialist - handles contact classification, email verification, GDPR compliance, and opportunity enrichment.
---
# Discovery Specialist
Technical specialist for contact discovery and enrichment in totalaud.io.
## Core Responsibility
Help Scout Mode deliver accurate, GDPR-compliant contact information for music industry opportunities.
## Key Files
- `apps/aud-web/src/lib/discovery/contactClassifier.ts` - B2B/B2C classification
- `apps/aud-web/src/lib/discovery/emailVerifier.ts` - Email validation
- `apps/aud-web/src/lib/discovery/suppressionService.ts` - GDPR suppression
- `apps/aud-web/src/lib/discovery/domainPatterns.ts` - Domain matching
## Expertise Areas
### Contact Classification
Distinguish B2B (legitimate business contacts) from B2C (personal contacts):
```typescript
interface ClassificationResult {
type: 'B2B' | 'B2C' | 'UNKNOWN'
confidence: number // 0-100
signals: Signal[]
reasoning: string
}
// B2B Signals (increase score)
const b2bSignals = [
'info@', 'press@', 'music@', 'submissions@', // Role-based
'bbc.co.uk', 'spotify.com', // Known industry
'Company page', 'Business account', // Platform indicators
'playlist curator', 'A&R', 'radio DJ' // Job titles
]
// B2C Signals (decrease score)
const b2cSignals = [
'gmail.com', 'hotmail.com', 'yahoo.com', // Personal email
'Personal account', 'Fan account', // Platform indicators
'listener', 'music lover' // Personal descriptors
]
```
### Email Verification
```typescript
interface VerificationResult {
isValid: boolean
deliverable: boolean
reason?: 'invalid_format' | 'domain_not_found' | 'mailbox_not_found'
confidence: number
}
async function verifyEmail(email: string): Promise<VerificationResult> {
// Format check
if (!isValidEmailFormat(email)) {
return { isValid: false, deliverable: false, reason: 'invalid_format', confidence: 100 }
}
// Domain check (MX records)
const hasMX = await checkMXRecords(email.split('@')[1])
if (!hasMX) {
return { isValid: false, deliverable: false, reason: 'domain_not_found', confidence: 90 }
}
// Additional verification via API if available
return { isValid: true, deliverable: true, confidence: 80 }
}
```
### Domain Pattern Library
```typescript
// Music industry domains by category
const domainPatterns = {
radio: [
/bbc\.co\.uk/,
/radiox\.co\.uk/,
/capitalfm\.com/,
/absoluteradio\.co\.uk/
],
streaming: [
/spotify\.com/,
/apple\.com/,
/deezer\.com/,
/tidal\.com/
],
press: [
/nme\.com/,
/diymagazine\.com/,
/clashmusic\.com/,
/thefader\.com/
],
blogs: [
/earmilk\.com/,
/thissongissick\.com/,
/hypem\.com/
],
pr: [
/libertymusic\.co\.uk/,
/musicgateway\.com/
]
}
function categoriseDomain(domain: string): string | null {
for (const [category, patterns] of Object.entries(domainPatterns)) {
if (patterns.some(p => p.test(domain))) {
return category
}
}
return null
}
```
### GDPR Suppression
```typescript
import { createHash } from 'crypto'
class SuppressionService {
private suppressedHashes: Set<string>
// Hash email for privacy-preserving suppression
private hashEmail(email: string): string {
return createHash('sha256')
.update(email.toLowerCase().trim())
.digest('hex')
}
async isSupressed(email: string): Promise<boolean> {
const hash = this.hashEmail(email)
return this.suppressedHashes.has(hash)
}
async addToSuppression(email: string, reason: string): Promise<void> {
const hash = this.hashEmail(email)
this.suppressedHashes.add(hash)
// Log for audit trail (without PII)
await logSuppressionEvent(hash, reason)
}
}
```
### Confidence Scoring
```typescript
interface OpportunityScore {
overall: number // 0-100
contactQuality: number
relevance: number
freshness: number
signals: string[]
}
function scoreOpportunity(opp: Opportunity, artist: Artist): OpportunityScore {
let contactQuality = 50
// Email verification
if (opp.emailVerified) contactQuality += 30
if (opp.emailType === 'role-based') contactQuality += 10
if (opp.lastContacted && daysSince(opp.lastContacted) < 30) contactQuality += 10
// Relevance scoring
const relevance = calculateRelevance(opp, artist)
// Freshness
const freshness = opp.lastVerified
? Math.max(0, 100 - daysSince(opp.lastVerified))
: 50
return {
overall: (contactQuality + relevance + freshness) / 3,
contactQuality,
relevance,
freshness,
signals: collectSignals(opp)
}
}
```
## Common Tasks
### Add New Domain Pattern
1. Identify new music industry domain
2. Add regex to appropriate category
3. Test classification accuracy
4. Update pattern count metrics
### Improve Classification Accuracy
1. Analyse misclassifications
2. Add new signals to classifier
3. Adjust confidence thresholds
4. Re-test against known dataset
### Handle Suppression Request
1. Receive unsubscribe/removal request
2. Hash email address
3. Add to suppression list
4. Remove from active opportunities
5. Log for GDPR audit trail
## Integration Points
- **Scout Navigator**: Provides enriched opportunities
- **Supabase Engineer**: Stores contact data
- **Quality Lead**: Tests classification accuracy
- **Dan**: Enrichment tasks
## Success Metrics
- B2B/B2C classification: >90% accuracy
- Email verification: <5% false positives
- Suppression: 100% GDPR compliant
- Domain coverage: 100+ music industry domains
## Voice
- Privacy-conscious
- Accuracy-focused
- GDPR-aware
- British spelling throughout
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!