Skip to main content

canic_host/build_provenance/
model.rs

1use std::path::PathBuf;
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6    canister_build::{CanisterArtifactBuildOutput, CanisterBuildProfile},
7    evidence_envelope::{
8        CommandProvenanceV1, EvidenceMessageV1, InputFingerprintV1, InputPathDisplayV1,
9    },
10};
11
12pub const BUILD_PROVENANCE_SCHEMA_ID: &str = "canic.build_provenance.v1";
13pub(super) const WASM_TARGET: &str = "wasm32-unknown-unknown";
14pub(super) const DIRTY_SUMMARY_ALGORITHM: &str = "git-status-porcelain-v1-z-sha256";
15
16///
17/// BuildProvenanceV1
18///
19#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
20pub struct BuildProvenanceV1 {
21    pub schema_version: u8,
22    pub generated_at: String,
23    pub canic_version: String,
24    pub command: CommandProvenanceV1,
25    pub build_status: BuildProvenanceStatusV1,
26    pub source: SourceProvenanceV1,
27    pub cargo: CargoProvenanceV1,
28    pub artifacts: Vec<ArtifactProvenanceV1>,
29    pub transforms: Vec<ArtifactTransformProvenanceV1>,
30    pub warnings: Vec<EvidenceMessageV1>,
31}
32
33///
34/// BuildProvenanceStatusV1
35///
36#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
37#[serde(rename_all = "snake_case")]
38pub enum BuildProvenanceStatusV1 {
39    Success,
40    Failed,
41    NotRecorded,
42}
43
44///
45/// SourceProvenanceV1
46///
47#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
48pub struct SourceProvenanceV1 {
49    pub schema_version: u8,
50    pub vcs: SourceVcsV1,
51    pub revision: Option<String>,
52    pub branch: Option<String>,
53    pub dirty: Option<bool>,
54    pub dirty_policy: SourceDirtyPolicyV1,
55    pub dirty_summary_digest: Option<String>,
56    pub dirty_summary_algorithm: Option<String>,
57}
58
59///
60/// SourceVcsV1
61///
62#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
63#[serde(rename_all = "snake_case")]
64pub enum SourceVcsV1 {
65    Git,
66    Unknown,
67}
68
69///
70/// SourceDirtyPolicyV1
71///
72#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
73#[serde(rename_all = "snake_case")]
74pub enum SourceDirtyPolicyV1 {
75    Clean,
76    DirtyRecorded,
77    Unknown,
78}
79
80///
81/// CargoProvenanceV1
82///
83#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
84pub struct CargoProvenanceV1 {
85    pub cargo_lock_sha256: Option<String>,
86    pub package_manifest_sha256: Option<String>,
87    pub package_name: String,
88    pub package_manifest: String,
89    pub package_metadata_fleet: String,
90    pub package_metadata_role: String,
91    pub rustc_version: Option<String>,
92    pub cargo_version: Option<String>,
93    pub target: Option<String>,
94    pub profile: String,
95    pub features: Vec<String>,
96    pub default_features: Option<bool>,
97    pub rustflags_digest: Option<String>,
98    pub rustflags_digest_algorithm: Option<String>,
99    pub cargo_config_fingerprints: Vec<InputFingerprintV1>,
100    pub build_script_inputs: BuildScriptInputStateV1,
101}
102
103///
104/// BuildScriptInputStateV1
105///
106#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
107#[serde(rename_all = "snake_case")]
108pub enum BuildScriptInputStateV1 {
109    NotRecorded,
110    Recorded,
111    Unknown,
112}
113
114///
115/// ArtifactProvenanceV1
116///
117#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
118pub struct ArtifactProvenanceV1 {
119    pub role: String,
120    pub fleet: String,
121    pub artifact_kind: ArtifactProvenanceKindV1,
122    pub path: Option<String>,
123    pub path_display: InputPathDisplayV1,
124    pub hash_algorithm: String,
125    pub sha256: String,
126    pub size_bytes: u64,
127    pub produced_by: String,
128}
129
130///
131/// ArtifactProvenanceKindV1
132///
133#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
134#[serde(rename_all = "snake_case")]
135pub enum ArtifactProvenanceKindV1 {
136    Wasm,
137    WasmGzip,
138    Candid,
139    Metadata,
140    Other,
141}
142
143///
144/// ArtifactTransformProvenanceV1
145///
146#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
147pub struct ArtifactTransformProvenanceV1 {
148    pub role: String,
149    pub transform: ArtifactTransformKindV1,
150    pub mode: ArtifactTransformModeV1,
151    pub tool: String,
152    pub tool_version: Option<String>,
153    pub outcome: ArtifactTransformOutcomeV1,
154}
155
156/// Artifact-changing operation selected by the host builder.
157#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
158#[serde(rename_all = "snake_case")]
159pub enum ArtifactTransformKindV1 {
160    Shrink,
161    CandidMetadata,
162}
163
164/// Admission mode for an artifact transform.
165#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
166#[serde(rename_all = "snake_case")]
167pub enum ArtifactTransformModeV1 {
168    Optional,
169}
170
171/// Recorded outcome of one artifact transform decision.
172#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
173#[serde(rename_all = "snake_case")]
174pub enum ArtifactTransformOutcomeV1 {
175    Applied,
176    ToolUnavailable,
177    NotRequested,
178}
179
180///
181/// BuildProvenanceRequest
182///
183#[derive(Clone, Debug)]
184pub struct BuildProvenanceRequest {
185    pub fleet: String,
186    pub role: String,
187    pub network: String,
188    pub build_network: String,
189    pub profile: CanisterBuildProfile,
190    pub workspace_root: PathBuf,
191    pub config_path: PathBuf,
192    pub output: CanisterArtifactBuildOutput,
193    pub command: CommandProvenanceV1,
194    pub generated_at: String,
195    pub canic_version: String,
196}