| 257 | /// ``` |
| 258 | #[must_use] |
| 259 | pub fn finalize( |
| 260 | self, |
| 261 | content: Vec<u8>, |
| 262 | provenance: Vec<Provenance>, |
| 263 | metadata_bytes: Vec<u8>, |
| 264 | ) -> Change { |
| 265 | let mut dependencies: Vec<Hash> = self.dependencies.into_iter().collect(); |
| 266 | dependencies.sort(); |
| 267 | |
| 268 | let mut extra_known: Vec<Hash> = self.extra_known.into_iter().collect(); |
| 269 | extra_known.sort(); |
| 270 | |
| 271 | let mut change = Change::with_file_ops( |
| 272 | self.header, |
| 273 | self.hunks, |
| 274 | self.file_ops, |
| 275 | content, |
| 276 | dependencies, |
| 277 | ); |
| 278 | change.hashed.extra_known = extra_known; |
| 279 | |
| 280 | // Set opaque metadata bytes (e.g., SessionEnvelope from atomic-agent) |
| 281 | if !metadata_bytes.is_empty() { |
| 282 | change.hashed.metadata = metadata_bytes; |
| 283 | } |
| 284 | |
| 285 | // Add AI provenance information |
| 286 | for entry in provenance { |
| 287 | change.add_provenance(entry); |
| 288 | } |
| 289 | |
| 290 | change |
| 291 | } |
| 292 | |
| 293 | /// Get the number of file operations collected. |
| 294 | #[must_use] |