pub struct ManifestProvenance {
pub build_git_sha: Option<String>,
pub build_lock_digest: Option<String>,
pub wire_crate_version: Option<String>,
pub store_schema_version: Option<String>,
}Expand description
Build facts a module DECLARES about its own binary at HELLO. The daemon
overlays process-identity evidence it alone can attest; the two halves are
served together via supervisor.provenance and never merged.
The canonical constructor form is a full 40-character lowercase hexadecimal
build_git_sha and a full 64-character lowercase hexadecimal
build_lock_digest; abbreviations are not conforming. The daemon’s HELLO
decoder intentionally remains lenient enough to relay older declarations,
so this construction contract is enforced by build_provenance rather
than by wire deserialization.
Honesty contract for constructors (ruled with the first adopters):
- Every field is a VERIFIED-AT-BUILD claim. No field is required: a module
may declare any subset, and omitting an inapplicable field is the honest
choice rather than inventing a value to fill it. Populate
build_git_shaonly from a value injected by the build/release pipeline (CK_BUILD_REVviaoption_env!guarded by the packaging path, or build.rs equivalent) — never from ambient env at an arbitrary consumer compile, which mints a provenance claim from an accident of whoever ran cargo. A builder that can determine whether the tree was clean may declare the sha regardless of whether a release pipeline exists. - Dirty or unstamped builds declare
Nonefor the affected fields. A populated field stops the reader asking; absent-and-honest beats present-and-best-effort. Absence is reported at two levels with two distinct words: a module that declared no provenance block at all readsunverifiable, while an omitted field inside a declared block is dropped from the wire and readsunavailable. So omitting a field never costs a module itsReportedstatus – declaration is decided by whether the manifest carried a block, not by which fields it filled. - Dirty-tree stamps are not canonical
build_git_shavalues. A pipeline that emits-dirtymust omit the affected field rather than pass that stamp to the canonical constructor. Stricter is better: cerebellum’s build.rs reports the commit ONLY when the tree was clean, on the argument that dirty bytes match no commit and a precise-looking wrong answer beats absence at being believed. - Two silent-when-wrong checks for any build-rev embedder (CEREB): does the builder know whether the tree was clean, and can its no-git sentinel (source-tarball builds) escape into a field parsed as a sha? Sentinels render as absence, never as a value.
- Fill fields FROM THE BUILD only: reading Cargo.lock or the wire crate version inside the manifest constructor describes the source tree sitting beside the running binary, not the binary — the exact claim this struct exists to avoid.
- Declare what you KNOW, not blanket-None (WERNI):
store_schema_versionneeds no pipeline — any module with a migration list can state its newest migration as fact, and a daemon comparing it against the store’s actual version sees a stale-binary mismatch directly. BlanketNonewhere a field is knowable wastes the field; blanket-fill where it is not mints a lie. Absence also beats sentinel values (CKCRED): omit the FIELD when BUILD_REV reads a builder sentinel (“unknown”, “unavailable”, “none”, any casing) — publishing the sentinel string as a fact is a well-formed lie shape validation cannot catch. Field omission, not block omission, is the target shape for SDK modules:wire_crate_versionis a compile-time constant of the linked crate, so a module using the SDK always has at least one honest fact andbuild_provenancereflects that by never returning an absent block. (Block absence remains meaningful on the wire — it readsunverifiable, the module made no claim — but it is the shape for non-adopters and proxied manifests, not a target for declarers; see #78.) The hazard in one sentence, for every referent and sentinel case alike: A PRESENT, WELL-FORMED FIELD STOPS THE READER ASKING — a value from the wrong domain and a sentinel from the wrong vocabulary are indistinguishable from a correct value to every check that inspects shape rather than meaning. - PROXIED MANIFESTS STAY None PERMANENTLY (CALLO): a process that
forwards another machine’s manifest cannot observe that build, and a
forwarded provenance claim is indistinguishable on the wire from a
verified one — filling it launders an unverifiable assertion. Same
reasoning as pinning a re-exported module’s trust_tier to Untrusted.
Record that at the construction site: injection-wiring sweeps grep for
provenance:and the obvious action at a re-export site is the wrong one.
Fields§
§build_git_sha: Option<String>§build_lock_digest: Option<String>§wire_crate_version: Option<String>REFERENT: the subc-protocol crate version linked into this binary
(subc_protocol::SUBC_PROTOCOL_CRATE_VERSION) — the fleet’s shared
wire vocabulary, one numbering space for every module. Never a
module’s own envelope/payload crate version: that is real information
in a different numbering space, and here it scores as a confident
wrong answer at any census gate. (QTA’s rule, learned live: a field
whose entire content is a referent cannot be documented by its
constraints — so the referent is stated here, where readers look.)
store_schema_version: Option<String>Implementations§
Source§impl ManifestProvenance
impl ManifestProvenance
pub fn validate(&self) -> Result<(), ManifestProvenanceError>
Trait Implementations§
Source§impl Clone for ManifestProvenance
impl Clone for ManifestProvenance
Source§fn clone(&self) -> ManifestProvenance
fn clone(&self) -> ManifestProvenance
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more