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
@@ -101,4 +102,4 @@ Any Standard Schema compatible library works:
101
102
-`errors` — same shape as workflow errors; produced via the `errors` constructors in the implementation's helpers argument, and rehydrated as a typed `AsyncResult` error union on the workflow side
102
103
-`defaultOptions` — contract-level `ActivityOptions` defaults (timeouts, retry). Merge precedence at the worker: `declareWorkflow``activityOptions` < `defaultOptions` < `activityOptionsByName`
103
104
104
-
`defineContract`rejects collisions between workflow-local and global activity names at runtime — `defineContract` runs a Zod validation pass and throws a descriptive error. Activities share a single flat namespace at the worker level, so two activities can't share a name even across workflows. See `packages/contract/src/builder.ts:441` for the validation schema.
105
+
`defineContract`validates the contract's structure at runtime with a hand-rolled structural validator (no zod runtime dependency) and throws a descriptive error: strict root keys (only `taskQueue`/`workflows`/`activities`), identifier-safe names, Standard Schema slots, and collision checks. Activities share a single flat namespace at the worker level, so two _different_ definitions can't share a name even across workflows — but reusing the **same definition object** across workflows is allowed (it's one activity), and the collision message recommends hoisting shared activities to the global `activities` block. A workflow name colliding with a global activity name is also rejected (they share the root of the worker implementations map). See `packages/contract/src/builder.ts` (`validateContractDefinition`).
-**Never throw** from activities — Temporal sees thrown errors as `ApplicationFailure(type: "Error", retryable: true)` by default, which masks the real failure type and triggers unwanted retries. Use `Err(ApplicationFailure.create({ type, message, nonRetryable })).toAsync()` (or a `fromPromise(promise, qualify)` chain whose `qualify` returns the `ApplicationFailure`) instead.
187
+
-**Never throw** from activities — Temporal sees thrown errors as `ApplicationFailure(type: "Error", retryable: true)` by default, which masks the real failure type and triggers unwanted retries. Use `Err(ApplicationFailure.create({ type, message, nonRetryable })).toAsync()` (or a `fromPromise(promise, qualifyFailure)` chain whose `qualifyFailure` returns the `ApplicationFailure`) instead.
185
188
-**Never use `any`** — use `unknown` and validate with schemas. Enforced by oxlint.
186
189
-**Always use `.js` extensions** in imports (even for TypeScript files) — required by ESM module resolution.
187
190
-**Don't `try/catch``CancelledFailure` in workflows** — use `cancellableScope` so cancellation flows through the same `AsyncResult` discipline as everything else.
Copy file name to clipboardExpand all lines: .agents/rules/project-overview.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -31,6 +31,6 @@
31
31
32
32
-**Contract** — defines task queue, workflows, activities, signals, queries, updates, search attributes with schemas. See [contract-patterns.md](./contract-patterns.md).
33
33
-**Worker** — `declareWorkflow` + `declareActivitiesHandler` with automatic validation. See [handlers.md](./handlers.md).
34
-
-**Client** — `TypedClient.create()`returns `AsyncResult<T, E>` for all operations.
34
+
-**Client** — `TypedClient.create({ client })`is connection-scoped; `client.for(contract)` hands out a contract-bound `ContractClient` whose operations return `AsyncResult<T, E>`.
35
35
-**Result** — `Result<T, E>` and `AsyncResult<T, E>` from unthrown for explicit error handling, plus a third `defect` channel for unanticipated failures.
36
36
-**Determinism** — workflow code runs in Temporal's replay sandbox. See [workflow-determinism.md](./workflow-determinism.md).
|[`contract.ts`](https://github.com/btravstack/temporal-contract/blob/main/examples/order-processing-contract/src/contract.ts)| The global vs workflow-scoped activity split |
0 commit comments