Skip to content
61 changes: 41 additions & 20 deletions dag/gunbc/fleet_desired_admission.dag
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import gunbc.fleet_revision_acceptance {
required_ci_refusal_message,
default_branch_refusal_message,
}
import gunbc.fleet_desired_observe { observe_fleet_revision_relation, observe_fleet_desired_revision }
import gunbc.fleet_desired_observe { observe_fleet_revision_relation, observe_fleet_desired_revision, observe_local_tree_revision }
import gunbc.fleet_main_revision {
FleetDesiredAdvanceInput,
FleetDesiredExpectationRefusedInput,
Expand Down Expand Up @@ -271,7 +271,10 @@ data fleet_desired_authorized_action_shell_dissolution_trigger: DissolutionCondi
// "authorization produced nothing" -- a transport or writer failure -- from "authorization said
// do nothing". If a no-op could render empty, those two states would collide at the only place
// that can still tell them apart, and a dropped authorization would read as a converged fleet.
fn fleet_desired_authorized_action_script(action: FleetDesiredAuthorizedAction) -> NonEmptyStr {
fn fleet_desired_authorized_action_script(
action: FleetDesiredAuthorizedAction,
judge_source_observed: GitObjectId,
) -> NonEmptyStr {
match action {
FleetDesiredRemoteAdvance { accepted: to, expected_prior: prior } => {
let request = GitRemoteRefCasRequest {
Expand All @@ -286,14 +289,16 @@ fn fleet_desired_authorized_action_script(action: FleetDesiredAuthorizedAction)
" ", request.remote as String,
" ", git_remote_ref_cas_refspec(request: request) as String, "\n",
"echo \"[fleet-desired] admitted ", git_object_id_wire_hex(oid: to) as String,
" expected-prior ", git_object_id_wire_hex(oid: prior) as String, "\"\n",
" expected-prior ", git_object_id_wire_hex(oid: prior) as String,
" judge-source-observed ", git_object_id_wire_hex(oid: judge_source_observed) as String, "\"\n",
], "") as NonEmptyStr
}
FleetDesiredAlreadyConvergedAction { revision: rev } =>
join([
"set -eu\n",
"echo \"[fleet-desired] already converged at ",
git_object_id_wire_hex(oid: rev) as String,
" judge-source-observed ", git_object_id_wire_hex(oid: judge_source_observed) as String,
"; no ref mutation\"\n",
], "") as NonEmptyStr
FleetDesiredSupersededAction { accepted: acc, current: cur } =>
Expand All @@ -302,6 +307,7 @@ fn fleet_desired_authorized_action_script(action: FleetDesiredAuthorizedAction)
"echo \"[fleet-desired] superseded: accepted ",
git_object_id_wire_hex(oid: acc) as String,
" is an ancestor of the current ", git_object_id_wire_hex(oid: cur) as String,
" judge-source-observed ", git_object_id_wire_hex(oid: judge_source_observed) as String,
"; no ref mutation\"\n",
], "") as NonEmptyStr
}
Expand Down Expand Up @@ -361,24 +367,39 @@ func admit_fleet_desired_from_floor_event_wet() -> ProcessExit {
),
) {
AdmissionRefused { cause: why } => exit_failure(reason: why)
AdmissionActionAuthorized { action: action } => {
let wrote = Filesystem.Write(
path: fleet_desired_admission_authorized_action_path,
content: fleet_desired_authorized_action_script(action: action) as String,
)
if wrote.success {
ExitSuccess
} else {
exit_failure(
reason: join([
"fleet_desired_admission: the action was authorized but could not be written to ",
fleet_desired_admission_authorized_action_path,
" -- the absent file is the transport-failure signal and must never be read as a no-op: ",
wrote.error,
], ""),
)
AdmissionActionAuthorized { action: action } =>
match observe_local_tree_revision(repo: fleet_desired_admission_repo_root) {
Absent =>
exit_failure(
reason: join([
"fleet_desired_admission: the action was authorized, but the admission checkout's ",
"source revision could not be observed, so the receipt cannot record which source ",
"this run adjudicated from -- refusing to actuate rather than publish an ",
"unattributable action",
], ""),
)
Present { value: judge_source_observed } => {
let wrote = Filesystem.Write(
path: fleet_desired_admission_authorized_action_path,
content: fleet_desired_authorized_action_script(
action: action,
judge_source_observed: judge_source_observed,
) as String,
)
if wrote.success {
ExitSuccess
} else {
exit_failure(
reason: join([
"fleet_desired_admission: the action was authorized but could not be written to ",
fleet_desired_admission_authorized_action_path,
" -- the absent file is the transport-failure signal and must never be read as a no-op: ",
wrote.error,
], ""),
)
}
}
}
}
}
}
WorkflowRunEventMemberAbsent { member: m } =>
Expand Down
64 changes: 64 additions & 0 deletions dag/test/claim/fleet_desired_admission_witness_test.dag
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import gunbc.fleet_desired_admission_workflow { expected_fleet_desired_yml }

data fixture_prior_hex: String = "1111111111111111111111111111111111111111"
data fixture_candidate_hex: String = "2222222222222222222222222222222222222222"
data fixture_judge_hex: String = "4444444444444444444444444444444444444444"
data fixture_repo: String = "gunb-ai/gunbc"

fn fixture_oid(hex: String) -> GitObjectId {
Expand Down Expand Up @@ -340,6 +341,7 @@ test fn the_authorized_advance_carries_the_observed_prior_as_the_cas_expectation
accepted: fixture_oid(hex: fixture_candidate_hex),
expected_prior: fixture_oid(hex: fixture_prior_hex),
},
judge_source_observed: fixture_oid(hex: fixture_judge_hex),
) as String
string_contains(s: script, pattern: concat("--force-with-lease=refs/fleet/desired:", fixture_prior_hex))
&& string_contains(s: script, pattern: concat(fixture_candidate_hex, ":refs/fleet/desired"))
Expand All @@ -361,6 +363,7 @@ test fn the_receipt_names_the_expected_prior_beside_the_target() -> Bool {
accepted: fixture_oid(hex: fixture_candidate_hex),
expected_prior: fixture_oid(hex: fixture_prior_hex),
},
judge_source_observed: fixture_oid(hex: fixture_judge_hex),
) as String
string_contains(s: script, pattern: concat(concat("admitted ", fixture_candidate_hex), concat(" expected-prior ", fixture_prior_hex)))
}
Expand All @@ -374,12 +377,14 @@ test fn the_receipt_names_the_expected_prior_beside_the_target() -> Bool {
test fn a_no_op_action_still_renders_a_nonempty_script() -> Bool {
let converged = fleet_desired_authorized_action_script(
action: FleetDesiredAlreadyConvergedAction { revision: fixture_oid(hex: fixture_candidate_hex) },
judge_source_observed: fixture_oid(hex: fixture_judge_hex),
) as String
let superseded = fleet_desired_authorized_action_script(
action: FleetDesiredSupersededAction {
accepted: fixture_oid(hex: fixture_prior_hex),
current: fixture_oid(hex: fixture_candidate_hex),
},
judge_source_observed: fixture_oid(hex: fixture_judge_hex),
) as String
(string_length(s: converged) > 0) && (string_length(s: superseded) > 0)
}
Expand All @@ -389,12 +394,14 @@ test fn a_no_op_action_still_renders_a_nonempty_script() -> Bool {
test fn a_no_op_action_renders_no_ref_mutation() -> Bool {
let converged = fleet_desired_authorized_action_script(
action: FleetDesiredAlreadyConvergedAction { revision: fixture_oid(hex: fixture_candidate_hex) },
judge_source_observed: fixture_oid(hex: fixture_judge_hex),
) as String
let superseded = fleet_desired_authorized_action_script(
action: FleetDesiredSupersededAction {
accepted: fixture_oid(hex: fixture_prior_hex),
current: fixture_oid(hex: fixture_candidate_hex),
},
judge_source_observed: fixture_oid(hex: fixture_judge_hex),
) as String
!string_contains(s: converged, pattern: "git push")
&& !string_contains(s: superseded, pattern: "git push")
Expand Down Expand Up @@ -532,3 +539,60 @@ test fn the_emitted_admission_yaml_disables_the_shared_home_cache_on_its_setup_a
let after_toolchain = split(s: yml, delimiter: "setup-rust-toolchain").last()
string_contains(s: after_toolchain, pattern: "cache: false")
}

// WHAT THIS FIELD IS, AND WHAT IT IS NOT. The receipt records the revision of the SOURCE TREE the
// admission checkout was sitting on when it adjudicated -- nothing stronger. It is NOT the
// revision of the binary that ran (nothing embeds that yet), NOT the candidate being admitted,
// and NOT the workflow transport identity that GITHUB_WORKFLOW_SHA carries. Those four coincide
// in today's workflow only because the job checks out one tree, builds the deciding binary from
// it in the same job, and adjudicates in that same checkout -- a property of the CALLER, not of
// this function. They diverge the moment the binary is pinned or prebuilt, which is exactly the
// cut this recording exists to make falsifiable. The field is named for the observation, not for
// the inference, so that the later pinning work has something to contradict.
test fn the_advance_receipt_names_the_observed_judge_source_revision() -> Bool {
let script = fleet_desired_authorized_action_script(
action: FleetDesiredRemoteAdvance {
accepted: fixture_oid(hex: fixture_candidate_hex),
expected_prior: fixture_oid(hex: fixture_prior_hex),
},
judge_source_observed: fixture_oid(hex: fixture_judge_hex),
) as String
string_contains(s: script, pattern: concat(" judge-source-observed ", fixture_judge_hex))
}

// PRESENCE BEFORE DISTINCTNESS, AND THE FIRST CONJUNCT IS NOT REDUNDANT. An earlier form of this
// row asserted only the two negations. Both are satisfied VACUOUSLY by deleting the operand
// altogether, so the row returned PASS against a receipt carrying no judge field at all while its
// sibling above returned FAIL -- a claim that could not fail for the reason it existed. Caught by
// a deliberately-emptied receipt, not by review.
test fn the_observed_judge_source_is_present_and_distinct_from_target_and_prior() -> Bool {
let script = fleet_desired_authorized_action_script(
action: FleetDesiredRemoteAdvance {
accepted: fixture_oid(hex: fixture_candidate_hex),
expected_prior: fixture_oid(hex: fixture_prior_hex),
},
judge_source_observed: fixture_oid(hex: fixture_judge_hex),
) as String
string_contains(s: script, pattern: " judge-source-observed ")
&& !string_contains(s: script, pattern: concat(" judge-source-observed ", fixture_candidate_hex))
&& !string_contains(s: script, pattern: concat(" judge-source-observed ", fixture_prior_hex))
}

// A NO-OP IS ALSO AN ADJUDICATION. Both no-op arms carry the field too: "this source decided not
// to mutate" is exactly as attributable a decision as an advance, and recording it only on the
// mutating arm would leave the two most common outcomes unattributable.
test fn both_no_op_receipts_also_name_the_observed_judge_source() -> Bool {
let converged = fleet_desired_authorized_action_script(
action: FleetDesiredAlreadyConvergedAction { revision: fixture_oid(hex: fixture_candidate_hex) },
judge_source_observed: fixture_oid(hex: fixture_judge_hex),
) as String
let superseded = fleet_desired_authorized_action_script(
action: FleetDesiredSupersededAction {
accepted: fixture_oid(hex: fixture_prior_hex),
current: fixture_oid(hex: fixture_candidate_hex),
},
judge_source_observed: fixture_oid(hex: fixture_judge_hex),
) as String
string_contains(s: converged, pattern: concat(" judge-source-observed ", fixture_judge_hex))
&& string_contains(s: superseded, pattern: concat(" judge-source-observed ", fixture_judge_hex))
}