| Dimension | Shared | Only in A | Only in B | Overlap |
|---|---|---|---|---|
| Sections | 0 | 6 | 38 | 0% |
| Commands | 0 | 2 | 25 | 0% |
| Section tags | 1 | 2 | 11 | 7% |
What each file covers
Sections
0 shared · 6 only in A · 38 only in B- − Database Package
- − Schema
- − Engine Versions
- − Creating Migrations
- − Index Migration Rules
- − Read Replicas
- + AGENTS.md
- + Build and Development Commands
- + pnpm run docker:full # Same + observability stack (Prometheus, Grafana, OTEL) and chaos tooling
- + Build packages (required before running)
- + Verifying Changes
- + Apps and internal packages — use typecheck
- + Public packages — use build
- + Testing
- + Testcontainers for Redis/PostgreSQL
- + Code Style
- + Formatting and linting
- + Imports
- + Changesets and Server Changes
- + Dependency Pinning
- + Architecture Overview
- + Request Flow
- + Apps
- + Public Packages
- + Internal Packages
- + v3 (engine V1) removed
- + Documentation
- + Reference Projects
- + Docker Image Guidelines
- + Writing Trigger.dev Tasks
- + SDK Documentation Rules
- + Testing with the hello-world Reference Project
- + Local Task Testing Workflow
- + Step 1: Start Webapp in Background
- + Run from repo root with run_in_background: true
- + Step 2: Start Trigger Dev in Background
- + in your triggerdotdev/references clone
- + Wait for "Local worker ready [node]"
- + Step 3: Trigger and Monitor Tasks via MCP
- + Skill mappings — when working in these areas, load the linked skill file into context.
- + agentcrumbs
- + Namespaces
- + For PR reviewers
- + CLI
Commands
0 shared · 2 only in A · 25 only in B- − pnpm run db:migrate:dev:create --name "descriptive_name"
- − pnpm run db:migrate:deploy && pnpm run generate
- + pnpm run docker
- + pnpm run db:migrate
- + pnpm run db:seed
- + pnpm run build --filter webapp && pnpm run build --filter trigger.dev && pnpm run build --filter @trigger.dev/sdk
- + pnpm run dev --filter webapp
- + pnpm run dev --filter trigger.dev --filter "@trigger.dev/*"
- + pnpm run typecheck --filter webapp
- + pnpm run typecheck --filter @internal/run-engine
- + pnpm run build --filter @trigger.dev/sdk
- + pnpm run build --filter @trigger.dev/core
- + pnpm run test --filter webapp
- + pnpm run test ./src/engine/tests/ttl.test.ts --run
- + pnpm run build --filter @internal/run-engine
- + pnpm run format
- + pnpm run lint:fix
- + pnpm run lint
- + pnpm run changeset:add
- + pnpm exec agentcrumbs collect
- + pnpm exec agentcrumbs tail --app trigger
- + pnpm exec agentcrumbs clear --app trigger
- + pnpm run
- + pnpm add
- + pnpm i
- + pnpm run build --filter trigger.dev
- + pnpm exec agentcrumbs query --app trigger
Section tags
1 shared · 2 only in A · 11 only in B- − types
- − database
- + setup
- + build
- + test
- + lint-format
- + code-style
- + architecture
- + testing-strategy
- + git-pr
- + dependencies
- + agent-behaviour
- + docs
- do-not
Line diff
triggerdotdev/trigger.dev · internal-packages/database/CLAUDE.md
@@ −1 @@
1# Database Package
2
3Prisma 6.14.0 client and schema for PostgreSQL (`@trigger.dev/database`).
4
5## Schema
6
7Located at `prisma/schema.prisma`. Key models include TaskRun, BackgroundWorker, BackgroundWorkerTask, WorkerDeployment, RuntimeEnvironment, and Project.
8
9### Engine Versions
10
11```prisma
12enum RunEngineVersion {
13 V1 // Retired v3 engine - no longer executes; kept for historical rows and rejection
14 V2 // Current (run-engine + redis-worker)
15}
16```
17
18New code should always target V2.
19
20## Creating Migrations
21
221. Edit `prisma/schema.prisma`
232. Generate migration:
24 ```bash
25 cd internal-packages/database
26 pnpm run db:migrate:dev:create --name "descriptive_name"
27 ```
283. **Clean up generated migration** - remove extraneous lines for:
29 - `_BackgroundWorkerToBackgroundWorkerFile`
30 - `_BackgroundWorkerToTaskQueue`
31 - `_TaskRunToTaskRunTag`
32 - `_WaitpointRunConnections`
33 - `_completedWaitpoints`
34 - `SecretStore_key_idx`
35 - Various `TaskRun` indexes (unless you added them)
364. Apply migration:
37 ```bash
38 pnpm run db:migrate:deploy && pnpm run generate
39 ```
40
41## Index Migration Rules
42
43When adding indexes to **existing tables**:
44
45- Use `CREATE INDEX CONCURRENTLY IF NOT EXISTS` to avoid table locks in production
46- CONCURRENTLY indexes **must be in their own separate migration file** - they cannot be combined with other schema changes (PostgreSQL requirement)
47- Only add one index per migration file
48- Pre-apply the index manually in production before deploying the migration (Prisma will skip creation if the index already exists)
49
50Indexes on **newly created tables** (in the same migration as `CREATE TABLE`) do not need CONCURRENTLY and can be in the same migration file.
51
52When adding an index on a **new column on an existing table**, use two migrations:
531. First migration: `ALTER TABLE ... ADD COLUMN IF NOT EXISTS ...` (the column)
542. Second migration: `CREATE INDEX CONCURRENTLY IF NOT EXISTS ...` (the index, in its own file)
55
56See `README.md` in this directory and `ai/references/migrations.md` for the full index workflow.
57
58## Read Replicas
59
60Use `$replica` from `~/db.server` for read-heavy queries in the webapp.
61
triggerdotdev/trigger.dev · AGENTS.md
@@ +1 @@
1# AGENTS.md
2
3This file provides guidance to Claude Code when working with this repository. Subdirectory CLAUDE.md files provide deeper context when you navigate into specific areas.
4
5## Build and Development Commands
6
7This is a pnpm 10.33.2 monorepo using Turborepo. Run commands from root with `pnpm run`.
8
9**Adding dependencies:** Edit `package.json` directly instead of using `pnpm add`, then run `pnpm i` from the repo root. See `.claude/rules/package-installation.md` for the full process.
10
11```bash
12pnpm run docker # Core dev services (Postgres, Redis, Electric, MinIO, ClickHouse, s2-lite)
13# pnpm run docker:full # Same + observability stack (Prometheus, Grafana, OTEL) and chaos tooling
14pnpm run db:migrate # Run database migrations
15pnpm run db:seed # Seed the database (required for reference projects)
16
17# Build packages (required before running)
18pnpm run build --filter webapp && pnpm run build --filter trigger.dev && pnpm run build --filter @trigger.dev/sdk
19
20pnpm run dev --filter webapp # Run webapp (http://localhost:3030)
21pnpm run dev --filter trigger.dev --filter "@trigger.dev/*" # Watch CLI and packages
22```
23
24### Verifying Changes
25
26The verification command depends on where the change lives:
27
28- **Apps and internal packages** (`apps/*`, `internal-packages/*`): Use `typecheck`. **Never use `build`** for these — building proves almost nothing about correctness.
29- **Public packages** (`packages/*`): Use `build`.
30
31```bash
32# Apps and internal packages — use typecheck
33pnpm run typecheck --filter webapp # ~1-2 minutes
34pnpm run typecheck --filter @internal/run-engine
35
36# Public packages — use build
37pnpm run build --filter @trigger.dev/sdk
38pnpm run build --filter @trigger.dev/core
39```
40
41Only run typecheck/build after major changes (new files, significant refactors, schema changes). For small edits, trust the types and let CI catch issues.
42
43## Testing
44
45We use vitest exclusively. **Never mock anything** - use testcontainers instead.
46
47```bash
48pnpm run test --filter webapp # All tests for a package
49cd internal-packages/run-engine
50pnpm run test ./src/engine/tests/ttl.test.ts --run # Single test file
51pnpm run build --filter @internal/run-engine # May need to build deps first
52```
53
54Test files go next to source files (e.g., `MyService.ts` -> `MyService.test.ts`).
55
56### Testcontainers for Redis/PostgreSQL
57
58```typescript
59import { redisTest, postgresTest, containerTest } from "@internal/testcontainers";
60
61redisTest("should use redis", async ({ redisOptions }) => {
62 /* ... */
63});
64postgresTest("should use postgres", async ({ prisma }) => {
65 /* ... */
66});
67containerTest("should use both", async ({ prisma, redisOptions }) => {
68 /* ... */
69});
70```
71
72## Code Style
73
74### Formatting and linting
75
76Format and lint are enforced by CI (`code-quality` check). Run before committing:
77
78```bash
79pnpm run format # oxfmt — auto-fixes formatting
80pnpm run lint:fix # oxlint — auto-fixes lint violations
81pnpm run lint # oxlint — check only (no fixes)
82```
83
84### Imports
85
86**Prefer static imports over dynamic imports.** Only use dynamic `import()` when:
87- Circular dependencies cannot be resolved otherwise
88- Code splitting is genuinely needed for performance
89- The module must be loaded conditionally at runtime
90
91Dynamic imports add unnecessary overhead in hot paths and make code harder to analyze. If you find yourself using `await import()`, ask if a regular `import` statement would work instead.
92
93## Changesets and Server Changes
94
95When modifying any public package (`packages/*` or `integrations/*`), add a changeset:
96
97```bash
98pnpm run changeset:add
99```
100
101- Default to **patch** for bug fixes and minor changes
102- Confirm with maintainers before selecting **minor** (new features)
103- **Never** select major without explicit approval
104
105When modifying only server components (`apps/webapp/`, `apps/supervisor/`, etc.) with no package changes, add a `.server-changes/` file instead. See `.server-changes/README.md` for format and documentation.
106
107**Write the description for users, not maintainers.** Both changesets and `.server-changes/` notes ship verbatim in user-visible release notes. Lead with what changed *for the user* - one plain sentence describing behavior, not implementation, and never naming internal tools or infra. The full writing guidance in `.server-changes/README.md` applies to changesets too.
108
109## Dependency Pinning
110
111Zod is pinned to a single version across the entire monorepo (currently `3.25.76`). When adding zod to a new or existing package, use the **exact same version** as the rest of the repo - never a different version or a range. Mismatched zod versions cause runtime type incompatibilities (e.g., schemas from one package can't be used as body validators in another).
112
113## Architecture Overview
114
115### Request Flow
116
117User API call -> Webapp routes -> Services -> RunEngine -> Redis Queue -> Supervisor -> Container execution -> Results back through RunEngine -> ClickHouse (analytics) + PostgreSQL (state)
118
119### Apps
120
121- **apps/webapp**: Remix 2.17.4 app - main API, dashboard, orchestration. Uses Express server.
122- **apps/supervisor**: Manages task execution containers (Docker/Kubernetes).
123
124### Public Packages
125
126- **packages/trigger-sdk** (`@trigger.dev/sdk`): Main SDK for writing tasks
127- **packages/cli-v3** (`trigger.dev`): CLI - also bundles code that goes into customer task images
128- **packages/core** (`@trigger.dev/core`): Shared types. **Import subpaths only** (never root).
129- **packages/build** (`@trigger.dev/build`): Build extensions and types
130- **packages/react-hooks**: React hooks for realtime and triggering
131- **packages/redis-worker** (`@trigger.dev/redis-worker`): Redis-based background job system
132
133### Internal Packages
134
135- **internal-packages/database**: Prisma 6.14.0 client and schema (PostgreSQL)
136- **internal-packages/clickhouse**: ClickHouse client, schema migrations, analytics queries
137- **internal-packages/run-engine**: "Run Engine 2.0" - core run lifecycle management
138- **internal-packages/redis**: Redis client creation utilities (ioredis)
139- **internal-packages/testcontainers**: Test helpers for Redis/PostgreSQL containers
140- **internal-packages/schedule-engine**: Durable cron scheduling
141
142### v3 (engine V1) removed
143
144v3 (engine V1: MarQS + Graphile worker) is end-of-life and its execution code has been removed. The `apps/webapp/app/v3/` directory name is historical - everything there now serves V2 (Run Engine 2.0, `@internal/run-engine` + redis-worker). There is no V1 execution path: a `RunEngineVersion` `V1` branch only rejects or finalizes gracefully so v3 clients get a clean 4xx, never a 5xx. Do not reintroduce V1. See `apps/webapp/CLAUDE.md` and `.claude/rules/legacy-v3-code.md`.
145
146### Documentation
147
148Docs live in `docs/` as a Mintlify site (MDX format). See `docs/CLAUDE.md` for conventions.
149
150### Reference Projects
151
152Reference/example projects for testing SDK and platform features live in a separate repo: [`triggerdotdev/references`](https://github.com/triggerdotdev/references). Clone it alongside this repo and use its `projects/hello-world` to manually test changes before submitting PRs. See that repo's README for setup and linking to a local monorepo build.
153
154## Docker Image Guidelines
155
156When updating Docker image references:
157
158- **Always use multiplatform/index digests**, not architecture-specific digests
159- Architecture-specific digests cause CI failures on different build environments
160- Use the digest from the main Docker Hub page, not from a specific OS/ARCH variant
161
162## Writing Trigger.dev Tasks
163
164Always import from `@trigger.dev/sdk`. Never use `@trigger.dev/sdk/v3` or deprecated `client.defineJob`.
165
166```typescript
167import { task } from "@trigger.dev/sdk";
168
169export const myTask = task({
170 id: "my-task",
171 run: async (payload: { message: string }) => {
172 // Task logic
173 },
174});
175```
176
177### SDK Documentation Rules
178
179The `rules/` directory contains versioned SDK documentation distributed via the SDK installer. Current version: `rules/manifest.json`. Do NOT update `rules/` or `.claude/skills/trigger-dev-tasks/` unless explicitly asked - these are maintained in separate dedicated passes.
180
181## Testing with the hello-world Reference Project
182
183The reference projects live in the separate [`triggerdotdev/references`](https://github.com/triggerdotdev/references) repo - clone it alongside this repo.
184
185First-time setup:
186
1871. `pnpm run db:seed` to seed the database (creates the References org + hello-world project)
1882. Build the CLI/packages you want to test: `pnpm run build --filter trigger.dev`
1893. In your `references` clone, follow its README to link to your local monorepo build, then authorize: `cd projects/hello-world && pnpm exec trigger login -a http://localhost:3030`
190
191Running (from your `references` clone): `cd projects/hello-world && pnpm exec trigger dev`
192
193## Local Task Testing Workflow
194
195### Step 1: Start Webapp in Background
196
197```bash
198# Run from repo root with run_in_background: true
199pnpm run dev --filter webapp
200curl -s http://localhost:3030/healthcheck # Verify running
201```
202
203### Step 2: Start Trigger Dev in Background
204
205```bash
206# in your triggerdotdev/references clone
207cd projects/hello-world && pnpm exec trigger dev
208# Wait for "Local worker ready [node]"
209```
210
211### Step 3: Trigger and Monitor Tasks via MCP
212
213```
214mcp__trigger__get_current_worker(projectRef: "proj_rrkpdguyagvsoktglnod", environment: "dev")
215mcp__trigger__trigger_task(projectRef: "proj_rrkpdguyagvsoktglnod", environment: "dev", taskId: "hello-world", payload: {"message": "Hello"})
216mcp__trigger__list_runs(projectRef: "proj_rrkpdguyagvsoktglnod", environment: "dev", taskIdentifier: "hello-world", limit: 5)
217```
218
219Dashboard: http://localhost:3030/orgs/references-9dfd/projects/hello-world-97DT/env/dev/runs
220
221<!-- intent-skills:start -->
222
223# Skill mappings — when working in these areas, load the linked skill file into context.
224
225skills:
226
227- task: "Using agentcrumbs for debug tracing, adding crumbs, trails, markers, querying traces, or stripping debug code before merge"
228 load: "node_modules/agentcrumbs/skills/agentcrumbs/SKILL.md"
229- task: "Setting up agentcrumbs in the project, initializing namespace catalog, running crumbs init"
230 load: "node_modules/agentcrumbs/skills/agentcrumbs/init/SKILL.md"
231<!-- intent-skills:end -->
232
233## agentcrumbs
234
235Add crumbs as you write code — not just when debugging. Mark lines with
236`// @crumbs` or wrap blocks in `// #region @crumbs`. They stay on the
237branch throughout development and are stripped by `agentcrumbs strip`
238before merge.
239
240### Namespaces
241
242| Namespace | Description | Path |
243| ----------------- | ---------------------------------------------- | ----------------------------------- |
244| `webapp` | Main Remix app — API, dashboard, orchestration | `apps/webapp` |
245| `supervisor` | Task execution container manager | `apps/supervisor` |
246| `sdk` | Main SDK for writing tasks | `packages/trigger-sdk` |
247| `cli` | CLI and task image bundling | `packages/cli-v3` |
248| `core` | Shared types and subpath exports | `packages/core` |
249| `build` | Build extensions and types | `packages/build` |
250| `react-hooks` | React hooks for realtime/triggering | `packages/react-hooks` |
251| `redis-worker` | Redis-based background job system | `packages/redis-worker` |
252| `run-engine` | Run Engine 2.0 — core run lifecycle | `internal-packages/run-engine` |
253| `database` | Prisma client and schema | `internal-packages/database` |
254| `clickhouse` | ClickHouse client, migrations, analytics | `internal-packages/clickhouse` |
255| `schedule-engine` | Durable cron scheduling | `internal-packages/schedule-engine` |
256| `run-queue` | Run queue management | `internal-packages/run-queue` |
257
258Do not invent new namespaces — pick from this table or ask first.
259
260### For PR reviewers
261
262Do not flag `// @crumbs` markers, `#region @crumbs` blocks, or agentcrumbs
263imports in reviews. These are temporary debug instrumentation stripped
264before merge. Data logged in crumbs (IDs, names, values) never reaches
265production.
266
267### CLI
268
269```bash
270pnpm exec agentcrumbs collect # start collector (multi-service)
271pnpm exec agentcrumbs tail --app trigger # live tail
272pnpm exec agentcrumbs clear --app trigger # remove crumbs before merge
273```
274
275The preferred way to query for crumbs is to use `pnpm exec agentcrumbs query --app trigger` with the `--limit` option and cursor pagination, and clear existing crumbs before reproducing a bug via `pnpm exec agentcrumbs clear --app trigger`.
276
@@ −1 +1 @@
1−# Database Package
1+# AGENTS.md
22
3−Prisma 6.14.0 client and schema for PostgreSQL (`@trigger.dev/database`).
3+This file provides guidance to Claude Code when working with this repository. Subdirectory CLAUDE.md files provide deeper context when you navigate into specific areas.
44
5−## Schema
5+## Build and Development Commands
66
7−Located at `prisma/schema.prisma`. Key models include TaskRun, BackgroundWorker, BackgroundWorkerTask, WorkerDeployment, RuntimeEnvironment, and Project.
7+This is a pnpm 10.33.2 monorepo using Turborepo. Run commands from root with `pnpm run`.
88
9−### Engine Versions
9+**Adding dependencies:** Edit `package.json` directly instead of using `pnpm add`, then run `pnpm i` from the repo root. See `.claude/rules/package-installation.md` for the full process.
1010
11−```prisma
12−enum RunEngineVersion {
13− V1 // Retired v3 engine - no longer executes; kept for historical rows and rejection
14− V2 // Current (run-engine + redis-worker)
15−}
11+```bash
12+pnpm run docker # Core dev services (Postgres, Redis, Electric, MinIO, ClickHouse, s2-lite)
13+# pnpm run docker:full # Same + observability stack (Prometheus, Grafana, OTEL) and chaos tooling
14+pnpm run db:migrate # Run database migrations
15+pnpm run db:seed # Seed the database (required for reference projects)
16+
17+# Build packages (required before running)
18+pnpm run build --filter webapp && pnpm run build --filter trigger.dev && pnpm run build --filter @trigger.dev/sdk
19+
20+pnpm run dev --filter webapp # Run webapp (http://localhost:3030)
21+pnpm run dev --filter trigger.dev --filter "@trigger.dev/*" # Watch CLI and packages
1622 ```
1723
18−New code should always target V2.
24+### Verifying Changes
1925
20−## Creating Migrations
26+The verification command depends on where the change lives:
2127
22−1. Edit `prisma/schema.prisma`
23−2. Generate migration:
24− ```bash
25− cd internal-packages/database
26− pnpm run db:migrate:dev:create --name "descriptive_name"
27− ```
28−3. **Clean up generated migration** - remove extraneous lines for:
29− - `_BackgroundWorkerToBackgroundWorkerFile`
30− - `_BackgroundWorkerToTaskQueue`
31− - `_TaskRunToTaskRunTag`
32− - `_WaitpointRunConnections`
33− - `_completedWaitpoints`
34− - `SecretStore_key_idx`
35− - Various `TaskRun` indexes (unless you added them)
36−4. Apply migration:
37− ```bash
38− pnpm run db:migrate:deploy && pnpm run generate
39− ```
28+- **Apps and internal packages** (`apps/*`, `internal-packages/*`): Use `typecheck`. **Never use `build`** for these — building proves almost nothing about correctness.
29+- **Public packages** (`packages/*`): Use `build`.
4030
41−## Index Migration Rules
31+```bash
32+# Apps and internal packages — use typecheck
33+pnpm run typecheck --filter webapp # ~1-2 minutes
34+pnpm run typecheck --filter @internal/run-engine
4235
43−When adding indexes to **existing tables**:
36+# Public packages — use build
37+pnpm run build --filter @trigger.dev/sdk
38+pnpm run build --filter @trigger.dev/core
39+```
4440
45−- Use `CREATE INDEX CONCURRENTLY IF NOT EXISTS` to avoid table locks in production
46−- CONCURRENTLY indexes **must be in their own separate migration file** - they cannot be combined with other schema changes (PostgreSQL requirement)
47−- Only add one index per migration file
48−- Pre-apply the index manually in production before deploying the migration (Prisma will skip creation if the index already exists)
41+Only run typecheck/build after major changes (new files, significant refactors, schema changes). For small edits, trust the types and let CI catch issues.
4942
50−Indexes on **newly created tables** (in the same migration as `CREATE TABLE`) do not need CONCURRENTLY and can be in the same migration file.
43+## Testing
5144
52−When adding an index on a **new column on an existing table**, use two migrations:
53−1. First migration: `ALTER TABLE ... ADD COLUMN IF NOT EXISTS ...` (the column)
54−2. Second migration: `CREATE INDEX CONCURRENTLY IF NOT EXISTS ...` (the index, in its own file)
45+We use vitest exclusively. **Never mock anything** - use testcontainers instead.
5546
56−See `README.md` in this directory and `ai/references/migrations.md` for the full index workflow.
47+```bash
48+pnpm run test --filter webapp # All tests for a package
49+cd internal-packages/run-engine
50+pnpm run test ./src/engine/tests/ttl.test.ts --run # Single test file
51+pnpm run build --filter @internal/run-engine # May need to build deps first
52+```
5753
58−## Read Replicas
54+Test files go next to source files (e.g., `MyService.ts` -> `MyService.test.ts`).
5955
60−Use `$replica` from `~/db.server` for read-heavy queries in the webapp.
56+### Testcontainers for Redis/PostgreSQL
57+
58+```typescript
59+import { redisTest, postgresTest, containerTest } from "@internal/testcontainers";
60+
61+redisTest("should use redis", async ({ redisOptions }) => {
62+ /* ... */
63+});
64+postgresTest("should use postgres", async ({ prisma }) => {
65+ /* ... */
66+});
67+containerTest("should use both", async ({ prisma, redisOptions }) => {
68+ /* ... */
69+});
70+```
71+
72+## Code Style
73+
74+### Formatting and linting
75+
76+Format and lint are enforced by CI (`code-quality` check). Run before committing:
77+
78+```bash
79+pnpm run format # oxfmt — auto-fixes formatting
80+pnpm run lint:fix # oxlint — auto-fixes lint violations
81+pnpm run lint # oxlint — check only (no fixes)
82+```
83+
84+### Imports
85+
86+**Prefer static imports over dynamic imports.** Only use dynamic `import()` when:
87+- Circular dependencies cannot be resolved otherwise
88+- Code splitting is genuinely needed for performance
89+- The module must be loaded conditionally at runtime
90+
91+Dynamic imports add unnecessary overhead in hot paths and make code harder to analyze. If you find yourself using `await import()`, ask if a regular `import` statement would work instead.
92+
93+## Changesets and Server Changes
94+
95+When modifying any public package (`packages/*` or `integrations/*`), add a changeset:
96+
97+```bash
98+pnpm run changeset:add
99+```
100+
101+- Default to **patch** for bug fixes and minor changes
102+- Confirm with maintainers before selecting **minor** (new features)
103+- **Never** select major without explicit approval
104+
105+When modifying only server components (`apps/webapp/`, `apps/supervisor/`, etc.) with no package changes, add a `.server-changes/` file instead. See `.server-changes/README.md` for format and documentation.
106+
107+**Write the description for users, not maintainers.** Both changesets and `.server-changes/` notes ship verbatim in user-visible release notes. Lead with what changed *for the user* - one plain sentence describing behavior, not implementation, and never naming internal tools or infra. The full writing guidance in `.server-changes/README.md` applies to changesets too.
108+
109+## Dependency Pinning
110+
111+Zod is pinned to a single version across the entire monorepo (currently `3.25.76`). When adding zod to a new or existing package, use the **exact same version** as the rest of the repo - never a different version or a range. Mismatched zod versions cause runtime type incompatibilities (e.g., schemas from one package can't be used as body validators in another).
112+
113+## Architecture Overview
114+
115+### Request Flow
116+
117+User API call -> Webapp routes -> Services -> RunEngine -> Redis Queue -> Supervisor -> Container execution -> Results back through RunEngine -> ClickHouse (analytics) + PostgreSQL (state)
118+
119+### Apps
120+
121+- **apps/webapp**: Remix 2.17.4 app - main API, dashboard, orchestration. Uses Express server.
122+- **apps/supervisor**: Manages task execution containers (Docker/Kubernetes).
123+
124+### Public Packages
125+
126+- **packages/trigger-sdk** (`@trigger.dev/sdk`): Main SDK for writing tasks
127+- **packages/cli-v3** (`trigger.dev`): CLI - also bundles code that goes into customer task images
128+- **packages/core** (`@trigger.dev/core`): Shared types. **Import subpaths only** (never root).
129+- **packages/build** (`@trigger.dev/build`): Build extensions and types
130+- **packages/react-hooks**: React hooks for realtime and triggering
131+- **packages/redis-worker** (`@trigger.dev/redis-worker`): Redis-based background job system
132+
133+### Internal Packages
134+
135+- **internal-packages/database**: Prisma 6.14.0 client and schema (PostgreSQL)
136+- **internal-packages/clickhouse**: ClickHouse client, schema migrations, analytics queries
137+- **internal-packages/run-engine**: "Run Engine 2.0" - core run lifecycle management
138+- **internal-packages/redis**: Redis client creation utilities (ioredis)
139+- **internal-packages/testcontainers**: Test helpers for Redis/PostgreSQL containers
140+- **internal-packages/schedule-engine**: Durable cron scheduling
141+
142+### v3 (engine V1) removed
143+
144+v3 (engine V1: MarQS + Graphile worker) is end-of-life and its execution code has been removed. The `apps/webapp/app/v3/` directory name is historical - everything there now serves V2 (Run Engine 2.0, `@internal/run-engine` + redis-worker). There is no V1 execution path: a `RunEngineVersion` `V1` branch only rejects or finalizes gracefully so v3 clients get a clean 4xx, never a 5xx. Do not reintroduce V1. See `apps/webapp/CLAUDE.md` and `.claude/rules/legacy-v3-code.md`.
145+
146+### Documentation
147+
148+Docs live in `docs/` as a Mintlify site (MDX format). See `docs/CLAUDE.md` for conventions.
149+
150+### Reference Projects
151+
152+Reference/example projects for testing SDK and platform features live in a separate repo: [`triggerdotdev/references`](https://github.com/triggerdotdev/references). Clone it alongside this repo and use its `projects/hello-world` to manually test changes before submitting PRs. See that repo's README for setup and linking to a local monorepo build.
153+
154+## Docker Image Guidelines
155+
156+When updating Docker image references:
157+
158+- **Always use multiplatform/index digests**, not architecture-specific digests
159+- Architecture-specific digests cause CI failures on different build environments
160+- Use the digest from the main Docker Hub page, not from a specific OS/ARCH variant
161+
162+## Writing Trigger.dev Tasks
163+
164+Always import from `@trigger.dev/sdk`. Never use `@trigger.dev/sdk/v3` or deprecated `client.defineJob`.
165+
166+```typescript
167+import { task } from "@trigger.dev/sdk";
168+
169+export const myTask = task({
170+ id: "my-task",
171+ run: async (payload: { message: string }) => {
172+ // Task logic
173+ },
174+});
175+```
176+
177+### SDK Documentation Rules
178+
179+The `rules/` directory contains versioned SDK documentation distributed via the SDK installer. Current version: `rules/manifest.json`. Do NOT update `rules/` or `.claude/skills/trigger-dev-tasks/` unless explicitly asked - these are maintained in separate dedicated passes.
180+
181+## Testing with the hello-world Reference Project
182+
183+The reference projects live in the separate [`triggerdotdev/references`](https://github.com/triggerdotdev/references) repo - clone it alongside this repo.
184+
185+First-time setup:
186+
187+1. `pnpm run db:seed` to seed the database (creates the References org + hello-world project)
188+2. Build the CLI/packages you want to test: `pnpm run build --filter trigger.dev`
189+3. In your `references` clone, follow its README to link to your local monorepo build, then authorize: `cd projects/hello-world && pnpm exec trigger login -a http://localhost:3030`
190+
191+Running (from your `references` clone): `cd projects/hello-world && pnpm exec trigger dev`
192+
193+## Local Task Testing Workflow
194+
195+### Step 1: Start Webapp in Background
196+
197+```bash
198+# Run from repo root with run_in_background: true
199+pnpm run dev --filter webapp
200+curl -s http://localhost:3030/healthcheck # Verify running
201+```
202+
203+### Step 2: Start Trigger Dev in Background
204+
205+```bash
206+# in your triggerdotdev/references clone
207+cd projects/hello-world && pnpm exec trigger dev
208+# Wait for "Local worker ready [node]"
209+```
210+
211+### Step 3: Trigger and Monitor Tasks via MCP
212+
213+```
214+mcp__trigger__get_current_worker(projectRef: "proj_rrkpdguyagvsoktglnod", environment: "dev")
215+mcp__trigger__trigger_task(projectRef: "proj_rrkpdguyagvsoktglnod", environment: "dev", taskId: "hello-world", payload: {"message": "Hello"})
216+mcp__trigger__list_runs(projectRef: "proj_rrkpdguyagvsoktglnod", environment: "dev", taskIdentifier: "hello-world", limit: 5)
217+```
218+
219+Dashboard: http://localhost:3030/orgs/references-9dfd/projects/hello-world-97DT/env/dev/runs
220+
221+<!-- intent-skills:start -->
222+
223+# Skill mappings — when working in these areas, load the linked skill file into context.
224+
225+skills:
226+
227+- task: "Using agentcrumbs for debug tracing, adding crumbs, trails, markers, querying traces, or stripping debug code before merge"
228+ load: "node_modules/agentcrumbs/skills/agentcrumbs/SKILL.md"
229+- task: "Setting up agentcrumbs in the project, initializing namespace catalog, running crumbs init"
230+ load: "node_modules/agentcrumbs/skills/agentcrumbs/init/SKILL.md"
231+<!-- intent-skills:end -->
232+
233+## agentcrumbs
234+
235+Add crumbs as you write code — not just when debugging. Mark lines with
236+`// @crumbs` or wrap blocks in `// #region @crumbs`. They stay on the
237+branch throughout development and are stripped by `agentcrumbs strip`
238+before merge.
239+
240+### Namespaces
241+
242+| Namespace | Description | Path |
243+| ----------------- | ---------------------------------------------- | ----------------------------------- |
244+| `webapp` | Main Remix app — API, dashboard, orchestration | `apps/webapp` |
245+| `supervisor` | Task execution container manager | `apps/supervisor` |
246+| `sdk` | Main SDK for writing tasks | `packages/trigger-sdk` |
247+| `cli` | CLI and task image bundling | `packages/cli-v3` |
248+| `core` | Shared types and subpath exports | `packages/core` |
249+| `build` | Build extensions and types | `packages/build` |
250+| `react-hooks` | React hooks for realtime/triggering | `packages/react-hooks` |
251+| `redis-worker` | Redis-based background job system | `packages/redis-worker` |
252+| `run-engine` | Run Engine 2.0 — core run lifecycle | `internal-packages/run-engine` |
253+| `database` | Prisma client and schema | `internal-packages/database` |
254+| `clickhouse` | ClickHouse client, migrations, analytics | `internal-packages/clickhouse` |
255+| `schedule-engine` | Durable cron scheduling | `internal-packages/schedule-engine` |
256+| `run-queue` | Run queue management | `internal-packages/run-queue` |
257+
258+Do not invent new namespaces — pick from this table or ask first.
259+
260+### For PR reviewers
261+
262+Do not flag `// @crumbs` markers, `#region @crumbs` blocks, or agentcrumbs
263+imports in reviews. These are temporary debug instrumentation stripped
264+before merge. Data logged in crumbs (IDs, names, values) never reaches
265+production.
266+
267+### CLI
268+
269+```bash
270+pnpm exec agentcrumbs collect # start collector (multi-service)
271+pnpm exec agentcrumbs tail --app trigger # live tail
272+pnpm exec agentcrumbs clear --app trigger # remove crumbs before merge
273+```
274+
275+The preferred way to query for crumbs is to use `pnpm exec agentcrumbs query --app trigger` with the `--limit` option and cursor pagination, and clear existing crumbs before reproducing a bug via `pnpm exec agentcrumbs clear --app trigger`.
61276
