efr-code-git

LOW
maintainer eggfriedrice 0 votes scanned 2026-10-31 10:01:39.664349
View on AUR
Why flagged

The external downloads in prepare() fetch Zig from ziglang.org (the official Zig project domain) and ghostty from github.com/ghostty-org/ghostty (the official ghostty repo), both verified via minisign with the published Zig project key and git commit hash respectively; this is legitimate build toolchain bootstrapping, not unreviewed remote code execution, though the package is new/low-votes and builds from a personal GitHub repo.

Triggered rules

Low Few votes, recently uploaded zero_votes_recent

Uploaded within the last 14 days with 2 or fewer community votes — little peer review so far.

Low AI review downgraded a static finding llm_review

The static rules flagged this MEDIUM, but an AI model (anthropic/claude-sonnet-4.6) reviewed the full PKGBUILD and judged it LOW (confidence 80%): The external downloads in prepare() fetch Zig from ziglang.org (the official Zig project domain) and ghostty from github.com/ghostty-org/ghostty (the official ghostty repo), both verified via minisign with the published Zig project key and git commit hash respectively; this is legitimate build toolchain bootstrapping, not unreviewed remote code execution, though the package is new/low-votes and builds from a personal GitHub repo.

1 higher static finding superseded - not the current verdict (shown for transparency)
Medium External download from an untrusted host, not in source=() external_download_not_in_source

curl/wget fetches a URL on a non-allowlisted host that is not part of source=(), so it is not checksum-verified by makepkg.

  • PKGBUILD:90 curl -fsSL --retry 3 -o "$zigdir.tar.xz" "https://ziglang.org/download/$zig/$zigdir.tar.xz"
  • PKGBUILD:91 curl -fsSL --retry 3 -o "$zigdir.tar.xz.minisig" "https://ziglang.org/download/$zig/$zigdir.tar.xz.minisig"

PKGBUILD

2 offending line(s) highlighted
1# Maintainer: eggfriedrice <eggfriedricew.g.o@gmail.com>
2
3# Builds efr from the newest commit of main, with the ghostty screen backend. The
4# efr-code package builds the release tag, and efr-code-bin installs its build.
5#
6# The ghostty screen needs a build of libghostty-vt by the exact Zig that
7# docs/ghostty-pin.md pins, from the ghostty commit that it names. Both move on main,
8# so this package reads them from that file of the checkout in prepare(). It fetches
9# ghostty by its commit, and it checks the official Zig build from ziglang.org with
10# the minisign key of the Zig project. It does not use the Zig of the Arch
11# repositories. All downloads happen in the sources and in prepare(); build() needs
12# no network.
13pkgname=efr-code-git
14pkgver=0.0.6.r2250.g8bb1c161
15pkgrel=1
16pkgdesc='Terminal-first AI agent harness that lives in zsh, with a daemon that owns the state (main branch)'
17arch=('x86_64')
18url='https://github.com/eggfriedrice24/eggfriedrice.code'
19license=('MIT')
20depends=('glibc' 'libgcc' 'zsh')
21makedepends=('cargo' 'git' 'minisign')
22# check() runs the tests with nextest, as CI does; the scope tests run git.
23checkdepends=('cargo-nextest' 'git')
24optdepends=('bubblewrap: the kernel sandbox of the auto mode (also needs Linux 7.1 or newer)'
25 'fzf: the live search picker of ,resume (0.46 or newer)'
26 'git: project roots and the git facts of a turn'
27 'xdg-dbus-proxy: read-only system queries in the auto mode (0.1.9 or newer)'
28 'xdg-utils: let efr login openai open the browser with EFR_OPEN_BROWSER=1')
29provides=("efr-code=${pkgver%%.r*}")
30conflicts=('efr-code' 'efr-code-bin')
31# The same file as packaging/efr-code/efr-code.install.
32install=efr-code.install
33# The -flto of makepkg.conf makes GCC write LTO bytecode into the C objects of
34# aws-lc-sys, which the lld of rustc cannot link. The Cargo profile has its own LTO.
35options=('!lto')
36source=("$pkgname::git+$url.git#branch=main")
37b2sums=('SKIP')
38# The minisign key of the Zig project, as https://ziglang.org/download/ shows it.
39_zig_key='RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U'
40
41# Keep debug info in the binaries so makepkg can split it into the -debug package.
42export CARGO_PROFILE_RELEASE_DEBUG=2 CARGO_PROFILE_RELEASE_STRIP=false
43
44# The release version of the workspace, the number of commits and the short commit.
45# The count only grows on main, so a newer commit always has a higher pkgver.
46pkgver() {
47 cd "$pkgname"
48 local version
49 version="$(sed -nE '/^\[workspace\.package\]/,/^\[/s/^version = "([^"]+)"/\1/p' Cargo.toml)"
50 printf '%s.r%s.g%s' "$version" "$(git rev-list --count HEAD)" "$(git rev-parse --short=8 HEAD)"
51}
52
53# The ghostty commit and the Zig version of docs/ghostty-pin.md in the checkout.
54_pin_ghostty() {
55 sed -nE 's/^\| ghostty \| `([0-9a-f]{40})`.*/\1/p' "$srcdir/$pkgname/docs/ghostty-pin.md"
56}
57_pin_zig() {
58 sed -nE 's/^\| Zig \| ([0-9]+\.[0-9]+\.[0-9]+) exactly.*/\1/p' "$srcdir/$pkgname/docs/ghostty-pin.md"
59}
60
61# aws-lc-sys (under rustls) must build its jitter entropy source with -O0 and fails
62# with any other level. cc appends CFLAGS last, so the -O2 of makepkg.conf would win.
63# Without a -O in CFLAGS, cc takes the level of the Cargo profile, so the rest of the
64# C code stays optimized.
65_drop_cflags_optimization() {
66 local flag kept=()
67 for flag in $CFLAGS; do
68 [[ $flag == -O* ]] || kept+=("$flag")
69 done
70 export CFLAGS="${kept[*]}"
71}
72
73prepare() {
74 local ghostty zig zigdir
75 ghostty="$(_pin_ghostty)"
76 zig="$(_pin_zig)"
77 if [[ -z "$ghostty" || -z "$zig" ]]; then
78 echo "no ghostty commit or Zig version in docs/ghostty-pin.md" >&2
79 return 1
80 fi
81 zigdir="zig-$CARCH-linux-$zig"
82
83 cd "$srcdir/$pkgname"
84 export RUSTUP_TOOLCHAIN=stable
85 cargo fetch --locked --target host-tuple
86
87 # Zig of the pin, checked against the key of the Zig project before it runs.
88 cd "$srcdir"
89 rm -rf zig "$zigdir" "$zigdir.tar.xz" "$zigdir.tar.xz.minisig"
90 curl -fsSL --retry 3 -o "$zigdir.tar.xz" "https://ziglang.org/download/$zig/$zigdir.tar.xz"
91 curl -fsSL --retry 3 -o "$zigdir.tar.xz.minisig" "https://ziglang.org/download/$zig/$zigdir.tar.xz.minisig"
92 minisign -V -q -P "$_zig_key" -m "$zigdir.tar.xz"
93 mkdir zig
94 tar -xJf "$zigdir.tar.xz" -C zig --strip-components=1
95
96 # ghostty at the commit of the pin. git checks the commit by its hash.
97 rm -rf ghostty
98 git init -q ghostty
99 git -C ghostty fetch -q --depth 1 https://github.com/ghostty-org/ghostty.git "$ghostty"
100 git -C ghostty -c advice.detachedHead=false checkout -q FETCH_HEAD
101
102 # The Zig packages of the ghostty build. Zig fetches them into zig-pkg/ of the
103 # ghostty source, where build() finds them. A lazy package is fetched only when
104 # the build asks for it, and --help asks for the ones of these options, so they
105 # must stay the options that libghostty-vt-sys's build.rs passes; zig build
106 # --fetch=all would fetch about 550 MB instead of 30 MB.
107 cd "$srcdir/ghostty"
108 ZIG_GLOBAL_CACHE_DIR="$srcdir/zig-global-cache" "$srcdir/zig/zig" build \
109 -Demit-lib-vt=true -Doptimize=ReleaseFast -Dcpu=baseline \
110 -Demit-xcframework=false -Dapp-runtime=none --help > /dev/null
111}
112
113build() {
114 cd "$pkgname"
115 export RUSTUP_TOOLCHAIN=stable
116 export CARGO_TARGET_DIR=target
117 # libghostty-vt-sys runs zig from PATH and builds this ghostty source with the
118 # packages from prepare(); docs/ghostty-pin.md lists its variables.
119 export PATH="$srcdir/zig:$PATH"
120 export GHOSTTY_SOURCE_DIR="$srcdir/ghostty"
121 export ZIG_GLOBAL_CACHE_DIR="$srcdir/zig-global-cache"
122 export LIBGHOSTTY_VT_SYS_CPU=baseline
123 _drop_cflags_optimization
124 # The packages and the feature of `just build-release`.
125 cargo build --frozen --release -p efr-daemon -p efr-cli -p efr-sbx \
126 --features efr-daemon/screen-ghostty
127
128 # A build with the sandbox's test seams lets a test replace the launcher and the
129 # probe; it must never ship.
130 if [[ "$(target/release/efrd --test-seams)" != off ]]; then
131 echo "target/release/efrd has the test-sandbox-fake feature" >&2
132 return 1
133 fi
134}
135
136check() {
137 cd "$pkgname"
138 export RUSTUP_TOOLCHAIN=stable
139 export CARGO_TARGET_DIR=target
140 # The leaf crates of the justfile, as `just test-leaf` runs them. The other tests
141 # need a real zsh session, bubblewrap and a kernel sandbox, which a build chroot
142 # does not have. nextest runs each test in a process of its own, as the tests
143 # expect: some of them install a log subscriber for their thread only.
144 local crate crates args=()
145 read -ra crates <<<"$(sed -nE 's/^leaf_crates := "(.*)"$/\1/p' justfile)"
146 if (( ${#crates[@]} == 0 )); then
147 echo "no leaf_crates in the justfile" >&2
148 return 1
149 fi
150 for crate in "${crates[@]}"; do
151 args+=(-p "$crate")
152 done
153 _drop_cflags_optimization
154 INSTA_UPDATE=no cargo nextest run --frozen "${args[@]}" --lib --tests
155}
156
157package() {
158 cd "$pkgname"
159 install -Dm0755 -t "$pkgdir/usr/bin/" target/release/efr target/release/efrd
160 # efrd finds its sandbox launcher in ../lib/efr/ next to its own directory. It is
161 # never on PATH.
162 install -Dm0755 -t "$pkgdir/usr/lib/efr/" target/release/efr-sbx
163 install -Dm0644 -t "$pkgdir/usr/share/zsh/plugins/efr/" shell/zsh/efr.plugin.zsh
164 # The unit of `just install` with the daemon in /usr/bin.
165 install -dm0755 "$pkgdir/usr/lib/systemd/user"
166 sed 's|^ExecStart=%h/\.local/bin/efrd$|ExecStart=/usr/bin/efrd|' systemd/efrd.service \
167 > "$pkgdir/usr/lib/systemd/user/efrd.service"
168 grep -qx 'ExecStart=/usr/bin/efrd' "$pkgdir/usr/lib/systemd/user/efrd.service"
169 # Each background job runs in a cgroup of its own below efrd's (ADR 0021).
170 grep -qx 'Delegate=yes' "$pkgdir/usr/lib/systemd/user/efrd.service"
171 install -Dm0644 -t "$pkgdir/usr/share/licenses/$pkgname/" LICENSE
172 install -Dm0644 -t "$pkgdir/usr/share/doc/efr-code/" README.md \
173 docs/config.md docs/permissions.md docs/sandbox.md
174 install -Dm0644 -t "$pkgdir/usr/share/doc/efr-code/examples/" crates/efr-config/examples/config.toml
175}
176

Scan history

Scanned at (UTC)SeverityRules
2026-10-31 10:01:39 Low 3
2026-10-31 09:58:05 Medium 2

Report a package

Reports go to the AURWatch maintainer (one person) and are read by hand. No login required.

0 / 4000
Your suggestion