Skip to main content

Module served

Module served 

Source
Expand description

What a deployment actually serves, observed from outside and judged against the commit that was meant to be there.

A green publication job is not proof that a reader receives the build. GitHub’s own Pages build can fail on a branch that was pushed perfectly, a CDN can hold the previous bytes, and a workflow can succeed while publishing nothing. The only evidence that a deployment carries a commit is the deployment saying so: the site serves its build identity (/build.json, written by scripts/site-build from the tree it built) and this module reads it the way a visitor would.

Three things are kept apart, because collapsing any two of them is how a deployment gets reported as current when nobody measured it:

  • fetching is behind Fetch; the executable’s implementation runs curl with a fixed argument vector and a bounded time, and tests substitute a fake;
  • judging is judge, a pure function of what was served, the commit expected and what git knows about the two;
  • recording appends one Observation to a checkout-local file. It is not the committed evidence ledger: an observation of a later deployment committed into the tree it observes would describe a commit that no longer is the tree’s.

Freshness is containment, never age. A served commit proves every commit it contains, so an observation made an hour ago still proves a commit that was already on the site then, and an observation made a second ago proves nothing about a commit the site does not contain. judge is the same function whether the served identity was fetched now or read back from a record: re-judging a record against a newer expected commit is how a proof goes stale without anyone deciding that it has.

Only ServedVerdict::Served passes. Unreachable, malformed, dirty and undecidable are each a reason the question was not answered, and none of them is an answer of yes.

use majordomus_cli::served::ServedVerdict;
assert!(ServedVerdict::Served.passes());
assert!(!ServedVerdict::Unreachable.passes());
assert_eq!(ServedVerdict::Stale.as_str(), "stale");

Structs§

BuildIdentity
The build identity a deployment serves, as far as this module relies on it. Other fields of the served document are ignored rather than refused: the document is written by another program, and a field it adds is not a malformation.
Curl
curl, run with a fixed argument vector: the URL is an argument, never shell text, and the probe is bounded so that an unreachable host costs a known number of seconds.
GitAncestry
The Ancestry the executable uses: this repository’s own git, asked read-only.
Judgement
The judgement of one served identity against one expected commit, with its reason. The reason travels with the verdict so that every surface can say why without re-deriving it.
Malformed
Why a served body is not a build identity. The reason is the value: a refusal that says only “invalid” sends the reader to look at the site by hand.
Observation
One observation of one deployment, as recorded: what was asked, what was served, what was judged and when. Everything needed to judge it again later is in the record, which is what lets Observation::rejudge answer without probing.

Enums§

Fetched
What the probe received: a body, or nothing and the reason. Nothing received is carried as a value rather than an error, because “the site could not be reached” is an answer the judgement acts on.
ServedVerdict
What an observation says about the expected commit. Only ServedVerdict::Served is a proof; the other five are each a different reason the question was not answered yes.

Constants§

DEFAULT_IDENTITY
The identity file a site serves when nothing names another.
DEFAULT_PROBE_SECONDS
The longest a single probe may take, in seconds, when the caller names no bound.
OBSERVATIONS_PATH
Where observations are appended, repository-relative. Checkout-local and ignored.
OBSERVATION_SCHEMA
The schema every recorded observation carries.

Traits§

Ancestry
What git knows about commits, asked through a trait so that the judgement is testable without a repository. Both answers are three-valued: None is “git could not be asked”, which is not a false, and collapsing the two is how a record from a history this clone has never seen gets read as current.
Fetch
How a served identity is fetched. Behind a trait so that every verdict can be tested without a network, and so that the one implementation that does reach the network is a single, reviewable place.

Functions§

append
Appends obs to the checkout’s observation file, creating it. The file is checkout-local and never tracked, so a record of a deployment cannot end up describing the tree it is committed into.
check_base
Refuses a base URL that is not plain http(s) with a host. The value reaches curl as an argument, so this is not what keeps a shell safe; it is what keeps file:// and friends from being read as a deployment.
identity_url
The identity URL of a site: its base with the identity file appended.
judge
Judges what was served against expected, a full commit sha.
latest
The newest observation of deployment, if any. The newest is what a reader judges by; the older ones are the history of what the deployment has served.
observe
Probes base once and judges the result against expected, returning the record. Writes nothing: append is what keeps it.
read_all
Every readable observation of the checkout, oldest first, and the number of lines that could not be read. A torn or foreign line is counted, never silently dropped: a reader that cannot tell “nothing recorded” from “the record is damaged” acts on the wrong one.