> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bijection.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Temporal workflows

> Resources, examples, configuration and evidence for Temporal workflows.

Use the `@bijection/connectors/temporal` entrypoint to declare Temporal workflows resources.

## Availability

This page describes the pinned source package. Published availability is unestablished for this artifact. [Source build and package availability](https://docs.bijection.com/client/sdk-distribution.md).

## Resources and modes

| Resource | Mode | Description |
| - | - | - |
| Workflow | `observed` | observed |

Declare a resource in application code, then bind deployment-specific settings and credentials. See [typed resources](https://docs.bijection.com/integrations/resources.md), [connections](https://docs.bijection.com/integrations/connections.md) and [source inspection](https://docs.bijection.com/integrations/cli.md).

## Workflow

### observed: observed

The following example matches configuration `standard`.

```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { temporal } from "@bijection/connectors/temporal";
import { makeFunctionReference } from "bijection/server";

export const fulfillment = temporal.workflow.observed({
  contract: {
    digest: "720e6099257f4aa61c968137ec47f1563eb4b24d1e82a55a0e97ce9d6786cf44",
    contract: {
      name: "acme.fulfillment",
      workflow_type: "FulfillOrder",
      payload_encoding: "json/plain",
      start: {
        args: [
          {
            type: "object",
            properties: {
              order_id: { type: "string" },
              process_id: { type: "string" },
              tenant_id: { type: "string" },
              terms_hash: { type: "string" },
            },
            required: ["tenant_id", "order_id", "process_id", "terms_hash"],
            additionalProperties: false,
          },
        ],
        returns: {
          type: "object",
          properties: { shipment_id: { type: "string" } },
          required: ["shipment_id"],
          additionalProperties: false,
        },
        recovery: "verify_original_start",
      },
      queries: {
        progress: {
          name: "fulfillmentProgress",
          args: [],
          returns: {
            type: "object",
            properties: {
              order_id: { type: "string" },
              phase: {
                type: "string",
                enum: [
                  "awaiting_approval",
                  "approved",
                  "shipping",
                  "fulfilled",
                ],
              },
              process_id: { type: "string" },
              revision: { type: "integer" },
              tenant_id: { type: "string" },
              terms_hash: { type: "string" },
            },
            required: [
              "tenant_id",
              "order_id",
              "process_id",
              "revision",
              "terms_hash",
              "phase",
            ],
            additionalProperties: false,
          },
        },
      },
      updates: {
        approve: {
          name: "approveOrder",
          args: [
            {
              type: "object",
              properties: {
                actor_id: { type: "string" },
                expected_revision: { type: "integer" },
                terms_hash: { type: "string" },
              },
              required: ["expected_revision", "terms_hash", "actor_id"],
              additionalProperties: false,
            },
          ],
          returns: {
            anyOf: [
              {
                type: "object",
                properties: {
                  kind: { type: "string", enum: ["approved"] },
                  revision: { type: "integer" },
                  terms_hash: { type: "string" },
                },
                required: ["kind", "revision", "terms_hash"],
                additionalProperties: false,
              },
              {
                type: "object",
                properties: {
                  kind: { type: "string", enum: ["refused"] },
                  reason: {
                    type: "string",
                    enum: [
                      "stale_revision",
                      "terms_changed",
                      "not_awaiting_approval",
                    ],
                  },
                  revision: { type: "integer" },
                },
                required: ["kind", "reason", "revision"],
                additionalProperties: false,
              },
            ],
          },
          refusal_kind: "refused",
          completion: "approval_recorded",
          target: "observed_run",
          recovery: "poll_original_run",
        },
      },
      signals: {
        document_received: {
          name: "documentReceived",
          args: [
            {
              type: "object",
              properties: { document_id: { type: "string" } },
              required: ["document_id"],
              additionalProperties: false,
            },
          ],
          recovery: "no_resend_after_unknown",
        },
      },
      progress_revision: "revision",
      progress_query: "progress",
      identity_fields: ["tenant_id", "order_id", "process_id"],
    },
  },
  release: {
    digest: "944a794438e2ecfd866d249a91447bf5480a821647f02db559ca65917f990ac8",
    release: {
      deployment: "fulfillment",
      executions: [],
      builds: [
        {
          build_id: "fulfillment-example-1",
          contract_digest:
            "720e6099257f4aa61c968137ec47f1563eb4b24d1e82a55a0e97ce9d6786cf44",
          workflow_type: "FulfillOrder",
          payload_encoding: "json/plain",
        },
      ],
    },
  },
  access: {
    read: makeFunctionReference<"query", any, [null]>("permissions:workflow"),
    reads: [],
  },
  governingRules: {
    start: makeFunctionReference<"query", any, [null]>("permissions:workflow"),
    approve: makeFunctionReference<"query", any, [null]>(
      "permissions:workflow",
    ),
    document_received: makeFunctionReference<"query", any, [null]>(
      "permissions:workflow",
    ),
    requestCancellation: makeFunctionReference<"query", any, [null]>(
      "permissions:workflow",
    ),
  },
});
```

> **Inferred record types**
>
> ```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "key": string;
>   "workflow_id": string;
>   "run_id": string;
>   "first_run_id": string;
>   "previous_run_id": string | null;
>   "lifecycle": string;
>   "progress": { readonly order_id: string; readonly phase: "shipping" | "awaiting_approval" | "approved" | "fulfilled"; readonly process_id: string; readonly revision: number; readonly tenant_id: string; readonly terms_hash: string; } & {};
>   "result": ({ readonly shipment_id: string; } & {}) | null;
>   "progress_revision": number;
>   "history_length": number;
>   "observation_id": string;
>   "contract_digest": string;
>   "observed_at": number;
> }
> ```

The function references identify application policy queries. Implement those policies in your application; the references alone grant no authority.

#### Configuration: standard

Case: `temporal/workflow/observed/standard`.

Connection and resource configuration are declared by this exact case.

Credential kind: `http`. Keep credential material in the private credential inventory.

| Setting | Type | Required | Owner |
| - | - | - | - |
| `endpoint` | string | Yes | Shared connection |
| `namespace_id` | string | Yes | Shared connection |
| `task_queue` | string | Yes | Shared connection |

> **Complete configuration contract**
>
> ```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "setup": [],
>   "resource": {
>     "access": {
>       "records": {
>         "read": {
>           "query": "permissions:workflow"
>         },
>         "reads": []
>       }
>     },
>     "defaults": {},
>     "connector": "http",
>     "output": {
>       "kind": "single",
>       "collection": "records"
>     },
>     "credential_kind": "http",
>     "connection_fields": [
>       "endpoint",
>       "namespace_id",
>       "task_queue"
>     ],
>     "address": {
>       "kind": "setup",
>       "field": "endpoint"
>     }
>   },
>   "connection_setup": {
>     "type": "object",
>     "value": {
>       "endpoint": {
>         "fieldType": {
>           "type": "string"
>         },
>         "optional": false
>       },
>       "namespace_id": {
>         "fieldType": {
>           "type": "string"
>         },
>         "optional": false
>       },
>       "task_queue": {
>         "fieldType": {
>           "type": "string"
>         },
>         "optional": false
>       }
>     }
>   },
>   "execution": null
> }
> ```

Native admission analysis is available for this exact declaration.

**Collection: records**

| Contract | Meaning |
| - | - |
| Initial | Enumeration of observed records |
| Changes | Repeated observations of current records |
| Deletions | Deletion detection unsupported |
| Resume | Opaque cursor |
| Gap | Explicit repair required after a gap |
| Retention | Unspecified |

> **Complete native profile**
>
> ```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "movement": {
>     "exchanges": {
>       "records": {
>         "200": {
>           "placement": "retained_bytes",
>           "interpretation": "json",
>           "projectsBeforeRetention": false,
>           "retainedBodyLimitBytes": "524288",
>           "fileLimitBytes": null
>         }
>       }
>     },
>     "nativeInputLimitBytes": null,
>     "steps": [
>       {
>         "id": "acquire.1",
>         "inputs": [],
>         "action": {
>           "operation": "acquire",
>           "subject": "exchange records",
>           "limitBytes": null
>         }
>       },
>       {
>         "id": "retain.1",
>         "inputs": [
>           "acquire.1"
>         ],
>         "action": {
>           "operation": "retain",
>           "subject": "acquisition evidence",
>           "reason": "recovery",
>           "release": "acquisition_custody"
>         }
>       },
>       {
>         "id": "interpret.1",
>         "inputs": [
>           "retain.1"
>         ],
>         "action": {
>           "operation": "interpret",
>           "subject": "acquired input",
>           "produces": "records"
>         }
>       },
>       {
>         "id": "materialize.1",
>         "inputs": [
>           "interpret.1"
>         ],
>         "action": {
>           "operation": "materialize",
>           "subject": "source rows",
>           "reason": "serving",
>           "release": "replacement"
>         }
>       },
>       {
>         "id": "publish.1",
>         "inputs": [
>           "materialize.1"
>         ],
>         "action": {
>           "operation": "publish",
>           "subject": "source rows",
>           "visibility": "with_acquisition"
>         }
>       }
>     ]
>   },
>   "initial": "enumeration",
>   "changes": "observations",
>   "deletions": "unsupported",
>   "resume": "opaque_cursor",
>   "retentionMs": null,
>   "gap": "explicit_repair",
>   "limits": {
>     "http_response_bytes": "524288"
>   },
>   "restrictions": [],
>   "commands": {
>     "approve": {
>       "target": "records",
>       "delivery": "single_attempt",
>       "condition": "unconditional",
>       "replayWindowMs": null,
>       "maxDeliveryHours": "1",
>       "providerEnforcedExpiry": false
>     },
>     "document_received": {
>       "target": "records",
>       "delivery": "single_attempt",
>       "condition": "unconditional",
>       "replayWindowMs": null,
>       "maxDeliveryHours": "1",
>       "providerEnforcedExpiry": false
>     },
>     "requestCancellation": {
>       "target": "records",
>       "delivery": "single_attempt",
>       "condition": "unconditional",
>       "replayWindowMs": null,
>       "maxDeliveryHours": "1",
>       "providerEnforcedExpiry": false
>     },
>     "start": {
>       "target": "records",
>       "delivery": "single_attempt",
>       "condition": "unconditional",
>       "replayWindowMs": null,
>       "maxDeliveryHours": "1",
>       "providerEnforcedExpiry": false
>     }
>   }
> }
> ```

**Commands**

| Command | Target | Condition | Delivery |
| - | - | - | - |
| `approve` | records | Unconditional | Single dispatch attempt |
| `document_received` | records | Unconditional | Single dispatch attempt |
| `requestCancellation` | records | Unconditional | Single dispatch attempt |
| `start` | records | Unconditional | Single dispatch attempt |

> **Commands, occurrences and artifacts**
>
> ```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "records": {
>     "records": {
>       "protocol": "record_observation",
>       "coverage": "records",
>       "consistency": "observations",
>       "atomicity": "record",
>       "history": "observations",
>       "recordRefresh": false,
>       "reconciliation": false,
>       "notifications": false,
>       "snapshotMaxRows": null,
>       "profile": {
>         "movement": {
>           "exchanges": {
>             "records": {
>               "200": {
>                 "placement": "retained_bytes",
>                 "interpretation": "json",
>                 "projectsBeforeRetention": false,
>                 "retainedBodyLimitBytes": "524288",
>                 "fileLimitBytes": null
>               }
>             }
>           },
>           "nativeInputLimitBytes": null,
>           "steps": [
>             {
>               "id": "acquire.1",
>               "inputs": [],
>               "action": {
>                 "operation": "acquire",
>                 "subject": "exchange records",
>                 "limitBytes": null
>               }
>             },
>             {
>               "id": "retain.1",
>               "inputs": [
>                 "acquire.1"
>               ],
>               "action": {
>                 "operation": "retain",
>                 "subject": "acquisition evidence",
>                 "reason": "recovery",
>                 "release": "acquisition_custody"
>               }
>             },
>             {
>               "id": "interpret.1",
>               "inputs": [
>                 "retain.1"
>               ],
>               "action": {
>                 "operation": "interpret",
>                 "subject": "acquired input",
>                 "produces": "records"
>               }
>             },
>             {
>               "id": "materialize.1",
>               "inputs": [
>                 "interpret.1"
>               ],
>               "action": {
>                 "operation": "materialize",
>                 "subject": "source rows",
>                 "reason": "serving",
>                 "release": "replacement"
>               }
>             },
>             {
>               "id": "publish.1",
>               "inputs": [
>                 "materialize.1"
>               ],
>               "action": {
>                 "operation": "publish",
>                 "subject": "source rows",
>                 "visibility": "with_acquisition"
>               }
>             }
>           ]
>         },
>         "initial": "enumeration",
>         "changes": "observations",
>         "deletions": "unsupported",
>         "resume": "opaque_cursor",
>         "retentionMs": null,
>         "gap": "explicit_repair",
>         "limits": {
>           "http_response_bytes": "524288"
>         },
>         "restrictions": [],
>         "commands": {
>           "approve": {
>             "target": "records",
>             "delivery": "single_attempt",
>             "condition": "unconditional",
>             "replayWindowMs": null,
>             "maxDeliveryHours": "1",
>             "providerEnforcedExpiry": false
>           },
>           "document_received": {
>             "target": "records",
>             "delivery": "single_attempt",
>             "condition": "unconditional",
>             "replayWindowMs": null,
>             "maxDeliveryHours": "1",
>             "providerEnforcedExpiry": false
>           },
>           "requestCancellation": {
>             "target": "records",
>             "delivery": "single_attempt",
>             "condition": "unconditional",
>             "replayWindowMs": null,
>             "maxDeliveryHours": "1",
>             "providerEnforcedExpiry": false
>           },
>           "start": {
>             "target": "records",
>             "delivery": "single_attempt",
>             "condition": "unconditional",
>             "replayWindowMs": null,
>             "maxDeliveryHours": "1",
>             "providerEnforcedExpiry": false
>           }
>         }
>       }
>     }
>   },
>   "occurrences": null,
>   "artifacts": {
>     "raw_archive": false,
>     "native_file_transfer_limit_bytes": null,
>     "external_versions": false,
>     "files": {}
>   },
>   "commands": {
>     "approve": {
>       "target": "records",
>       "condition": {
>         "kind": "unconditional"
>       },
>       "delivery": {
>         "kind": "single_attempt",
>         "retention": {
>           "kind": "unknown"
>         },
>         "max_delivery_hours": 1
>       }
>     },
>     "document_received": {
>       "target": "records",
>       "condition": {
>         "kind": "unconditional"
>       },
>       "delivery": {
>         "kind": "single_attempt",
>         "retention": {
>           "kind": "unknown"
>         },
>         "max_delivery_hours": 1
>       }
>     },
>     "requestCancellation": {
>       "target": "records",
>       "condition": {
>         "kind": "unconditional"
>       },
>       "delivery": {
>         "kind": "single_attempt",
>         "retention": {
>           "kind": "unknown"
>         },
>         "max_delivery_hours": 1
>       }
>     },
>     "start": {
>       "target": "records",
>       "condition": {
>         "kind": "unconditional"
>       },
>       "delivery": {
>         "kind": "single_attempt",
>         "retention": {
>           "kind": "unknown"
>         },
>         "max_delivery_hours": 1
>       }
>     }
>   }
> }
> ```

**Recorded checks**

| Requirement | Scope | Evidence | Result |
| - | - | - | - |
| page-publication-recovery | \{"kind":"collection","name":"records"} | Uses the shared record-observation publication owner; no Temporal-specific native publication history has been run. | Execution result unavailable |
| stated-cursor-empty-page-advances | \{"kind":"collection","name":"records"} | The shared HTTP record recipe owns cursor interpretation; Temporal deployment coverage is unestablished. | Execution result unavailable |
| stated-cursor-repeat-refused | \{"kind":"collection","name":"records"} | The shared HTTP record recipe owns cursor refusal; Temporal deployment coverage is unestablished. | Execution result unavailable |
| command-response-lost | \{"kind":"command","name":"approve"} | The CLI Temporal bridge tests lost-reply recovery against a mocked WorkflowService; native call/publication histories on a deployment are not established. | Execution result unavailable |
| command-response-lost | \{"kind":"command","name":"document\_received"} | The CLI Temporal bridge tests lost-reply recovery against a mocked WorkflowService; native call/publication histories on a deployment are not established. | Execution result unavailable |
| command-response-lost | \{"kind":"command","name":"requestCancellation"} | The CLI Temporal bridge tests lost-reply recovery against a mocked WorkflowService; native call/publication histories on a deployment are not established. | Execution result unavailable |
| command-response-lost | \{"kind":"command","name":"start"} | The CLI Temporal bridge tests lost-reply recovery against a mocked WorkflowService; native call/publication histories on a deployment are not established. | Execution result unavailable |
| identity-account | \{"kind":"connection"} | Fixture: ./src/connectors/temporal/fixtures/identity.json | passed (2026-10-24T21:36:12.446Z) |

Hosted qualification: **unestablished for this catalog configuration**. Installed connections report their own identity, authority and current status.

## Provider guidance

Temporal keeps workflow execution and customer workers. This resource uses the
stateless `bijection temporal serve` gRPC bridge and the existing Bijection HTTP
request, external-call and record-observation owners. The bridge holds no journal
and starts no workers.

Compile a workflow contract with `bijection temporal generate`. The source may be
portable JSON or a TypeScript module whose default export is `defineContract(...)`
from `@bijection/connectors/temporal/contract`.
Import the generated artifact, then declare:

Compiled declaration examples and configuration details are published in the [connector reference](https://docs.bijection.com/integrations/connectors/index).

Bind `setup.endpoint`, `setup.namespace_id` (the immutable Temporal namespace UUID),
and `setup.task_queue` to the authenticated HTTPS bridge and use
`temporal.credential("TEMPORAL_ORDERS")` for its private HTTP bearer credential.
The bridge configuration names the compiled artifact and release manifest.
Temporal namespace, task queue, API key or mTLS files belong to the bridge's
operator configuration. Its listener binds loopback; remote deployments put it
behind their existing authenticated TLS ingress.

The ordinary `ctx.calls.add` path accepts start, Update, Signal and cancellation
commands. A start addresses the collection; other commands address one acquired
local workflow row. A message with one object argument exposes that object's fields as command
arguments, optional fields included. Several positional arguments, or one
non-object argument, require `parameters` naming each position; Temporal still
receives the positional tuple. `requestCancellation` takes no arguments.
Every command requires its native governing rule. The resource's ordinary read
rule governs workflow facts and their disclosure.

The target key freezes Workflow ID, Run ID and first Run ID. Updates use the
native operation ID as Update ID; recovery polls that exact run. Signals and
cancellations report server acceptance and never imply handler completion.
Unknown commands are not automatically resent. Signals and cancellation can be
accepted while workers are offline; they use the acquired contract-stamped target
and service identity rather than requiring a fresh worker query. Start reconciliation checks the
original request, argument digest and contract in the execution's memo.

Discovery uses Visibility only to find candidate executions. Published records
come from exact execution descriptions and the declared progress query, after
the worker's generated `__bijection_contract` handshake matches. Records expose
`workflow_id`, `run_id`, `first_run_id`, `previous_run_id`, `lifecycle`,
`progress`, `result` and `observed_at`. Completion results are validated against the
workflow result schema, and predecessor IDs come from exact start history.
Distinct facts have content-addressed record keys and expose `progress_revision`,
`history_length`, `observation_id` and `contract_digest`; applications select the
newest revision/history position and refuse equal-position conflicts. A late
response cannot overwrite a newer source identity. The record protocol makes no
complete-history or deletion claim. Application
operations must verify tenant/order/process identity before attaching a row.

The supported encoding is Temporal `json/plain`, with bounded explicit schemas.
Custom converters are refused. Worker bindings include deterministic validation
and typed SDK messages. The customer must install the generated contract handler
and implement its workflow messages. Update `refusal_kind` optionally declares a
business result's `kind` that denotes refusal; other schema-valid completed
Updates establish their declared completion only. Their full result stays in the
retained response evidence; ordinary call inspection exposes delivery status.

The Go CLI bridge tests and package declaration tests do not establish deployed
qualification. The catalog names remaining native coverage explicitly.

Read-only binding checks validate server/namespace identity and retention, the
current/ramping/tracked worker versions and task queue membership against the
release. Known executions may be named in `release.executions`. Missing pollers
are an availability warning. Protocol, namespace, task queue, interface and
release are carried in host-bound request headers; use distinct immutable bridge
endpoints for changed bindings and keep original endpoints for retained calls.
Worker generation is optional. `ContractTypes<typeof contract>` exposes portable
argument tuples and result types without a general-purpose Temporal client.

## Application helpers

All workflow adapters share one application vocabulary. Object-typed inputs are
named command arguments, optional fields included: adding an optional field
never wraps or renames existing arguments. Other values travel as `input`.
Bijection-owned members are camelCase (`start`, `requestCancellation`); names a
contract declares keep their spelling. Serialized routes, capability keys and
records keep their snake\_case wire names.

`<adapter>.commands(contract)` returns each command's target and argument
validators for `commandPolicy` from `bijection/server`, so a policy module types
its inputs without importing the schema that installs the resource.
`<adapter>.policies(contract, "permissions", { reads })` references one exported
policy per command name (`permissions:decideShipment`, ...). Names follow the
contract; a missing export fails deployment analysis.

`<adapter>.observations.select(rows, { bound })` interprets acquired execution
rows the application read through its own indexed queries. It returns
`current`, `missing`, `conflict` (with its reason) or `exceeded`; it never
invents ordering or infers deletion from absence. The application still decides
business association, actor permission and acceptable freshness.
`<adapter>.trace(...)` resolves a retained call's interaction from the generated
`capabilities` and composes it with an authorized observation.

`temporal.observations.select` orders one run by progress revision and history
length. `temporal.observations.follow({ contract, start, runs, successors, bound })`
follows continue-as-new successors from an associated run, keeping contract,
workflow, first-run and declared identity fields, and refuses ambiguous successors.

## Provider references

Provider references and prerequisites are maintained in the connector guidance above. No separate provider-documentation review date is recorded.

## Source and evidence

[Canonical connector source](https://github.com/bijectionhq/component-support/blob/b632604330ce9cbcfe17a5a680ef4fbe80f6f672/packages/connectors/src/connectors/temporal/README.md), [native analysis](https://github.com/bijectionhq/component-support/blob/b632604330ce9cbcfe17a5a680ef4fbe80f6f672/packages/connectors/contract-analysis.json) and [check receipts](https://github.com/bijectionhq/component-support/blob/b632604330ce9cbcfe17a5a680ef4fbe80f6f672/packages/connectors/evidence.json).

Connector artifact: `905888ea276a2a28e36981a79e8142b2547ea451c3e63162cb6915ad4a7d1305`.

The resource declaration examples above are compiled and compared with exact catalog declarations. Recorded checks apply only to their source, declaration and runtime identities. Configure a connection and inspect its status to establish deployment-specific readiness.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.