Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 4 additions & 4 deletions .agents/skills/add-block/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -902,16 +902,16 @@ Every block declares a one-line prose summary that replaces its card's field row

```
Slack ← header (already names the block)
Posts ⟨Ship it 🚀⟩ to ⟨#eng⟩ ← the sentence; ⟨…⟩ are live value chips
Post ⟨Ship it 🚀⟩ to ⟨#eng⟩ ← the sentence; ⟨…⟩ are live value chips
```

Write one `byOperation` entry per operation dropdown option (or a single `default`
when the block has no operation dropdown).

**The full authoring contract — voice, structure, and the two mistakes that break
**The full authoring contract — voice, structure, and the four mistakes that break
Comment thread
waleedlatif1 marked this conversation as resolved.
cards silently — is `apps/sim/blocks/AGENTS.md` → "Canvas sentences". Read it
before writing any.** The two failures worth repeating here, because both are
invisible at runtime:
before writing any.** Two of those four are worth repeating here, because both
are invisible at runtime:

1. A clause naming only one member of a `canonicalParamId` pair drops the sentence
for every advanced-mode user. List all members:
Expand Down
6 changes: 3 additions & 3 deletions .agents/skills/add-column-type/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,13 @@ Registering the *type* is compiler-enforced. Registering its *metadata* is not,
- [ ] Icon added, centered on the family's optical center, exported alphabetically
- [ ] `migrateCellsTo` / `migrateCellsFrom` added if the stored bytes change
- [ ] New metadata keys added to `TYPE_SPECIFIC_COLUMN_KEYS` + `FOREIGN_METADATA_VERB`
- [ ] Unit tests for `coerce` / `isCompatibleWith` round-trips, verified to fail without the code
- [ ] Unit tests for `coerce` / `isCompatibleWith` round-trips only if they pass the `test-audit` authoring gate, verified to fail without the code
- [ ] Docs row added to `apps/docs/content/docs/tables/index.mdx`

## Final Validation (Required)

1. **`cd apps/sim && bun run type-check`** — must be clean. If any file *outside* `column-types/` errors, that file has a hardcoded type list; fix it to read the registry.
2. **Grep for leaks** — `grep -rnE "(===|!==) '{id}'|case '{id}':" apps/sim --include='*.ts' --include='*.tsx' | grep -v column-types/`. (All three forms: a plain `!==` and a `case` are how half of `currency`'s real branches are written.) Hits are expected; judge each. A hit is fine when it mounts a specific React component or encodes a genuinely one-off behavior (`json`'s mono textarea, `date`'s timezone-aware parsing). A hit is a **leak** when it restates something the registry could answer — an icon, a label, a colour, an operator set, a cast, a coercion. Leaks get a registry field, not a new branch.
3. **Run the suite** — `bunx vitest run lib/table 'app/workspace/[workspaceId]/tables' lib/api app/api/table app/api/v1 lib/copilot/tools/server/table`. Existing tests must pass **unchanged**; needing to edit one means you changed behavior for the other types.
4. **`bun run lint:check`, `bun run check:api-validation`, `bun run check:client-boundary`** from the repo root.
3. **Run the suite** — `bun run --cwd apps/sim test lib/table 'app/workspace/[workspaceId]/tables' lib/api app/api/table app/api/v1 lib/copilot/tools/server/table`. Existing tests must pass **unchanged**; needing to edit one means you changed behavior for the other types.
4. **`bun run lint`, `bun run check:api-validation`, `bun run check:client-boundary`** from the repo root.
5. **Exercise it in the running app** on a table with one column of every type: create, edit inline / in the expanded popover / in the row modal, paste from a spreadsheet, filter, sort, convert to and from other types, export CSV, undo a column delete.
4 changes: 2 additions & 2 deletions .agents/skills/add-feature-flag/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ Critically, **none of this is expressible in code** — gating (especially `admi

4. **(Prod) configure in AppConfig.** The infra `feature-flags` profile schema is permissive, so a new flag needs **no infra change**. Operators add the flag to the hosted `feature-flags` document using `enabled` for global rollout or only the selected `workspaceIds`/`orgIds`/`userIds`/`adminEnabled` clauses for scoped rollout, then start a `sim-<env>-fast` deployment (see the AppConfig runbook in the infra README — same flow as `access-control`). The fallback secret only applies when AppConfig is disabled.

5. **Test.** Add a case to `apps/sim/lib/core/config/feature-flags.test.ts` that matches the chosen granularity. For a global flag, exercise `isFeatureEnabled('<flag-name>')` with an AppConfig `enabled` rule and toggle the fallback secret for the off-AppConfig path. For scoped rollout, cover only the selected clauses and mock `isPlatformAdmin` when testing `adminEnabled`.
5. **Test only new evaluation logic.** A flag that reuses the existing clauses is already covered by `apps/sim/lib/core/config/feature-flags.test.ts`; add no per-flag case. When you change how flags evaluate (a new clause kind, a new fallback path), add a case there that passes the `test-audit` authoring gate.

6. **Clean up after rollout.** When the feature ships to everyone, delete the flag's entry from `FEATURE_FLAGS`, the `<FLAG_SECRET>` env entry, the AppConfig document, the call sites, and the test. Leaving dead flags around is the main failure mode of flag systems.
6. **Clean up after rollout.** When the feature ships to everyone, delete the flag's entry from `FEATURE_FLAGS`, the `<FLAG_SECRET>` env entry, the AppConfig document, and the call sites. Leaving dead flags around is the main failure mode of flag systems.

## Notes

Expand Down
10 changes: 3 additions & 7 deletions .agents/skills/add-managed-cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ Do not special-case a CLI in those layers unless the registry contract cannot ex

## 6. Test the Addition

Extend tests when the new entry introduces behavior not already covered:
Extend tests only when the new entry introduces behavior not already covered and the test passes the `test-audit` authoring gate:

- For every upgrade, add a regression proving the old ID and recipe remain resolvable but non-selectable, while the replacement ID is selectable.
- Add important executable aliases to the table-driven search assertion.
Expand All @@ -110,17 +110,13 @@ Never commit downloaded artifacts or credentials.

## Required Validation

From `apps/sim`:

```bash
bunx vitest run \
bun run --cwd apps/sim test \
Comment thread
waleedlatif1 marked this conversation as resolved.
lib/execution/remote-sandbox/cli-tools.test.ts \
lib/execution/remote-sandbox/cli-tools-boundary.test.ts \
lib/execution/remote-sandbox/sandbox-spec.test.ts \
lib/execution/remote-sandbox/resolve.test.ts \
lib/api/contracts/sandboxes.test.ts \
'app/workspace/[workspaceId]/settings/components/sandboxes/utils.test.ts' \
'app/workspace/[workspaceId]/settings/components/sandboxes/components/sandbox-editor.test.tsx'
'app/workspace/[workspaceId]/settings/components/sandboxes/utils.test.ts'
```

From the repository root:
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/add-permission-group-item/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ bun run check:permission-group-enforcement
bun run check:application-graph
bun run check:capability-subject
cd apps/sim && bun run type-check
cd apps/sim && bunx vitest run lib/permission-groups
bun run --cwd apps/sim test lib/permission-groups
```

Also `bun run check:api-validation` if you touched a contract or the group routes. `bun run check:audits` runs all of these; it derives its list from the `check:*` scripts in `package.json`, so a new audit is opted *out* deliberately rather than opted in.
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/add-selector/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ list, manifest/registry exhaustiveness plus an existing provider primitive test
Run the smallest relevant set, then:

```bash
bunx vitest run <focused selector tests>
bun run --cwd apps/sim test <focused selector tests>
bun run --cwd apps/sim type-check
bun run check:fork-dependent-coverage
bun run check:client-boundary
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/add-tools/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ Hard rules:
provider responses, filenames, URLs, and errors remain unchanged when Sim did not resolve a
secret into them.

Add focused tests covering named projection, ordinary identical text without provenance, nested and
Run the `test-audit` authoring gate, then cover these risks at the boundary that owns them: named projection, ordinary identical text without provenance, nested and
serialized shape handling, unchanged ordinary external inputs, malformed/incomplete private metadata
failing closed, headerless legacy requests, and absence of private metadata in the public tool result.
For durable sinks, also cover legacy `NULL` markers, exact-empty new writes, tracked secret writes,
Expand Down
10 changes: 4 additions & 6 deletions .agents/skills/babysit/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,13 @@ conditions freshly after every push.
```

6. **Before pushing, re-run the full sync check from `/ship` step 2** — not just the log command,
the whole check-and-recover flow (stash WIP if needed, rebase, verify the rebase didn't just
the whole check-and-recover flow (stash WIP pinned by SHA as `/ship` step 2 shows, rebase, verify the rebase didn't just
cleanly replay stray commits, cherry-pick rebuild if it did or if it conflicted). A babysit
loop spanning a long session is exactly the scenario where a branch can drift, and pushing
review fixes on top of undetected drift is how an oversized PR happens even after the branch
was fixed once. Then run the repo's pre-ship checks the same way `/ship` does before
committing — not just lint/typecheck/boundary-validation, but also the conditional `/cleanup`
(if this round's fix touched UI code) and `/db-migrate` (if it touched schema/migrations)
gates from `/ship` steps 4 and 5. A review-fix round is still a code change and can trip
either gate just as easily as the original commit did.
was fixed once. Then run `/ship` steps 4–6 on this round's diff — the cleanup and test gates,
migration safety, and the regenerate + audit phases. A review-fix round is still a code change
and can trip any of them just as easily as the original commit did.

7. **Commit and push** the round's fixes as one commit — `--force-with-lease` whenever step 6's
sync check rewrote history, which includes a plain `git rebase origin/staging` that completed
Expand Down
10 changes: 5 additions & 5 deletions .agents/skills/cleanup/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ User arguments: $ARGUMENTS

Parse `$ARGUMENTS` into `scope` and `fix`: extract the `fix=true|false` token wherever it appears in the string and strip it from `scope`; defaults are the current changes and `fix=true`. `fix` is consumed by Step 3 only — the passes below always run `fix=false`.

Spawn all nine passes concurrently as subagents in a **single message** (multiple Agent tool calls). Each runs its skill on the parsed `scope` with `fix=false` — analysis and proposals ONLY, no edits. Instruct each agent to return its findings as a structured list: for every proposed change, the file path, line range, a one-line description of the change, and the exact before/after so the orchestrator can apply it without re-deriving.
Spawn up to nine passes concurrently as subagents in a **single message** (multiple Agent tool calls); pass 9 runs only when its condition holds. Each runs its skill on the parsed `scope` with `fix=false` — analysis and proposals ONLY, no edits. Instruct each agent to return its findings as a structured list: for every proposed change, the file path, line range, a one-line description of the change, and the exact before/after so the orchestrator can apply it without re-deriving.

Run these nine in parallel on the parsed `scope`:
Run these in parallel on the parsed `scope`:

1. `/you-might-not-need-an-effect <scope> fix=false`
2. `/you-might-not-need-a-memo <scope> fix=false`
Expand All @@ -28,7 +28,7 @@ Run these nine in parallel on the parsed `scope`:
6. `/emcn-design-review <scope> fix=false`
7. `/you-might-not-need-url-state <scope> fix=false`
8. `/you-might-not-need-a-comment <scope> fix=false`
9. `/test-audit audit <scope>` — read-only; only when the scope adds or changes test files (`*.test.ts(x)`, `*.integration.ts`, `e2e/**`). It applies the authoring gate to every new or changed test and proposes deleting the ones that fail it.
9. `/test-audit audit <test paths>` — read-only; only when the scope adds or changes test files (`*.test.ts(x)`, `*.integration.ts`, `**/e2e/**`, `apps/sim/scripts/test-*-e2e.ts`). First resolve a free-form scope to the concrete list of added or changed test paths (`git diff --name-only` against the scope's base) and pass those paths. It applies the authoring gate to every new or changed test and proposes deleting the ones that fail it.

## Step 2 — Converge

Expand All @@ -52,12 +52,12 @@ Comments apply after every structural pass, on purpose: that pass operates on wh
2. If the `old_string` still matches verbatim, apply it — a content-anchored edit is safe even if its line moved.
3. If it no longer matches (an earlier pass altered that region), do **not** force the stale patch. Re-derive the change from the current code by re-applying that pass's rule to the construct, or drop it if a prior pass already made it moot. Never apply a proposal against text it wasn't computed from.

After all edits, run `bun run lint:check` (it runs `turbo run lint:check` across the repo — there is no per-file target, so run the full check).
After all edits, run `bun run lint` from the repo root (it autofixes formatting across the repo; there is no per-file target).

## Step 4 — Summary

Output a summary across all passes that ran: what each found, what was applied vs. skipped-as-redundant, and any proposals that need a human decision.

## Boundary findings

Never resolve a boundary finding by adding a `// boundary-raw-fetch` / `// double-cast-allowed` annotation — fix the call (adopt the contract + `requestJson`, or narrow the type). Annotations are only for the documented exceptions in CLAUDE.md → Boundary annotations.
Never resolve a boundary finding by adding a `// boundary-raw-fetch` / `// double-cast-allowed` annotation — fix the call (adopt the contract + `requestJson`, or narrow the type). Annotations are only for the documented exceptions in `.claude/rules/sim-api-contracts.md` → Boundary annotations.
22 changes: 10 additions & 12 deletions .agents/skills/migrate-application-operation/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Preserve behavior unless the task explicitly changes it. Stop and report a decis

## Freeze observable behavior before editing

Treat the legacy route or tool as an ordered program, not merely a bag of business logic. Before moving code, write a compact baseline for every in-scope entry point and add focused characterization tests for behavior not already pinned down.
Treat the legacy route or tool as an ordered program, not merely a bag of business logic. Before moving code, write a compact baseline for every in-scope entry point. Pin behavior no existing test covers with a characterization test only where it passes the `test-audit` gate; otherwise record it in the baseline and verify it by hand after the move.

Capture all of these when they apply:

Expand Down Expand Up @@ -315,26 +315,24 @@ Do not force these through an ordinary JSON migration:

Stop and report a missing design rather than weakening identity, authorization, limits, or errors.

## Test the complete matrix
## Test each risk at one boundary

Add focused tests for every migrated surface and principal kind allowed by the operation:
Run the `test-audit` authoring gate before writing any test. Own each risk at exactly one boundary:

- Application use-case tests own authorization, principal-kind rejection before canonical loading, workspace assertion mismatch, delegated scope, not found, conflict, no-op, audit derived from authoritative results, and infrastructure failures (storage, rate-limit, provider, or database errors raised by delegated services) propagating as 5xx-mapped errors — never converted to not-found or forbidden.
- One `*.integration.ts` owns repository semantics: canonical active lookup, workspace-predicated writes, archived resources, authoritative affected rows, and database error propagation.
- Add a surface test only for a surface-specific risk (for example, a v2 envelope or rate header, a Copilot forged-scope rejection, or a legacy redirect/cookie behavior the characterization baseline pinned). Do not restate the operation registry or the shared builders' auth-before-parse behavior per surface.

Risks that usually earn a test when the change introduces them:

- Application: allowed and disallowed roles, principal-kind rejection before canonical loading, workspace assertion mismatch, delegated scope, not found, conflict, no-op, and infrastructure propagation.
- Operation registry: role/workspace-key/principal-kind/delegated-service consistency and fail-fast rejection of invalid definitions.
- Repository: canonical active lookup, workspace-predicated writes, archived resources, authoritative affected rows, and database error propagation.
- Internal API: authentication before parsing, exact contract, typed errors, and surface analytics only after success.
- Public API: personal and workspace keys, rate behavior, concealment, exact external envelope, and rate headers.
- Copilot or tools: trusted context, exact registered operation membership, rejected forged scope, aliases and resume paths, permission re-check, safe errors, and unchanged tool result shapes.
- Side effects: audit derives from authoritative results; shared notifications follow audit; neither occurs for rejection or no-op.
- Compatibility characterization: legacy normalization, exact response/redirect/cookie behavior, concealment, error subclass precedence, and branch-specific output.
- Failure sequencing: inject a failure after each independently committing step and assert persisted state plus audit, analytics, and notification effects.
- Concurrency: overlap stateful browser or provider flows and prove each callback consumes only its own state and return destination.
- Rendering boundaries: exercise hostile values for every newly connected input that reaches HTML, inline JavaScript, URLs, logs, or provider requests.

Run at minimum:

```bash
bunx vitest run <focused test files>
bun run --cwd apps/sim test <focused test files>
bunx biome check <changed source and test files>
bunx turbo run type-check --filter=@sim/app --filter=@sim/auth
bun run check:api-validation:strict
Expand Down
4 changes: 2 additions & 2 deletions .agents/skills/react-query-best-practices/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Read these before analyzing:
## Rules to enforce

### Query keys and hooks
Enforce CLAUDE.md "React Query" and `.claude/rules/sim-queries.md` (key factory with `all` + plural prefixes, `signal` forwarding, named `staleTime` constants reused by prefetches, `keepPreviousData` only on variable keys, `requestJson` boundary). Additionally:
Enforce `.claude/rules/sim-queries.md` (key factory with `all` + plural prefixes, `signal` forwarding, named `staleTime` constants reused by prefetches, `keepPreviousData` only on variable keys, `requestJson` boundary). Additionally:
- Key factories live next to their hooks — except a factory, standalone fetcher/mapper, or `staleTime` constant that a server module (a `prefetch.ts`, route, block, trigger) imports, which must live in a non-`'use client'` module under `hooks/queries/utils/` per `.claude/rules/sim-queries.md` (a `'use client'` export called from the server crashes SSR)
- Use `enabled` to prevent queries from running without required params
- Warm data for hover/focus intent with `queryClient.prefetchQuery` and shared `queryOptions`; never temporarily enable a mounted hidden observer, which can remain active after focus restoration and refetch data for closed UI
Expand All @@ -37,7 +37,7 @@ Enforce CLAUDE.md "React Query" and `.claude/rules/sim-queries.md` (key factory
- Server prefetches must call the authorized use case, apply the route presenter/response schema, and reuse the client's exact key, mapper, and stale time. Keep all fallible auth/read/parse work inside `queryFn` so an optional warm cannot fail the page, and never bypass a route that redacts fields.

### Mutations
Enforce CLAUDE.md "Mutation Hooks" (targeted invalidation, `onMutate`/`onError` rollback, mutation objects out of `useCallback` deps). Additionally:
Enforce `.claude/rules/sim-queries.md` "Mutation Hook" (targeted invalidation, `onMutate`/`onError` rollback, mutation objects out of `useCallback` deps). Additionally:
- Plain mutations invalidate in `onSuccess`; optimistic mutations reconcile in `onSettled` (fires on success and error) with rollback in `onError` — see `.claude/rules/sim-queries.md` "Mutation Hook" / "Optimistic Updates"

### Server state ownership
Expand Down
Loading
Loading