# Examples

> Complete annotated workflows from the conformance corpus — atomic, generative, linear chain, and conditional with a human gate.

Every document below comes from the [conformance corpus](/conformance) — the workflows that run as a regression suite, so they cannot silently drift from the schema.

**All 22 are downloadable**, not just the four annotated here: [`/corpus/index.json`](/corpus/index.json) lists them with task, asset and participant counts, and each is at `/corpus/<file>`. Fetch one as a starting point rather than retyping from this page.

```bash
curl -O https://openworkflowgraph.org/corpus/W05.owg.json
owg-validate W05.owg.json --json
```

> These are the corpus documents brought up to v0.9 — every one validates against the current schema. Where an earlier iteration of a document omitted something v0.9 requires, the omission has been corrected here and the correction is noted, because a specification's own examples should obey it.

## W01 — atomic single task

The simplest complete workflow: transcode one file. One task, one participant, one input, one output.

```json
{
  "$schema": "https://openworkflowgraph.org/schemas/core/v0.9.json",
  "owg_version": "0.9",
  "id": "W01-transcode-mov-mp4",
  "profiles": ["core", "cloud-services"],
  "description": "The simplest possible OWG workflow: transcode one source file MOV→MP4. One task, one participant, one input, one output.",
  "objective": "Produce an MP4 delivery from a MOV source.",
  "organizations": [
    { "id": "org_mediasvc", "name": "Example Media Services" }
  ],
  "participants": [
    { "id": "transcode_svc", "kind": "service", "name": "Transcode Service", "organization_id": "org_mediasvc" }
  ],
  "infrastructure": [
    { "id": "cloud_platform", "type": "saas_platform", "owner": "org_mediasvc" }
  ],
  "assets": [
    {
      "id": "source_mov", "role": "source", "type": "video.master",
      "content_type": "video/quicktime",
      "storage": { "provider": "s3", "locator": "s3://studio-media/in/clip.mov", "zone": "us-east-2" }
    },
    {
      "id": "delivery_mp4", "role": "delivery", "type": "video.delivery",
      "content_type": "video/mp4",
      "version_relation": "representation", "predecessor": "source_mov",
      "produced_by": "transcode",
      "storage": { "provider": "s3", "locator": "s3://studio-media/out/clip.mp4", "zone": "us-east-2" }
    }
  ],
  "tasks": [
    {
      "id": "transcode",
      "label": "Transcode MOV → MP4",
      "executor": { "type": "service", "ref": "transcode", "environment": "saas" },
      "performed_by": "transcode_svc",
      "ran_on": "cloud_platform",
      "used": ["source_mov"],
      "produced": ["delivery_mp4"],
      "failure_mode": "HALT",
      "billing": { "tier": "standard", "unit": "per_job" }
    }
  ]
}
```

**What to take from it:**

- The five registries in order: `organizations`, `participants`, `infrastructure`, `assets`, `tasks`.
- The **double linkage** between assets and tasks — `assets[].produced_by` points at the task, `tasks[].produced` points at the asset. The task side is authoritative.
- `version_relation: "representation"` plus `predecessor` is the whole lineage statement. An MP4 of a MOV is a format change, not a revision.
- Assets carry `storage.locator`, so nothing moved in order to be governed.

## W03 — generative task with a subgraph

A single generative step, encapsulating a whole node graph, producing a credentialed asset.

```json
{
  "$schema": "https://openworkflowgraph.org/schemas/core/v0.9.json",
  "owg_version": "0.9",
  "id": "W03",
  "project_id": "generative-ai",
  "profiles": ["core", "generative-ai"],
  "description": "W03 (T0 Atomic) — Single text→image via one ComfyUI graph. One generative task on cloud GPU, producing a C2PA-credentialed asset.",
  "objective": "Generate a single AI image from a text prompt with C2PA provenance.",
  "organizations": [
    { "id": "org_mediasvc", "name": "Example Media Services" }
  ],
  "participants": [
    { "id": "s.okafor", "kind": "human", "name": "Art Director", "role": "art-director", "organization_id": "org_mediasvc" },
    { "id": "concept_bot", "kind": "agent", "name": "SDXL Generator", "operated_by": "s.okafor", "organization_id": "org_mediasvc" }
  ],
  "infrastructure": [
    { "id": "gpu_cloud", "type": "gpu_compute", "owner": "org_mediasvc", "spec": "cloud GPU" }
  ],
  "assets": [
    {
      "id": "text_prompt", "role": "source", "type": "text.prompt",
      "content_type": "text/plain"
    },
    {
      "id": "generate_out", "role": "generated_image", "type": "image.generated",
      "content_type": "image/png",
      "version_relation": "derivation", "predecessor": "text_prompt",
      "produced_by": "generate",
      "credentials": { "scheme": "c2pa" }
    }
  ],
  "tasks": [
    {
      "id": "generate",
      "label": "SDXL text→image graph",
      "executor": { "type": "comfyui_graph", "ref": "sdxl_txt2img", "environment": "cloud" },
      "ai_role": "generative",
      "performed_by": "concept_bot",
      "ran_on": "gpu_cloud",
      "used": ["text_prompt"],
      "produced": ["generate_out"],
      "failure_mode": "HALT",
      "billing": { "tier": "custom", "unit": "per_job" },
      "subgraph": { "format": "comfyui", "ref": "graphs/sdxl_txt2img.json" }
    }
  ]
}
```

**What to take from it:**

- `profiles: ["core", "generative-ai"]` declares the vocabulary in use.
- **The agent carries `operated_by`**, chaining to a named human. The generative-AI profile requires this, and it is what makes the generated image attributable to a person rather than to a process.
- **`ai_role: "generative"`** is declared explicitly. Without it the task would fail compliance rule [R1](/compliance#the-baseline-rule-pack) — an AI-capable executor with no declaration is a finding, not an assumption of innocence.
- `subgraph` with `format: "comfyui"` encapsulates the entire node network as [one governed task](/subgraphs-and-turnovers) whose interior is stored opaquely.
- `executor.ref` names the tool; `subgraph.ref` names the interior. They describe different things and need not match.
- `credentials: { "scheme": "c2pa" }` sits on the **asset**, not the task.
- `version_relation: "derivation"` — an image from a prompt is a new thing acknowledging its source, not a reformat.

## W04 — linear chain across human, desktop, and SaaS

Four tasks, four executor types, two organizations. The first workflow where the executor abstraction earns its keep.

```json
{
  "$schema": "https://openworkflowgraph.org/schemas/core/v0.9.json",
  "owg_version": "0.9",
  "id": "W04",
  "project_id": "audio-workflows",
  "profiles": ["core", "cloud-services"],
  "description": "W04 (T1 Linear Chain) — Record raw podcast audio (human), edit in DAW (local_app), normalise levels (cloud service), publish to an RSS host (SaaS API).",
  "objective": "Produce and publish a finished podcast episode to an RSS host.",
  "organizations": [
    { "id": "org_studio_media", "name": "Example Studio Media" },
    { "id": "org_mediasvc", "name": "Example Media Services" }
  ],
  "participants": [
    { "id": "podcast_host", "kind": "human", "name": "Podcast Host", "role": "host", "organization_id": "org_studio_media" },
    { "id": "audacity_app", "kind": "service", "name": "Audacity", "organization_id": "org_studio_media" },
    { "id": "media_svc", "kind": "service", "name": "Media Services", "organization_id": "org_mediasvc" },
    { "id": "publish_api", "kind": "service", "name": "Example Publishing" }
  ],
  "infrastructure": [
    { "id": "studio_ws", "type": "workstation", "owner": "org_studio_media", "apps": ["audacity"] },
    { "id": "cloud_platform", "type": "saas_platform", "owner": "org_mediasvc" },
    { "id": "publish_platform", "type": "saas_platform" }
  ],
  "assets": [
    { "id": "raw_wav", "role": "source", "type": "audio.raw",
      "content_type": "audio/wav", "produced_by": "record" },
    { "id": "edited_wav", "role": "edited_audio", "type": "audio.edited",
      "content_type": "audio/wav",
      "version_relation": "revision", "predecessor": "raw_wav",
      "produced_by": "edit" },
    { "id": "episode_mp3", "role": "delivery", "type": "audio.delivery",
      "content_type": "audio/mpeg",
      "version_relation": "representation", "predecessor": "edited_wav",
      "produced_by": "normalize" },
    { "id": "publish_out", "role": "publish_record", "type": "record.json",
      "content_type": "application/json",
      "version_relation": "derivation", "predecessor": "episode_mp3",
      "produced_by": "publish" }
  ],
  "tasks": [
    {
      "id": "record",
      "label": "Record raw podcast audio",
      "executor": { "type": "human", "environment": "manual" },
      "performed_by": "podcast_host",
      "ran_on": "studio_ws",
      "produced": ["raw_wav"],
      "failure_mode": "HALT"
    },
    {
      "id": "edit",
      "label": "Edit recording in Audacity",
      "executor": { "type": "local_app", "ref": "audacity", "environment": "desktop" },
      "performed_by": "audacity_app",
      "ran_on": "studio_ws",
      "depends_on": ["record"],
      "used": ["raw_wav"],
      "produced": ["edited_wav"],
      "failure_mode": "HALT"
    },
    {
      "id": "normalize",
      "label": "Normalise loudness and encode MP3",
      "executor": { "type": "service", "ref": "transcode_from_url", "environment": "saas" },
      "performed_by": "media_svc",
      "ran_on": "cloud_platform",
      "depends_on": ["edit"],
      "used": ["edited_wav"],
      "produced": ["episode_mp3"],
      "failure_mode": "CONTINUE",
      "billing": { "tier": "standard", "unit": "per_minute" },
      "retry": { "max_attempts": 2, "initial_interval_seconds": 5 }
    },
    {
      "id": "publish",
      "label": "Publish episode to host",
      "executor": { "type": "saas_api", "ref": "publish_upload", "environment": "saas" },
      "performed_by": "publish_api",
      "ran_on": "publish_platform",
      "depends_on": ["normalize"],
      "used": ["episode_mp3"],
      "produced": ["publish_out"],
      "failure_mode": "HALT",
      "retry": { "max_attempts": 3, "initial_interval_seconds": 10, "backoff_coefficient": 2.0, "retryable_errors": ["RATE_LIMIT", "TRANSIENT_ERROR"] }
    }
  ]
}
```

**What to take from it:**

- **Four executor types in one graph** — `human`, `local_app`, `service`, `saas_api` — scheduled and attributed identically. This is the central claim of the model, made concrete.
- The **version chain is typed at every hop**: raw → edited is a `revision`, edited → MP3 is a `representation`, MP3 → publish record is a `derivation`. Three different relationships, three different meanings.
- `record` has **no `used`** — it is an origin task. Assets can enter the graph by being captured.
- `failure_mode: "CONTINUE"` on `normalize` lets other branches proceed.
- `publish_api` has **no `organization_id`** — a third party. Legitimate, but nothing in the graph vouches for it.
- Two organizations means this document already crosses a company boundary.

## W05 — conditional execution and a human review gate

Five tasks with a conditional AI step, a human gate, and fan-in.

```json
{
  "$schema": "https://openworkflowgraph.org/schemas/core/v0.9.json",
  "owg_version": "0.9",
  "id": "W05",
  "project_id": "video-workflows",
  "profiles": ["core", "cloud-services"],
  "description": "W05 (T1 Linear + Conditional) — Import UGC footage (local Premiere), colour grade and edit, conditionally generate captions via AI agent, thumbnail review by human, then publish.",
  "objective": "Edit, caption, and publish a UGC video.",
  "params": {
    "add_captions": { "type": "boolean", "required": false, "default": false }
  },
  "organizations": [
    { "id": "org_studio_media", "name": "Example Studio Media" }
  ],
  "participants": [
    { "id": "premiere_app", "kind": "service", "name": "Premiere Pro", "organization_id": "org_studio_media" },
    { "id": "caption_agent", "kind": "agent", "name": "Caption Agent", "operated_by": "creator", "organization_id": "org_studio_media" },
    { "id": "creator", "kind": "human", "name": "Creator", "role": "creator", "organization_id": "org_studio_media" },
    { "id": "youtube_api", "kind": "service", "name": "YouTube" }
  ],
  "infrastructure": [
    { "id": "edit_ws", "type": "workstation", "owner": "org_studio_media", "apps": ["premiere"] },
    { "id": "agent_cloud", "type": "saas_platform", "owner": "org_studio_media" },
    { "id": "youtube_saas", "type": "saas_platform" }
  ],
  "assets": [
    { "id": "project_prproj", "role": "project", "type": "project.premiere",
      "content_type": "application/octet-stream", "produced_by": "ingest" },
    { "id": "master_mp4", "role": "edited_master", "type": "video.master",
      "content_type": "video/mp4",
      "version_relation": "derivation", "predecessor": "project_prproj",
      "produced_by": "edit" },
    { "id": "captions_srt", "role": "captions", "type": "text.captions",
      "content_type": "text/vtt",
      "version_relation": "derivation", "predecessor": "master_mp4",
      "produced_by": "caption" },
    { "id": "thumbnail_jpg", "role": "thumbnail", "type": "image.thumbnail",
      "content_type": "image/jpeg",
      "version_relation": "derivation", "predecessor": "master_mp4",
      "produced_by": "thumbnail_review" },
    { "id": "publish_out", "role": "publish_record", "type": "record.json",
      "content_type": "application/json",
      "version_relation": "derivation", "predecessor": "master_mp4",
      "produced_by": "publish" }
  ],
  "tasks": [
    {
      "id": "ingest",
      "label": "Import UGC footage into Premiere",
      "executor": { "type": "local_app", "ref": "premiere", "environment": "desktop" },
      "performed_by": "premiere_app",
      "ran_on": "edit_ws",
      "produced": ["project_prproj"],
      "failure_mode": "HALT"
    },
    {
      "id": "edit",
      "label": "Edit, grade and export master",
      "executor": { "type": "local_app", "ref": "premiere", "environment": "desktop" },
      "performed_by": "premiere_app",
      "ran_on": "edit_ws",
      "depends_on": ["ingest"],
      "used": ["project_prproj"],
      "produced": ["master_mp4"],
      "failure_mode": "HALT"
    },
    {
      "id": "caption",
      "label": "AI generate captions (SRT)",
      "executor": { "type": "agent", "ref": "generate_captions", "environment": "saas" },
      "ai_role": "generative",
      "performed_by": "caption_agent",
      "ran_on": "agent_cloud",
      "depends_on": ["edit"],
      "when": "$.params.add_captions == true",
      "used": ["master_mp4"],
      "produced": ["captions_srt"],
      "failure_mode": "SKIP_DEPENDENTS"
    },
    {
      "id": "thumbnail_review",
      "label": "Creator reviews thumbnail",
      "type": "review",
      "executor": { "type": "human", "environment": "manual" },
      "performed_by": "creator",
      "ran_on": "edit_ws",
      "depends_on": ["edit"],
      "used": ["master_mp4"],
      "produced": ["thumbnail_jpg"],
      "failure_mode": "HALT"
    },
    {
      "id": "publish",
      "label": "Upload to YouTube",
      "executor": { "type": "saas_api", "ref": "youtube_upload", "environment": "saas" },
      "performed_by": "youtube_api",
      "ran_on": "youtube_saas",
      "depends_on": ["edit", "thumbnail_review", "caption"],
      "used": ["master_mp4", "thumbnail_jpg"],
      "inputs": {
        "captions_key": "$.tasks.caption.outputs.output_key",
        "include_captions": "exists($.tasks.caption.outputs.output_key)"
      },
      "produced": ["publish_out"],
      "failure_mode": "HALT",
      "retry": { "max_attempts": 3, "initial_interval_seconds": 30, "backoff_coefficient": 2.0, "retryable_errors": ["RATE_LIMIT", "QUOTA_EXCEEDED", "TRANSIENT_ERROR"] }
    }
  ]
}
```

**What to take from it:**

- `"type": "review"` marks the human gate. The graph knows this is a decision point, not just work.
- `depends_on: ["edit", "thumbnail_review"]` is **fan-in** — two branches converge.
- `failure_mode: "SKIP_DEPENDENTS"` on the optional caption step contains the blast radius.

**Three details worth studying, because each is a rule the earlier version of this document broke:**

1. **The condition resolves.** `"when": "$.params.add_captions == true"` reads a parameter the document declares in `params`. An earlier version referenced an undeclared parameter, which v0.9 rejects as `OWG_UNRESOLVED_REFERENCE` — the reference grammar is validated, not merely stored. See [Reference syntax](/reference-syntax).
2. **`publish` does not claim a lineage edge it cannot guarantee.** `captions_srt` is *not* in `used[]`, because `caption` may be skipped. The captions path is passed through `inputs` and gated with `exists()`, so the executor learns whether captions exist without the graph asserting an edge to an asset that may never have been produced.
3. **The agent has an accountability chain.** `caption_agent` carries `operated_by: "creator"`, so the generated captions trace to a person.

The second is the subtle one, and the mistake people make most often. `depends_on` establishes ordering; `used[]` asserts that consumption actually happened. Conflating them produces lineage that reads as fact but is conditional.

## Going further

Other corpus documents worth reading:

- **W14** — the headline case. Ten tasks, LoRA training, two human gates, C2PA signing.
- **`helios-concept-dev`** — the only document exercising the full QC re-route vocabulary (`on_pass`, `on_fail`, `reroute_feedback`, `max_reroutes`).
- **`tams-live-sports`** and **`usd-scene-composition`** — the standards bindings in practice: a growing asset under governance, and USD composition arcs as typed edges.
- **`europa-project`**, **`helios-project`** — registry-only documents with zero tasks.
