diff --git a/skills/receiving-code-review/SKILL.md b/skills/receiving-code-review/SKILL.md index 4ea72cd..0f3025f 100644 --- a/skills/receiving-code-review/SKILL.md +++ b/skills/receiving-code-review/SKILL.md @@ -27,7 +27,7 @@ WHEN receiving code review feedback: ## Forbidden Responses **NEVER:** -- "You're absolutely right!" (explicit CLAUDE.md violation) +- "You're absolutely right!" (explicit AGENTS.md violation) - "Great point!" / "Excellent feedback!" (performative) - "Let me implement that now" (before verification) diff --git a/skills/supabase/SKILL.md b/skills/supabase/SKILL.md index 2d17789..53b8056 100644 --- a/skills/supabase/SKILL.md +++ b/skills/supabase/SKILL.md @@ -3,15 +3,17 @@ name: supabase description: "Use when doing ANY task involving Supabase. Triggers: Supabase products (Database, Auth, Edge Functions, Realtime, Storage, Vectors, Cron, Queues); client libraries and SSR integrations (supabase-js, @supabase/ssr) in Next.js, React, SvelteKit, Astro, Remix; auth issues (login, logout, sessions, JWT, cookies, getSession, getUser, getClaims, RLS); Supabase CLI or MCP server; schema changes, migrations, security audits, Postgres extensions (pg_graphql, pg_cron, pg_vector)." metadata: author: supabase - version: "0.1.1" + version: "0.1.2" --- # Supabase ## Core Principles -**1. Supabase changes frequently — verify against current docs before implementing.** -Do not rely on training data for Supabase features. Function signatures, config.toml settings, and API conventions change between versions. Before implementing, look up the relevant topic using the documentation access methods below. +**1. Supabase changes frequently — verify against changelog and current docs before implementing.** +Do not rely on training data for Supabase features. Function signatures, config.toml settings, and API conventions change between versions. + +First, fetch `https://supabase.com/changelog.md` (a lightweight summary index — not a heavy pull), scan for `breaking-change` tags relevant to your task, and follow the linked page for any that apply. Then look up the relevant topic using the documentation access methods below. **2. Verify your work.** After implementing any fix, run a test query to confirm the change works. A fix without verification is incomplete. @@ -19,28 +21,33 @@ After implementing any fix, run a test query to confirm the change works. A fix **3. Recover from errors, don't loop.** If an approach fails after 2-3 attempts, stop and reconsider. Try a different method, check documentation, inspect the error more carefully, and review relevant logs when available. Supabase issues are not always solved by retrying the same command, and the answer is not always in the logs, but logs are often worth checking before proceeding. -**4. RLS by default in exposed schemas.** -Enable RLS on every table in any exposed schema, especially `public`. This is critical in Supabase because tables in exposed schemas can be reachable through the Data API. For private schemas, prefer RLS as defense in depth. After enabling RLS, create policies that match the actual access model rather than defaulting every table to the same `auth.uid()` pattern. +**4. Exposing tables to the Data API:** Depending on the user's [Data API settings](https://supabase.com/dashboard/project//integrations/data_api/settings), newly created tables may not be automatically exposed via the Data (REST) API. If this is the case, `anon` and `authenticated` roles will need to be explicitly granted access. -**5. Security checklist.** +> Note that this is separate from RLS, which controls which _rows_ are visible once a table is accessible, not whether the table is accessible at all. + +When a user reports a SQL-created table is unexpectedly inaccessible, check their Data API settings and whether the roles have been granted access via explicit `GRANT` SQL. When granting public (`anon`/`authenticated`) access, always enable RLS too. See [Exposing a Table to the Data API](https://supabase.com/docs/guides/api/securing-your-api.md) for the full setup workflow. + +**5. RLS in exposed schemas.** +Enable RLS on every table in any exposed schema, which includes `public` by default. This is critical in Supabase because tables in exposed schemas can be reachable through the Data API when the `anon`/`authenticated` roles have access (see [Exposing a Table to the Data API](https://supabase.com/docs/guides/api/securing-your-api.md)). For private schemas, prefer RLS as defense in depth. After enabling RLS, create policies that match the actual access model rather than defaulting every table to the same `auth.uid()` pattern. + +**6. Security checklist.** When working on any Supabase task that touches auth, RLS, views, storage, or user data, run through this checklist. These are Supabase-specific security traps that silently create vulnerabilities: - **Auth and session security** - - **Never use `user_metadata` claims in JWT-based authorization decisions.** In Supabase, `raw_user_meta_data` is user-editable and can appear in `auth.jwt()`, so it is unsafe for RLS policies or any other authorization logic. Store authorization data in `raw_app_meta_data` / `app_metadata` instead. - - **Deleting a user does not invalidate existing access tokens.** Sign out or revoke sessions first, keep JWT expiry short for sensitive apps, and for strict guarantees validate `session_id` against `auth.sessions` on sensitive operations. - - **If you use `app_metadata` or `auth.jwt()` for authorization, remember JWT claims are not always fresh until the user's token is refreshed.** + - **Never use `user_metadata` claims in JWT-based authorization decisions.** In Supabase, `raw_user_meta_data` is user-editable and can appear in `auth.jwt()`, so it is unsafe for RLS policies or any other authorization logic. Store authorization data in `raw_app_meta_data` / `app_metadata` instead. + - **Deleting a user does not invalidate existing access tokens.** Sign out or revoke sessions first, keep JWT expiry short for sensitive apps, and for strict guarantees validate `session_id` against `auth.sessions` on sensitive operations. + - **If you use `app_metadata` or `auth.jwt()` for authorization, remember JWT claims are not always fresh until the user's token is refreshed.** - **API key and client exposure** - - **Never expose the `service_role` or secret key in public clients.** Prefer publishable keys for frontend code. Legacy `anon` keys are only for compatibility. In Next.js, any `NEXT_PUBLIC_` env var is sent to the browser. + - **Never expose the `service_role` or secret key in public clients.** Prefer publishable keys for frontend code. Legacy `anon` keys are only for compatibility. In Next.js, any `NEXT_PUBLIC_` env var is sent to the browser. - **RLS, views, and privileged database code** - - **Views bypass RLS by default.** In Postgres 15 and above, use `CREATE VIEW ... WITH (security_invoker = true)`. In older versions of Postgres, protect your views by revoking access from the `anon` and `authenticated` roles, or by putting them in an unexposed schema. - - **UPDATE requires a SELECT policy.** In Postgres RLS, an UPDATE needs to first SELECT the row. Without a SELECT policy, updates silently return 0 rows — no error, just no change. - - **Do not put `security definer` functions in an exposed schema.** Keep them in a private or otherwise unexposed schema. - + - **Views bypass RLS by default.** In Postgres 15 and above, use `CREATE VIEW ... WITH (security_invoker = true)`. In older versions of Postgres, protect your views by revoking access from the `anon` and `authenticated` roles, or by putting them in an unexposed schema. + - **UPDATE requires a SELECT policy.** In Postgres RLS, an UPDATE needs to first SELECT the row. Without a SELECT policy, updates silently return 0 rows — no error, just no change. + - **Do not put `security definer` functions in an exposed schema.** Keep them in a private or otherwise unexposed schema. - **Storage access control** - - **Storage upsert requires INSERT + SELECT + UPDATE.** Granting only INSERT allows new uploads but file replacement (upsert) silently fails. You need all three. + - **Storage upsert requires INSERT + SELECT + UPDATE.** Granting only INSERT allows new uploads but file replacement (upsert) silently fails. You need all three. For any security concern not covered above, fetch the Supabase product security index: `https://supabase.com/docs/guides/security/product-security.md` @@ -55,6 +62,7 @@ supabase --help # Flags for a specific command ``` **Supabase CLI Known gotchas:** + - `supabase db query` requires **CLI v2.79.0+** → use MCP `execute_sql` or `psql` as fallback - `supabase db advisors` requires **CLI v2.81.3+** → use MCP `get_advisors` as fallback - When you need a new migration SQL file, **always** create it with `supabase migration new ` first. Never invent a migration filename or rely on memory for the expected format. diff --git a/skills/using-git-worktrees/SKILL.md b/skills/using-git-worktrees/SKILL.md index e153843..74dfded 100644 --- a/skills/using-git-worktrees/SKILL.md +++ b/skills/using-git-worktrees/SKILL.md @@ -27,17 +27,17 @@ ls -d worktrees 2>/dev/null # Alternative **If found:** Use that directory. If both exist, `.worktrees` wins. -### 2. Check CLAUDE.md +### 2. Check AGENTS.md ```bash -grep -i "worktree.*director" CLAUDE.md 2>/dev/null +grep -i "worktree.*director" AGENTS.md 2>/dev/null ``` **If preference specified:** Use it without asking. ### 3. Ask User -If no directory exists and no CLAUDE.md preference: +If no directory exists and no AGENTS.md preference: ``` No worktree directory found. Where should I create worktrees? @@ -148,7 +148,7 @@ Ready to implement | `.worktrees/` exists | Use it (verify ignored) | | `worktrees/` exists | Use it (verify ignored) | | Both exist | Use `.worktrees/` | -| Neither exists | Check CLAUDE.md → Ask user | +| Neither exists | Check AGENTS.md → Ask user | | Directory not ignored | Add to .gitignore + commit | | Tests fail during baseline | Report failures + ask | | No package.json/Cargo.toml | Skip dependency install | @@ -163,7 +163,7 @@ Ready to implement ### Assuming directory location - **Problem:** Creates inconsistency, violates project conventions -- **Fix:** Follow priority: existing > CLAUDE.md > ask +- **Fix:** Follow priority: existing > AGENTS.md > ask ### Proceeding with failing tests @@ -198,10 +198,10 @@ Ready to implement auth feature - Skip baseline test verification - Proceed with failing tests without asking - Assume directory location when ambiguous -- Skip CLAUDE.md check +- Skip AGENTS.md check **Always:** -- Follow directory priority: existing > CLAUDE.md > ask +- Follow directory priority: existing > AGENTS.md > ask - Verify directory is ignored for project-local - Auto-detect and run project setup - Verify clean test baseline diff --git a/skills/writing-skills/testing-skills-with-subagents.md b/skills/writing-skills/testing-skills-with-subagents.md index a5acfea..8d33179 100644 --- a/skills/writing-skills/testing-skills-with-subagents.md +++ b/skills/writing-skills/testing-skills-with-subagents.md @@ -12,7 +12,7 @@ You run scenarios without the skill (RED - watch agent fail), write skill addres **REQUIRED BACKGROUND:** You MUST understand superpowers:test-driven-development before using this skill. That skill defines the fundamental RED-GREEN-REFACTOR cycle. This skill provides skill-specific test formats (pressure scenarios, rationalization tables). -**Complete worked example:** See examples/CLAUDE_MD_TESTING.md for a full test campaign testing CLAUDE.md documentation variants. +**Complete worked example:** See examples/AGENTS_MD_TESTING.md for a full test campaign testing AGENTS.md documentation variants. ## When to Use