Release input document
Reference: every field a release policy rule can read for a deployment.
The input document
Every evaluation gets an input document with set to and set to . Release and pull request inputs share a core (, , , , , , , , , , , , , , ); the fields below this point are the release subject's own section, plus that shared core:
{
"version": "prodgator.input/v1",
"subject": "release",
"evaluatedAt": "2026-09-28T15:30:00.000Z",
"repository": { "name": "acme/api", "id": "365246789" },
"commitSha": "4f2c1e0",
"commitSeenAt": "2026-09-28T15:28:00.000Z",
"commitAgeSeconds": 120,
"actor": { "login": "octocat", "providerUserId": "583231", "prodgatorUserId": "user_01H...", "groups": ["grp_release"], "isBot": false },
"checks": [{ "name": "test", "source": "check_run", "app": null, "status": "completed", "conclusion": "success", "url": null }],
"labels": ["release"],
"security": null,
"release": {
"deploymentId": "d_123",
"provider": "github",
"repository": "acme/api",
"environment": "production",
"workflow": "Deploy",
"runId": 123456789,
"commitSha": "4f2c1e0",
"branch": "main",
"releaseName": null,
"actor": { "login": "octocat", "providerUserId": "583231", "prodgatorUserId": "user_01H...", "groups": ["grp_release"], "isBot": false }
},
"github": {
"branch": "main",
"checks": [{ "name": "test", "status": "completed", "conclusion": "success" }],
"labels": ["release"],
"commitMessage": "Bump version",
"prTitle": "Release 1.4.0"
},
"approvals": [
{
"prodgatorUserId": "user_01H...",
"email": "jane@example.com",
"groups": ["group-id"],
"decision": "approved",
"at": "2026-09-28T15:20:00.000Z",
"providerLogin": "jane",
"commitSha": null
}
],
"aiAssisted": { "value": true, "tools": ["claude"], "signals": ["pull_request"], "current": true },
"settings": { "selfApproval": false, "reviewerForwarding": true },
"attestations": [
{
"id": "3f1c...",
"kind": "coverage",
"name": "unit",
"status": "pass",
"trusted": true,
"workflowRef": "acme/api/.github/workflows/ci.yml@refs/heads/main",
"jobWorkflowRef": "acme/platform/.github/workflows/build.yml@refs/tags/v2",
"workflowSha": "4f2c1e0b7a9d3c5e1f8a6b4d2c0e9f7a5b3d1c8e",
"jobWorkflowSha": "1b9e4c7d2f0a8e6b5c3d1f9a7e5c3b1d9f7a5e3c",
"eventName": "push",
"runId": "123456700",
"attempt": 1,
"job": "test",
"createdAt": "2026-09-28T15:10:00.000Z",
"data": { "lines": 87.5, "branches": null, "functions": null, "threshold": 80 }
}
],
"workflows": {
"supported": true,
"known": true,
"settled": true,
"runs": [{ "runId": "123456789", "workflow": "Deploy", "finished": false }],
"referenced": [
{
"path": "acme/platform/.github/workflows/build.yml",
"ref": "refs/tags/v2",
"sha": "1b9e4c7d2f0a8e6b5c3d1f9a7e5c3b1d9f7a5e3c",
"runId": "123456789",
"workflow": "Deploy"
}
]
},
"tickets": [],
"webhooks": []
}- , , , , , and are the shared core; is the same object as . and repeat and in the shared shape (Rego shared between subjects reads these; release-only Rego can keep reading ).
- is when Prodgator could not read facts from GitHub; and are then too.
- is when the deployment was created, and the whole number of seconds from then to . Both are when unknown. The Required checks rule counts its wait for checks to start from here.
- is when the person who started the deployment has not linked their GitHub account in Prodgator.
- lists the approver group ids of that linked account (empty when not linked), and is for a GitHub account of type or a login ending in . Inputs stored before these fields existed lack them. The Allowed actors rule reads them.
- holds each person's latest approval or rejection given in Prodgator, with the approver groups they belong to. is always here, since a release approval is per deployment, not per commit; it is set for a pull request approval.
- is reserved for findings introduced by the change and is until that ships.
- says whether the release ships AI-assisted changes; it is when your plan does not include AI impact (Business and Enterprise), no policy on the release has an AI-assisted changes rule, custom rules or Rego (it is only read then), or Prodgator could not read the release's history. is when it does. lists the AI tools found (, , , , , , , , or ). lists the kinds of evidence: (a shipped pull request was AI-assisted), (a shipped commit has an AI trailer) and (the labels of the pull request that produced the commit, read only when the history could not be). is once the release's changes were read. The AI-assisted changes rule reads it.
- holds the attestations sent by the Prodgator report action for , from any run and attempt, oldest first. Only the newest per kind, name, workflow file, reusable workflow file and value is included.
- holds the results sent through Any CI, in the same shape as , each with set to and set to . It is present only when a rule of the policy has the Count self-reported results from other CI option on, and it is when Prodgator could not read them. Stored policies that do not read it never see these results.
- In each attestation, and name the workflow file of the run that sent it and the commit of that file (GitHub's and token claims). When the job ran inside a reusable workflow, and name that reusable workflow and its commit ( and ); otherwise they are . GitLab attestations carry the pipeline configuration's commit () as ; Bitbucket attestations have for both SHAs, and so do attestations sent before Prodgator stored them.
- lists the reusable workflows the deployment's GitHub Actions run called, for the Required reusable workflow rule. Its fields are described in the pull request input document. For a release, holds the deployment's run and is GitHub's run id. is while Prodgator has not recorded the run's calls, and is for GitLab and Bitbucket deployments. It is when Prodgator could not read the run. has the fields listed in Run reports. It is without a commit SHA and when Prodgator could not read attestations.
- and are reserved and always empty for now.
Pull request policies read the same core plus their own section. See Pull request input document.
Release risk
Release inputs carry : , or when there is no rating for the deployment. is , or (the highest rating the deployment received, so regenerating cannot lower it), is when the rating was written, is the deployment it was written for, and is when it came from another deployment with the same code and checks. The summary text is never included. The Release risk rule reads it; treat as unknown, never as low risk.
says where the rating stands: ( is set), (being written, or it could not be read just now, so it may still arrive) or (it will not come without someone acting, or no policy reads it). Wait while it is rather than failing.
Change, lineage and evidence
Release inputs also carry , and . These are without release provenance in the plan (Business and above), or when the required facts cannot be read. can also be when the commit has no landed change record. Never interpret as a verified change or a passed promotion.
The top-level boolean is when a change or lineage read failed. When is , promotion rules use it to distinguish a read failure from release provenance missing from the plan.
Change
| Field | Meaning |
|---|---|
| , , or . | |
| Verification basis, including when the provider merged the checked head. | |
| Recorded bypass kinds, such as . | |
| , | Whether the bypass was expected or acknowledged; neither rewrites its verdict. |
| Why the change was acknowledged: , or ; when it was not acknowledged. Prodgator sets when a later change reverts the bypass, which does not make the bypassed commit safe to release. | |
| Time to the first successful protected deployment, or . | |
| Number of the pull request that produced the change, or for a direct push. | |
| Count of contained open unverified changes, excluding expected or acknowledged changes; when ancestry could not be checked. |
To require a verified change with no bypass, use the Verified change form rule. It reads these fields, handles missing or unreadable data, and links failures to Provenance.
Lineage
| Field | Meaning |
|---|---|
| , or . Pending collection is retried. | |
| , , | Whether the walk finished, why it stopped and whether any input was cut short. An incomplete or truncated walk must not pass. |
| Release first, then upstream deployments, pull requests and pushes, ordered by . | |
| Upstream deployment summaries, nearest first: , , , , , , . | |
| For ready lineage, the repository or organization fallback trace, or when no path applies. If a path applies but the release is off it, the trace has and no steps. identifies the setting used. | |
| Policy-defined traces keyed by a derived path key. Each also has , and . | |
| , or : release-policy or compliance override, user ID, time and unmet rule IDs or check names. The reason remains in the timeline and audit record. |
Each hop includes , , , , , (number, source and target branches, method and optional for a fork pull request), , , , (, , ), , , , , , , and . marks a hop whose source branch cannot meet a branch step; a verified fork pull request can still land a commit on its target branch. can be , , or . contains and when known.
Both trace shapes expose , , , , , , , and . is , or . Policy traces always set ; fallback traces set it to for an off-path release and can omit it for an on-path release. Each step carries branch, environment (and gate for a policy step), status, change ID, merge SHA, run ID and status, deployment ID and status, and time. Status is , , , , , , or .
At evaluation, distinct policy paths are traced against stored lineage. Keys have the form plus 24 hexadecimal characters derived from the canonical steps. Generated Rego refers only to ; it does not embed customer branch, environment or gate text. At most five distinct policy paths are traced per evaluation. A path beyond that limit has no trace and its rule returns .
Evidence
contains one aggregate per hop with its . covers the release backward until the first changed or unknown hop. covers the whole path, including changed content. All aggregates have:
| Field | Shape |
|---|---|
| , , , , | |
| , , , (name and lines); percentages are without reports | |
| , , , , | |
| , | |
| Count of ignored untrusted evidence rows |
Only trusted reports count toward tests, coverage and findings. Sources are deduplicated. Coverage takes the minimum; findings take the highest count per severity across distinct content groups. Zero counts without a report or scan do not prove evidence exists.
Example: UAT ran the released code
This adapts the promotion example to reject missing, incomplete and truncated lineage. It waits while collection is pending and requires UAT to have unchanged code and passing tests.
package prodgator.policy
lineage := object.get(input, "lineage", null)
lin := lineage if is_object(lineage) else := {}
uat := [e | some e in object.get(lin, "environments", []); lower(e.name) == "uat"]
status := "pending" if object.get(lin, "state", null) == "pending"
else := "pass" if {
lin.state == "ready"
lin.complete == true
lin.truncated == false
count(uat) == 1
uat[0].unchanged == true
uat[0].tested == true
}
else := "fail"
results := [{
"rule": "uat_unchanged",
"status": status,
"blocking": true,
"reason": "UAT must run the released code with passing tests",
"evidence": {"uat": uat}
}]