Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T01:55:00.731Z 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

omega_harness.rs

489 lines · 19.3 KB · rust
1//! Harness maintenance with pinning and provenance. `OMEGA-DELTA-0025`,
2//! omega#81.
3//!
4//! Omega wraps harnesses it did not build — `codex-acp` and every other ACP
5//! registry agent — and those harnesses run with the tool permissions of the
6//! thread that started them. Upstream resolves whichever version the registry
7//! document currently advertises, downloads it, and runs it. There is no record
8//! of which bytes ran, and no way for an owner to say *not that one*.
9//!
10//! This crate is the decision layer for both halves:
11//!
12//! * **Pins.** A ledger on disk freezes a harness at a version *and* at the
13//!   digest of the tree that version installed. It is re-read on every
14//!   decision, so it survives a restart by construction rather than by
15//!   discipline, and an unreadable ledger refuses rather than reads as empty.
16//! * **Provenance.** Every maintenance action produces a receipt bound to the
17//!   SHA-256 of the installed tree, measured by this host. A record that
18//!   predates the digest — an installation from an earlier Omega, a log line
19//!   from a schema this build does not know — decodes, reports its provenance
20//!   as unavailable, and is refused. Nothing is backfilled.
21//!
22//! It is a leaf: `serde`, `serde_json`, `sha2` and nothing else. The filesystem
23//! and the GPUI entities live in `crates/project/src/agent_server_store.rs`,
24//! which is the only caller that enforces any of this.
25
26mod front_door;
27mod measured;
28mod pins;
29mod receipt;
30
31pub use front_door::{
32    HarnessDistribution, HarnessFrontDoorState, PinControl, harness_front_door_state,
33};
34pub use measured::MeasuredDigest;
35pub use pins::{
36    HARNESS_PIN_LEDGER_FILE_NAME, HARNESS_PIN_LEDGER_SCHEMA, HarnessPin, HarnessPinLedger,
37    HarnessPinLedgerError, MAX_HARNESS_PINS, decode_harness_pin_ledger, encode_harness_pin_ledger,
38};
39pub use receipt::{
40    ADMITTED_MAINTENANCE_ACTIONS, CandidateArtifact, HARNESS_MAINTENANCE_LOG_FILE_NAME,
41    HARNESS_MAINTENANCE_RECEIPT_SCHEMA, HarnessMaintenanceReceipt,
42    HarnessMaintenanceReceiptError, HarnessMaintenanceRecord, InstallationProvenance,
43    MAX_HARNESS_REF_LEN, MAX_HARNESS_TIMESTAMP_MS, MaintenanceAction, MaintenanceAffordance,
44    MaintenanceDecision, MaintenanceOutcome, MaintenanceOutcomeInput, MaintenanceRefusal,
45    PinState, ProvenanceGap, ProvenanceVerdict, admits_package_manager_launch, admits_version,
46    build_harness_maintenance_receipt, decide_maintenance, decode_harness_maintenance_receipt,
47    decode_harness_maintenance_record, receipt_for_decision, update_affordance,
48    verify_installation,
49};
50
51/// The pin ledger as the enforcement path found it.
52///
53/// Three states, not two. "The file is not there" and "the file is there and I
54/// cannot read it" are different facts about a machine, and collapsing them is
55/// how corrupting one file would silently unfreeze every harness on it.
56#[derive(Clone, Debug, PartialEq, Eq)]
57pub enum LoadedPinLedger {
58    /// No ledger file exists. Nothing is frozen.
59    Absent,
60    Loaded(HarnessPinLedger),
61    /// A ledger file exists and does not parse.
62    Unreadable(HarnessPinLedgerError),
63}
64
65impl LoadedPinLedger {
66    /// Interpret the ledger file's contents.
67    ///
68    /// `None` is the file not existing. Anything else is bytes that have to
69    /// parse.
70    #[must_use]
71    pub fn read(contents: Option<&str>) -> Self {
72        match contents {
73            None => Self::Absent,
74            Some(text) => match decode_harness_pin_ledger(text) {
75                Ok(ledger) => Self::Loaded(ledger),
76                Err(error) => Self::Unreadable(error),
77            },
78        }
79    }
80
81    /// What this ledger says about one harness.
82    #[must_use]
83    pub fn pin_state(&self, harness_id: &str) -> PinState<'_> {
84        match self {
85            Self::Absent => PinState::Unpinned,
86            Self::Unreadable(_) => PinState::Unreadable,
87            Self::Loaded(ledger) => match ledger.pin(harness_id) {
88                Some(pin) => PinState::Pinned(pin),
89                None => PinState::Unpinned,
90            },
91        }
92    }
93
94    /// The ledger, when there is one to edit.
95    #[must_use]
96    pub fn ledger(&self) -> Option<&HarnessPinLedger> {
97        match self {
98            Self::Loaded(ledger) => Some(ledger),
99            Self::Absent | Self::Unreadable(_) => None,
100        }
101    }
102}
103
104/// One receipt, as a line of the append-only log.
105///
106/// Serialising through the typed receipt rather than the caller's document
107/// keeps the log's lines and the contract's shape the same thing.
108pub fn receipt_log_line(receipt: &HarnessMaintenanceReceipt) -> String {
109    let mut line = serde_json::to_string(receipt).unwrap_or_default();
110    line.push('\n');
111    line
112}
113
114/// The most recent record covering one harness, read out of the log.
115///
116/// Unreadable lines are not skipped past. If the newest line naming this
117/// harness is one this build cannot read, that is the answer — reaching further
118/// back for an older line this build *can* read would report provenance from
119/// before the thing it cannot read happened.
120#[must_use]
121pub fn latest_record_for(log: &str, harness_id: &str) -> InstallationProvenance {
122    let harness_ref = format!("harness.{harness_id}");
123    for line in log.lines().rev() {
124        let line = line.trim();
125        if line.is_empty() {
126            continue;
127        }
128        match decode_harness_maintenance_record(line) {
129            Ok(HarnessMaintenanceRecord::Attested(receipt)) => {
130                if receipt.harness_ref == harness_ref {
131                    return InstallationProvenance::Recorded(HarnessMaintenanceRecord::Attested(
132                        receipt,
133                    ));
134                }
135            }
136            Ok(HarnessMaintenanceRecord::ProvenanceUnavailable { schema }) => {
137                // A record whose schema this build does not know may or may not
138                // be about this harness — the field that would say is part of a
139                // shape this build cannot read. Treating it as "not about us"
140                // would let a future Omega's records be silently ignored, so it
141                // is reported once the reader reaches it.
142                if line.contains(&harness_ref) {
143                    return InstallationProvenance::Recorded(
144                        HarnessMaintenanceRecord::ProvenanceUnavailable { schema },
145                    );
146                }
147            }
148            Err(_) => continue,
149        }
150    }
151    InstallationProvenance::Unattested
152}
153
154#[cfg(test)]
155mod tests {
156    use super::*;
157
158    const HOST: &str = "host.omega.device-alpha";
159    const NOW: u64 = 1_784_894_400_000;
160
161    fn measured(bytes: &[u8]) -> MeasuredDigest {
162        MeasuredDigest::measure(bytes)
163    }
164
165    fn scratch_dir(name: &str) -> std::path::PathBuf {
166        let dir = std::env::temp_dir().join(format!("omega-harness-{name}-{}", std::process::id()));
167        std::fs::remove_dir_all(&dir).ok();
168        std::fs::create_dir_all(&dir).expect("scratch directory");
169        dir
170    }
171
172    // -------------------------------------------------------------------
173    // The pin survives a restart
174    // -------------------------------------------------------------------
175
176    /// The restart law, through a real file.
177    ///
178    /// The enforcement path holds no ledger between calls: it reads this file
179    /// every time it decides. "Survives a restart" is therefore the same
180    /// statement as "the bytes on disk still decide", which is what this
181    /// asserts — a second, independent read of the same path refuses the update
182    /// the first one refused.
183    #[test]
184    fn a_pin_taken_before_a_restart_is_read_back_after_one() {
185        let dir = scratch_dir("restart");
186        let path = dir.join(HARNESS_PIN_LEDGER_FILE_NAME);
187        let installed = measured(b"codex-acp 0.9.4 tree");
188
189        // Session one: the owner pins the installed version.
190        let mut ledger = HarnessPinLedger::empty();
191        ledger.set_pin("codex-acp", "0.9.4", &installed);
192        std::fs::write(&path, encode_harness_pin_ledger(&ledger).expect("encodes"))
193            .expect("the ledger is written");
194
195        // Session two: a different process, holding nothing, reads the file.
196        let reloaded = LoadedPinLedger::read(Some(
197            &std::fs::read_to_string(&path).expect("the ledger is still there"),
198        ));
199        let candidate = measured(b"codex-acp 0.9.5 tree");
200        let decision = decide_maintenance(
201            reloaded.pin_state("codex-acp"),
202            CandidateArtifact::Measured {
203                version: "0.9.5",
204                digest: &candidate,
205            },
206        );
207        assert_eq!(
208            decision.refusal().map(MaintenanceRefusal::reason_class),
209            Some("pinned_version"),
210            "a pin that does not outlive the process is not a pin"
211        );
212
213        // And the same file still permits the version it froze.
214        assert!(
215            decide_maintenance(
216                reloaded.pin_state("codex-acp"),
217                CandidateArtifact::Measured {
218                    version: "0.9.4",
219                    digest: &installed,
220                },
221            )
222            .is_permitted()
223        );
224
225        std::fs::remove_dir_all(&dir).ok();
226    }
227
228    /// Removing the ledger file unfreezes; corrupting it does not.
229    #[test]
230    fn a_missing_ledger_is_unpinned_and_a_corrupt_one_is_not() {
231        assert_eq!(
232            LoadedPinLedger::read(None).pin_state("codex-acp"),
233            PinState::Unpinned
234        );
235        assert_eq!(
236            LoadedPinLedger::read(Some("{ truncated")).pin_state("codex-acp"),
237            PinState::Unreadable
238        );
239        assert_eq!(
240            LoadedPinLedger::read(Some(r#"{"schema":"something.else","pins":[]}"#))
241                .pin_state("codex-acp"),
242            PinState::Unreadable
243        );
244    }
245
246    // -------------------------------------------------------------------
247    // The log
248    // -------------------------------------------------------------------
249
250    fn applied_line(harness: &str, version: &str, digest: &MeasuredDigest, at: u64) -> String {
251        receipt_log_line(
252            &build_harness_maintenance_receipt(
253                HOST,
254                harness,
255                at,
256                MaintenanceAction::Update,
257                &MaintenanceOutcomeInput::Applied { version, digest },
258            )
259            .expect("emits"),
260        )
261    }
262
263    #[test]
264    fn the_log_reports_the_newest_record_for_the_harness_that_was_asked_about() {
265        let codex_old = measured(b"codex-acp 0.9.4 tree");
266        let codex_new = measured(b"codex-acp 0.9.5 tree");
267        let gemini = measured(b"gemini-cli 1.0.0 tree");
268        let log = [
269            applied_line("codex-acp", "0.9.4", &codex_old, NOW - 2000),
270            applied_line("gemini-cli", "1.0.0", &gemini, NOW - 1000),
271            applied_line("codex-acp", "0.9.5", &codex_new, NOW),
272        ]
273        .concat();
274
275        assert_eq!(
276            verify_installation(&latest_record_for(&log, "codex-acp"), &codex_new),
277            ProvenanceVerdict::Verified {
278                digest: codex_new.as_str().to_string()
279            }
280        );
281        assert_eq!(
282            verify_installation(&latest_record_for(&log, "gemini-cli"), &gemini),
283            ProvenanceVerdict::Verified {
284                digest: gemini.as_str().to_string()
285            }
286        );
287        assert_eq!(
288            latest_record_for(&log, "never-installed"),
289            InstallationProvenance::Unattested
290        );
291    }
292
293    /// The no-backfill law at the log level. A newer schema's record about this
294    /// harness is reported as unreadable rather than skipped in favour of the
295    /// older record underneath it, which would report provenance from before
296    /// whatever that newer record described.
297    #[test]
298    fn a_newer_record_this_build_cannot_read_is_not_skipped_for_an_older_one_it_can() {
299        let old = measured(b"codex-acp 0.9.4 tree");
300        let mut log = applied_line("codex-acp", "0.9.4", &old, NOW - 1000);
301        log.push_str(
302            &serde_json::json!({
303                "schema": "openagents.omega.harness.maintenance.v2",
304                "harnessRef": "harness.codex-acp",
305                "signedBy": "future-omega",
306            })
307            .to_string(),
308        );
309        log.push('\n');
310
311        assert_eq!(
312            verify_installation(&latest_record_for(&log, "codex-acp"), &old),
313            ProvenanceVerdict::Refused(ProvenanceGap::RecordUnreadable),
314            "an unreadable newer record must not be stepped over"
315        );
316    }
317
318    #[test]
319    fn a_corrupt_line_does_not_stop_the_reader_finding_the_record_underneath_it() {
320        let digest = measured(b"codex-acp 0.9.4 tree");
321        let mut log = applied_line("codex-acp", "0.9.4", &digest, NOW);
322        log.push_str("<<< partially written line\n");
323        assert_eq!(
324            verify_installation(&latest_record_for(&log, "codex-acp"), &digest),
325            ProvenanceVerdict::Verified {
326                digest: digest.as_str().to_string()
327            }
328        );
329    }
330
331    #[test]
332    fn an_empty_log_attests_nothing() {
333        assert_eq!(
334            latest_record_for("", "codex-acp"),
335            InstallationProvenance::Unattested
336        );
337        assert_eq!(
338            latest_record_for("\n\n  \n", "codex-acp"),
339            InstallationProvenance::Unattested
340        );
341    }
342
343    // -------------------------------------------------------------------
344    // The whole flow
345    // -------------------------------------------------------------------
346
347    /// The acceptance sentence on omega#81, end to end and on disk: install is
348    /// one action and produces a receipt; update is one action and produces a
349    /// receipt; a pin blocks an unwanted update with a reason the front door
350    /// can render.
351    #[test]
352    fn install_then_update_then_pin_then_a_blocked_update() {
353        let dir = scratch_dir("flow");
354        let ledger_path = dir.join(HARNESS_PIN_LEDGER_FILE_NAME);
355        let log_path = dir.join(HARNESS_MAINTENANCE_LOG_FILE_NAME);
356
357        let read_ledger = |path: &std::path::Path| {
358            LoadedPinLedger::read(std::fs::read_to_string(path).ok().as_deref())
359        };
360        let read_log = |path: &std::path::Path| std::fs::read_to_string(path).unwrap_or_default();
361        let append = |path: &std::path::Path, line: String| {
362            let mut existing = std::fs::read_to_string(path).unwrap_or_default();
363            existing.push_str(&line);
364            std::fs::write(path, existing).expect("the log is appended");
365        };
366
367        // Install, on a clean machine: one action.
368        let installed = measured(b"codex-acp 0.9.4 tree");
369        let decision = decide_maintenance(
370            read_ledger(&ledger_path).pin_state("codex-acp"),
371            CandidateArtifact::Measured {
372                version: "0.9.4",
373                digest: &installed,
374            },
375        );
376        assert!(decision.is_permitted());
377        append(
378            &log_path,
379            receipt_log_line(
380                &receipt_for_decision(
381                    HOST,
382                    "codex-acp",
383                    NOW,
384                    MaintenanceAction::Install,
385                    &decision,
386                )
387                .expect("an install writes a receipt"),
388            ),
389        );
390        assert_eq!(
391            verify_installation(&latest_record_for(&read_log(&log_path), "codex-acp"), &installed),
392            ProvenanceVerdict::Verified {
393                digest: installed.as_str().to_string()
394            }
395        );
396
397        // Update, unpinned: one action, and a receipt bound to the new bytes.
398        let updated = measured(b"codex-acp 0.9.5 tree");
399        let decision = decide_maintenance(
400            read_ledger(&ledger_path).pin_state("codex-acp"),
401            CandidateArtifact::Measured {
402                version: "0.9.5",
403                digest: &updated,
404            },
405        );
406        assert!(decision.is_permitted());
407        append(
408            &log_path,
409            receipt_log_line(
410                &receipt_for_decision(HOST, "codex-acp", NOW + 1, MaintenanceAction::Update, &decision)
411                    .expect("an update writes a receipt"),
412            ),
413        );
414        assert_eq!(
415            verify_installation(&latest_record_for(&read_log(&log_path), "codex-acp"), &updated),
416            ProvenanceVerdict::Verified {
417                digest: updated.as_str().to_string()
418            }
419        );
420
421        // The owner pins what is installed.
422        let mut ledger = HarnessPinLedger::empty();
423        ledger.set_pin("codex-acp", "0.9.5", &updated);
424        std::fs::write(&ledger_path, encode_harness_pin_ledger(&ledger).expect("encodes"))
425            .expect("the ledger is written");
426
427        // The registry now offers 0.9.6. The pin blocks it, visibly.
428        let unwanted = measured(b"codex-acp 0.9.6 tree");
429        let decision = decide_maintenance(
430            read_ledger(&ledger_path).pin_state("codex-acp"),
431            CandidateArtifact::Measured {
432                version: "0.9.6",
433                digest: &unwanted,
434            },
435        );
436        assert!(!decision.is_permitted());
437        let affordance = update_affordance(&decision);
438        let reason = affordance.reason().expect("a blocked update says why");
439        assert!(reason.contains("0.9.5") && reason.contains("0.9.6"), "{reason:?}");
440        append(
441            &log_path,
442            receipt_log_line(
443                &receipt_for_decision(HOST, "codex-acp", NOW + 2, MaintenanceAction::Update, &decision)
444                    .expect("a refusal writes a receipt too"),
445            ),
446        );
447
448        // And the refusal did not disturb what is installed: the last applied
449        // record still describes 0.9.5, and 0.9.6's bytes verify against
450        // nothing.
451        let log = read_log(&log_path);
452        assert_eq!(
453            verify_installation(&latest_record_for(&log, "codex-acp"), &updated),
454            ProvenanceVerdict::Refused(ProvenanceGap::LastActionRefused)
455        );
456        assert_eq!(log.lines().count(), 3, "every action left exactly one record");
457
458        std::fs::remove_dir_all(&dir).ok();
459    }
460
461    /// Every admitted action is reachable and round-trips, so a new action
462    /// cannot be added to the enum without a wire token that decodes.
463    #[test]
464    fn every_admitted_action_round_trips_through_a_receipt() {
465        let digest = measured(b"tree");
466        for action in ADMITTED_MAINTENANCE_ACTIONS {
467            let receipt = build_harness_maintenance_receipt(
468                HOST,
469                "codex-acp",
470                NOW,
471                *action,
472                &MaintenanceOutcomeInput::Applied {
473                    version: "1.0.0",
474                    digest: &digest,
475                },
476            )
477            .expect("emits");
478            assert_eq!(receipt.action, *action);
479            let encoded = serde_json::to_string(&receipt).expect("serialises");
480            assert_eq!(
481                decode_harness_maintenance_receipt(&encoded)
482                    .expect("decodes")
483                    .action,
484                *action
485            );
486        }
487    }
488}
489
Served at tenant.openagents/omega Member data and write actions are omitted.