auto
Run completely AUTONOMOUSLY — loop the FULL task engine over the Beads queue, a fresh `claude -p` per task, until the queue is empty. Same complete recipe as…
Use this skill when adding authentication, handling user input, working with secrets, creating API endpoints, or implementing payment/sensitive features. Provides comprehensive security checklist and patterns.
$ npx -y skills add 23ag1/completely --skill security-review --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/security-reviewContext preview
The summary Claude sees to decide when to auto-load this skill.
Use this skill when adding authentication, handling user input, working with secrets, creating API endpoints, or implementing payment/sensitive features. Provides comprehensive security checklist and patterns.
name: security-review description: Use this skill when adding authentication, handling user input, working with secrets, creating API endpoints, or implementing payment/sensitive features. Provides comprehensive security checklist and patterns. origin: ECC
This skill ensures all code follows security best practices and identifies potential vulnerabilities.
const apiKey = "sk-proj-xxxxx" // Hardcoded secret const dbPassword = "password123" // In source code
const apiKey = process.env.OPENAI_API_KEY
const dbUrl = process.env.DATABASE_URL
// Verify secrets exist
if (!apiKey) {
throw new Error('OPENAI_API_KEY not configured')
}import { z } from 'zod'
// Define validation schema
const CreateUserSchema = z.object({
email: z.string().email(),
name: z.string().min(1).max(100),
age: z.number().int().min(0).max(150)
})
// Validate before processing
export async function createUser(input: unknown) {
try {
const validated = CreateUserSchema.parse(input)
return await db.users.create(validated)
} catch (error) {
if (error instanceof z.ZodError) {
return { success: false, errors: error.errors }
}
throw error
}
}function validateFileUpload(file: File) {
// Size check (5MB max)
const maxSize = 5 * 1024 * 1024
if (file.size > maxSize) {
throw new Error('File too large (max 5MB)')
}
// Type check
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']
if (!allowedTypes.includes(file.type)) {
throw new Error('Invalid file type')
}
// Extension check
const allowedExtensions = ['.jpg', '.jpeg', '.png', '.gif']
const extension = file.name.toLowerCase().match(/\.[^.]+$/)?.[0]
if (!extension || !allowedExtensions.includes(extension)) {
throw new Error('Invalid file extension')
}
return true
}// DANGEROUS - SQL Injection vulnerability
const query = `SELECT * FROM users WHERE email = '${userEmail}'`
await db.query(query)// Safe - parameterized query
const { data } = await supabase
.from('users')
.select('*')
.eq('email', userEmail)
// Or with raw SQL
await db.query(
'SELECT * FROM users WHERE email = $1',
[userEmail]
)// FAIL: WRONG: localStorage (vulnerable to XSS)
localStorage.setItem('token', token)
// PASS: CORRECT: httpOnly cookies
res.setHeader('Set-Cookie',
`token=${token}; HttpOnly; Secure; SameSite=Strict; Max-Age=3600`)export async function deleteUser(userId: string, requesterId: string) {
// ALWAYS verify authorization first
const requester = await db.users.findUnique({
where: { id: requesterId }
})
if (requester.role !== 'admin') {
return NextResponse.json(
{ error: 'Unauthorized' },
{ status: 403 }
)
}
// Proceed with deletion
await db.users.delete({ where: { id: userId } })
}-- Enable RLS on all tables ALTER TABLE users ENABLE ROW LEVEL SECURITY; -- Users can only view their own data CREATE POLICY "Users view own data" ON users FOR SELECT USING (auth.uid() = id); -- Users can only update their own data CREATE POLICY "Users update own data" ON users FOR UPDATE USING (auth.uid() = id);
import DOMPurify from 'isomorphic-dompurify'
// ALWAYS sanitize user-provided HTML
function renderUserContent(html: string) {
const clean = DOMPurify.sanitize(html, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p'],
ALLOWED_ATTR: []
})
return <div dangerouslySetInnerHTML={{ __html: clean }} />
}Start strict and loosen only with a documented removal plan. Do not default to `'unsafe-inline'` or `'unsafe-eval'`; they neutralize much of CSP's protection and should be treated as temporary compatibility debt.
// next.config.js
const securityHeaders = [
{
key: 'Content-Security-Policy',
value: `
default-src 'self';
base-uri 'self';
object-src 'none';
frame-ancestors 'none';
script-src 'self';
style-src 'self';
img-src 'self' data: https:;
font-src 'self';
connect-src 'self' https://api.example.com;
`.replace(/\s{2,}/g, ' ').trim()
}
]A quality-first harness for autonomous AI coding agents. It turns "the agent said it's done" into *"here's the proof — graded by an independent, default-FAIL checker."* Done is earned, not asserted.
Repo: 23ag1/completely
Run completely AUTONOMOUSLY — loop the FULL task engine over the Beads queue, a fresh `claude -p` per task, until the queue is empty. Same complete recipe as…
Run all configured quality checks (lint, types, tests) in one pass with terse output — reports "clean" when green, and only the failing check's output when…
Overview and entry point for the completely harness — a quality-first agent workflow unifying GSD (planning depth), Ralph (autonomous loop), and Beads (the…
Run completely UNDER CONTROL — execute the SINGLE next Beads task through the FULL task engine (understand → map → plan-check → parallel subagents → TDD →…
Scaffold the completely thin layer into the current repository — Definition of Done, the harness rules snippet in CLAUDE.md, and an optional project-specific…