From d8f879e671fa2e522df8cdf80472250b0b736b0f Mon Sep 17 00:00:00 2001 From: Affaan Mustafa Date: Mon, 11 May 2026 05:03:34 -0400 Subject: [PATCH] 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 --- skills/backend-patterns/SKILL.md | 51 +++++--------------------------- skills/deep-research/SKILL.md | 4 +++ skills/exa-search/SKILL.md | 4 +++ skills/fal-ai-media/SKILL.md | 4 +++ skills/search-first/SKILL.md | 25 ++++++++++++++-- skills/security-review/SKILL.md | 12 ++++++-- skills/x-api/SKILL.md | 4 +++ 7 files changed, 56 insertions(+), 48 deletions(-) diff --git a/skills/backend-patterns/SKILL.md b/skills/backend-patterns/SKILL.md index 30898b4d..b7a7343c 100644 --- a/skills/backend-patterns/SKILL.md +++ b/skills/backend-patterns/SKILL.md @@ -430,51 +430,14 @@ export const DELETE = requirePermission('delete')( ## 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 -class RateLimiter { - private requests = new Map() - - async checkLimit( - identifier: string, - maxRequests: number, - windowMs: number - ): Promise { - 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 -} -``` +Keep the backend layer responsible for choosing the integration point and error +shape; use `api-design` for the HTTP contract and `security-review` for abuse +case review. ## Background Jobs & Queues diff --git a/skills/deep-research/SKILL.md b/skills/deep-research/SKILL.md index 5a412b7e..cfab08a6 100644 --- a/skills/deep-research/SKILL.md +++ b/skills/deep-research/SKILL.md @@ -6,6 +6,10 @@ origin: ECC # 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. ## When to Activate diff --git a/skills/exa-search/SKILL.md b/skills/exa-search/SKILL.md index 567dc944..5b9e6c19 100644 --- a/skills/exa-search/SKILL.md +++ b/skills/exa-search/SKILL.md @@ -6,6 +6,10 @@ origin: ECC # 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. ## When to Activate diff --git a/skills/fal-ai-media/SKILL.md b/skills/fal-ai-media/SKILL.md index ffe701d1..44343a7f 100644 --- a/skills/fal-ai-media/SKILL.md +++ b/skills/fal-ai-media/SKILL.md @@ -6,6 +6,10 @@ origin: ECC # 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. ## When to Activate diff --git a/skills/search-first/SKILL.md b/skills/search-first/SKILL.md index 73dcedde..e095b662 100644 --- a/skills/search-first/SKILL.md +++ b/skills/search-first/SKILL.md @@ -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 │ │ Define what functionality is needed │ │ Identify language/framework constraints │ @@ -57,6 +61,19 @@ Use this skill when: ## 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) 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: ``` -Task(subagent_type="general-purpose", prompt=" +Agent(subagent_type="general-purpose", prompt=" Research existing tools for: [DESCRIPTION] Language/framework: [LANG] 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 ### Development Tooling @@ -96,7 +116,7 @@ Task(subagent_type="general-purpose", prompt=" - Document processing → `unstructured`, `pdfplumber`, `mammoth` ### Data & APIs -- HTTP clients → `httpx` (Python), `ky`/`got` (Node) +- HTTP clients → `httpx` (Python), `ky`/`undici` (Node) - Validation → `zod` (TS), `pydantic` (Python) - 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 - **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 - **Dependency bloat**: Installing a massive package for one small feature diff --git a/skills/security-review/SKILL.md b/skills/security-review/SKILL.md index af848b95..4afc85d1 100644 --- a/skills/security-review/SKILL.md +++ b/skills/security-review/SKILL.md @@ -208,6 +208,11 @@ function renderUserContent(html: string) { ``` #### 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 // next.config.js const securityHeaders = [ @@ -215,8 +220,11 @@ const securityHeaders = [ key: 'Content-Security-Policy', value: ` default-src 'self'; - script-src 'self' 'unsafe-eval' 'unsafe-inline'; - style-src 'self' 'unsafe-inline'; + 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; diff --git a/skills/x-api/SKILL.md b/skills/x-api/SKILL.md index 9100664c..c60e8f72 100644 --- a/skills/x-api/SKILL.md +++ b/skills/x-api/SKILL.md @@ -6,6 +6,10 @@ origin: ECC # 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. ## When to Activate