Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T00:47:11.182Z 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

review-omega-candidate

359 lines · 13.6 KB · text
1#!/usr/bin/env python3
2"""Independently review an installed Omega candidate.
3
4This is the reviewer half of omega#67. It is deliberately NOT given the
5producer's evidence directory. It receives the candidate artifact and a small
6producer *claim*, then reproduces every check itself and compares.
7
8The distinction matters: reading the producer's JSON and confirming it parses
9is not review, it is proofreading. Everything below is recomputed from the
10artifact itself. The application it checks is the one inside the candidate
11disk image, not whatever is installed.
12
13Independence is structural, not declared:
14
15- The reviewer key is read from a path a producer run does not set. If
16  OMEGA_REVIEWER_KEY_FILE is absent, this refuses rather than falling back to
17  any ambient credential.
18- The receipt is signed, so a producer cannot write the reviewer's public key
19  into a document it authored itself.
20- `accepted` requires every reproduction to agree. `inconclusive` exists so a
21  check that cannot run reports honestly instead of being rounded to either
22  approval or rejection.
23
24Usage:
25    OMEGA_REVIEWER_KEY_FILE=~/work/.secrets/omega-independent-reviewer.env \\
26    review-omega-candidate \\
27        --candidate-dmg <dmg> \\
28        --producer-claim <claim.json> --output <receipt.json>
29"""
30
31from __future__ import annotations
32
33import argparse
34import hashlib
35import json
36import os
37import subprocess
38import sys
39import tempfile
40from contextlib import contextmanager
41from datetime import datetime, timezone
42from pathlib import Path
43from typing import Any
44
45SCHEMA = "openagents.assurance.independent-review.v1"
46
47#: Strings that must not appear in a shipped binary. Kept here rather than
48#: imported from the producer's tooling: a reviewer that shares the producer's
49#: definition of "clean" cannot catch a wrong definition.
50FORBIDDEN_STRINGS = [
51    "Unrecognized Project",
52    "Review .zed/settings.json",
53    "Zed's hosted models",
54    "14 day free trial",
55    "Pro trial",
56    "Move Omega to Applications",
57]
58
59
60class ReviewError(Exception):
61    pass
62
63
64def sha256_file(path: Path) -> str:
65    digest = hashlib.sha256()
66    with path.open("rb") as handle:
67        for chunk in iter(lambda: handle.read(1024 * 1024), b""):
68            digest.update(chunk)
69    return digest.hexdigest()
70
71
72def canonical_digest(value: Any) -> str:
73    return hashlib.sha256(
74        json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=False).encode(
75            "utf-8"
76        )
77    ).hexdigest()
78
79
80def load_reviewer_key() -> tuple[str, str]:
81    """Read the reviewer identity from a path a producer run does not set.
82
83    There is no fallback on purpose. An ambient-credential fallback would mean
84    a producer that happens to have some key in scope could sign a review.
85    """
86    location = os.environ.get("OMEGA_REVIEWER_KEY_FILE")
87    if not location:
88        raise ReviewError(
89            "OMEGA_REVIEWER_KEY_FILE is not set; a review cannot borrow an "
90            "ambient credential"
91        )
92    path = Path(location).expanduser()
93    if path.is_symlink() or not path.is_file():
94        raise ReviewError("reviewer key file is missing or is not a regular file")
95    mode = path.stat().st_mode & 0o077
96    if mode != 0:
97        raise ReviewError("reviewer key file is readable by group or others")
98    secret = public = ""
99    for line in path.read_text(encoding="utf-8").splitlines():
100        if line.startswith("OMEGA_REVIEWER_SECRET_KEY_HEX="):
101            secret = line.split("=", 1)[1].strip()
102        elif line.startswith("OMEGA_REVIEWER_PUBLIC_KEY_HEX="):
103            public = line.split("=", 1)[1].strip()
104    if len(secret) != 64 or len(public) != 64:
105        raise ReviewError("reviewer key file does not contain a usable keypair")
106    return secret, public
107
108
109def signing_package_root() -> Path:
110    """Locate the package whose `node_modules` carry the signing curves.
111
112    This was derived from the script's own location, three parents up plus
113    `openagents/packages/sarah`. That holds only when the reviewer runs from
114    the canonical omega checkout beside a canonical openagents checkout — and
115    an independent reviewer is supposed to run from an isolated worktree,
116    where it raises `FileNotFoundError` from inside `subprocess`. A reviewer
117    that cannot sign from an isolated tree pushes reviews back into the
118    producer's directory layout, which is the opposite of the point.
119
120    Candidates are tried in order and the first that exists wins, so an
121    unusual layout can be handled by setting the environment variable rather
122    than by moving the checkout.
123    """
124    override = os.environ.get("OMEGA_REVIEW_SIGNING_PACKAGE")
125    candidates = [Path(override).expanduser()] if override else []
126    here = Path(__file__).resolve()
127    candidates += [
128        here.parent.parent.parent / "openagents" / "packages" / "sarah",
129        Path.home() / "work" / "openagents" / "packages" / "sarah",
130    ]
131    for candidate in candidates:
132        if (candidate / "node_modules").is_dir():
133            return candidate
134    raise ReviewError(
135        "cannot find a package providing the signing curves; set "
136        "OMEGA_REVIEW_SIGNING_PACKAGE to a directory whose node_modules has "
137        "@noble/curves"
138    )
139
140
141def sign(message_hex: str, secret_hex: str) -> str:
142    """Schnorr-sign the evidence digest with the reviewer key."""
143    result = subprocess.run(
144        [
145            "node",
146            "--input-type=module",
147            "-e",
148            (
149                "import { schnorr } from '@noble/curves/secp256k1';"
150                "import { bytesToHex, hexToBytes } from '@noble/hashes/utils';"
151                "const [msg, sk] = process.argv.slice(1);"
152                "process.stdout.write(bytesToHex(schnorr.sign(hexToBytes(msg), hexToBytes(sk))));"
153            ),
154            message_hex,
155            secret_hex,
156        ],
157        capture_output=True,
158        text=True,
159        cwd=str(signing_package_root()),
160    )
161    if result.returncode != 0 or len(result.stdout.strip()) != 128:
162        raise ReviewError(f"reviewer signature failed: {result.stderr.strip()[:200]}")
163    return result.stdout.strip()
164
165
166def observe(command: list[str]) -> tuple[bool, str]:
167    """Run a check. Returns (ran, output). A check that cannot run is not a fail."""
168    try:
169        result = subprocess.run(command, capture_output=True, text=True, timeout=1800)
170    except (OSError, subprocess.TimeoutExpired):
171        return False, ""
172    return True, (result.stdout + result.stderr)
173
174
175@contextmanager
176def mounted_candidate(dmg: Path):
177    """Yield the `Omega.app` inside `dmg`, mounted read-only.
178
179    Every check must bind to one artifact. This existed as `--app`, defaulting
180    to `/Applications/Omega.app`, and two of the four checks read it while the
181    other two read the disk image. An independent review run exactly as
182    documented then returned `accepted` with zero disagreements while
183    `notarization` and `forbidden_strings` were reading a *different candidate*
184    that happened to be installed — the reviewer caught it only by comparing
185    `CFBundleVersion`, the host binary digest and the CDHash by hand.
186
187    A review that can pass against an artifact nobody named is worse than no
188    review, so the app is no longer an input. It comes out of the disk image
189    the claim is about.
190    """
191    mount_point = Path(tempfile.mkdtemp(prefix="omega-review-"))
192    attach = subprocess.run(
193        ["hdiutil", "attach", "-nobrowse", "-readonly", "-quiet",
194         "-mountpoint", str(mount_point), str(dmg)],
195        capture_output=True, text=True,
196    )
197    if attach.returncode != 0:
198        raise ReviewError(f"cannot mount the candidate: {attach.stderr.strip()[:200]}")
199    try:
200        apps = sorted(mount_point.glob("*.app"))
201        if len(apps) != 1:
202            raise ReviewError(
203                f"expected exactly one application in the candidate, found {len(apps)}"
204            )
205        yield apps[0]
206    finally:
207        subprocess.run(["hdiutil", "detach", str(mount_point), "-quiet"],
208                       capture_output=True)
209
210
211def main() -> int:
212    parser = argparse.ArgumentParser()
213    parser.add_argument("--candidate-dmg", type=Path, required=True)
214    parser.add_argument("--producer-claim", type=Path, required=True)
215    parser.add_argument("--obligation", default="omega#16")
216    parser.add_argument("--output", type=Path, required=True)
217    args = parser.parse_args()
218
219    secret, reviewer_pubkey = load_reviewer_key()
220    claim = json.loads(args.producer_claim.read_text(encoding="utf-8"))
221    producers = claim.get("producerPubkeys") or []
222    if not producers:
223        raise ReviewError("producer claim names no producer")
224    if reviewer_pubkey in producers:
225        raise ReviewError("the reviewer key is also a producer key; this is not a review")
226
227    reproductions: list[dict[str, Any]] = []
228    disagreements: list[dict[str, str]] = []
229    inconclusive = False
230
231    def record(check: str, command: str, observed: str, claimed: str) -> None:
232        agrees = observed == claimed
233        reproductions.append(
234            {
235                "check": check,
236                "command": command,
237                "observedDigest": "sha256:" + hashlib.sha256(observed.encode()).hexdigest(),
238                "agreesWithProducer": agrees,
239            }
240        )
241        if not agrees:
242            disagreements.append(
243                {
244                    "criterion": check,
245                    "producerClaim": claimed[:200],
246                    "reviewerObservation": observed[:200],
247                }
248            )
249
250    # 1. The artifact digest, recomputed from the file rather than read.
251    artifact = sha256_file(args.candidate_dmg)
252    record(
253        "artifact_digest",
254        f"shasum -a 256 {args.candidate_dmg.name}",
255        artifact,
256        claim.get("artifactSha256", ""),
257    )
258
259    # Checks 2 to 4 bind to the application inside the candidate, never to
260    # whatever happens to be installed. See mounted_candidate().
261    with mounted_candidate(args.candidate_dmg) as app:
262        binary = app / "Contents" / "MacOS" / "omega"
263
264        # 2. Gatekeeper's own verdict on the candidate's application.
265        ran, output = observe(["spctl", "-a", "-vvv", "-t", "exec", str(app)])
266        if not ran:
267            inconclusive = True
268        else:
269            notarized = "source=Notarized Developer ID" in output
270            record(
271                "notarization",
272                f"spctl -a -vvv -t exec <candidate>/{app.name}",
273                "notarized" if notarized else "not_notarized",
274                claim.get("notarization", ""),
275            )
276
277        # 3. The stapled ticket on the disk image, because the bundler staples
278        #    the image. The application inside it is stapled separately.
279        ran, output = observe(["xcrun", "stapler", "validate", str(args.candidate_dmg)])
280        if not ran:
281            inconclusive = True
282        else:
283            stapled = "The validate action worked" in output
284            record(
285                "stapled_ticket",
286                f"xcrun stapler validate {args.candidate_dmg.name}",
287                "stapled" if stapled else "not_stapled",
288                claim.get("stapled", ""),
289            )
290
291        # 4. Forbidden strings, scanned from the shipped binary. This is the
292        #    check that caught two Zed surfaces a source review had passed.
293        ran, output = observe(["strings", str(binary)])
294        if not ran:
295            inconclusive = True
296        else:
297            found = sorted({needle for needle in FORBIDDEN_STRINGS if needle in output})
298            record(
299                "forbidden_strings",
300                f"strings <candidate>/{app.name}/Contents/MacOS/omega | grep -F <forbidden>",
301                ",".join(found) if found else "none",
302                claim.get("forbiddenStrings", ""),
303            )
304
305    if inconclusive:
306        outcome = "inconclusive"
307        disagreements.append(
308            {
309                "criterion": "reviewer environment",
310                "producerClaim": "all checks reproducible",
311                "reviewerObservation": "one or more checks could not run on this host",
312            }
313        )
314    elif disagreements:
315        outcome = "refused"
316    else:
317        outcome = "accepted"
318
319    receipt: dict[str, Any] = {
320        "schema": SCHEMA,
321        "reviewerPubkey": reviewer_pubkey,
322        "producerPubkeys": producers,
323        "candidateDigest": "sha256:" + artifact,
324        "obligationRef": args.obligation,
325        "reviewedAt": datetime.now(timezone.utc)
326        .isoformat(timespec="seconds")
327        .replace("+00:00", "Z"),
328        "outcome": outcome,
329        "reproductions": reproductions,
330        "disagreements": disagreements,
331    }
332    receipt["evidenceSha256"] = "sha256:" + canonical_digest(receipt)
333    receipt["reviewerSignature"] = sign(receipt["evidenceSha256"].split(":", 1)[1], secret)
334
335    args.output.parent.mkdir(parents=True, exist_ok=True)
336    args.output.write_text(
337        json.dumps(receipt, indent=2, sort_keys=True) + "\n", encoding="utf-8"
338    )
339    print(
340        json.dumps(
341            {
342                "schema": SCHEMA,
343                "outcome": outcome,
344                "reproductions": len(reproductions),
345                "disagreements": len(disagreements),
346                "output": str(args.output),
347            }
348        )
349    )
350    return 0 if outcome == "accepted" else 1
351
352
353if __name__ == "__main__":
354    try:
355        sys.exit(main())
356    except ReviewError as error:
357        print(f"error: {error}", file=sys.stderr)
358        sys.exit(2)
359
Served at tenant.openagents/omega Member data and write actions are omitted.