Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T03:02:44.864Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

public_store.rs

243 lines · 8.1 KB · rust
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
Served at tenant.openagents/omega Member data and write actions are omitted.