A stale install on one cypher silently produces different rollup numbers: the provincial run looks fine, and the bcfishpass parity diff then contains version drift as well as methodology drift, with no way to separate them afterwards. This is the #183 sibling-host parity hook, absorbed into link#246.
Arguments
- stamps
A data frame, one row per host, from
lnk_preflight_stamp().- n_expected
Number of hosts that were supposed to report. Required.
- keys
Fields that must be identical across hosts.
- forbid_na
Fields that may not be the literal
"NA"on any host.- forbid_dirty
Fail when any host's checkout is dirty.
- quiet
Suppress the human-readable report.
Details
Three properties, each of which fails toward stop:
Everybody answered.
n_expectedhas no default on purpose. A dropped ssh yields a short table, and a short table judged on its own terms produces "no mismatches found" — an affirmative claim of agreement among hosts that never replied.Nothing is unresolved. A field that is the literal
"NA"on any host is a failure, not a neutral.NA == NAis not agreement.Nothing is dirty. A SHA recorded against a dirty tree is a lie, the same position
lnk_stamp()already takes for packages.
Only then are the key fields compared, against row 1 (the dispatcher) as reference.
fresh_sha became a key in link#264 and link_sha did not. Until
then both were excluded together, on the joint grounds that link_sha
can only ever fail and fresh_sha could only ever pass vacuously
(NA == NA). Only the first half is still true. fresh_sha now
resolves on every host — from RemoteSha on the dispatcher, from the
env var a cypher's prep writes — and both routes name the same commit,
so it is the one field that proves every host is running the same
fresh build rather than the same version string. A cypher that
silently ran the image's fresh is exactly link#246, and it is a
version-and-SHA drift that fresh_version alone can miss.
link_sha stays excluded, unchanged: it is a real SHA on a load_all
dispatcher and NA on every pak-installed cypher, so keying on it
fails every legitimate run. repo_sha is the field that carries link's
cross-host identity — see lnk_preflight_stamp().
See also
Other preflight:
lnk_fanout_judge(),
lnk_preflight_fresh(),
lnk_preflight_stamp(),
lnk_preflight_vintage()
Examples
row <- function(host, ...) {
d <- list(host = host, link_version = "0.46.0", link_sha = "NA",
fresh_version = "0.33.0", fresh_sha = "7f12d99115b7",
repo_sha = "abc123def456", repo_dirty = "FALSE",
config_hash = "cfg012345678", fwapg_sha = "e6e1eb0aaaaa",
r_version = "4.4.1")
as.data.frame(utils::modifyList(d, list(...)), stringsAsFactors = FALSE)
}
agree <- rbind(row("m1"), row("cy-job1"))
lnk_preflight_parity(agree, n_expected = 2, quiet = TRUE)$ok
#> [1] TRUE
drift <- rbind(row("m1"), row("cy-job1", fresh_version = "0.31.0"))
lnk_preflight_parity(drift, n_expected = 2, quiet = TRUE)$offenders
#> [1] "cy-job1"
