Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T03:15:45.979Z 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

pin.rs

292 lines · 11.8 KB · rust
1//! Which Exo. `OMEGA-DELTA-0042`, omega#87.
2//!
3//! Exo declares itself unstable and writes the house rule "do not write
4//! fallback code or handle backwards compatibility" into its own `AGENTS.md`.
5//! `0.1.0`, no tags, nothing published. A lane that said "whatever `exo` is on
6//! `PATH`" would be a lane whose behaviour is decided by somebody else's next
7//! push.
8//!
9//! So the lane names an exact commit, and it names the tree that commit points
10//! at. Both, for the same reason `omega-effectd` is pinned by release tag *and*
11//! asset digest in `script/prove-omega-rc-install`: a commit id alone is
12//! satisfied by a force-pushed branch that still answers to the same forty
13//! characters in a clone nobody re-fetched, and a tree alone produces a refusal
14//! nobody can act on.
15//!
16//! # What this file does and does not pin
17//!
18//! [`EXO_PIN`] is an **identity**: upstream, commit, tree, version. It is the
19//! same on every machine, it is checked in, and it is what a reader compares a
20//! clone against.
21//!
22//! The **bytes that actually run** are a different fact, because Exo has no
23//! release artifact — the install path is `curl setup.sh | bash`, which clones
24//! and builds from source, so two hosts at the same commit hold two different
25//! binaries. Those bytes go through the mechanism that already exists for
26//! exactly this: [`omega_harness::HarnessPinLedger`], under the harness id
27//! [`EXO_HARNESS_ID`], holding a [`MeasuredDigest`] the host computed from the
28//! binary it is about to run.
29//!
30//! [`MeasuredDigest`]: omega_harness::MeasuredDigest
31//!
32//! That split is the whole point. The identity is a claim anyone can check
33//! against upstream; the digest is a measurement only this host can make. They
34//! must not share a type and they must not share a file.
35
36use omega_harness::MeasuredDigest;
37
38/// The harness id the Exo lane is frozen under in the pin ledger.
39///
40/// The same namespace `codex-acp` uses, because Exo is the same kind of thing:
41/// an external harness Omega runs and does not own.
42pub const EXO_HARNESS_ID: &str = "exo";
43
44/// The Exo this lane drives.
45///
46/// **The maintained `OpenAgentsInc/exo` fork of `exoharness/exo`**, the
47/// recursive-self-improvement agent harness. This is not exo labs'
48/// `exo-explore/exo` cluster-inference appliance. The fork contains the ACP
49/// transport that Omega needs while the upstream change is under review.
50#[derive(Clone, Copy, Debug, PartialEq, Eq)]
51pub struct ExoPin {
52    /// The repository, in full. See the type documentation for why.
53    pub upstream: &'static str,
54    /// The exact commit the lane was audited and driven against.
55    pub source_commit: &'static str,
56    /// The tree that commit points at.
57    pub source_tree: &'static str,
58    /// The workspace version at that commit, for a message a person can read.
59    pub version: &'static str,
60}
61
62/// The pin. Audited in the openagents teardown
63/// `docs/teardowns/2026-07-25-exoharness-exo-teardown.md` and driven for real
64/// by omega#87.
65pub const EXO_PIN: ExoPin = ExoPin {
66    upstream: "https://github.com/OpenAgentsInc/exo",
67    source_commit: "cd7c0d29db869e953fb7261d8390ca93007d36a6",
68    source_tree: "c61846e3f44daaf445930d1a499432ca9b069306",
69    version: "0.1.0",
70};
71
72/// Why a local Exo checkout is not the pinned one.
73#[derive(Clone, Copy, Debug, PartialEq, Eq)]
74pub enum ExoPinMismatch {
75    /// The clone is a different repository. This is the omega#86 failure: the
76    /// other Exo.
77    Upstream,
78    /// The checkout is at a different commit.
79    Commit,
80    /// The checkout is at the pinned commit and the tree underneath it is not
81    /// the pinned tree — a rewritten history, a dirty tree, or a substituted
82    /// object store.
83    Tree,
84    /// The bytes about to run are not the bytes the owner froze.
85    Bytes,
86}
87
88impl std::fmt::Display for ExoPinMismatch {
89    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90        formatter.write_str(match self {
91            Self::Upstream => "the Exo checkout is not the maintained exoharness/exo fork",
92            Self::Commit => "the Exo checkout is not at the pinned commit",
93            Self::Tree => "the Exo checkout's tree is not the pinned tree",
94            Self::Bytes => "the Exo binary is not the bytes frozen in the pin ledger",
95        })
96    }
97}
98
99impl std::error::Error for ExoPinMismatch {}
100
101/// What a host observed about a local Exo checkout.
102///
103/// Every field is something the host read: `git config --get remote.origin.url`,
104/// `git rev-parse HEAD`, `git rev-parse HEAD^{tree}`. A record of observations,
105/// which is why it is a separate type from [`ExoPin`], which is a record of
106/// decisions.
107#[derive(Clone, Debug, PartialEq, Eq)]
108pub struct ObservedExoCheckout {
109    /// The remote the checkout came from.
110    pub upstream: String,
111    /// `HEAD`.
112    pub commit: String,
113    /// `HEAD^{tree}`.
114    pub tree: String,
115}
116
117impl ExoPin {
118    /// Whether an observed checkout is the Exo this lane admits.
119    ///
120    /// Upstream is compared after normalising a trailing `.git` and a trailing
121    /// slash, because `https://github.com/exoharness/exo.git` and
122    /// `https://github.com/exoharness/exo` are the same repository and refusing
123    /// one of them would be a cosmetic refusal. `git@github.com:exoharness/exo`
124    /// is *not* normalised into the same string; it is compared by its
125    /// `owner/name` suffix, which is the part that carries the identity.
126    ///
127    /// # Errors
128    ///
129    /// Returns the first thing that differed, most-identifying first: a
130    /// checkout of the wrong repository is reported as the wrong repository
131    /// even though its commit also differs.
132    pub fn admits(&self, observed: &ObservedExoCheckout) -> Result<(), ExoPinMismatch> {
133        if !same_repository(self.upstream, &observed.upstream) {
134            return Err(ExoPinMismatch::Upstream);
135        }
136        if !self
137            .source_commit
138            .eq_ignore_ascii_case(observed.commit.trim())
139        {
140            return Err(ExoPinMismatch::Commit);
141        }
142        if !self.source_tree.eq_ignore_ascii_case(observed.tree.trim()) {
143            return Err(ExoPinMismatch::Tree);
144        }
145        Ok(())
146    }
147}
148
149/// Whether the bytes this host measured are the bytes the owner froze.
150///
151/// Takes the frozen digest as a `&str` and the live one as a [`MeasuredDigest`]
152/// for the reason that type exists: a pin read back from a file is a recorded
153/// claim about a past measurement, and this process did not make it.
154///
155/// An **unfrozen** Exo is admitted, and that is deliberate rather than an
156/// oversight. `codex-acp` behaves the same way: a pin is the owner freezing a
157/// version, not a precondition for running anything at all. What is refused is
158/// a *disagreement* — the case where the owner said "these bytes" and the host
159/// is holding different ones.
160///
161/// # Errors
162///
163/// [`ExoPinMismatch::Bytes`] when a pin exists and the measurement differs.
164pub fn admits_bytes(frozen: Option<&str>, measured: &MeasuredDigest) -> Result<(), ExoPinMismatch> {
165    match frozen {
166        Some(frozen) if !measured.matches_recorded(frozen) => Err(ExoPinMismatch::Bytes),
167        Some(_) | None => Ok(()),
168    }
169}
170
171/// Whether two remote strings name the same repository.
172fn same_repository(pinned: &str, observed: &str) -> bool {
173    normalize_remote(pinned) == normalize_remote(observed)
174}
175
176/// `owner/name`, lowercased, with the transport, host, trailing slash and
177/// `.git` suffix removed.
178fn normalize_remote(remote: &str) -> String {
179    let remote = remote.trim().trim_end_matches('/');
180    let remote = remote.strip_suffix(".git").unwrap_or(remote);
181    let tail = remote.rsplit(['/', ':']).take(2).collect::<Vec<_>>();
182    tail.into_iter()
183        .rev()
184        .collect::<Vec<_>>()
185        .join("/")
186        .to_ascii_lowercase()
187}
188
189#[cfg(test)]
190mod tests {
191    use super::*;
192
193    fn pinned_checkout() -> ObservedExoCheckout {
194        ObservedExoCheckout {
195            upstream: EXO_PIN.upstream.to_string(),
196            commit: EXO_PIN.source_commit.to_string(),
197            tree: EXO_PIN.source_tree.to_string(),
198        }
199    }
200
201    /// The commit and tree are forty hex characters each. A pin that had been
202    /// filled in with a branch name, a tag, or a truncated id would name
203    /// something that can move, which is the whole thing the pin exists to
204    /// stop.
205    #[test]
206    fn the_pin_names_an_exact_commit_and_an_exact_tree() {
207        for value in [EXO_PIN.source_commit, EXO_PIN.source_tree] {
208            assert_eq!(value.len(), 40, "{value} is not a full object id");
209            assert!(
210                value
211                    .chars()
212                    .all(|c| c.is_ascii_hexdigit() && !c.is_ascii_uppercase()),
213                "{value} is not a lowercase hexadecimal object id"
214            );
215        }
216        assert_ne!(
217            EXO_PIN.source_commit, EXO_PIN.source_tree,
218            "a commit and the tree it points at are different objects"
219        );
220    }
221
222    /// omega#86's failure, as a test. The two Exos share a name and nothing
223    /// else, and the one this lane drives is the harness.
224    #[test]
225    fn the_pin_names_the_harness_exo_and_not_the_cluster_one() {
226        assert_eq!(EXO_PIN.upstream, "https://github.com/OpenAgentsInc/exo");
227        let cluster = ObservedExoCheckout {
228            upstream: "https://github.com/exo-explore/exo".into(),
229            ..pinned_checkout()
230        };
231        assert_eq!(EXO_PIN.admits(&cluster), Err(ExoPinMismatch::Upstream));
232    }
233
234    #[test]
235    fn the_pinned_checkout_is_admitted() {
236        assert_eq!(EXO_PIN.admits(&pinned_checkout()), Ok(()));
237    }
238
239    /// A remote that differs only in `.git`, a trailing slash, case, or SSH
240    /// versus HTTPS transport is the same repository, and refusing it would be
241    /// a refusal about punctuation.
242    #[test]
243    fn the_same_repository_written_four_ways_is_the_same_repository() {
244        for spelling in [
245            "https://github.com/OpenAgentsInc/exo.git",
246            "https://github.com/OpenAgentsInc/exo/",
247            "https://GitHub.com/OpenAgentsInc/Exo",
248            "git@github.com:OpenAgentsInc/exo.git",
249        ] {
250            let observed = ObservedExoCheckout {
251                upstream: spelling.into(),
252                ..pinned_checkout()
253            };
254            assert_eq!(EXO_PIN.admits(&observed), Ok(()), "{spelling}");
255        }
256    }
257
258    /// A moved branch that keeps the commit id it answers to is exactly the
259    /// substitution a commit-only pin cannot see, so the tree is checked too.
260    #[test]
261    fn the_pinned_commit_over_a_different_tree_is_refused() {
262        let rewritten = ObservedExoCheckout {
263            tree: "0000000000000000000000000000000000000000".into(),
264            ..pinned_checkout()
265        };
266        assert_eq!(EXO_PIN.admits(&rewritten), Err(ExoPinMismatch::Tree));
267    }
268
269    #[test]
270    fn a_different_commit_is_refused() {
271        let moved = ObservedExoCheckout {
272            commit: "1111111111111111111111111111111111111111".into(),
273            ..pinned_checkout()
274        };
275        assert_eq!(EXO_PIN.admits(&moved), Err(ExoPinMismatch::Commit));
276    }
277
278    /// The bytes half. An unfrozen harness runs; a frozen one that changed
279    /// underneath the owner does not.
280    #[test]
281    fn frozen_bytes_that_changed_are_refused_and_unfrozen_bytes_run() {
282        let measured = MeasuredDigest::measure(b"the exo binary this host built");
283        assert_eq!(admits_bytes(None, &measured), Ok(()));
284        assert_eq!(admits_bytes(Some(measured.as_str()), &measured), Ok(()));
285        let other = MeasuredDigest::measure(b"a different exo binary");
286        assert_eq!(
287            admits_bytes(Some(other.as_str()), &measured),
288            Err(ExoPinMismatch::Bytes)
289        );
290    }
291}
292
Served at tenant.openagents/omega Member data and write actions are omitted.