This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: temporal-workflow-determinism-and-patch-versioning

Temporal Durable Execution Determinism and Replay Versioning Invariants

Enforces strict static determinism barriers prohibiting non-deterministic system clocks, random generators, native timers, and direct I/O inside Temporal workflow scopes. Mandates deterministic Temporal SDK primitives and structural versioning via workflow.patched() to guarantee identical event history replays across multi-year long-running workflows.

Prohibited Anti-Pattern: Executing Non-Deterministic Host Runtime Calls and Unversioned Workflow DAG Mutations

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Temporal Durable Execution Determinism and Replay Versioning Invariants - Enforces strict static determinism barriers prohibiting non-deterministic system clocks, random generators, native timers, and direct I/O inside Temporal workflow scopes. Mandates deterministic Temporal SDK primitives and structural versioning via workflow.patched() to guarantee identical event history replays across multi-year long-running workflows.
globs: src/**/workflows/**/*.ts, src/**/workflows/*.ts, workflows/**/*.ts
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/temporal-workflow-determinism-and-patch-versioning"
---

# Temporal Durable Execution Determinism and Replay Versioning Invariants

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Executing Non-Deterministic Host Runtime Calls and Unversioned Workflow DAG Mutations

## System Constraints
You are a Principal Software Architect enforcing Temporal durable execution invariants. Workflow functions must remain purely deterministic state machines whose exact execution path can be identically reconstructed from event history. Never introduce native timers, host clocks, non-deterministic random generators, direct network/database I/O, or unversioned control flow transitions in workflow files.

## Strict Guidelines
- Engineers MUST NOT invoke non-deterministic runtime primitives such as `Date.now()`, `new Date()`, `Math.random()`, or `crypto.randomUUID()` inside workflow logic.
- Workflows MUST ALWAYS use Temporal SDK deterministic equivalents, including `workflow.now()`, `workflow.uuid4()`, and `workflow.sleep()` instead of host language built-ins.
- Workflow functions MUST NEVER execute direct network I/O, database access, or file system modifications; all external side effects MUST be encapsulated in Activities via `proxyActivities`.
- Engineers MUST ALWAYS gate any control-flow alterations, activity sequence shifts, or parameter transformations in existing workflows using `workflow.patched(patchId)` to maintain backward replay compatibility for running executions.
- Workflows MUST NOT use mutable module-scoped global state, native thread primitives, or floating Promises detached from Temporal's cancellation scopes.
- Deprecation of version patches MUST ONLY proceed via `workflow.deprecatePatch(patchId)` after telemetry guarantees zero in-flight executions remain on the legacy event history schema.

## Bad vs Good Implementations
### Workflow Non-Determinism and Broken Replay vs. Deterministic Patched Flow

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Using Date.now(), crypto.randomUUID(), axios, native setTimeout, and mutable global state inside a workflow breaches the fundamental Temporal determinism contract. On worker recovery or event replay, the values diverge and the workflow fails with a NonDeterministicWorkflowError. Adding 'sendWelcomeEmailV2' directly without a patch breaks history replay for in-flight workflows that expected the V1 activity.
```typescript
import { proxyActivities } from '@temporalio/workflow';
import axios from 'axios';

const activities = proxyActivities<any>({ startToCloseTimeout: '1m' });
let globalAttemptCounter = 0; // Anti-pattern: Shared mutable module state

export async function subscriptionWorkflow(userId: string): Promise<void> {
  // Anti-pattern: Non-deterministic host timestamp breaks replay verification
  const timestamp = Date.now(); 
  
  // Anti-pattern: Non-deterministic host UUID generation
  const idempotencyKey = crypto.randomUUID(); 

  // Anti-pattern: Direct I/O in workflow definition causes runtime panic
  await axios.post('https://api.billing.com/v1/charge', { userId });

  // Anti-pattern: Native setTimeout breaks Temporal durable timer scheduler
  await new Promise((resolve) => setTimeout(resolve, 86400000));

  // Anti-pattern: Structural mutation without workflow.patched() corrupts in-flight history
  await activities.sendWelcomeEmailV2({ userId, timestamp, idempotencyKey });
}
```

#### Production Standard (Correct)
> **Standard**: Adheres to Temporal execution determinism by replacing native clocks with now(), UUIDs with uuid4(), and timers with sleep(). External communication is strictly handled via proxyActivities. Changes to the DAG are gated with patched('use-welcome-email-v2'), allowing existing executions to replay historical V1 paths while routing new workflows through V2 safely.
```typescript
import {
  proxyActivities,
  sleep,
  patched,
  now,
  uuid4
} from '@temporalio/workflow';
import type * as activities from './activities';

const { chargeSubscription, sendWelcomeEmailV1, sendWelcomeEmailV2 } = 
  proxyActivities<typeof activities>({
    startToCloseTimeout: '1 minute',
    retry: {
      initialInterval: '2 seconds',
      maximumAttempts: 5,
    },
  });

export async function subscriptionWorkflow(userId: string): Promise<void> {
  // Invariant: Deterministic clock derived from workflow event timestamp
  const timestamp = now();
  
  // Invariant: Deterministic pseudo-random UUID seeded by workflow execution
  const idempotencyKey = uuid4();

  // Invariant: Side-effects exclusively isolated in Activity execution
  await chargeSubscription({ userId, idempotencyKey, timestamp });

  // Invariant: Durable, replayable timer handled by Temporal cluster
  await sleep('24 hours');

  // Invariant: Structural changes guarded by deterministic patch markers
  if (patched('use-welcome-email-v2')) {
    await sendWelcomeEmailV2({ userId, timestamp, idempotencyKey });
  } else {
    await sendWelcomeEmailV1({ userId });
  }
}
```

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Temporal Durable Execution Determinism and Replay Versioning Invariants

Temporal Durable Execution Determinism and Replay Versioning Invariants defines an industrial-grade behavioral standard for backend engineering. Enforces strict static determinism barriers prohibiting non-deterministic system clocks, random generators, native timers, and direct I/O inside Temporal workflow scopes. Mandates deterministic Temporal SDK primitives and structural versioning via workflow.patched() to guarantee identical event history replays across multi-year long-running workflows. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Executing Non-Deterministic Host Runtime Calls and Unversioned Workflow DAG Mutations Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftExecuting Non-Deterministic Host Runtime Calls and Unversioned Workflow DAG MutationsCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST NOT invoke non-deterministic runtime primitives such as `Date.now()`, `new Date()`, `Math.random()`, or `crypto.randomUUID()` inside workflow logic.

Engineers MUST NOT invoke non-deterministic runtime primitives such as `Date.now()`, `new Date()`, `Math.random()`, or `crypto.randomUUID()` inside workflow logic.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Workflows MUST ALWAYS use Temporal SDK deterministic equivalents, including `workflow.now()`, `workflow.uuid4()`, and `workflow.sleep()` instead of host language built-ins.

Workflows MUST ALWAYS use Temporal SDK deterministic equivalents, including `workflow.now()`, `workflow.uuid4()`, and `workflow.sleep()` instead of host language built-ins.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Workflow functions MUST NEVER execute direct network I/O, database access, or file system modifications

Workflow functions MUST NEVER execute direct network I/O, database access, or file system modifications; all external side effects MUST be encapsulated in Activities via `proxyActivities`.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Engineers MUST ALWAYS gate any control-flow alterations, activity sequence shifts, or parameter transformations in existing workflows using `workflow.patched(patchId)` to maintain backward replay compatibility for running executions.

Engineers MUST ALWAYS gate any control-flow alterations, activity sequence shifts, or parameter transformations in existing workflows using `workflow.patched(patchId)` to maintain backward replay compatibility for running executions.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Workflows MUST NOT use mutable module-scoped global state, native thread primitives, or floating Promises detached from Temporal's cancellation scopes.

Workflows MUST NOT use mutable module-scoped global state, native thread primitives, or floating Promises detached from Temporal's cancellation scopes.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
6

Deprecation of version patches MUST ONLY proceed via `workflow.deprecatePatch(patchId)` after telemetry guarantees zero in-flight executions remain on the legacy event history schema.

Deprecation of version patches MUST ONLY proceed via `workflow.deprecatePatch(patchId)` after telemetry guarantees zero in-flight executions remain on the legacy event history schema.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Temporal Durable Execution Determinism and Replay Versioning Invariants critical for AI coding assistants?

Enforces strict static determinism barriers prohibiting non-deterministic system clocks, random generators, native timers, and direct I/O inside Temporal workflow scopes. Mandates deterministic Temporal SDK primitives and structural versioning via workflow.patched() to guarantee identical event history replays across multi-year long-running workflows. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Executing Non-Deterministic Host Runtime Calls and Unversioned Workflow DAG Mutations) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

Temporal