Skip to main content Início Criadores jeremylongshore tons-of-skills-marketplace clay-policy-guardrails
clay-policy-guardrails Implement credit spending limits, data privacy enforcement, and input validation guardrails for Clay pipelines.
Use when enforcing spending caps, blocking PII enrichment,
or adding pre-enrichment validation rules.
Trigger with phrases like "clay policy", "clay guardrails", "clay spending limit",
"clay data privacy rules", "clay validation", "clay controls".
Ir para a instalação Skills Marketplace Descubra e explore skills de IA criadas pela comunidade.
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Copiar promptMostrar detalhes do prompt Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
npx skills add https://github.com/jeremylongshore/tons-of-skills-marketplace --skill clay-policy-guardrailsO comando permanece em uma só linha. Role horizontalmente para revisá-lo antes de copiar.
Prefere uma cópia local? Baixe os arquivos disponíveis atualmente no SkillsMP.
Baixar Zip Baixando... Mais deste repositório langchain-deploy-integration Deploy a LangChain 1.0 / LangGraph 1.0 app to Cloud Run, Vercel, or LangServe correctly — with timeouts sized for chain length, cold-start mitigation, SSE anti-buffering headers, and Secret Manager over .env. Use when prepping a first production deploy, debugging a stream that hangs behind a proxy, or diagnosing p99 latency spikes. Trigger with "langchain deploy", "langchain cloud run", "langchain vercel python", "langchain langserve", or "langchain docker".
langchain-langgraph-agents Build a correct LangGraph 1.0 ReAct agent with create_react_agent — typed tools, error propagation, recursion caps, and stop conditions that actually stop. Use when writing a first tool-calling agent, migrating from AgentExecutor or initialize_agent, or diagnosing an agent that loops on vague prompts. Trigger with "langgraph agent", "create_react_agent", "langgraph tool calling", "AgentExecutor migration", or "agent loop cost".
langchain-langgraph-human-in-loop Build LangGraph 1.0 human-in-the-loop approval flows with interrupt_before /
interrupt_after and Command(resume=...) — JSON-serializable state, clean
resume semantics, and UI wiring for approval decisions. Use when adding an
approval gate before an expensive tool call, wiring a Slack/web UI for agent
approvals, or debugging a graph that crashes on interrupt.
Trigger with "langgraph human in loop", "langgraph interrupt_before",
"langgraph approval flow", "Command resume", "langgraph HITL".
name clay-policy-guardrails description Implement credit spending limits, data privacy enforcement, and input validation guardrails for Clay pipelines.
Use when enforcing spending caps, blocking PII enrichment,
or adding pre-enrichment validation rules.
Trigger with phrases like "clay policy", "clay guardrails", "clay spending limit",
"clay data privacy rules", "clay validation", "clay controls".
allowed-tools Read, Write, Edit, Bash(node:*) version 1.14.0 license MIT author Jeremy Longshore <jeremy@intentsolutions.io> tags ["saas","clay","clay-policy"] compatibility Designed for Claude Code
Clay Policy Guardrails
Overview
Policy enforcement and guardrails for Clay data enrichment pipelines. Clay processes personal and business data at scale, requiring strict controls around credit spending, data privacy compliance, input validation, and export restrictions.
Prerequisites
Clay integration in production or pre-production
Understanding of GDPR/CCPA requirements
Credit budget defined by management
Data classification policy for your organization
Instructions
Step 1: Credit Spending Guardrails
interface CreditPolicy {
dailyLimit : number ;
perTableLimit : number ;
perBatchLimit : number ;
alertThresholdPct : number ;
hardStopEnabled : boolean ;
}
const CREDIT_POLICIES : Record <string , CreditPolicy > = {
conservative : {
dailyLimit : 200 ,
perTableLimit : 500 ,
perBatchLimit : 100 ,
alertThresholdPct : 70 ,
hardStopEnabled : true ,
},
standard : {
dailyLimit : 500 ,
perTableLimit : 2000 ,
perBatchLimit : 500 ,
alertThresholdPct : 80 ,
hardStopEnabled : true ,
},
: {
: ,
: ,
: ,
: ,
: ,
},
};
{
dailyUsed = ;
tableUsage = < , >();
( ) {}
( : , : , : ): {
: ;
?: ;
} {
estimated = rowCount * creditsPerRow;
(estimated > . . ) {
{
: ,
: ,
};
}
( . + estimated > . . ) {
( . . ) {
{
: ,
: ,
};
}
. ( );
}
tableTotal = ( . . (tableId) || ) + estimated;
(tableTotal > . . ) {
{
: ,
: ,
};
}
dailyPct = (( . + estimated) / . . ) * ;
(dailyPct > . . ) {
. ( );
}
{ : };
}
( ) {
. += credits;
. . (tableId, ( . . (tableId) || ) + credits);
}
}
aggressive
dailyLimit
2000
perTableLimit
10000
perBatchLimit
2000
alertThresholdPct
90
hardStopEnabled
false
class
CreditPolicyEnforcer
private
0
private
new
Map
string
number
constructor
private policy : CreditPolicy
checkBatch
tableId
string
rowCount
number
creditsPerRow
number
allowed
boolean
reason
string
const
if
this
policy
perBatchLimit
return
allowed
false
reason
`Batch (${estimated} credits) exceeds per-batch limit (${this .policy.perBatchLimit} ). Split into smaller batches.`
if
this
dailyUsed
this
policy
dailyLimit
if
this
policy
hardStopEnabled
return
allowed
false
reason
`Would exceed daily limit: ${this .dailyUsed} + ${estimated} > ${this .policy.dailyLimit} `
console
warn
`WARNING: Exceeding daily limit (${this .dailyUsed + estimated} /${this .policy.dailyLimit} )`
const
this
tableUsage
get
0
if
this
policy
perTableLimit
return
allowed
false
reason
`Table ${tableId} would exceed limit: ${tableTotal} > ${this .policy.perTableLimit} `
const
this
dailyUsed
this
policy
dailyLimit
100
if
this
policy
alertThresholdPct
console
warn
`Credit alert: ${dailyPct.toFixed(0 )} % of daily limit used`
return
allowed
true
recordUsage
tableId : string , credits : number
this
dailyUsed
this
tableUsage
set
this
tableUsage
get
0
Step 2: Data Privacy Guardrails
const BLOCKED_ENRICHMENT_FIELDS = new Set ([
'ssn' , 'social_security' , 'tax_id' ,
'date_of_birth' , 'dob' , 'birthday' ,
'home_address' , 'home_phone' ,
'personal_phone' , 'personal_mobile' ,
'bank_account' , 'credit_card' ,
'medical_history' , 'health_records' ,
'salary' , 'compensation' ,
'political_affiliation' , 'religion' ,
'ethnic_origin' , 'sexual_orientation' ,
]);
const CONSENT_REQUIRED_FIELDS = new Set ([
'personal_email' , 'phone_number' , 'mobile_phone' ,
]);
interface PrivacyCheckResult {
allowed : boolean ;
violations : string [];
warnings : string [];
}
function checkPrivacy (
fieldsToEnrich : string [],
hasExplicitConsent : boolean = false ,
): PrivacyCheckResult {
const violations : string [] = [];
const warnings : string [] = [];
for (const field of fieldsToEnrich) {
const normalized = field.toLowerCase ().replace (/[\s-]/g , '_' );
if (BLOCKED_ENRICHMENT_FIELDS .has (normalized)) {
violations.push (`BLOCKED: "${field} " is a restricted field (never enrich)` );
}
if (CONSENT_REQUIRED_FIELDS .has (normalized) && !hasExplicitConsent) {
warnings.push (`CONSENT: "${field} " requires explicit consent to enrich` );
}
}
return {
allowed : violations.length === 0 ,
violations,
warnings,
};
}
Step 3: Input Validation Guardrails
const PERSONAL_EMAIL_DOMAINS = new Set ([
'gmail.com' , 'yahoo.com' , 'hotmail.com' , 'outlook.com' , 'icloud.com' ,
'aol.com' , 'protonmail.com' , 'mail.com' , 'yandex.com' , 'gmx.com' ,
]);
const DISPOSABLE_EMAIL_DOMAINS = new Set ([
'tempmail.com' , 'guerrillamail.com' , 'throwaway.email' , 'yopmail.com' ,
'mailinator.com' , '10minutemail.com' , 'trashmail.com' ,
]);
interface ValidationResult {
valid : Record <string , unknown >[];
rejected : { row : Record <string , unknown >; reason : string }[];
stats : {
total : number ;
valid : number ;
invalidDomain : number ;
personalDomain : number ;
disposableDomain : number ;
missingRequiredField : number ;
duplicates : number ;
};
}
function validateBatch (
rows : Record <string , unknown >[],
requiredFields : string [] = ['domain' ],
): ValidationResult {
const seen = new Set <string >();
const stats = {
total : rows.length , valid : 0 , invalidDomain : 0 ,
personalDomain : 0 , disposableDomain : 0 , missingRequiredField : 0 , duplicates : 0 ,
};
const valid : Record <string , unknown >[] = [];
const rejected : { row : Record <string , unknown >; reason : string }[] = [];
for (const row of rows) {
const missing = requiredFields.filter (f => !row[f]);
if (missing.length > 0 ) {
rejected.push ({ row, reason : `Missing required: ${missing.join(', ' )} ` });
stats.missingRequiredField ++;
continue ;
}
const domain = String (row.domain || '' ).toLowerCase ().trim ();
if (!domain.includes ('.' ) || domain.length < 4 ) {
rejected.push ({ row, reason : `Invalid domain: "${domain} "` });
stats.invalidDomain ++;
continue ;
}
if (PERSONAL_EMAIL_DOMAINS .has (domain)) {
rejected.push ({ row, reason : `Personal email domain: ${domain} ` });
stats.personalDomain ++;
continue ;
}
if (DISPOSABLE_EMAIL_DOMAINS .has (domain)) {
rejected.push ({ row, reason : `Disposable email domain: ${domain} ` });
stats.disposableDomain ++;
continue ;
}
const key = `${domain} :${String (row.first_name || '' ).toLowerCase()} :${String (row.last_name || '' ).toLowerCase()} ` ;
if (seen.has (key)) {
stats.duplicates ++;
continue ;
}
seen.add (key);
valid.push ({ ...row, domain });
stats.valid ++;
}
return { valid, rejected, stats };
}
Step 4: Export Restrictions
type ExportDestination = 'crm' | 'outreach' | 'analytics' | 'csv' ;
const EXPORT_RULES : Record <ExportDestination , {
allowedFields : string [];
blockedFields : string [];
requiresApproval : boolean ;
}> = {
crm : {
allowedFields : ['email' , 'first_name' , 'last_name' , 'company_name' , 'job_title' , 'icp_score' ],
blockedFields : ['personal_email' , 'home_address' ],
requiresApproval : false ,
},
outreach : {
allowedFields : ['email' , 'first_name' , 'company_name' , 'personalized_opener' ],
blockedFields : ['phone_number' , 'linkedin_url' , 'personal_email' ],
requiresApproval : false ,
},
analytics : {
allowedFields : ['company_name' , 'industry' , 'employee_count' , 'icp_score' ],
blockedFields : ['email' , 'first_name' , 'last_name' , 'phone_number' ],
requiresApproval : false ,
},
csv : {
allowedFields : ['*' ],
blockedFields : ['personal_email' , 'home_address' , 'ssn' ],
requiresApproval : true ,
},
};
function filterForExport (
rows : Record <string , unknown >[],
destination : ExportDestination ,
): Record <string , unknown >[] {
const rules = EXPORT_RULES [destination];
return rows.map (row => {
const filtered : Record <string , unknown > = {};
for (const [key, value] of Object .entries (row)) {
if (rules.blockedFields .includes (key)) continue ;
if (rules.allowedFields [0 ] !== '*' && !rules.allowedFields .includes (key)) continue ;
filtered[key] = value;
}
return filtered;
});
}
Error Handling Issue Cause Solution Credit overrun No spending limits enforced Implement credit policy enforcer PII enrichment violation No privacy checks Add blocked field validation Wasted credits on bad data No input validation Pre-validate all batches Unauthorized data export No export restrictions Implement per-destination field filtering
Resources
Next Steps For architecture patterns at scale, see clay-architecture-variants.