Skip to content

Commit e07c307

Browse files
committed
docs(agents): correct review findings in skills and rules
Scope SSRF, client-boundary, forcedToolUse, canonicalParamId, integration metadata, and HEAD claims to what the code does; fix the ship migration pathspec, the babysit conflict path, enrichment folder placeholders, framer-motion samples, and stale connector and column-type references.
1 parent af3e506 commit e07c307

22 files changed

Lines changed: 34 additions & 32 deletions

File tree

‎.agents/skills/add-column-type/SKILL.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ Registering the *type* is compiler-enforced. Registering its *metadata* is not,
132132
| `column-types/types.ts` `TYPE_SPECIFIC_COLUMN_KEYS` | it is never stripped on conversion, and poisons the target type |
133133
| `lib/api/contracts/tables.ts` — the schema slot in all three column schemas, plus `refineColumnOptions` | zod strips it at the boundary; silently never saved |
134134
| `columns/service.ts` `addTableColumn` param type | callers cannot pass it |
135-
| A metadata-only update in `lib/table/columns/service.ts` (`updateColumnCurrency` is the model) + a branch in `updateColumn` in `lib/table/orchestration/columns.ts` | changing it on an existing column is a silent 200 no-op |
135+
| A metadata-only update in `lib/table/columns/service.ts` (`updateColumnCurrency` is the model) + a branch in `performUpdateTableColumn` in `lib/table/orchestration/columns.ts` | changing it on an existing column is a silent 200 no-op |
136136
| `column-config-sidebar.tsx` | no UI to set it |
137137
| `table-grid.tsx` delete-column undo + `use-table-undo.ts` restore | undo silently resets it to the default |
138138

‎.agents/skills/add-connector/SKILL.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ mapTags: (metadata: Record<string, unknown>): Record<string, unknown> => {
515515

516516
## External API Calls — Use `fetchWithRetry`
517517

518-
All external API calls must use `fetchWithRetry` from `@/lib/knowledge/documents/secure-fetch.server` (SSRF-guarded) instead of raw `fetch()`; use `secureFetchWithRetry` for user-controlled hosts. This provides exponential backoff with retries on 429/502/503/504 errors. It returns a standard `Response` — all `.ok`, `.json()`, `.text()` checks work unchanged.
518+
All external API calls must use `fetchWithRetry` from `@/lib/knowledge/documents/secure-fetch.server` instead of raw `fetch()`. It does not validate the host (on a direct outbound route it calls plain `fetch`), so use `secureFetchWithRetry` for user-controlled hosts. This provides exponential backoff with retries on 429/502/503/504 errors. It returns a standard `Response` — all `.ok`, `.json()`, `.text()` checks work unchanged.
519519

520520
For `validateConfig` (user-facing, called on save), pass `VALIDATE_RETRY_OPTIONS` to cap wait time at ~7s. Background operations (`listDocuments`, `getDocument`) use the built-in defaults (5 retries within a 150s budget).
521521

@@ -605,7 +605,7 @@ export const CONNECTOR_META_REGISTRY: ConnectorMetaRegistry = {
605605
- **OAuth + contentDeferred**: `apps/sim/connectors/google-drive/google-drive.ts` — file download with metadata-based hash, `orderBy` for deterministic pagination
606606
- **OAuth + contentDeferred (blocks API)**: `apps/sim/connectors/notion/notion.ts` — complex block content extraction deferred to `getDocument`
607607
- **OAuth + contentDeferred (git)**: `apps/sim/connectors/github/github.ts` — blob SHA hash, tree listing
608-
- **OAuth + inline content**: `apps/sim/connectors/slack/slack.ts` — list API returns message content inline; `contentHash` hashes that content
608+
- **OAuth + inline content**: `apps/sim/connectors/airtable/airtable.ts` — list API returns record fields inline; `listDocuments` and `getDocument` share `recordToDocument`, which hashes that content
609609
- **OAuth + contentDeferred + config fields**: `apps/sim/connectors/confluence/confluence.ts` — multiple config field types, `mapTags`, label fetching
610610
- **API key**: `apps/sim/connectors/fireflies/fireflies.ts` — GraphQL API with Bearer token auth
611611

‎.agents/skills/add-enrichment/SKILL.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Because enrichments run on Sim's hosted keys by default, **every provider tool y
1616
|------|------|-------|
1717
| 1 | Pick the data-source tool(s) for each output | `tools/{service}/` + `tools/registry.ts` |
1818
| 2 | **Verify each tool has `hosting`; if not, run `/add-hosted-key`** | `tools/{service}/{action}.ts` |
19-
| 3 | Write the enrichment definition | `enrichments/{name}/{name}.ts` + `index.ts` |
19+
| 3 | Write the enrichment definition | `enrichments/{id}/{id}.ts` + `index.ts` |
2020
| 4 | Register it | `enrichments/registry.ts` |
2121
| 5 | Verify | tsc / biome / manual run |
2222

@@ -60,7 +60,7 @@ Why it matters: the cascade runner only bills (and only reads `output.cost.total
6060

6161
## Step 3: Write the enrichment definition
6262

63-
Create `apps/sim/enrichments/{name}/{name}.ts` and a barrel `index.ts`. Mirror the entries registered in `enrichments/registry.ts`.
63+
Create `apps/sim/enrichments/{id}/{id}.ts` and a barrel `index.ts`. Mirror the entries registered in `enrichments/registry.ts`.
6464

6565
```typescript
6666
import { SomeIcon } from '@sim/emcn/icons'
@@ -104,7 +104,7 @@ export const myEnrichment: EnrichmentConfig = {
104104
```
105105

106106
```typescript
107-
// apps/sim/enrichments/{name}/index.ts
107+
// apps/sim/enrichments/{id}/index.ts
108108
export { myEnrichment } from './my-enrichment'
109109
```
110110

‎.agents/skills/add-integration/SKILL.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ Use the basic/advanced mode pattern:
497497
},
498498
```
499499

500-
**Critical:** `canonicalParamId` must NOT match any subblock `id`.
500+
**Critical:** `canonicalParamId` must NOT match the `id` of a subblock outside its canonical group.
501501

502502
#### 2. Normalize File Input in Block Config
503503

‎.agents/skills/add-model/SKILL.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ Use a precise WebFetch prompt: *"Extract for {model_id}: exact model id string,
4949
|---|---|---|
5050
| `temperature` | All providers (passed through if set) | Safe but inert on always-reasoning models that reject it |
5151
| `toolUsageControl` | All providers (provider-level default) | Override per model only when that model differs |
52-
| `forcedToolUse` | Defaults to `toolUsageControl` | Set only when the model cannot force tools |
52+
| `forcedToolUse` | `anthropic/core.ts` (anthropic, azure-anthropic, kie); defaults to `toolUsageControl` | Ignored by every other provider; set `false` only on a model behind that core that cannot force tools |
5353
| `promptCaching` | Caller-placed cache breakpoints | Set only where the vendor charges for opt-in caching (absent for OpenAI/Gemini implicit caching) |
5454
| `reasoningEffort` | `openai/core.ts`, `azure-openai`, `xai`, `deepseek`, `groq`, `zai`, `kimi`, `cerebras`, `meta`, `litellm` (each `index.ts`) | Not read by anthropic/gemini (they use `thinking`) or by mistral, openrouter, fireworks, vertex — re-grep before assuming |
5555
| `verbosity` | `openai/core.ts`, `azure-openai/index.ts` only | Dead elsewhere |

‎.agents/skills/add-permission-group-item/SKILL.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ Allowlist when the safe posture is "only what the admin named" and the member se
6060

6161
The second argument is the field's `feature` (`PlatformFeatureMeta`); `PLATFORM_FEATURES` spreads it and appends `configKey`, so those four values are what the editor renders. `PLATFORM_FEATURES` is *derived* from the registry in `features.ts`, so a boolean key cannot reach the config without reaching the editor.
6262

63-
- **Declaration order is the wire order** of `PermissionGroupConfig`, both zod schemas, and every config JSON crossing the API. No test catches a reorder (schemas and defaults all derive from the registry), and `ee/access-control/components/group-detail.tsx` dirty-checks by comparing stringified configs, so a moved key makes every open editor read as unsaved. Extend the tail; do not tidy the middle.
63+
- **Declaration order is the wire order** of `PermissionGroupConfig`, both zod schemas, and every config JSON crossing the API, since all of them derive from the registry. Extend the tail; do not tidy the middle.
6464
- **The default must be the permissive value.** Every stored `permission_group.config` row predates your key; `parsePermissionGroupConfig` fills the gap from the default and the update route merges a partial write over the stored config, so a restrictive default silently applies a new restriction to every existing group in every enterprise org. The builders hardcode `false` / `null` / `[]`, so a new key must be *phrased* so the permissive value is falsy: a `requireWidgetApproval` whose safe default is `true` must be inverted before it can use `booleanRestriction`.
6565
- **The checkbox is inverted.** `group-detail.tsx` renders `checked={!editingConfig[feature.configKey]}` — ticked means *allowed*, so an `allowX` name renders backwards.
6666
- **The hint must describe access withheld, never a surface hidden.** A `'capability'` key refuses at the API; "Hide the Tables module from the sidebar" tells an admin they are tidying a nav bar while they revoke a module. The same string is read again by `getActivePermissionGroupRestrictions` in `features.ts` as the prose for an *active* restriction — reaching users through the Copilot workspace VFS and the enterprise platform context — where "hide" is simply false. Write "Revoke the Tables module. Members cannot read or write any table." `PlatformFeatureMeta.hint` carries the rule in its TSDoc.
@@ -213,7 +213,7 @@ cd apps/sim && bun run type-check
213213
bun run --cwd apps/sim test lib/permission-groups
214214
```
215215

216-
Also `bun run check:api-validation:strict` if you touched a contract or the group routes. `bun run check:audits` runs every one of these (including the `:strict` variant); it derives its list from the `check:*` scripts in `package.json`, so a new audit is opted *out* deliberately rather than opted in.
216+
Also `bun run check:api-validation:strict` if you touched a contract or the group routes. `bun run check:audits` runs every `check:*` command here (including the `:strict` variant) but not type-check or the tests; it derives its list from the `check:*` scripts in `package.json`, so a new audit is opted *out* deliberately rather than opted in.
217217

218218
Read the success lines, not the exit codes — compare the counts against the previous run and check they grew by exactly what you added: an operation-declared capability adds one operation and one capability; a raw-route or parameterized capability adds one capability and no operation; an executor-gated or UI-only item adds neither:
219219

‎.agents/skills/babysit/SKILL.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,9 @@ conditions freshly after every push.
8888
across all pages has `isResolved: true`, and every check has finished and passed, stop —
8989
report the outcome (see "Reporting" below) and skip the rest of this list.
9090

91-
2. **If the PR has a merge conflict**, merge `origin/staging`, resolve the conflicts, run `/ship`
92-
steps 4–6 on the merge result, push, and go to step 8 to re-trigger review.
91+
2. **If the PR has a merge conflict**, merge `origin/staging`, resolve the conflicts, then
92+
follow steps 6–8 on the merge result: the full sync check plus `/ship` steps 4–6, push, and
93+
re-trigger review.
9394

9495
3. **If no review has run yet** (fresh PR, no bot comments): both run automatically on PR open —
9596
confirm via `gh pr checks <n>` (look for `Greptile Review` and `cubic · AI code reviewer`) and

‎.agents/skills/design-taste-frontend/SKILL.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ source: https://github.com/leonxlnx/taste-skill — skills/taste-skill/SKILL.md
44
description: Anti-slop frontend skill for landing pages, portfolios, and redesigns. The agent reads the brief, infers the right design direction, and ships interfaces that do not look templated. Real design systems when applicable, audit-first on redesigns, strict pre-flight check.
55
---
66

7-
> **In this repo:** Tailwind 4 (CSS-first config in `apps/sim/app/_styles/globals.css`); animation via `import { motion } from 'framer-motion'` (not `motion/react` — rewrite every `motion/react` import in the samples below); icons from `@sim/emcn/icons`; colors through the CSS-variable tokens in `.claude/rules/sim-styling.md` (no hardcoded `text-gray-*`/hex/`zinc` utilities, no paired `dark:` utilities). This note overrides any conflicting guidance or code sample anywhere in this file. Fonts are fixed (Season body, Inter); never introduce new families, and never use Martian Mono on landing (`apps/sim/app/(landing)/CLAUDE.md`). Font weight is only `font-normal`/`font-medium`/`font-semibold`. Elevation uses the `shadow-subtle|medium|overlay|card` tokens. Type size uses named tokens, never `text-[Npx]`. Product forms use `ChipModalField`. Use `bunx`, never `npx`. Do not add GSAP, Lenis, Three, or shadcn. Landing copy and SEO follow `.claude/rules/constitution.md` and `.claude/rules/landing-seo-geo.md`.
7+
> **In this repo:** Tailwind 4 (CSS-first config in `apps/sim/app/_styles/globals.css`); animation via `import { motion } from 'framer-motion'` (not `motion/react`); icons from `@sim/emcn/icons`; colors through the CSS-variable tokens in `.claude/rules/sim-styling.md` (no hardcoded `text-gray-*`/hex/`zinc` utilities, no paired `dark:` utilities). This note overrides any conflicting guidance or code sample anywhere in this file. Fonts are fixed (Season body, Inter); never introduce new families, and never use Martian Mono on landing (`apps/sim/app/(landing)/CLAUDE.md`). Font weight is only `font-normal`/`font-medium`/`font-semibold`. Elevation uses the `shadow-subtle|medium|overlay|card` tokens. Type size uses named tokens, never `text-[Npx]`. Every labeled field inside a `ChipModalBody` is a `ChipModalField`. Use `bunx`, never `npx`. Do not add GSAP, Lenis, Three, or shadcn. Landing copy and SEO follow `.claude/rules/constitution.md` and `.claude/rules/landing-seo-geo.md`.
88
99
# tasteskill: Anti-Slop Frontend Skill
1010

@@ -345,7 +345,7 @@ These are tools, not defaults. Use them when the design read calls for them. **N
345345
import { useRef, useEffect } from "react";
346346
import { gsap } from "gsap";
347347
import { ScrollTrigger } from "gsap/ScrollTrigger";
348-
import { useReducedMotion } from "motion/react";
348+
import { useReducedMotion } from "framer-motion";
349349

350350
gsap.registerPlugin(ScrollTrigger);
351351

@@ -407,7 +407,7 @@ Critical points: `start: "top top"`, `pin: true`, every card except the last is
407407
import { useRef, useEffect } from "react";
408408
import { gsap } from "gsap";
409409
import { ScrollTrigger } from "gsap/ScrollTrigger";
410-
import { useReducedMotion } from "motion/react";
410+
import { useReducedMotion } from "framer-motion";
411411

412412
gsap.registerPlugin(ScrollTrigger);
413413

@@ -454,7 +454,7 @@ For simple "items appear as they enter viewport" (no pinning), prefer Motion's `
454454

455455
```tsx
456456
"use client";
457-
import { motion, useReducedMotion } from "motion/react";
457+
import { motion, useReducedMotion } from "framer-motion";
458458

459459
export function RevealStagger({ items }: { items: string[] }) {
460460
const reduce = useReducedMotion();

‎.agents/skills/make-interfaces-feel-better/animations.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ When icons appear or disappear contextually (on hover, on state change), animate
191191
### Motion Example
192192

193193
```tsx
194-
import { AnimatePresence, motion } from "motion/react";
194+
import { AnimatePresence, motion } from "framer-motion";
195195

196196
function IconButton({ isActive, icon: Icon }) {
197197
return (
@@ -261,7 +261,7 @@ The non-absolute icon (InactiveIcon) defines the layout size. The absolute icon
261261
| **Enter animation** | Yes | Yes |
262262
| **Exit animation** | Yes (via `AnimatePresence`) | Yes (cross-fade — icon never unmounts) |
263263
| **Spring physics** | Yes | No — use `cubic-bezier(0.2, 0, 0, 1)` as approximation |
264-
| **When to use** | Project already uses `motion/react` | No motion dependency, or keeping bundle small |
264+
| **When to use** | Project already uses `framer-motion` (or `motion/react`) | No motion dependency, or keeping bundle small |
265265

266266
**Rule:** Check the project's `package.json` for `motion` or `framer-motion`. If present, use the Motion approach. If not, use the CSS cross-fade pattern — don't add a dependency just for icon transitions.
267267

‎.agents/skills/memory-load-check/SKILL.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ For those, require all three:
7474

7575
Skip the pattern when the source already bounds the payload:
7676
- pure API/structured-data connectors (Jira, Linear, Sentry, Slack, Zendesk, Gmail, ...) — paginated JSON/text; apply normal pagination + concurrency bounds instead of a per-file byte cap
77-
- native-document connectors capped by the platform (Evernote ~25 MB/note, ...) — a 100 MB cap can never fire there
77+
- native-document connectors whose platform caps each document — a 100 MB cap can never fire there
7878

7979
Some connectors also budget the response body (google-docs `MAX_DOCS_RESPONSE_BYTES`, google-sheets `MAX_CONTENT_BYTES`, a remaining-bytes budget in notion); Confluence attachments use the full file pattern. Follow the connector's existing approach rather than adding a cap to every `response.json()`.
8080

0 commit comments

Comments
 (0)