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
2 changes: 2 additions & 0 deletions .github/workflows/fleet-converge.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Generated by gunbc.fleet_converge_workflow expected_fleet_converge_yml — do not hand-edit.
# Authority: gunbc.fleet_converge_workflow fleet_converge_workflow; regen via tools.generated_artifact_gate main_wet.
name: fleet-converge
run-name: fleet-converge ${{ inputs.mode }} ${{ inputs.host }} nonce=${{ inputs.transaction_nonce }}
on:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/fleet-desired.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Generated by gunbc.fleet_desired_admission_workflow expected_fleet_desired_yml — do not hand-edit.
# Authority: gunbc.fleet_desired_admission_workflow fleet_desired_admission_workflow; regen via tools.generated_artifact_gate main_wet.
name: fleet-desired
on:
workflow_run:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/witnesses.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Generated by gunbc.witness_floor_workflow expected_witness_floor_yml — do not hand-edit.
# Authority: gunbc.witness_floor_workflow witness_floor_workflow; regen via tools.generated_artifact_gate main_wet.
name: witnesses
on:
workflow_dispatch:
Expand Down
4 changes: 3 additions & 1 deletion dag/gunbc/fleet/fleet_converge_workflow.dag
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,9 @@ fn fleet_converge_yml_after_toolchain_admission() -> FleetConvergeYamlGeneration
JobTimeoutExceedsCeiling { minutes: _, ceiling: _ } =>
FleetConvergeYamlGenerationRefused { reason: "fleet-converge job backstop timeout exceeds extdeps.github.actions max_job_timeout_minutes — split the job or reduce a tier's per-step budget, do not raise past the platform ceiling (see gunbc_ci_fleet_job_backstop_timeout_note in gunbc.fleet_workflow_steps)" }
JobTimeoutWithinCeiling { minutes: _ } =>
FleetConvergeYamlGenerated { content: serialize_yaml(v: project_workflow_to_yaml(workflow: fleet_converge_workflow)) }
FleetConvergeYamlGenerated {
content: serialize_yaml(v: project_workflow_to_yaml(workflow: fleet_converge_workflow))
}
}
} else {
FleetConvergeYamlGenerationRefused { reason: fleet_converge_capability_closure_refusal }
Expand Down
1 change: 0 additions & 1 deletion dag/gunbc/generated_artifact.dag
Original file line number Diff line number Diff line change
Expand Up @@ -222,4 +222,3 @@ fn artifact_eq(a: GeneratedArtifact, b: GeneratedArtifact) -> Bool {
fn registry_contains(a: GeneratedArtifact) -> Bool {
any(generated_artifact_registry, x => artifact_eq(a: x, b: a))
}

33 changes: 32 additions & 1 deletion dag/gunbc/generated_artifact_emit.dag
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,16 @@ import gunbc.generated_artifact {
Stage0CratePartitionGeneratedDagArtifact, Stage0ExecutableAssemblyGeneratedDagArtifact,
V1InterpreterDispatchGeneratedRsArtifact,
artifact_path,
artifact_commit_policy,
CommitRequired, NotCommitted,
GitProtocol, GithubActionsWorkflow, ProjectDocumentation, HostReconciler,
committed_generated_artifacts
}
import gunbc.generated_workflow_provenance {
generated_workflow_provenance_header,
GeneratedWorkflowProvenanceHeaderProduced,
GeneratedWorkflowProvenanceHeaderNotApplicable,
}
import gunbc.fleet_converge_workflow { expected_fleet_converge_yml, FleetConvergeYamlGenerated, FleetConvergeYamlGenerationRefused }
import gunbc.fleet_desired_admission_workflow { expected_fleet_desired_yml, FleetDesiredGenerationOutcome, FleetDesiredGenerated, FleetDesiredGenerationRefused }
import gunbc.witness_floor_workflow { expected_witness_floor_yml, WitnessFloorGenerationOutcome, WitnessFloorGenerated, WitnessFloorGenerationRefused }
Expand Down Expand Up @@ -54,7 +62,7 @@ fn artifact_generated(content: String) -> ArtifactGenerationOutcome {
ArtifactGenerated { content: content }
}

fn artifact_generate(a: GeneratedArtifact) -> ArtifactGenerationOutcome {
fn artifact_generate_unadorned(a: GeneratedArtifact) -> ArtifactGenerationOutcome {
match a {
WitnessFloorYamlArtifact => match expected_witness_floor_yml() {
WitnessFloorGenerated { content } => artifact_generated(content: content)
Expand Down Expand Up @@ -110,6 +118,29 @@ fn artifact_generate(a: GeneratedArtifact) -> ArtifactGenerationOutcome {
}
}

// One bytes boundary owns workflow provenance. A workflow admitted by the commit-policy registry
// without a provenance projection refuses here; non-workflow artifacts pass through unchanged.
// This is a rung-3 wall, not a rung-4 constructor removal: the inconsistent pair remains writable
// in the two authorities, but it cannot produce committed workflow bytes.
fn artifact_generate(a: GeneratedArtifact) -> ArtifactGenerationOutcome {
let generated = artifact_generate_unadorned(a: a)
match generated_workflow_provenance_header(a: a) {
GeneratedWorkflowProvenanceHeaderProduced { content: header } => match generated {
ArtifactGenerated { content } => artifact_generated(content: concat(header, content))
ArtifactGenerationRefused { reason } => ArtifactGenerationRefused { reason: reason }
}
GeneratedWorkflowProvenanceHeaderNotApplicable => match artifact_commit_policy(a: a) {
CommitRequired { consumer: GithubActionsWorkflow } => ArtifactGenerationRefused {
reason: "GithubActionsWorkflow artifact has no generated-workflow provenance projection"
}
CommitRequired { consumer: GitProtocol } => generated
CommitRequired { consumer: ProjectDocumentation } => generated
CommitRequired { consumer: HostReconciler } => generated
NotCommitted => generated
}
}
}

// P0 (operator-directed, 2026-08-05; loyal-ram-550 review of #7823): takes the ALREADY-COMPUTED
// generation outcome rather than calling artifact_generate itself. The two variants whose extra
// check depends on generation success (Stage0EmitPlanGeneratedDagArtifact,
Expand Down
53 changes: 53 additions & 0 deletions dag/gunbc/generated_workflow_provenance.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
module gunbc.generated_workflow_provenance

import std.types { String }
import gunbc.generated_artifact {
GeneratedArtifact,
WitnessFloorYamlArtifact,
FleetConvergeYamlArtifact,
FleetDesiredAdmissionYamlArtifact,
}

// A generated workflow is reviewed at the bytes boundary, where its producing .dag graph is not
// visible. Keep the provenance in that boundary rather than asking a reviewer to infer it from the
// path or from a separate generated-artifact roster. The generator and authority are parameters
// because they are different facts; the header's spelling alone is shared.
type GeneratedWorkflowProvenanceHeader
= GeneratedWorkflowProvenanceHeaderProduced { content: String }
| GeneratedWorkflowProvenanceHeaderNotApplicable

type GeneratedWorkflowProvenance {
generator: String
authority: String
}

fn generated_workflow_provenance(a: GeneratedArtifact) -> GeneratedWorkflowProvenance? {
match a {
WitnessFloorYamlArtifact => Present { value: GeneratedWorkflowProvenance {
generator: "gunbc.witness_floor_workflow expected_witness_floor_yml",
authority: "gunbc.witness_floor_workflow witness_floor_workflow",
} }
FleetConvergeYamlArtifact => Present { value: GeneratedWorkflowProvenance {
generator: "gunbc.fleet_converge_workflow expected_fleet_converge_yml",
authority: "gunbc.fleet_converge_workflow fleet_converge_workflow",
} }
FleetDesiredAdmissionYamlArtifact => Present { value: GeneratedWorkflowProvenance {
generator: "gunbc.fleet_desired_admission_workflow expected_fleet_desired_yml",
authority: "gunbc.fleet_desired_admission_workflow fleet_desired_admission_workflow",
} }
_ => none
}
}

fn generated_workflow_provenance_header(a: GeneratedArtifact) -> GeneratedWorkflowProvenanceHeader {
match generated_workflow_provenance(a: a) {
Absent => GeneratedWorkflowProvenanceHeaderNotApplicable
Present { value: provenance } => GeneratedWorkflowProvenanceHeaderProduced {
content: join([
concat("# Generated by ", concat(provenance.generator, " — do not hand-edit.")),
concat("# Authority: ", concat(provenance.authority, "; regen via tools.generated_artifact_gate main_wet.")),
""
], "\n")
}
}
}
9 changes: 9 additions & 0 deletions dag/gunbc/non_fold_residue.dag
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ data nfr_reason_acceptance_verdict_append: String = "one-variant append over Dag

data nfr_dissolve_acceptance_verdict_append: DissolutionCondition = unbound_dissolution(description: "the verdict is assembled once from the receipt's derived outcome partition (first and further labels computed together) rather than appended one label at a time, so the two append fns have no caller and delete with their rows — or the two matches become total over the three verdict arms")

data nfr_reason_generated_workflow_provenance_projection: String = "subset projection over GeneratedArtifact: the three workflow artifact identities carry provenance and every non-workflow artifact shares one Absent arm. Enumerating the non-workflow variants would copy a live population beside the generated-artifact commit-policy registry. The production join in generated_artifact_emit refuses GeneratedWorkflowProvenanceHeaderNotApplicable whenever artifact_commit_policy says GithubActionsWorkflow, so omission on a future workflow admission is refused even though the inconsistent pair remains writable in the two authorities. This join does not adjudicate whether a present projected generator agrees with the actual producer; that disagreement class remains open until the projection is fused with generation. Declared when the required nfr_roster_receipt first exercised the new projection on #9954, so the ratchet re-arms with the site."

data nfr_dissolve_generated_workflow_provenance_projection: DissolutionCondition = unbound_dissolution(description: "the generated-artifact registry admission for GithubActionsWorkflow carries provenance fused with its generating dispatch, so the artifact-visible citation is derivable only from the actual producer and neither an omitted nor a disagreeing provenance row is constructible; emission consumes that refined workflow-artifact declaration without projecting from the full GeneratedArtifact coproduct, and this wildcard match deletes with its row")

data non_fold_residue_frontier: List<FrontierRow> = [
FrontierRow {
subject: PathSubject { path: "dag/gunbc/dispatch_selection.dag::offer_matches_request_shape" },
Expand Down Expand Up @@ -355,6 +359,11 @@ data non_fold_residue_frontier: List<FrontierRow> = [
reason: nfr_reason_land_red_era,
dissolution: nfr_dissolve_owning_fold,
},
FrontierRow {
subject: PathSubject { path: "dag/gunbc/generated_workflow_provenance.dag::generated_workflow_provenance" },
reason: nfr_reason_generated_workflow_provenance_projection,
dissolution: nfr_dissolve_generated_workflow_provenance_projection,
},
FrontierRow {
subject: PathSubject { path: "dag/gunbc/commit_workflow.dag::commit_workflow_surface_eq" },
reason: nfr_reason_land_red_era,
Expand Down
4 changes: 3 additions & 1 deletion dag/gunbc/witness/witness_floor_workflow.dag
Original file line number Diff line number Diff line change
Expand Up @@ -2052,7 +2052,9 @@ fn expected_witness_floor_yml() -> WitnessFloorGenerationOutcome {
WitnessFloorGenerationRefused { reason: toolchain_home_refusal_reason(job_id: j, refusal: r) }
WorkflowToolchainHomesAdmitted =>
if witness_floor_capability_closure_holds() && build_lane_capability_closure_holds() && rust_unit_tests_capability_closure_holds() && fabric_evidence_capability_closure_holds() && emit_copy_qualification_capability_closure_holds() && required_lanes_gate_is_renderable() {
WitnessFloorGenerated { content: serialize_yaml(v: project_workflow_to_yaml(workflow: witness_floor_workflow)) }
WitnessFloorGenerated {
content: serialize_yaml(v: project_workflow_to_yaml(workflow: witness_floor_workflow))
}
} else {
WitnessFloorGenerationRefused { reason: witness_floor_capability_closure_refusal_reason }
}
Expand Down
Loading