Skip to repository content489 lines · 19.3 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T01:55:00.731Z 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
omega_harness.rs
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