docs: salvage focused skill curation updates (#1723)

Port the safe, narrow pieces from contributor PR #1694 without taking the broad 11-skill rewrite.

- add drift-prone warnings to external research/media/API skills

- make search-first verify tool availability and use current agent naming

- remove unsafe in-memory rate limiter example from backend patterns

- tighten the CSP example in security-review

Validation: node scripts/ci/validate-skills.js --strict; npx markdownlint targeted skill files; node tests/ci/validators.test.js && node tests/ci/catalog.test.js; npm run lint; node tests/run-all.js
This commit is contained in:
Affaan Mustafa 2026-05-11 05:03:34 -04:00 committed by GitHub
parent d352270b9a
commit d8f879e671
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 56 additions and 48 deletions

View File

@ -430,51 +430,14 @@ export const DELETE = requirePermission('delete')(
## Rate Limiting ## Rate Limiting
### Simple In-Memory Rate Limiter Rate limiting must use a shared store such as Redis, a gateway, or the
platform's native limiter. Do not use per-process in-memory counters for
production APIs: they reset on deploy, split across replicas, and fail open in
serverless or multi-instance environments.
```typescript Keep the backend layer responsible for choosing the integration point and error
class RateLimiter { shape; use `api-design` for the HTTP contract and `security-review` for abuse
private requests = new Map<string, number[]>() case review.
async checkLimit(
identifier: string,
maxRequests: number,
windowMs: number
): Promise<boolean> {
const now = Date.now()
const requests = this.requests.get(identifier) || []
// Remove old requests outside window
const recentRequests = requests.filter(time => now - time < windowMs)
if (recentRequests.length >= maxRequests) {
return false // Rate limit exceeded
}
// Add current request
recentRequests.push(now)
this.requests.set(identifier, recentRequests)
return true
}
}
const limiter = new RateLimiter()
export async function GET(request: Request) {
const ip = request.headers.get('x-forwarded-for') || 'unknown'
const allowed = await limiter.checkLimit(ip, 100, 60000) // 100 req/min
if (!allowed) {
return NextResponse.json({
error: 'Rate limit exceeded'
}, { status: 429 })
}
// Continue with request
}
```
## Background Jobs & Queues ## Background Jobs & Queues

View File

@ -6,6 +6,10 @@ origin: ECC
# Deep Research # Deep Research
> **Drift-prone skill.** Firecrawl/Exa MCP tool names, quotas, and result
> shapes change. Verify the configured MCP tools and current API docs before
> promising coverage or quoting live source counts.
Produce thorough, cited research reports from multiple web sources using firecrawl and exa MCP tools. Produce thorough, cited research reports from multiple web sources using firecrawl and exa MCP tools.
## When to Activate ## When to Activate

View File

@ -6,6 +6,10 @@ origin: ECC
# Exa Search # Exa Search
> **Drift-prone skill.** Exa MCP tool names, parameters, and account limits can
> change. Confirm the exposed tool surface and current Exa docs before relying
> on a specific search mode, category, or livecrawl behavior.
Neural search for web content, code, companies, and people via the Exa MCP server. Neural search for web content, code, companies, and people via the Exa MCP server.
## When to Activate ## When to Activate

View File

@ -6,6 +6,10 @@ origin: ECC
# fal.ai Media Generation # fal.ai Media Generation
> **Drift-prone skill.** fal.ai model IDs, pricing, inputs, and MCP tool names
> change quickly. Search or fetch the current model metadata before promising a
> specific model, parameter, output format, or cost.
Generate images, videos, and audio using fal.ai models via MCP. Generate images, videos, and audio using fal.ai models via MCP.
## When to Activate ## When to Activate

View File

@ -20,6 +20,10 @@ Use this skill when:
``` ```
┌─────────────────────────────────────────────┐ ┌─────────────────────────────────────────────┐
│ 0. TOOL AVAILABILITY PREFLIGHT │
│ Check search channels before relying on │
│ them; report skipped channels honestly │
├─────────────────────────────────────────────┤
│ 1. NEED ANALYSIS │ │ 1. NEED ANALYSIS │
│ Define what functionality is needed │ │ Define what functionality is needed │
│ Identify language/framework constraints │ │ Identify language/framework constraints │
@ -57,6 +61,19 @@ Use this skill when:
## How to Use ## How to Use
### Step 0: Tool Availability Preflight
This is agent guidance, not an executable setup script. Check only the channels
that are relevant to the task and project in front of you.
| Channel | Check | If missing |
|---------|-------|------------|
| Repository search | `rg --files` and targeted `rg` queries | State that only visible files were inspected |
| Package registry | `npm --version`, `python -m pip --version`, or project package manager | Use web/docs search and avoid claiming registry coverage |
| GitHub CLI | `gh auth status` | Use public web or local git history only |
| MCP/docs tools | Available tool list or local MCP config | Fall back to official docs/web search |
| Skills directory | `ls ~/.claude/skills ~/.codex/skills` where applicable | Say no local skill catalog was available |
### Quick Mode (inline) ### Quick Mode (inline)
Before writing a utility or adding functionality, mentally run through: Before writing a utility or adding functionality, mentally run through:
@ -72,7 +89,7 @@ Before writing a utility or adding functionality, mentally run through:
For non-trivial functionality, launch the researcher agent: For non-trivial functionality, launch the researcher agent:
``` ```
Task(subagent_type="general-purpose", prompt=" Agent(subagent_type="general-purpose", prompt="
Research existing tools for: [DESCRIPTION] Research existing tools for: [DESCRIPTION]
Language/framework: [LANG] Language/framework: [LANG]
Constraints: [ANY] Constraints: [ANY]
@ -82,6 +99,9 @@ Task(subagent_type="general-purpose", prompt="
") ")
``` ```
Older Claude Code docs may call this `Task(...)`; use the current agent/subagent
tool name exposed by the active harness.
## Search Shortcuts by Category ## Search Shortcuts by Category
### Development Tooling ### Development Tooling
@ -96,7 +116,7 @@ Task(subagent_type="general-purpose", prompt="
- Document processing → `unstructured`, `pdfplumber`, `mammoth` - Document processing → `unstructured`, `pdfplumber`, `mammoth`
### Data & APIs ### Data & APIs
- HTTP clients → `httpx` (Python), `ky`/`got` (Node) - HTTP clients → `httpx` (Python), `ky`/`undici` (Node)
- Validation → `zod` (TS), `pydantic` (Python) - Validation → `zod` (TS), `pydantic` (Python)
- Database → Check for MCP servers first - Database → Check for MCP servers first
@ -157,5 +177,6 @@ Result: 1 package + 1 schema file, no custom validation logic
- **Jumping to code**: Writing a utility without checking if one exists - **Jumping to code**: Writing a utility without checking if one exists
- **Ignoring MCP**: Not checking if an MCP server already provides the capability - **Ignoring MCP**: Not checking if an MCP server already provides the capability
- **Silent skipping**: Reporting "nothing found" when a search channel was unavailable
- **Over-customizing**: Wrapping a library so heavily it loses its benefits - **Over-customizing**: Wrapping a library so heavily it loses its benefits
- **Dependency bloat**: Installing a massive package for one small feature - **Dependency bloat**: Installing a massive package for one small feature

View File

@ -208,6 +208,11 @@ function renderUserContent(html: string) {
``` ```
#### Content Security Policy #### Content Security Policy
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.
```typescript ```typescript
// next.config.js // next.config.js
const securityHeaders = [ const securityHeaders = [
@ -215,8 +220,11 @@ const securityHeaders = [
key: 'Content-Security-Policy', key: 'Content-Security-Policy',
value: ` value: `
default-src 'self'; default-src 'self';
script-src 'self' 'unsafe-eval' 'unsafe-inline'; base-uri 'self';
style-src 'self' 'unsafe-inline'; object-src 'none';
frame-ancestors 'none';
script-src 'self';
style-src 'self';
img-src 'self' data: https:; img-src 'self' data: https:;
font-src 'self'; font-src 'self';
connect-src 'self' https://api.example.com; connect-src 'self' https://api.example.com;

View File

@ -6,6 +6,10 @@ origin: ECC
# X API # X API
> **Drift-prone skill.** X API endpoints, access tiers, quotas, and write
> permissions change frequently. Verify current developer docs and account
> access before quoting rate limits or implementing a posting/search flow.
Programmatic interaction with X (Twitter) for posting, reading, searching, and analytics. Programmatic interaction with X (Twitter) for posting, reading, searching, and analytics.
## When to Activate ## When to Activate