Skip to repository content243 lines · 8.1 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T04:13:09.856Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitBrowse files
public_store.rs
1use std::{
2 fs,
3 io::{self, Write},
4 path::Path,
5};
6
7use app_identity::AppChannel;
8use atomic_write_file::AtomicWriteFile;
9use serde::de::DeserializeOwned;
10use thiserror::Error;
11
12use crate::{CompletionRecord, ContractError, IdentityManifest, KeyringLocator};
13
14#[derive(Debug, Error)]
15pub enum PublicStoreError {
16 #[error("public identity document violates the Omega contract")]
17 Contract(#[from] ContractError),
18 #[error("public identity document serialization failed")]
19 Serialization(#[from] serde_json::Error),
20 #[error("public identity document write failed")]
21 Io(#[from] io::Error),
22}
23
24pub fn write_identity_manifest(
25 path: impl AsRef<Path>,
26 manifest: &IdentityManifest,
27 channel: AppChannel,
28) -> Result<(), PublicStoreError> {
29 manifest.validate(channel)?;
30 write_public_document(path.as_ref(), manifest)
31}
32
33pub(crate) fn write_identity_manifest_for_locator(
34 path: impl AsRef<Path>,
35 manifest: &IdentityManifest,
36 locator: &KeyringLocator,
37) -> Result<(), PublicStoreError> {
38 manifest.validate_for_locator(locator)?;
39 write_public_document(path.as_ref(), manifest)
40}
41
42pub fn write_completion_record(
43 path: impl AsRef<Path>,
44 record: &CompletionRecord,
45 manifest: &IdentityManifest,
46 channel: AppChannel,
47) -> Result<(), PublicStoreError> {
48 record.validate_against(manifest, channel)?;
49 write_public_document(path.as_ref(), record)
50}
51
52pub(crate) fn write_completion_record_for_locator(
53 path: impl AsRef<Path>,
54 record: &CompletionRecord,
55 manifest: &IdentityManifest,
56 locator: &KeyringLocator,
57) -> Result<(), PublicStoreError> {
58 record.validate_against_locator(manifest, locator)?;
59 write_public_document(path.as_ref(), record)
60}
61
62pub fn read_identity_manifest(
63 path: impl AsRef<Path>,
64 channel: AppChannel,
65) -> Result<Option<IdentityManifest>, PublicStoreError> {
66 let Some(bytes) = read_public_document(path.as_ref())? else {
67 return Ok(None);
68 };
69 let manifest: IdentityManifest = serde_json::from_slice(&bytes)?;
70 manifest.validate(channel)?;
71 Ok(Some(manifest))
72}
73
74pub(crate) fn read_identity_manifest_for_locator(
75 path: impl AsRef<Path>,
76 locator: &KeyringLocator,
77) -> Result<Option<IdentityManifest>, PublicStoreError> {
78 let Some(bytes) = read_public_document(path.as_ref())? else {
79 return Ok(None);
80 };
81 let manifest: IdentityManifest = serde_json::from_slice(&bytes)?;
82 manifest.validate_for_locator(locator)?;
83 Ok(Some(manifest))
84}
85
86pub fn read_completion_record(
87 path: impl AsRef<Path>,
88 manifest: &IdentityManifest,
89 channel: AppChannel,
90) -> Result<Option<CompletionRecord>, PublicStoreError> {
91 let Some(bytes) = read_public_document(path.as_ref())? else {
92 return Ok(None);
93 };
94 let record: CompletionRecord = serde_json::from_slice(&bytes)?;
95 record.validate_against(manifest, channel)?;
96 Ok(Some(record))
97}
98
99pub(crate) fn read_completion_record_for_locator(
100 path: impl AsRef<Path>,
101 manifest: &IdentityManifest,
102 locator: &KeyringLocator,
103) -> Result<Option<CompletionRecord>, PublicStoreError> {
104 let Some(bytes) = read_public_document(path.as_ref())? else {
105 return Ok(None);
106 };
107 let record: CompletionRecord = serde_json::from_slice(&bytes)?;
108 record.validate_against_locator(manifest, locator)?;
109 Ok(Some(record))
110}
111
112pub(crate) fn read_json_document<T: DeserializeOwned>(
113 path: &Path,
114) -> Result<Option<T>, PublicStoreError> {
115 let Some(bytes) = read_public_document(path)? else {
116 return Ok(None);
117 };
118 Ok(Some(serde_json::from_slice(&bytes)?))
119}
120
121pub(crate) fn write_json_document(
122 path: &Path,
123 value: &impl serde::Serialize,
124) -> Result<(), PublicStoreError> {
125 write_public_document(path, value)
126}
127
128fn read_public_document(path: &Path) -> Result<Option<Vec<u8>>, PublicStoreError> {
129 match fs::read(path) {
130 Ok(bytes) => Ok(Some(bytes)),
131 Err(error) if error.kind() == io::ErrorKind::NotFound => Ok(None),
132 Err(error) => Err(error.into()),
133 }
134}
135
136pub(crate) fn remove_public_document(path: &Path) -> Result<(), PublicStoreError> {
137 match fs::remove_file(path) {
138 Ok(()) => Ok(()),
139 Err(error) if error.kind() == io::ErrorKind::NotFound => Ok(()),
140 Err(error) => Err(error.into()),
141 }
142}
143
144fn write_public_document(
145 path: &Path,
146 value: &impl serde::Serialize,
147) -> Result<(), PublicStoreError> {
148 let serialized = serde_json::to_vec_pretty(value)?;
149 if let Some(parent) = path.parent()
150 && !parent.as_os_str().is_empty()
151 {
152 fs::create_dir_all(parent)?;
153 }
154 let mut file = AtomicWriteFile::open(path)?;
155 file.write_all(&serialized)?;
156 file.write_all(b"\n")?;
157 file.commit()?;
158 Ok(())
159}
160
161#[cfg(test)]
162mod tests {
163 use serde::ser::Error as _;
164
165 use app_identity::AppChannel;
166
167 use super::*;
168 use crate::{IdentityRef, KeyringLocator, PublicIdentity, ReceiptRef};
169
170 const PUBLIC_KEY_HEX: &str = "f86c44a2de95d9149b51c6a29afeabba264c18e2fa7c49de93424a0c56947785";
171
172 #[test]
173 fn public_documents_are_written_atomically_and_round_trip() {
174 let temporary_directory = tempfile::tempdir().expect("create temporary directory");
175 let identity = PublicIdentity::from_public_key_hex(
176 IdentityRef::new("omega-test-identity").expect("valid fixture reference"),
177 PUBLIC_KEY_HEX,
178 )
179 .expect("valid fixture public key");
180 let receipt_ref = ReceiptRef::new("creation-receipt").expect("valid fixture reference");
181 let manifest = IdentityManifest::new(
182 identity,
183 KeyringLocator::for_channel(AppChannel::Dev),
184 vec![receipt_ref.clone()],
185 );
186 let completion = crate::CompletionRecord::new(&manifest, receipt_ref, AppChannel::Dev)
187 .expect("completion record");
188
189 let manifest_path = temporary_directory.path().join("identity.json");
190 let completion_path = temporary_directory.path().join("identity.complete.json");
191 write_identity_manifest(&manifest_path, &manifest, AppChannel::Dev)
192 .expect("write manifest");
193 write_completion_record(&completion_path, &completion, &manifest, AppChannel::Dev)
194 .expect("write completion");
195
196 let stored_manifest: IdentityManifest =
197 serde_json::from_slice(&fs::read(&manifest_path).expect("read stored manifest"))
198 .expect("parse stored manifest");
199 stored_manifest
200 .validate(AppChannel::Dev)
201 .expect("stored manifest remains valid");
202
203 let stored_completion: crate::CompletionRecord =
204 serde_json::from_slice(&fs::read(&completion_path).expect("read stored completion"))
205 .expect("parse stored completion");
206 assert_eq!(stored_completion, completion);
207 assert_eq!(
208 read_identity_manifest(&manifest_path, AppChannel::Dev).expect("read public manifest"),
209 Some(manifest.clone())
210 );
211 assert_eq!(
212 read_completion_record(&completion_path, &manifest, AppChannel::Dev)
213 .expect("read completion record"),
214 Some(completion)
215 );
216 }
217
218 #[test]
219 fn serialization_failure_preserves_existing_document() {
220 struct AlwaysFails;
221
222 impl serde::Serialize for AlwaysFails {
223 fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
224 where
225 S: serde::Serializer,
226 {
227 Err(S::Error::custom("intentional fixture failure"))
228 }
229 }
230
231 let temporary_directory = tempfile::tempdir().expect("create temporary directory");
232 let document_path = temporary_directory.path().join("identity.json");
233 fs::write(&document_path, b"existing public document")
234 .expect("write existing public document");
235
236 assert!(write_public_document(&document_path, &AlwaysFails).is_err());
237 assert_eq!(
238 fs::read(document_path).expect("read preserved public document"),
239 b"existing public document"
240 );
241 }
242}
243