# What does github.workflow_run.succeeded prove?

> Prove that the dispatched workflow run finished with success. Version 1.0.0, certification Community.

Canonical: https://provely.sh/verify/github/github.workflow_run.succeeded  
Last reviewed: 2026-09-05  
Skill version: 0.1.0  
Certification: community  

**Prove that the dispatched workflow run finished with success. A completed run is not a successful run. The contract reads the conclusion of the run and an event that carries it.**

*Contract identity.*

| Fact | Value |
| --- | --- |
| Contract id | `github.workflow_run.succeeded` |
| Version | `1.0.0` |
| Hash | `310fe9de68836705` |
| Completion level | `succeeded` |
| Certification | Community |
| Skill | [GitHub REST API 0.1.0](/verify/github) |
| Valid for provider API versions | `2022-11-28` |

## What is the intent?

Start the workflow on the reference and let it finish with success.

## What is the subject and the action?

| Member | Value |
| --- | --- |
| Subject type | `github.workflow_run` |
| Subject identity | workflow_run_id = `$action.result.workflow_run_id` |
| Canonical effect | `ci.workflow_run_start` |
| Provider operation | `POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches` |
| Idempotency | none, retry is not safe |

## How does the evidence correlate with this operation?

| Strategy | Assurance | Keys | Required |
| --- | --- | --- | --- |
| `resource_id` | strong | workflow_run_id from `$action.result.workflow_run_id` | yes |
| `fingerprint` | weak | workflow_id from `$input.workflow_id`; ref from `$input.ref` | no |

## Which evidence does the contract require?

Minimum evidence level `E2`. An independent channel is required. Minimum channels: 1.

| Channel | Level | Independence | Verifier | Description |
| --- | --- | --- | --- | --- |
| `workflow_run_readback` | E2 | provider readback | `http` | Read the workflow run from the provider. A condition path is $observed.workflow_run_readback.conclusion. |
| `workflow_run_completed_events` | E3 | provider event | `webhook` | The workflow_run.completed events of this run that carry the conclusion success. The webhook verifier returns {events, count, latest, earliest, types, duplicates_dropped}. |
| `workflow_run_requested_events` | E3 | provider event | `webhook` | The workflow_run.requested events for the reference since the operation started. The webhook verifier returns {events, count, latest, earliest, types, duplicates_dropped}. A count above one shows a second run. |

## Which conditions must all hold for VERIFIED?

| Condition | Meaning | Path | Operator | Expected | Evidence |
| --- | --- | --- | --- | --- | --- |
| `workflow_run_completed` | The run reached the terminal status. | `$observed.workflow_run_readback.status` | `eq` | `completed` | `workflow_run_readback` |
| `workflow_run_conclusion_success` | The conclusion of the run is success. A completed run is not a success. | `$observed.workflow_run_readback.conclusion` | `eq` | `success` | `workflow_run_readback` |
| `workflow_run_ref_matches` | The run used the reference that the intent named. | `$observed.workflow_run_readback.head_branch` | `eq` | `$input.ref` | `workflow_run_readback` |
| `workflow_run_started_in_window` | The provider created the run after the operation started. | `$observed.workflow_run_readback.created_at` | `time_after` | `$operation.created_at` | `workflow_run_readback` |
| `workflow_run_success_event` | At least one workflow_run.completed event of this run carries the conclusion success. | `$observed.workflow_run_completed_events.count` | `gte` | `1` | `workflow_run_completed_events` |

## Which conditions give CONTRADICTED?

| Condition | Class | Reason | Path | Operator | Expected |
| --- | --- | --- | --- | --- | --- |
| `workflow_run_on_wrong_ref` | wrong subject | The workflow run used a different reference than the intent named. | `$observed.workflow_run_readback.head_branch` | `ne` | `$input.ref` |
| `workflow_run_not_a_dispatch` | other | The run started from another event. It is not the run of this dispatch. | `$observed.workflow_run_readback.event` | `ne` | `workflow_dispatch` |
| `workflow_run_predates_operation` | pre existing state | The workflow run is older than the operation. It proves nothing. | `$observed.workflow_run_readback.created_at` | `time_before` | `$operation.created_at` |
| `duplicate_workflow_run_present` | duplicate side effect | GitHub started more than one run for the reference since the operation started. Do not retry. | `$observed.workflow_run_requested_events.count` | `gt` | `1` |

## Which observed states map to a verdict before completion?

| Rule | Match | Verdict | Reason |
| --- | --- | --- | --- |
| `terminal_failure` | `$observed.workflow_run_readback.conclusion` in `["failure","timed_out","startup_failure"]` | FAILED | The run is complete and a job of it failed. |
| `cancelled` | `$observed.workflow_run_readback.conclusion` eq `"cancelled"` | CONTRADICTED | A person or an agent cancelled the run. No work finished. |
| `still_running` | `$observed.workflow_run_readback.status` in `["queued","in_progress","requested","waiting","pending"]` | PENDING | The run has not finished. The runtime observes again later. |

## How long does the runtime observe?

| Timing member | Value |
| --- | --- |
| Initial delay | 1000 ms |
| Poll interval | 5000 ms |
| Backoff | exponential factor 2, max 60000 ms |
| Maximum attempts | 40 |
| Timeout | 86400000 ms |
| Stale read window | 20000 ms |
| On timeout | UNVERIFIABLE (`evidence_unavailable_before_timeout`), escalated to a person |

## Where do these rules come from?

- `github.openapi#/paths/~1repos~1{owner}~1{repo}~1actions~1workflows~1{workflow_id}~1dispatches/post`: [github.openapi](https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json), retrieved 2026-09-08
- `github.openapi#/paths/~1repos~1{owner}~1{repo}~1actions~1workflows~1{workflow_id}~1dispatches/post/responses/200`: [github.openapi](https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json), retrieved 2026-09-08
- `github.openapi#/components/schemas/workflow-run/properties/status`: [github.openapi](https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json), retrieved 2026-09-08
- `github.openapi#/components/schemas/workflow-run/properties/conclusion`: [github.openapi](https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json), retrieved 2026-09-08
- `github.docs.workflows#workflow-runs/dispatch-a-workflow`: [github.docs.workflows](https://docs.github.com/rest/actions/workflow-runs), retrieved 2026-09-08
- `github.docs.workflows#workflow-runs/the-status-of-a-run`: [github.docs.workflows](https://docs.github.com/rest/actions/workflow-runs), retrieved 2026-09-08
- `github.docs.workflows#workflow-runs/the-conclusion-of-a-run`: [github.docs.workflows](https://docs.github.com/rest/actions/workflow-runs), retrieved 2026-09-08
- `github.openapi#/components/schemas/workflow-run/properties/head_branch`: [github.openapi](https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json), retrieved 2026-09-08
- `github.openapi#/components/schemas/workflow-run/properties/created_at`: [github.openapi](https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json), retrieved 2026-09-08
- `github.events#/events/workflow_run.completed`: [github.events](https://docs.github.com/webhooks/webhook-events-and-payloads), retrieved 2026-09-08
- `github.docs.workflows#workflow-runs/events`: [github.docs.workflows](https://docs.github.com/rest/actions/workflow-runs), retrieved 2026-09-08

### Can github.workflow_run.succeeded return VERIFIED from the action response alone?

No. The minimum evidence level is E2. The action response is E1. The completion conditions read `workflow_run_readback` and `workflow_run_completed_events`.

### What happens after the timeout?

The verdict is UNVERIFIABLE with the reason `evidence_unavailable_before_timeout`. The operation goes to a person for review.

## Read next

- [Read the GitHub REST API verification page](https://provely.sh/verify/github)
- [Read the github.pull_request.merged contract](https://provely.sh/verify/github/github.pull_request.merged)
- [Read the github.pull_request.open contract](https://provely.sh/verify/github/github.pull_request.open)
- [Read what a completion contract contains](https://provely.sh/contracts)
- [Read what a receipt proves](https://provely.sh/docs/receipts)
