You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 0d5c74a
Browse filesBrowse the repository at this point in the historyBrowse files
docs(agents): fix contradictions and stale facts in platform skills
tool-registry-boundary told tests to re-mock a global (check:test-patterns
fails that); db-migrate listed a nonexistent annotate rule and omitted the
pending-drop-tables contract; permission-group skills cited a removed
descriptions record, a nonexistent key-order test, and a single
principal-wide capability where there are two; v2-api-conventions cited a
removed helper; memory-load-check called a pattern the connectors use
cargo-culting. Gates now name check:api-validation:strict / check:audits,
ship runs CI's schema/migration sync step, test-audit points at CLAUDE.md
instead of copying it, and incident narration became current-state rules.
Copy file name to clipboardExpand all lines: .agents/skills/db-migrate/SKILL.md
+4-3Lines changed: 4 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -34,7 +34,7 @@ Never put expand and contract in the same PR. If this PR both removes the code t
34
34
| Change a column type | add a new column of the new type; dual-write | backfill, swap reads, drop old |
35
35
| Add FK / CHECK |`ADD CONSTRAINT ... NOT VALID`|`VALIDATE CONSTRAINT` separately |
36
36
| Index an existing table |`COMMIT;` breakpoint → `SET lock_timeout = 0` → `CREATE INDEX CONCURRENTLY IF NOT EXISTS` (see `packages/db/scripts/migrate.ts`) | — |
37
-
| Drop an index |`COMMIT;` breakpoint → `DROP INDEX CONCURRENTLY` — plain `DROP INDEX` takes ACCESS EXCLUSIVE on the table | — |
37
+
| Drop an index |`COMMIT;` breakpoint → `DROP INDEX CONCURRENTLY IF EXISTS` — plain `DROP INDEX` takes ACCESS EXCLUSIVE on the table | — |
A `CREATE INDEX`, `ADD COLUMN`, or `ADD CONSTRAINT` against a table **created in the same migration** is always safe (no rows, no live traffic) — the lint already suppresses those.
Format: `contract-pending(<precondition>): <what to drop> — <why it's safe once the precondition holds>`. The precondition names the PR/release that removes the last reader and **must be fully deployed** before the contract ships.
54
54
55
55
-**The TODO list is a grep** — always accurate, never drifts: `grep -rn "contract-pending" packages/db apps/sim`. Run it when starting migration work to see what is owed.
56
+
- While a drop is pending, tag each doomed column `@deprecated` and make every read of that table name its columns: no argless `select().from(t)`, `findFirst()` without `columns`, argless `.returning()`, or bare `getTableColumns(t)` — use `omit(getTableColumns(t), [...])`. `check:pending-drop-tables` enforces this.
56
57
- For anything with a real owner or schedule, also open a tracking issue and put its number in the marker.
57
58
-**Close the loop in the contract PR:** the contract migration's `-- migration-safe:` annotation references the expand, and you **delete the `contract-pending` marker** in the same PR:
58
59
```sql
@@ -74,8 +75,8 @@ The lint flags risky *shapes*; it cannot know whether a given drop is *safe righ
74
75
1. Edit `packages/db/schema.ts`, then `cd packages/db && bunx drizzle-kit generate` to produce the SQL. If this is an expand that defers a drop, leave a `contract-pending` marker on the legacy column (see "Tracking the contract"). If this is the contract, delete the marker it resolves.
75
76
2. Hand-edit the generated SQL where the playbook requires it: `CONCURRENTLY` + `COMMIT;` breakpoint for indexes on existing tables, `NOT VALID` for constraints, batching for backfills.
76
77
3. Run `bun run check:migrations` (base defaults to `origin/staging`).
77
-
-**Hard errors** (`add-not-null-no-default`, `rename`, `index-not-concurrent`, `constraint-not-valid`, …): rewrite into expand/contract. Do **not** try to annotate them away — the lint won't accept it.
78
-
-**Annotate tier** (`drop-table`, `drop-column`, `drop-default`, `set-not-null`, `alter-type`, `drop-index`): only after you've confirmed steps 1–3 above, add a comment on the line directly above the statement:
78
+
-**Hard errors** (`add-not-null-no-default`, `rename`, `index-not-concurrent`, `concurrent-index-not-idempotent`, `concurrent-index-no-commit`, `drop-index-not-concurrent`, `concurrent-drop-index-not-idempotent`, `concurrent-drop-index-no-commit`, `constraint-not-valid`, …): rewrite into expand/contract. Do **not** try to annotate them away — the lint won't accept it.
79
+
-**Annotate tier** (`drop-table`, `drop-column`, `drop-constraint`, `drop-default`, `set-not-null`, `alter-type`): only after you've confirmed steps 1–3 above, add a comment on the line directly above the statement:
79
80
```sql
80
81
-- migration-safe: `secret` read removed in v0.6.1 (#1234), shipped two deploys ago
Copy file name to clipboardExpand all lines: .agents/skills/memory-load-check/SKILL.md
+1-3Lines changed: 1 addition & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -72,9 +72,7 @@ For those, require all three:
72
72
- skip oversize at listing (`stubOrSkipBySize` with the reported size) and again at fetch time (overflow -> `markSkipped`), since the listing size can be missing or under-reported
73
73
- never drop/truncate silently — oversized files become content-less failed rows carrying `skippedReason`, so they stay visible in the KB UI instead of vanishing from the index
74
74
75
-
Skip the pattern when the source already bounds the payload:
76
-
- pure API/structured-data connectors (Jira, Linear, Notion, Confluence, 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 (Google Docs ~50 MB, Google Sheets via `MAX_ROWS`, Evernote ~25 MB/note) — a 100 MB cap can never fire, and wrapping a `response.json()`/Thrift parse in `readBodyWithLimit` is cargo-culting
75
+
Skip the *per-file `CONNECTOR_MAX_FILE_BYTES` + skipped-row* pattern when the source bounds the item count (paginated JSON: Jira, Linear, Sentry, Slack, Zendesk, Gmail, ...). Every response body is still read through `readBodyWithLimit` with a connector-specific budget (`MAX_DOCS_RESPONSE_BYTES` in google-docs, `MAX_CONTENT_BYTES` in google-sheets, a remaining-bytes budget in notion). Confluence attachments use the full file pattern.
78
76
79
77
Litmus test: "Can a user make this one fetch arbitrarily large, with nothing upstream stopping it?" Yes -> use the pattern. No (platform hard-cap, or already paginated) -> a per-file byte cap adds noise, not safety. Borderline: a user-configured/self-hosted endpoint with no platform cap (e.g. Obsidian) — bound it only if the content is genuinely unbounded.
Copy file name to clipboardExpand all lines: .agents/skills/migrate-application-operation/SKILL.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -166,7 +166,7 @@ Do not create internal-, public-, or Copilot-specific versions of the same seman
166
166
167
167
Choose principal kinds from actual behavior. Do not accept every principal merely because the use case is shared. Workspace API keys have a write ceiling and cannot satisfy admin operations. The operation definition must fail fast when its role, workspace-key policy, and principal kinds disagree.
168
168
169
-
`capability` is required — name the permission-group capability that governs the operation, or `'none'` with a `// permission-group-exempt: <reason>` comment directly above it. `defineWorkspaceOperation` throws at definition time when it is absent. See `add-permission-group-item`.
169
+
`capability` is required: a static, operation-declarable capability (not parameterized, not principal-wide), or `'none'` with a `// permission-group-exempt: <reason>` comment directly above it. If `principalKinds` includes `oauth_access_token`, `oauthScope` (`api:read` | `api:write` | `search:read`) is required. `defineWorkspaceOperation` throws at definition time on any violation. See `add-permission-group-item`.
170
170
171
171
Route declarations, tool adapters, and use cases must use the same literal operation. Runtime operation selection is permitted only from a trusted, code-defined registry. Never accept an operation ID or permission tag from an HTTP body, model argument, or other untrusted input.
172
172
@@ -317,7 +317,7 @@ Stop and report a missing design rather than weakening identity, authorization,
317
317
318
318
## Test each risk at one boundary
319
319
320
-
Run the `test-audit` authoring gate before writing any test. Own each risk at exactly one boundary:
320
+
Run the `test-audit` authoring gate before writing any test. Prefer one E2E/integration run over the real boundary; where a use-case unit test is justified, list its failure modes before writing code (CLAUDE.md → Testing). Own each risk at exactly one boundary:
321
321
322
322
- 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.
323
323
- One `*.integration.ts` owns repository semantics: canonical active lookup, workspace-predicated writes, archived resources, authoritative affected rows, and database error propagation.
@@ -335,7 +335,7 @@ Run at minimum:
335
335
bun run --cwd apps/sim test<focused test files>
336
336
bunx biome check <changed source and test files>
337
337
bunx turbo run type-check --filter=@sim/app --filter=@sim/auth
Copy file name to clipboardExpand all lines: .agents/skills/ship/SKILL.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -45,6 +45,7 @@ When the user runs `/ship`:
45
45
- Then run root `bun run test` from the repo root. It chains `test:scripts` (the `scripts/*.test.ts` suite CI runs) before every workspace suite; workspace-scoped runs skip it, which is how a `scripts/check-*.test.ts` failure has reached CI. A failing test aborts ship.
46
46
5. **Run migration safety** — only if the diff touches `packages/db/migrations/**` or `packages/db/schema.ts`:
47
47
- Run `/db-migrate` to review the migration for zero-downtime safety (expand/contract phasing, backward-compatibility with the deployed app version).
48
+
- `cd packages/db && bunx drizzle-kit generate` must leave `git status --porcelain packages/db/migrations` empty (CI's schema/migration sync step).
48
49
- `bun run check:migrations origin/staging` must pass (staging is the PR base). Do not silence a flagged statement with a `-- migration-safe:` annotation unless `/db-migrate` confirmed the old code no longer depends on it; otherwise split the destructive change into a later deploy.
49
50
6. **Run pre-ship checks** from the repo root before staging. This has two phases: first **regenerate** every committed artifact so generated files never drift into a CI failure (this is what catches things like `agent-stream-docs` going stale after a `models.ts` edit), then run the **full audit suite** CI's `Lint and Test` job enforces. Both phases parallelize — but only across commands that write **disjoint** outputs — and a bare `wait` swallows child exit codes, so both phases below explicitly collect each job's status and abort ship if any failed.
0 commit comments