Skip to repository content

tenant.openagents/omega

No repository description is available.

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

front_door.rs

549 lines · 22.3 KB · rust
1//! What the owner's front door shows for one wrapped harness, and which of the
2//! two pin controls it offers. `OMEGA-DELTA-0033`, omega#81.
3//!
4//! The first landing of omega#81 built every decision and rendered none of
5//! them: `MaintenanceAffordance::Disabled { reason }` structurally could not be
6//! built without a sentence, and nothing ever put that sentence on a screen. A
7//! refusal that reaches the owner only as agent-launch error text is a refusal
8//! the owner cannot act on, and the standing rule is that owner-facing
9//! operations get working controls rather than a file to hand-edit.
10//!
11//! This module is the whole answer to *what does the settings row say and which
12//! buttons are live*, as one value, computed by one function, with no
13//! filesystem and no GPUI. The widget that renders it makes no judgement: it
14//! matches on [`PinControl`] to decide which button exists, and it prints
15//! sentences the decision layer produced. That split is why the rendered state
16//! can be tested at the speed of a leaf crate, and why "the disabled control
17//! carries its reason" is checkable without a window.
18//!
19//! # Every state is total
20//!
21//! [`PinControl`] has no "nothing to offer" that lacks a sentence, for the same
22//! reason [`MaintenanceAffordance`] does not: a control that is absent and
23//! unexplained reads to an owner as a bug in Omega rather than as a fact about
24//! their machine.
25
26use crate::{
27    HarnessPin, InstallationProvenance, MaintenanceAffordance, MeasuredDigest, PinState,
28    ProvenanceGap, ProvenanceVerdict, admits_package_manager_launch, decide_maintenance,
29    update_affordance, verify_installation,
30};
31
32/// How a harness's bytes reach the machine.
33///
34/// Two variants, because pinning is possible in exactly one of them. A harness
35/// whose bytes Omega downloads into a directory it owns can be hashed and
36/// therefore frozen; a harness a package manager resolves at launch cannot be,
37/// and the front door has to say which kind it is looking at rather than show a
38/// pin button that would not hold.
39///
40/// Owner-named custom binaries are not here at all. They have no registry id,
41/// no version Omega resolved, and no update path Omega drives, so there is no
42/// maintenance state to show — the owner named the file.
43#[derive(Clone, Debug, PartialEq, Eq)]
44pub enum HarnessDistribution {
45    /// Omega downloads a release archive into a directory it owns.
46    OwnedTree,
47    /// A package manager resolves the bytes at launch.
48    PackageManager {
49        /// The resolver that owns them, e.g. `npx`.
50        resolver: String,
51    },
52}
53
54impl HarnessDistribution {
55    /// The resolver's name, when a resolver owns the bytes.
56    #[must_use]
57    pub fn resolver(&self) -> Option<&str> {
58        match self {
59            Self::OwnedTree => None,
60            Self::PackageManager { resolver } => Some(resolver.as_str()),
61        }
62    }
63}
64
65/// The one pin control the front door offers for a harness, if any.
66///
67/// One control, not two: "pin" and "unpin" are never both live, because a
68/// harness is frozen or it is not. Re-pinning is deliberately two actions —
69/// remove, then pin — so that moving a pin from one release to another is
70/// something the owner did twice on purpose rather than something a single
71/// click could do to a frozen harness by accident.
72#[derive(Clone, Debug, PartialEq, Eq)]
73pub enum PinControl {
74    /// Nothing is frozen and this host measured the installed tree, so a pin can
75    /// be taken at bytes that were read rather than at a version that was typed.
76    Take {
77        version: String,
78        digest: MeasuredDigest,
79    },
80    /// Frozen. The control removes the pin.
81    Remove { pinned_version: String },
82    /// Neither control is offered, and this is why.
83    Unavailable { reason: String },
84}
85
86impl PinControl {
87    /// The sentence to show where a control would have been.
88    #[must_use]
89    pub fn unavailable_reason(&self) -> Option<&str> {
90        match self {
91            Self::Take { .. } | Self::Remove { .. } => None,
92            Self::Unavailable { reason } => Some(reason.as_str()),
93        }
94    }
95}
96
97/// Everything the front door shows for one harness.
98#[derive(Clone, Debug, PartialEq, Eq)]
99pub struct HarnessFrontDoorState {
100    pub harness_id: String,
101    /// The version the registry currently names.
102    pub version: String,
103    pub distribution: HarnessDistribution,
104    /// The pin, when one covers this harness. Carried whole so the row can name
105    /// the frozen version without re-reading the ledger.
106    pub pin: Option<HarnessPin>,
107    /// What the host can conclude about the bytes that would run.
108    pub provenance: ProvenanceVerdict,
109    /// Whether this harness may launch, and if not, why.
110    ///
111    /// The same value the launch path computes, from the same function. A front
112    /// door that derived its own answer could disagree with the gate, and the
113    /// disagreement would show up as a control that looks live and then fails.
114    pub launch: MaintenanceAffordance,
115    pub pin_control: PinControl,
116}
117
118impl HarnessFrontDoorState {
119    /// Whether this row has anything to say beyond its name and version.
120    #[must_use]
121    pub fn has_detail(&self) -> bool {
122        !self.launch.is_enabled()
123            || self.pin.is_some()
124            || !matches!(self.provenance, ProvenanceVerdict::Verified { .. })
125    }
126}
127
128/// Compute the front door's state for one harness.
129///
130/// `measured` is `None` when this host could not read the installed tree, which
131/// is a different fact from an empty tree and is not collapsed into one.
132///
133/// Everything here routes through the same decision functions the launch path
134/// uses. There is no second opinion in this module: `launch` is
135/// [`update_affordance`] over [`decide_maintenance`] for an owned tree and over
136/// [`admits_package_manager_launch`] for a resolved one, which are exactly the
137/// two gates `crates/project/src/harness_maintenance.rs` enforces.
138#[must_use]
139pub fn harness_front_door_state(
140    harness_id: &str,
141    version: &str,
142    distribution: HarnessDistribution,
143    pin_state: PinState<'_>,
144    measured: Option<&MeasuredDigest>,
145    provenance: &InstallationProvenance,
146) -> HarnessFrontDoorState {
147    let pin = match pin_state {
148        PinState::Pinned(pin) => Some(pin.clone()),
149        PinState::Unpinned | PinState::Unreadable => None,
150    };
151
152    let (launch, provenance_verdict, pin_control) = match &distribution {
153        HarnessDistribution::PackageManager { resolver } => {
154            let launch = match admits_package_manager_launch(pin_state, resolver) {
155                None => MaintenanceAffordance::Enabled,
156                Some(refusal) => MaintenanceAffordance::Disabled {
157                    reason: refusal.reason(),
158                },
159            };
160            let pin_control = match pin_state {
161                PinState::Pinned(pin) => PinControl::Remove {
162                    pinned_version: pin.version.clone(),
163                },
164                // Offering "pin" here would offer a freeze Omega cannot hold.
165                // The sentence says so rather than leaving a gap where a
166                // control is on every other row.
167                PinState::Unpinned | PinState::Unreadable => PinControl::Unavailable {
168                    reason: format!(
169                        "This agent runs through {resolver}, which resolves its own bytes when \
170                         it starts. Omega has nothing to freeze, so it cannot pin this agent."
171                    ),
172                },
173            };
174            (
175                launch,
176                ProvenanceVerdict::Refused(ProvenanceGap::ResolvedAtLaunch),
177                pin_control,
178            )
179        }
180        HarnessDistribution::OwnedTree => {
181            let candidate = match measured {
182                Some(digest) => crate::CandidateArtifact::Measured { version, digest },
183                None => crate::CandidateArtifact::Unmeasured { version },
184            };
185            let decision = decide_maintenance(pin_state, candidate);
186            let launch = update_affordance(&decision);
187
188            let provenance_verdict = match measured {
189                Some(digest) => verify_installation(provenance, digest),
190                None => ProvenanceVerdict::Refused(ProvenanceGap::TreeUnreadable),
191            };
192
193            let pin_control = match (pin_state, measured) {
194                (PinState::Pinned(pin), _) => PinControl::Remove {
195                    pinned_version: pin.version.clone(),
196                },
197                // A pin is only worth taking at bytes this host read. Taking one
198                // from an unreadable tree would freeze a digest nobody measured,
199                // which is the failure the whole contract exists to prevent.
200                (PinState::Unpinned, Some(digest)) => PinControl::Take {
201                    version: version.to_string(),
202                    digest: digest.clone(),
203                },
204                (PinState::Unpinned, None) => PinControl::Unavailable {
205                    reason: "Omega could not read this agent's installed files, so it has no \
206                             measurement to pin. Reinstall it, then pin."
207                        .to_string(),
208                },
209                (PinState::Unreadable, _) => PinControl::Unavailable {
210                    reason: "Omega could not read the pin ledger, so it cannot change what is \
211                             frozen without risking overwriting a pin it cannot see."
212                        .to_string(),
213                },
214            };
215
216            (launch, provenance_verdict, pin_control)
217        }
218    };
219
220    HarnessFrontDoorState {
221        harness_id: harness_id.to_string(),
222        version: version.to_string(),
223        distribution,
224        pin,
225        provenance: provenance_verdict,
226        launch,
227        pin_control,
228    }
229}
230
231#[cfg(test)]
232mod tests {
233    use super::*;
234    use crate::{
235        HarnessMaintenanceRecord, HarnessPinLedger, LoadedPinLedger, MaintenanceAction,
236        MaintenanceOutcomeInput, build_harness_maintenance_receipt,
237    };
238
239    const TREE: &[u8] = b"codex-acp 0.9.4 installed tree";
240    const OTHER_TREE: &[u8] = b"codex-acp 0.9.5 installed tree";
241    const NOW: u64 = 1_784_894_400_000;
242
243    fn pinned_at(version: &str, bytes: &[u8]) -> LoadedPinLedger {
244        let mut ledger = HarnessPinLedger::empty();
245        ledger.set_pin("codex-acp", version, &MeasuredDigest::measure(bytes));
246        LoadedPinLedger::Loaded(ledger)
247    }
248
249    fn attested(bytes: &[u8]) -> InstallationProvenance {
250        let digest = MeasuredDigest::measure(bytes);
251        let receipt = build_harness_maintenance_receipt(
252            "host.omega.local",
253            "codex-acp",
254            NOW,
255            MaintenanceAction::Install,
256            &MaintenanceOutcomeInput::Applied {
257                version: "0.9.4",
258                digest: &digest,
259            },
260        )
261        .expect("a receipt");
262        InstallationProvenance::Recorded(HarnessMaintenanceRecord::Attested(receipt))
263    }
264
265    fn owned(
266        ledger: &LoadedPinLedger,
267        measured: Option<&MeasuredDigest>,
268        provenance: &InstallationProvenance,
269    ) -> HarnessFrontDoorState {
270        harness_front_door_state(
271            "codex-acp",
272            "0.9.4",
273            HarnessDistribution::OwnedTree,
274            ledger.pin_state("codex-acp"),
275            measured,
276            provenance,
277        )
278    }
279
280    /// The state a healthy, freshly installed, unpinned harness is in: it runs,
281    /// its bytes are attested, and the owner is offered the one control that
282    /// changes anything — a pin at the bytes this host just read.
283    #[test]
284    fn an_attested_unpinned_harness_offers_a_pin_at_the_measured_bytes() {
285        let digest = MeasuredDigest::measure(TREE);
286        let state = owned(&LoadedPinLedger::Absent, Some(&digest), &attested(TREE));
287
288        assert!(state.launch.is_enabled());
289        assert_eq!(
290            state.provenance,
291            ProvenanceVerdict::Verified {
292                digest: digest.as_str().to_string()
293            }
294        );
295        assert_eq!(
296            state.pin_control,
297            PinControl::Take {
298                version: "0.9.4".to_string(),
299                digest,
300            }
301        );
302        assert!(state.pin.is_none());
303    }
304
305    /// The acceptance sentence's second half, as rendered state: a pin at one
306    /// version disables the control for another, and the sentence beside the
307    /// disabled control names both versions and what to do.
308    #[test]
309    fn a_pin_at_another_version_disables_the_launch_and_says_why() {
310        let ledger = pinned_at("0.9.4", TREE);
311        let digest = MeasuredDigest::measure(OTHER_TREE);
312        let state = harness_front_door_state(
313            "codex-acp",
314            "0.9.5",
315            HarnessDistribution::OwnedTree,
316            ledger.pin_state("codex-acp"),
317            Some(&digest),
318            &attested(OTHER_TREE),
319        );
320
321        let reason = state.launch.reason().expect("a disabled launch has a reason");
322        assert!(reason.contains("0.9.4"), "names the pinned version: {reason}");
323        assert!(reason.contains("0.9.5"), "names the offered version: {reason}");
324        assert!(reason.contains("remove the pin"), "says what to do: {reason}");
325        assert_eq!(
326            state.pin_control,
327            PinControl::Remove {
328                pinned_version: "0.9.4".to_string()
329            }
330        );
331    }
332
333    /// A pinned harness is never offered a second pin. There is exactly one
334    /// control, and while a pin stands it is the one that removes it.
335    #[test]
336    fn a_pinned_harness_is_never_offered_a_pin() {
337        for (version, bytes) in [("0.9.4", TREE), ("0.9.5", OTHER_TREE)] {
338            let ledger = pinned_at("0.9.4", TREE);
339            let digest = MeasuredDigest::measure(bytes);
340            let state = harness_front_door_state(
341                "codex-acp",
342                version,
343                HarnessDistribution::OwnedTree,
344                ledger.pin_state("codex-acp"),
345                Some(&digest),
346                &attested(bytes),
347            );
348            assert!(
349                !matches!(state.pin_control, PinControl::Take { .. }),
350                "a pinned harness offered a pin at {version}"
351            );
352        }
353    }
354
355    /// An unreadable tree yields no pin control, because a pin taken from one
356    /// would freeze a digest nobody measured.
357    #[test]
358    fn an_unreadable_tree_offers_no_pin_and_refuses_the_launch() {
359        let state = owned(&LoadedPinLedger::Absent, None, &attested(TREE));
360        assert!(!state.launch.is_enabled());
361        assert_eq!(
362            state.provenance,
363            ProvenanceVerdict::Refused(ProvenanceGap::TreeUnreadable)
364        );
365        assert!(state.pin_control.unavailable_reason().is_some());
366        assert!(!matches!(state.pin_control, PinControl::Take { .. }));
367    }
368
369    /// An unreadable ledger must not offer a control that writes to it: the
370    /// write would drop pins the reader could not see.
371    #[test]
372    fn an_unreadable_ledger_offers_no_control_that_would_rewrite_it() {
373        let ledger = LoadedPinLedger::Unreadable(crate::HarnessPinLedgerError::InvalidJson);
374        let digest = MeasuredDigest::measure(TREE);
375        let state = owned(&ledger, Some(&digest), &attested(TREE));
376        assert!(!state.launch.is_enabled());
377        assert!(
378            state.pin_control.unavailable_reason().is_some(),
379            "an unreadable ledger offered a write"
380        );
381    }
382
383    /// An installation from before omega#81 runs — the bytes are measurable and
384    /// nothing is frozen — but it is reported as unattested rather than
385    /// upgraded by assumption.
386    #[test]
387    fn an_installation_with_no_record_runs_and_is_reported_unattested() {
388        let digest = MeasuredDigest::measure(TREE);
389        let state = owned(
390            &LoadedPinLedger::Absent,
391            Some(&digest),
392            &InstallationProvenance::Unattested,
393        );
394        assert!(state.launch.is_enabled());
395        assert_eq!(
396            state.provenance,
397            ProvenanceVerdict::Refused(ProvenanceGap::Unattested)
398        );
399    }
400
401    /// The npx half of the gap this delta closes. An unpinned package-manager
402    /// harness still launches — refusing every one of them is a different
403    /// change than this issue asks for — but the row says there is nothing to
404    /// attest and no pin to take, instead of showing a control that would not
405    /// hold.
406    #[test]
407    fn an_unpinned_package_manager_harness_launches_and_says_it_cannot_be_pinned() {
408        let state = harness_front_door_state(
409            "some-npx-agent",
410            "1.2.3",
411            HarnessDistribution::PackageManager {
412                resolver: "npx".to_string(),
413            },
414            LoadedPinLedger::Absent.pin_state("some-npx-agent"),
415            None,
416            &InstallationProvenance::Unattested,
417        );
418        assert!(state.launch.is_enabled());
419        assert_eq!(
420            state.provenance,
421            ProvenanceVerdict::Refused(ProvenanceGap::ResolvedAtLaunch)
422        );
423        let reason = state
424            .pin_control
425            .unavailable_reason()
426            .expect("a missing pin control has a reason");
427        assert!(reason.contains("npx"), "names the resolver: {reason}");
428    }
429
430    /// The safety half: a pin on an npx harness is not silently ignored. It
431    /// refuses the launch and offers removal, so the owner's "not that one"
432    /// means something even where Omega cannot enforce a version.
433    #[test]
434    fn a_pinned_package_manager_harness_refuses_rather_than_ignoring_the_pin() {
435        let ledger = pinned_at("1.2.3", TREE);
436        let state = harness_front_door_state(
437            "codex-acp",
438            "1.2.3",
439            HarnessDistribution::PackageManager {
440                resolver: "npx".to_string(),
441            },
442            ledger.pin_state("codex-acp"),
443            None,
444            &InstallationProvenance::Unattested,
445        );
446        assert!(!state.launch.is_enabled());
447        let reason = state.launch.reason().expect("a refusal has a reason");
448        assert!(reason.contains("npx"), "names the resolver: {reason}");
449        assert_eq!(
450            state.pin_control,
451            PinControl::Remove {
452                pinned_version: "1.2.3".to_string()
453            }
454        );
455    }
456
457    /// The binding property of this module: the front door and the launch path
458    /// must not be able to disagree. Whatever `decide_maintenance` says for an
459    /// owned tree is what the row shows, across every combination of pin state
460    /// and measurement.
461    #[test]
462    fn the_rendered_launch_state_equals_what_the_gate_would_decide() {
463        let measured = MeasuredDigest::measure(TREE);
464        let other = MeasuredDigest::measure(OTHER_TREE);
465        let ledgers = [
466            LoadedPinLedger::Absent,
467            pinned_at("0.9.4", TREE),
468            pinned_at("0.9.4", OTHER_TREE),
469            pinned_at("0.9.5", TREE),
470            LoadedPinLedger::Unreadable(crate::HarnessPinLedgerError::InvalidJson),
471        ];
472
473        for ledger in &ledgers {
474            for candidate in [Some(&measured), Some(&other), None] {
475                let state = owned(ledger, candidate, &attested(TREE));
476                let expected = update_affordance(&decide_maintenance(
477                    ledger.pin_state("codex-acp"),
478                    match candidate {
479                        Some(digest) => crate::CandidateArtifact::Measured {
480                            version: "0.9.4",
481                            digest,
482                        },
483                        None => crate::CandidateArtifact::Unmeasured { version: "0.9.4" },
484                    },
485                ));
486                assert_eq!(
487                    state.launch, expected,
488                    "the row disagreed with the gate for {ledger:?}"
489                );
490            }
491        }
492    }
493
494    /// Every state a row can be in either enables its control or explains
495    /// itself. A blank disabled control is the defect this module exists to
496    /// prevent, so it is asserted over the whole space rather than per case.
497    #[test]
498    fn no_reachable_state_withholds_a_control_without_a_sentence() {
499        let measured = MeasuredDigest::measure(TREE);
500        let distributions = [
501            HarnessDistribution::OwnedTree,
502            HarnessDistribution::PackageManager {
503                resolver: "npx".to_string(),
504            },
505        ];
506        let ledgers = [
507            LoadedPinLedger::Absent,
508            pinned_at("0.9.4", TREE),
509            pinned_at("0.9.5", TREE),
510            LoadedPinLedger::Unreadable(crate::HarnessPinLedgerError::InvalidJson),
511        ];
512        let provenances = [
513            InstallationProvenance::Unattested,
514            attested(TREE),
515            attested(OTHER_TREE),
516        ];
517
518        for distribution in &distributions {
519            for ledger in &ledgers {
520                for measurement in [Some(&measured), None] {
521                    for provenance in &provenances {
522                        let state = harness_front_door_state(
523                            "codex-acp",
524                            "0.9.4",
525                            distribution.clone(),
526                            ledger.pin_state("codex-acp"),
527                            measurement,
528                            provenance,
529                        );
530                        if !state.launch.is_enabled() {
531                            let reason = state.launch.reason().unwrap_or("");
532                            assert!(
533                                !reason.trim().is_empty(),
534                                "a disabled launch with no sentence: {state:?}"
535                            );
536                        }
537                        if let PinControl::Unavailable { reason } = &state.pin_control {
538                            assert!(
539                                !reason.trim().is_empty(),
540                                "a withheld pin control with no sentence: {state:?}"
541                            );
542                        }
543                    }
544                }
545            }
546        }
547    }
548}
549
Served at tenant.openagents/omega Member data and write actions are omitted.