Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions dag/extdeps/github/workflow_runs.dag
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import std.dissolution { unbound_dissolution }
import std.decl_ref { decl_ref }
import std.algebra { Cons, Empty }
import std.resources { Network }
import std.serialization { Text }
import extdeps.transports.rest { RestResult }

// WorkflowJobRun.labels are read by gunbc.public_workload_census (observed_job_labels) to
Expand Down Expand Up @@ -194,6 +195,13 @@ fn workflow_job_attempt_filter_wire(f: WorkflowJobAttemptFilter) -> String {
// rendered name. The parenthetical of combination VALUES in axis order is the rendering this
// tree observed on those names; it is not a REST field. Standing is TranscribedUncited until
// GitHub's Jobs docs state that encoding.
//
// runner_name IS WHICH REGISTRATION TOOK THE JOB, and labels cannot say it. labels echo the job's
// runs-on, which every candidate runner had to match, so a job whose runs-on names a per-attempt
// label is evidence about which runners COULD serve it and nothing about which one DID. The job
// object publishes runner_name as string-or-null: null until a runner is assigned, so Absent here
// is GitHub's own "no runner yet", never "not read" (gunbc.runner.runner_qualification_dispatch
// reads it to refuse a run that never reached the attempt's runner).
type WorkflowJobRun {
id: Int
run_id: Int
Expand All @@ -202,6 +210,7 @@ type WorkflowJobRun {
status: WorkflowRunStatus
conclusion: WorkflowRunConclusion?
labels: List<String>
runner_name: String?
created_at: Timestamp?
started_at: Timestamp?
completed_at: Timestamp?
Expand All @@ -212,6 +221,22 @@ type WorkflowJobRunList {
jobs: List<WorkflowJobRun>
}

// THE RUN'S ARTIFACTS, as the Artifacts REST resource lists them
// (docs.github.com/en/rest/actions/artifacts#list-workflow-run-artifacts, X-GitHub-Api-Version
// 2026-03-10). Only the fields a consumer reads are modeled; the archive itself is a zip behind
// archive_download_url and is not decoded here.
type WorkflowRunArtifact {
id: Int
name: String
size_in_bytes: Int
expired: Bool
}

type WorkflowRunArtifactList {
total_count: Int
artifacts: List<WorkflowRunArtifact>
}

data workflow_job_name_matrix_parenthetical_standing: CitedFigureStanding = TranscribedUncited {
read_obligation: "docs.github.com/en/rest/actions/workflow-jobs (X-GitHub-Api-Version 2026-03-10) publishes Job.name as a string and does not document a matrix object or that a combination is encoded as a parenthetical of the combination values in axis order; jobs.<job_id>.name in workflow-syntax-for-github-actions likewise does not state that encoding. The parenthetical is the rendering observed on Job.name in this tree, not a deduced REST field",
}
Expand Down Expand Up @@ -442,4 +467,58 @@ service github.WorkflowRuns {
500 => GitHubErrorShape
}
}

operation ListRunArtifacts {
requires Network
input {
auth_token: Secret
owner: String
repo: String
run_id: String
per_page: Int = max_per_page
}
output {
result: WorkflowRunArtifactList
}
readonly
transport rest {
method: GET,
path: "/repos/\{owner\}/\{repo\}/actions/runs/\{run_id\}/artifacts",
query: { per_page: per_page }
}
response {
200 => WorkflowRunArtifactList
401 => GitHubErrorShape
403 => GitHubErrorShape
404 => GitHubErrorShape
500 => GitHubErrorShape
}
}

operation DownloadJobLogs {
requires Network
input {
auth_token: Secret
owner: String
repo: String
job_id: String
}
output {
log: String
}
readonly
transport rest {
method: GET,
path: "/repos/\{owner\}/\{repo\}/actions/jobs/\{job_id\}/logs",
response_format: Text
}
response {
200 => String
401 => GitHubErrorShape
403 => GitHubErrorShape
404 => GitHubErrorShape
410 => GitHubErrorShape
5xx => GitHubErrorShape
}
}
}
29 changes: 10 additions & 19 deletions dag/extdeps/github/workflows.dag
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@ import extdeps.ietf.http_semantics { POST }
import extdeps.github.github { default_api_base }
import extdeps.github.errors { GitHubErrorShape }
import std.credentials { EnvVar }
import std.types { CommitSha, List, NonEmptyStr }
import std.types { Map, NonEmptyStr, String }
import extdeps.external_authority { ExternalAuthority }
import extdeps.uri { Uri, Https }
import std.roster_frontier { FrontierRow, frontier_row_decl }
import std.dissolution { unbound_dissolution }
import std.decl_ref { decl_ref }
import std.resources { Network }
import extdeps.ietf.http_semantics { POST }
import extdeps.transports.rest { RestResult }
Expand Down Expand Up @@ -42,19 +39,13 @@ type WorkflowDispatchReceipt {
// WorkflowDispatchReceipt would fabricate a run that was refused. The owning workflow may be
// retriggered after diagnosis; this operation never assumes a git push created a run.
//
// FROZEN UPSTREAM SHAPE: tools.ci_heal_dispatch, the only production caller, is deleted. Restoring
// heal auto-dispatch does not consume this operation. `expected_healed_sha` is the `inputs`
// key GitHub accepts for this repository's workflow_dispatch contract; it is not a second heal
// policy and must not grow more heal-specific keys here. Disposition:
// create_dispatch_unconsumed_frontier_rows.

data create_dispatch_unconsumed_frontier_rows: List<FrontierRow> = [
frontier_row_decl(
ref: decl_ref(module_path: "extdeps.github.workflows", decl_name: "WorkflowDispatchReceipt"),
reason: "github.Workflows CreateDispatch and WorkflowDispatchReceipt are the cited REST shape with no production caller after tools.ci_heal_dispatch was deleted; frozen: no new heal-specific keys or auto-invoke rows",
dissolution: unbound_dissolution(description: "a production fold that is not heal auto-dispatch calls github.Workflows CreateDispatch, or CreateDispatch and WorkflowDispatchReceipt are deleted. NOT satisfied by restoring tools.ci_heal_dispatch, nor by a witness constructing WorkflowDispatchReceipt"),
)
]
// `inputs` IS THE UPSTREAM SHAPE: "Input keys and values configured in the workflow file", an
// object of at most 25 keys. It was once a single `expected_healed_sha` key -- one workflow's
// contract spelled into the interface, which is policy leaked into extdeps (DESIGN section 3). Which
// keys a dispatch carries is the dispatching workflow's fact and is passed as a parameter
// (gunbc.runner.runner_qualification_dispatch qualification_dispatch_inputs). Values are strings:
// GitHub coerces every workflow_dispatch input from its string form, and no caller here sends
// another JSON kind.

service github.Workflows {
config {
Expand All @@ -70,7 +61,7 @@ service github.Workflows {
repo: String
workflow_id: String
ref: String
expected_healed_sha: CommitSha
inputs: Map<String, String>
}
output {
workflow_run_id: Int
Expand All @@ -83,7 +74,7 @@ service github.Workflows {
headers: { "X-GitHub-Api-Version": workflows_api_version },
body: {
ref: ref,
inputs: { expected_healed_sha: expected_healed_sha }
inputs: inputs
}
}
response {
Expand Down
15 changes: 15 additions & 0 deletions dag/gunbc/auth/privileged_effect_census.dag
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,21 @@ data privileged_effect_census: List<PrivilegedEffectSite> = [
realized: RealizedFederatedGrant,
divergence_reason: none,
},
PrivilegedEffectSite {
site: site(module_path: "gunbc.runner.runner_qualification_dispatch", decl_name: "perform_qualification_dispatch"),
effect: PrivilegedEffect {
subject: "dispatch the qualification workflow with the delivered JIT registration's attempt label as its runs-on input, under the dispatching run's own GITHUB_TOKEN (actions: write), pre-approved under the dispatching run's authorization (operator ruling 2026-10-03)" as NonEmptyStr,
frequency: EveryProvision,
reversibility: ReversibleByReapply,
surface: ApiSurface,
workload_identity: WorkloadIdentityBindable { member: "the dispatching workflow run's GITHUB_TOKEN, minted by GitHub for that run's job and scoped to this repository" as NonEmptyStr },
minted_reach: MintsNoCredential,
billing: NoBillingConsequence,
witness_discharge: NoWitnessDischarge,
},
realized: RealizedFederatedGrant,
divergence_reason: none,
},
PrivilegedEffectSite {
site: site(module_path: "gunbc.runner.runner_jit_deregistration", decl_name: "ensure_jit_runner_deregistered"),
effect: PrivilegedEffect {
Expand Down
2 changes: 0 additions & 2 deletions dag/gunbc/census_closure_frontier.dag
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import extdeps.github.workflow_runs {
conclusion_authority_consolidation_frontier_rows,
}
import extdeps.github.app { modeled_webhook_event_vocabulary_frontier_rows }
import extdeps.github.workflows { create_dispatch_unconsumed_frontier_rows }
import gunbc.public_workload_census {
public_workload_census_replay_consumer_frontier_rows,
public_workload_census_run_attempt_consumer_frontier_rows,
Expand Down Expand Up @@ -110,7 +109,6 @@ fn census_closure_frontier_row_groups() -> List<List<FrontierRow>> {
endpoint_string_type_frontier_rows,
merge_state_graphql_transport_frontier_rows,
conclusion_authority_consolidation_frontier_rows,
create_dispatch_unconsumed_frontier_rows,
modeled_webhook_event_vocabulary_frontier_rows,
census_app_installation_route_frontier_rows,
census_app_installation_population_frontier_rows,
Expand Down
8 changes: 8 additions & 0 deletions dag/gunbc/public_workload_census.dag
Original file line number Diff line number Diff line change
Expand Up @@ -1020,6 +1020,7 @@ data candidate_biome_test: WorkloadCandidate = WorkloadCandidate {
status: Completed,
conclusion: Present { value: Success },
labels: ["depot-ubuntu-24.04-arm-16"],
runner_name: Present { value: "depot-1mw2k81zm2" },
created_at: Absent,
started_at: Present { value: "2026-09-04T16:03:32Z" },
completed_at: Present { value: "2026-09-04T16:08:13Z" },
Expand Down Expand Up @@ -1082,6 +1083,7 @@ data candidate_pdns_dnsdist_arm: WorkloadCandidate = WorkloadCandidate {
status: Completed,
conclusion: Present { value: Success },
labels: ["ubuntu-24.04-arm"],
runner_name: Present { value: "GitHub Actions 1001032445" },
created_at: Absent,
started_at: Present { value: "2026-09-04T09:57:28Z" },
completed_at: Present { value: "2026-09-04T10:07:09Z" },
Expand Down Expand Up @@ -1149,6 +1151,7 @@ data candidate_openobserve_arm_build: WorkloadCandidate = WorkloadCandidate {
status: Completed,
conclusion: Present { value: Success },
labels: ["ubicloud-standard-16-arm"],
runner_name: Present { value: "grgnv0w7chpy4gjd3ct967jfdk" },
created_at: Absent,
started_at: Present { value: "2026-09-01T10:02:21Z" },
completed_at: Present { value: "2026-09-01T10:27:44Z" },
Expand Down Expand Up @@ -1218,6 +1221,7 @@ data candidate_openobserve_amd64: WorkloadCandidate = WorkloadCandidate {
status: Completed,
conclusion: Present { value: Success },
labels: ["ubicloud-standard-8"],
runner_name: Present { value: "grz9sp8b0z7p5msnsp6wr1av9m" },
created_at: Absent,
started_at: Present { value: "2026-09-01T10:02:15Z" },
completed_at: Absent,
Expand Down Expand Up @@ -1271,6 +1275,7 @@ data candidate_openobserve_manifest: WorkloadCandidate = WorkloadCandidate {
status: Completed,
conclusion: Present { value: Success },
labels: ["ubicloud-standard-16-arm"],
runner_name: Present { value: "gr8d3jb981pt1k24ayh3gznkgj" },
created_at: Absent,
started_at: Present { value: "2026-09-01T10:28:12Z" },
completed_at: Absent,
Expand Down Expand Up @@ -1324,6 +1329,7 @@ data candidate_biome_test_windows: WorkloadCandidate = WorkloadCandidate {
status: Completed,
conclusion: Present { value: Success },
labels: ["depot-windows-2022-16"],
runner_name: Present { value: "depot-51t7207c32" },
created_at: Absent,
started_at: Present { value: "2026-09-04T16:03:31Z" },
completed_at: Present { value: "2026-09-04T16:13:50Z" },
Expand Down Expand Up @@ -1371,6 +1377,7 @@ data candidate_biome_test_macos: WorkloadCandidate = WorkloadCandidate {
status: Completed,
conclusion: Present { value: Success },
labels: ["depot-macos-latest"],
runner_name: Present { value: "depot-bl6zht5z75" },
created_at: Absent,
started_at: Present { value: "2026-09-04T16:08:06Z" },
completed_at: Absent,
Expand Down Expand Up @@ -1416,6 +1423,7 @@ data candidate_openobserve_summary: WorkloadCandidate = WorkloadCandidate {
status: Completed,
conclusion: Present { value: Success },
labels: ["ubuntu-latest"],
runner_name: Present { value: "GitHub Actions 1000683105" },
created_at: Absent,
started_at: Present { value: "2026-09-01T10:29:11Z" },
completed_at: Absent,
Expand Down
1 change: 1 addition & 0 deletions dag/gunbc/runner/runner_jit_perform.dag
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ fn dispatch_jit_mint(
decl_ref(module_path: "gunbc.runner_microvm_slot_controller", decl_name: "attempt_dispatch"),
decl_ref(module_path: "test.claim.github_app_registry", decl_name: "dispatched"),
decl_ref(module_path: "test.claim.github_app_registry", decl_name: "witness_jit_dispatch_refuses_when_the_attempt_binding_is_deferred"),
decl_ref(module_path: "test.claim.github_app_registry", decl_name: "host_unit_dispatched"),
] {
match plan_jit_mint(
binding: binding,
Expand Down
Loading