Skip to main content

canic_host/build_provenance/
model.rs

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