/usr/src tools build standalone, which need prereqsDeep-dive investigation triggered by CI failure on PR #107 (drop FreeBSD-rescue pkg, build /rescue/ from /usr/src): the standalone make -C rescue/rescue failed because rescue/rescue's crunchgen pulls in lib/libifconfig which generates a header at lib build time. Question: how many other tools have this kind of prereq, and what's the right scope for srclist-rescue.txt and srclist-runtime.txt in tickets #104 / #105?
TL;DR. Three findings, in order of importance:
/rescue/ — ever. macOS recovery is a separate Recovery partition (recoveryOS), not a directory of statically-linked tools. Per architectural rule 3 ("don't invent things Apple doesn't do"), the right answer for ticket #104 is to drop FreeBSD-rescue entirely and not replace it. Issue #104 + PR #107 closed 2026-05-26. See §2.srclist-fbsdglue.txt = 25 entries after iter 2 minimal-shippable cut (down from initial 44 estimate). BSD-debug toolkit (fstat/sockstat/procstat/kdump/ktrace/strings/top/vmstat/etc.) DEFERRED to #120 — nothing in current CI needs them and they pull in FreeBSD privatelib chains (libsysdecode/libelftc/libprocstat) for marginal benefit; add back when actual debug sessions demand them. The other ~175–200 binaries come from Apple sources. Nine sequential PRs (§9.2): #105a iter 1 (mechanism + minimal; PR #118 merged), #105a iter 2 (25-entry shippable; PR #119 in flight), then #105b file_cmds → #105g network_cmds → #105h final pkg drop. Each PR is shippable; CI green throughout; OpenPAM iter-3 overlay-overwrite pattern. On future Linux port, fbsdglue entries swap 1:1 for Linux equivalents (modprobe/util-linux/strace/…) and the Apple-source userland transfers identically.buildworld needed anywhere. Per-subdir make against pkgbase-installed headers/libs is sufficient. CI budget: trivial — only ~25–30 entries to build from /usr/src, the rest from Apple sources we vendor under src/./rescue/? (No.)PR #107 (proof-of-concept for ticket #104) failed CI with this error:
lib/libifconfig/libifconfig_sfp.h:33:10: fatal error:
'libifconfig_sfp_tables.h' file not found
*** Error code 1
Stop.
That header is generated at lib build time by sfp.lua in lib/libifconfig/Makefile. Standalone make -C rescue/rescue doesn't trigger the prerequisite lib/libifconfig build, so the header never exists in ${OBJTOP}/lib/libifconfig/ when the crunchgen step needs it.
The question this investigation answers: is this prereq pattern an outlier, or pervasive? If pervasive, the manifest-driven build mechanism in srclist-rescue.txt / srclist-runtime.txt needs significant scaffolding (full buildworld prologue, etc.). If outlier, we can drop the offending tools and keep the simple per-subdir make pattern.
Four parallel research agents inventoried four orthogonal facets:
buildworld does and how long it costs (agent 2)/usr/src dirs (agent 3)/rescue/? (No.)This question wasn't part of the original investigation but came up reviewing the data. The answer reframes ticket #104 significantly.
macOS has never had a /rescue/ directory. Apple's recovery story is a separate Recovery partition (recoveryOS) — an entire stripped-down macOS image living on its own APFS volume in the same container. Boot paths:
| Mechanism | How it works |
|---|---|
| Cmd+R at boot (Intel Macs) | Boots into the local Recovery partition's recoveryOS. Provides Disk Utility, Terminal, Safari, Reinstall macOS, Time Machine restore. |
| Cmd+Option+R (Intel Macs) | Internet Recovery — downloads recoveryOS over network. |
| Long-press Power button (Apple Silicon) | Brings up Startup Options menu including Recovery. |
Single-user mode (boot -s, Intel only) | Boots normal macOS but drops to /bin/sh before launchd starts services. Uses regular /bin and /sbin, not a separate rescue dir. |
| Safe Boot (Shift at boot) | Normal macOS with extension loading restricted. |
Crucially: no statically-linked emergency-tools directory exists on macOS at any path. If /bin/sh or /sbin/mount is broken, you boot recoveryOS (a separate OS image) and use its tools instead. The convention of "one statically-linked crunchgen binary with command-name symlinks at /rescue/" is BSD-only.
/rescue/FreeBSD's /rescue/ is a single statically-linked multi-call binary built via crunchgen that ships every essential tool name as a symlink (ls, cp, mv, sh, mount, fsck, kldload, etc.). The rationale: if /usr is unmountable or /lib is corrupted, /rescue/ still works because nothing it does requires shared libraries.
Worth noting: FreeBSD's single-user mode also drops to /bin/sh first (just like macOS), and only escalates to /rescue/sh if /bin/sh can't execute (e.g., /lib/libc.so.7 missing). The path of recovery is layered: shared-lib tools first, statically-linked rescue tools as fallback.
freebsd-launchd-machWe're building a live ISO that boots in QEMU for CI testing and on real hardware as a dev/research environment. We're not building a production OS where someone's data hangs on recovering from a corrupted /lib. The actual failure modes we care about:
So per architectural rule 3 ("don't invent things Apple doesn't do"), and per practical need: we don't need /rescue/ at all.
The original framing of #104 ("Drop FreeBSD-rescue pkg; build /rescue/ from /usr/src") is solving the wrong problem. The right framing is: drop FreeBSD-rescue pkg; don't replace it. /rescue/ simply doesn't exist on our ISO. Single-user mode (if anyone invokes it) falls through to /bin/sh from FreeBSD-runtime (ticket #105 will continue to provide that via bin/sh in srclist-runtime.txt).
This eliminates the entire crunchgen + libifconfig prereq question for #104. The "proof-of-concept for the manifest mechanism" claim of #104 stays valid — we still need the manifest mechanism for #105's runtime+utilities replacement — but we don't need to exercise it on rescue. We can validate the mechanism on a single leaf tool (e.g. building bin/echo from src) as a smaller proof-of-concept, then move directly to #105.
Updated recommendation for #104: close PR #107 in favor of a simpler one that just drops the FreeBSD-rescue pkgbase line and adjusts run.sh + boot-test.sh to expect /rescue/ to NOT exist (rather than to exist with src-built contents). Optionally pick a different proof-of-concept tool for the manifest mechanism — or skip the proof and go straight to #105's smaller-scoped runtime work where the mechanism is actually load-bearing.
Inventoried live from pkg.freebsd.org/FreeBSD:14:amd64/base_latest/ pkgbase manifests on 2026-05-26.
| Pkg | Binaries | Distinct /usr/src dirs | Notes |
|---|---|---|---|
FreeBSD-runtime | 187 | ~96 | Includes 27 LINK aliases of sbin/md5 (md5sum, sha1, sha256, etc.) + reboot family (halt/poweroff/fastboot) + ln/link, pkill family, etc. After collapsing LINKs: ~96 distinct dirs. |
FreeBSD-utilities | 604 | ~330 | The long tail. ~245 usr.bin/*, ~70 usr.sbin/*, ~15 libexec/*, plus ~20 contrib/ consumers (less, gzip, bzip2, xz, zstd, libarchive, mandoc, ldns, ntp, sendmail, tcpdump, dialog, …). |
FreeBSD-rescue | 148 | 0 new | All 148 files in /rescue/ are hardlinks of one crunchgen multi-call binary (rescue/rescue). Every source dir is already in runtime or utilities — no new src dirs needed. |
Combined runtime + utilities (the scope of srclist-runtime.txt): | ~400 dirs | 791 binaries | |
Rescue contributing zero new dirs is a useful finding: once srclist-runtime.txt covers runtime + utilities, we have everything we need to also re-build the rescue crunchgen.
Curated 48-tool sample focused on the v3-plan "irreducible /usr/src" set + key daily-driver tools. Each tool's Makefile inspected directly for LIBADD + generated-header chains.
| Category | Count | % | Build pattern | Examples |
|---|---|---|---|---|
| A — Leaf (pure libc) | 25 | 52% | make -C dir obj && make && make install works trivially. No LIBADD, no generated headers. | kldload, kldunload, devfs, reboot, cp, mv, rm, mkdir, cat, chmod, echo, ln, test, find, xargs, sed, grep, true, false, mdmfs, newfs_msdos, dumpon (MK_OPENSSL=no), ... |
| B — Lib-dependent (prebuilt libs in pkgbase) | 22 | 46% | Standalone make works because libs are already in /usr/lib from pkgbase clibs / utilities / etc. | kldstat (libutil), mdconfig (libgeom), geom, savecore (libxo+z+zstd), mount (libutil+xo), fsck_ffs (libufs), newfs, tunefs, init (libcrypt), login (libpam+bsm), getty, sysctl (libjail), dmesg (libkvm), ls (libutil+termcapw), gzip (libbz2+lzma+z+zstd), tar (libarchive), ... |
| C — .PATH into sibling source | 8 | 17% (overlap with B) | Works fine if full /usr/src checkout is present (it is, via src.txz). No buildworld needed. | sh (uses bin/kill, bin/test, usr.bin/printf sources via .PATH), awk (contrib/one-true-awk), csh (contrib/tcsh), umount (.PATH onto sbin/mount), fsck_msdosfs (.PATH onto sbin/fsck), fsck_ffs (.PATH onto sys/ufs/ffs), newfs (.PATH onto sys/geom), tar (contrib/libarchive) |
| D — Crunchgen with lib-build prereq | 1 | 2% | Fails standalone. Crunchgen pulls in libifconfig.a via CRUNCH_LIBS+= ${OBJTOP}/lib/libifconfig/libifconfig.a AND a -I ${OBJTOP}/lib/libifconfig include path that depends on the generated libifconfig_sfp_tables.h. | rescue/rescue (the only one) |
E — Full buildworld required | 0 | 0% | n/a | (none in the inventory) |
Result: 47 of 48 tools (98%) build standalone with make -C dir obj && make && make install DESTDIR=... against a stock FreeBSD-runtime target plus a full /usr/src checkout. Only rescue/rescue requires a prereq step.
From Makefile.inc1 + freebsd-launchd-mach's own build.sh / GitHub Actions inspection.
| Build approach | Wall time on 4-vCPU VM | Notes |
|---|---|---|
Full make buildworld | 45–90 min | Cold cache (vmactions reality — no /usr/obj populated). The _cross-tools phase (rebuilding clang+lld+lldb) is the single biggest cost at 8–15 min. |
Stacked WITHOUT_* knobs (CLANG+LLD+LLDB+TESTS+MAN+LIB32+NLS+PROFILE+GAMES) + WITHOUT_CLEAN | 20–30 min | Floor. Still over our 15-min CI budget. |
SUBDIR_OVERRIDE=lib/libifconfig make buildworld | ~15 min | Still runs _cross-tools prologue. Saves everything phase but not bootstrap. |
Per-subdir make -C lib/libifconfig obj && make | ~30 sec | Uses host's clang + headers + libc already in /usr/lib. Just builds that one lib's .a + populates its obj dir with the generated header. This is the right pattern for one-off prereqs. |
Per-subdir make -C bin/cp obj && make && make install (leaf) | ~5–15 sec | The existing build.sh step 3a2 pattern. Works for every Category A / B / C tool. |
Recommendation from agent 2: stay on the leaf-only pattern (already validated by step 3a2 for rescue/rescue). Treat any "needs full buildworld" finding as a signal to drop the tool, not to add buildworld machinery. CI budget remains at ~15 min for the whole pipeline.
/usr/src/lib/The actual landmines — libs whose Makefile runs code-gen at build time, producing headers that external consumers need:
| Lib | Generator | Generated headers | External consumers in our scope |
|---|---|---|---|
lib/libifconfig | sfp.lua (src.lua.mk) | libifconfig_sfp_tables.h, libifconfig_sfp_tables_internal.h | sbin/ifconfig, rescue/rescue crunchgen |
lib/libpcap | yacc/bison | tokdefs.h from grammar.h | sbin/ipf (rescue), tcpdump (utilities), many others outside scope |
lib/libsysdecode | mktables sh + mkioctls | tables.h, tables_linux.h, ioctl.c | kdump, truss (utilities; not load-bearing) |
lib/ncurses/{tinfo,ncurses} | sh + awk MK* scripts | term.h, curses.h, init_keytry.h, nomacros.h, hashsize.h, parametrized.h (6 headers) | None in our srclist scope — ls and less link against the installed libtermcapw.a from pkgbase clibs, not requiring rebuild. |
| libfetch, libedit, libsm*, libypclnt | (internal codegens) | (internal headers) | None — codegen is intra-lib, builds in a single make pass. |
| Sub-tool | Source dir | Generated-header dep | Decision | Why |
|---|---|---|---|---|
ifconfig | sbin/ifconfig | libifconfig | DROP | Emergency-mode rescue rarely needs full ifconfig. Apple's network_cmds/ifconfig in v3 plan replaces /sbin/ifconfig later anyway. |
ipf | sbin/ipf/ipf | libpcap | DROP | Packet filter not needed in single-user/emergency shell. |
| All other ~70 crunchgen entries | various | None (verified) | KEEP | Including iscsictl/iscsid (libiscsiutil has NO codegen — that was a red herring in earlier analysis), ping/ping6, dhclient, pfctl, ipfw, zfs/zpool/zdb, camcontrol, geom/fdisk/bsdlabel, md5, savecore, mount/mount_*, fsck/fsck_*, sh/ls/ps/cp/etc., nc/tar/gzip/bzip2/xz/zstd/less/vi. |
Net rescue change: patch rescue/rescue/Makefile to remove ~7 lines (the ifconfig entry + the MK_IPFILTER ipf block + the CRUNCH_LIBS+= libifconfig.a + the CRUNCH_BUILDOPTS+= -I ${OBJTOP}/lib/libifconfig + the CRUNCH_LIBS_ifconfig+= ${LIBNV}). After that, crunchgen has no external lib-build prereqs.
Of 96 distinct /usr/src dirs in FreeBSD-runtime, exactly one binary force the libifconfig prereq:
| Installed path | /usr/src dir | Generated-header LIBADD | Decision | Why |
|---|---|---|---|---|
/sbin/ifconfig | sbin/ifconfig | libifconfig | DROP from srclist-runtime.txt | Apple network_cmds/ifconfig replacement on roadmap. Same rationale as rescue's ifconfig. |
| All other 95 dirs | various | None | KEEP | cat, chmod, cp, ls, mv, rm, init, mount, fsck, login, getty, sysctl, dmesg, sh, etc. Empty LIBADD or libutil/libmd/libxo/libjail/libcrypt/libgeom only. |
Net runtime change: srclist-runtime.txt will list ~95 dirs (instead of 96); /sbin/ifconfig stays missing on the ISO until ticket #106's first per-tool Apple swap (or until network_cmds/ifconfig port lands as a separate per-Apple-repo ticket later in the v3 plan).
Agent 4 spot-checked the utilities list. Two more potential concerns surfaced:
| Installed path | /usr/src dir | Concern | Decision |
|---|---|---|---|
/usr/bin/kdump, /usr/bin/truss | usr.bin/{kdump,truss} | LIBADD libsysdecode (has codegen) | drop or keep — not load-bearing for boot. Drop unless someone needs them. |
| (others) | various | None confirmed | KEEP |
Conclusion: the universe of "tools with generated-header lib prereqs" is essentially {ifconfig, ipf, kdump, truss, tcpdump (libpcap)} across all three pkgs. Everything else builds clean per-subdir.
The data + the Apple-shape reframing (§2) settle the question decisively:
/rescue/ entirely. Per rule 3 (don't invent things Apple doesn't do): Apple has Recovery partition, not /rescue/ directory. Eliminates the rescue crunchgen / libifconfig prereq problem at its root.build.sh step 3a2 wiring is right; just point it at a different srclist file./sbin/ifconfig from srclist-runtime.txt — matches the existing Apple-userland-cmds v3 plan (network_cmds replacement).kdump/truss in utilities — drop unless someone needs them; otherwise add lib/libsysdecode as a prereq entry.Close PR #107 (the "build /rescue/ from src" approach) and open a simpler PR:
FreeBSD-rescue commented out in pkglist-base.txt (as PR #107 already did).srclist-rescue.txt — we don't need it; the manifest mechanism gets proven in #105 instead.RESCUE-SRC-OK check to instead verify /rescue/ does NOT exist (Apple-shape sanity check). Or just remove the check entirely — absence-of-/rescue/ is a trivial filesystem state, not really worth a CI gate.RESCUE-SRC-OK expect block (or change to RESCUE-ABSENT-OK matching the run.sh change).This is much smaller than PR #107: it's the original pkglist-base.txt change + a small run.sh + boot-test.sh delta. ~10 LOC net change, no new files.
Proof-of-concept for the manifest mechanism (the second rationale for #104) doesn't need rescue. It gets proven naturally by #105 (drop runtime + utilities, build from manifest). If we want a tiny standalone POC first, build a single leaf tool (bin/echo or usr.bin/yes) via a one-entry manifest — that exercises the build.sh wiring without engaging the rescue/crunchgen prereq problem.
Major reframing (2026-05-26 evening): the v3 plan's "drop FreeBSD-runtime, ship interim FreeBSD-source from /usr/src" approach is wrong for the project's actual long-term goal. The user's ultimate goal is future Linux portability — the freebsd-launchd-mach stack should one day run on Linux too. FreeBSD-source binaries can't port to Linux; Apple-source binaries can (with platform-shim work, same pattern as macOS → FreeBSD already proven on libxpc/libdispatch/configd/PAM/etc.).
So: port the Apple userland-cmds repos now, alongside #105, and only ship from srclist-fbsdglue.txt for the ~30-35 irreducibly-platform-specific items (combined runtime + utilities). The earlier 47-KEEP / 21-REPLACE / 15-DEFER / 13-DROP breakdown was scoped under the wrong assumption.
The single rule that drives every classification:
srclist-fbsdglue.txt for now.Prior plan revisions distinguished "REPLACE-now (Apple value-add)" from "KEEP (Apple version is same)" — that distinction is gone. Whole-repo porting means whole-repo replacement.
Re-auditing the original 47-KEEP list under the strict "is there an Apple counterpart?" test, only ~13 entries are truly FreeBSD-only:
| /usr/src dir | Why FreeBSD-only | Linux equivalent (future) |
|---|---|---|
| bin/freebsd-version | FreeBSD release version reporter | lsb_release / /etc/os-release |
| bin/kenv | FreeBSD-only kernel environment | /proc/cmdline + custom parsing |
| sbin/camcontrol | FreeBSD CAM/SCSI control | lsblk + smartctl |
| sbin/devfs | FreeBSD devfs.rules subsystem | udev / systemd-udev rules |
| sbin/fsck | FreeBSD UFS fsck driver | e2fsck / fsck.ext4 |
| sbin/mount, umount | FreeBSD VFS mount | util-linux mount/umount |
| sbin/kldconfig, kldload, kldstat, kldunload, usr.sbin/kldxref | FreeBSD kld(4) module family | modprobe/lsmod/rmmod/depmod (kmod) |
| sbin/ldconfig | FreeBSD rtld hint cache | glibc ldconfig (different binary, same purpose) |
| usr.sbin/pw | FreeBSD user/group mgmt | useradd/usermod/groupadd |
That's the entire "must-stay-platform-source" set: ~13 entries in srclist-fbsdglue.txt on FreeBSD. On a future Linux port, the same 13 paths get filled by the Linux equivalents above. Everything else — the other 89%+ of daily-driver userland — comes from Apple sources and ports identically across platforms.
Each entry below was previously "KEEP" under the old "Apple version is identical, no urgency" reasoning. Under the strict rule (whole-repo porting means whole-repo replacement), they all flip to REPLACE because they live inside Apple userland-cmds repos we're vendoring:
| Apple repo | KEEP entries that should be REPLACE |
|---|---|
file_cmds | bin/cat, chflags, dd, ln, mkdir, realpath, rm, rmdir, sync, usr.bin/install |
shell_cmds | bin/echo, expr, pwd, sh, sleep, test, date, usr.bin/mktemp, env, uname, logger |
adv_cmds | bin/df, du, kill, pgrep, stty, groups, id |
text_cmds | bin/tr |
system_cmds | sbin/md5 (27 hash aliases → Apple md5/shasum family), usr.bin/passwd, usr.sbin/pwd_mkdb |
| upstream contrib (vendor directly, not via FreeBSD pkg) | usr.bin/bsdtar (libarchive), less, ncurses |
Combined with the original 21 already-REPLACE entries: ~34 KEEP-now entries reclassified to REPLACE. Everything except the 13-entry FreeBSD-glue set gets sourced from Apple repos (or upstream contrib for libarchive/less/ncurses).
srclist-fbsdglue.txt mechanism FIRST, then Apple-repo portsTwo patterns are in flight:
pkg set -A 0 FreeBSD-runtime FreeBSD-utilities FreeBSD-pam-lib blocks autoremove. Low risk.srclist-fbsdglue.txt per-subdir /usr/src builds — just had PR #107 fail on the libifconfig prereq. High risk — the actual unknown. Other generated-header libs (libsysdecode for kdump/truss, etc.) may surface similar prereqs.Therefore: validate the FreeBSD-glue mechanism as iter 1, before committing to six months of Apple-repo ports built on top of it.
| PR | What lands | Risk |
|---|---|---|
| #105a iter 1 | srclist-fbsdglue.txt mechanism + minimal entries (~10-11). Boot-critical leaf binaries only: kld* family, mount, umount, fsck, devfs, ldconfig, kenv, freebsd-version. All Category A or B per §4 agent 1 (leaf libc / standard libs only — no codegen prereqs). Overlay onto FreeBSD-runtime paths; FreeBSD-runtime stays installed. CI marker FBSDGLUE-MIN-OK. This is the iter that validates the mechanism. | HIGH — mechanism unproven post-#107 failure |
| #105a iter 2 | Expand srclist-fbsdglue.txt to the full 44 entries (§9.6.6 ready-to-paste). Includes codegen-prereq cases (kdump/truss link libsysdecode, which has its own mktables-generated headers — same shape as libifconfig prereq from PR #107). Add lib/libsysdecode as a prereq entry above kdump/truss in the manifest. Validate ordered-manifest semantics work. | Medium |
| #105b | file_cmds port — 27 Apple binaries (cat, cp, mv, ls, chmod, chflags, chown, dd, df, du, gzip, install, ln, mkdir, mkfifo, mknod, mtree, pax, rm, rmdir, stat, touch, truncate, …). Overlay /bin + /usr/bin paths. pkg set -A 0 applied. CI markers per binary. First Apple-repo port via overlay pattern. | Low |
| #105c | shell_cmds port — ~45 binaries. /bin/sh swap is load-bearing; basename/dirname/echo/env/expr/find/getopt/hexdump/jot/kill/mktemp/printf/seq/sleep/test/tee/true/false/uname/xargs/… | Low |
| #105d | adv_cmds port — 15 binaries. /bin/ps and /bin/pkill (Apple kinfo_proc layout shim). Also: stty, tty, finger, last, whois, locale, localedef, cap_mkdb, gencat, tabs, lsvfs. | Low-Medium (kinfo_proc shim) |
| #105e | text_cmds port — 34 binaries. sort (Mach semaphores) + grep/sed/tr/wc/tail/head/uniq/comm/cut/paste/… (pure POSIX vendor). | Low |
| #105f | system_cmds port — ~50 binaries. The big one: getty, login, sysctl, dmesg, halt/shutdown/reboot, dynamic_pager, hash family (md5/sha1/sha256/… 27 aliases), passwd, pwd_mkdb. Subsumes ticket #106 (getty swap) entirely. | Medium (mach.ko traps for lsmp/hostinfo/stackshot) |
| #105g | network_cmds port — 15 binaries: ifconfig, ping, ping6, route, arp, ndp, rtadvd, rtsol, netstat, traceroute, traceroute6, kdumpd. Resolves the libifconfig prereq permanently — Apple's ifconfig replaces FreeBSD's at /sbin/ifconfig. | Low-Medium (struct ABI drift) |
| #105h | Final pkg drop — comment out FreeBSD-runtime + FreeBSD-utilities + FreeBSD-pam-lib lines in pkglist-base.txt. Trivial 3-line PR. Closes #103 (pam-lib phantom). | Trivial |
Why this ordering is better than "Apple repos first":
Concretely for #105a (file_cmds port, the first PR):
apple-oss-distributions/file_cmds into src/file_cmds/ at a pinned tagpkg set -A 0 FreeBSD-runtime FreeBSD-utilities applied right after pkg install (mirrors the OpenPAM iter-3 pattern at build.sh:175-198)FILECMD-CP-OK (verify Apple cp via clonefile attempt or Apple-specific behavior), FILECMD-LS-OK (verify -e flag for ACL display works), etc.Per-iteration scope thereafter is the same shape: vendor one Apple repo, build all its binaries, overlay onto pkgbase paths, ship. No interim srclist mechanism needed until #105g when the final pkg drop happens.
The srclist mechanism (and srclist-rescue.txt's failed shape from PR #107) is no longer load-bearing. It's only needed for the final ~13-entry fbsdglue manifest at #105g, which is tiny and trivial.
Applying the simple two-bucket rule (REPLACE if Apple has it; KEEP only if kernel-bound or BSD-specific debug tool). Supersedes all prior per-tool verdict tables in this doc.
| /usr/src dir | Why no Apple equivalent | Linux equivalent (future) |
|---|---|---|
| bin/freebsd-version | FreeBSD release reporter | /etc/os-release |
| bin/kenv | FreeBSD kernel env interface | /proc/cmdline |
| sbin/camcontrol (deferred 2026-05-26 — see §9.6.2) | FreeBSD CAM/SCSI | lsblk + smartctl |
| sbin/devfs | FreeBSD devfs.rules subsystem | udev |
| sbin/fsck | FreeBSD UFS fsck driver (UFS2 + SU+J port "too much work" per user) | fsck.ext4 / e2fsck |
| sbin/kldconfig, kldload, kldstat, kldunload | FreeBSD kld(4) | modprobe/lsmod/rmmod |
| sbin/ldconfig | FreeBSD rtld hint cache | glibc ldconfig |
| sbin/mount, umount | FreeBSD VFS | util-linux mount/umount |
| usr.sbin/kldxref | FreeBSD kld(4) cache | depmod |
| usr.sbin/pw | FreeBSD user/group mgmt | useradd/groupadd |
| FreeBSD-specific debug tools (no Apple analogue): | ||
| usr.bin/fstat, sockstat, procstat | FreeBSD-specific process/socket introspection (Apple uses lsof + sample). (fuser is a LINK from usr.bin/fstat — binary appears at /usr/bin/fuser via fstat's Makefile LINKS=.) | lsof / ss / fuser (procps) |
| usr.bin/ktrace, kdump, truss, ktrdump | FreeBSD ktrace/truss (Apple uses dtrace/sample) | strace |
| usr.bin/ldd | FreeBSD-specific rtld query (Apple uses otool -L) | ldd (glibc) |
| usr.bin/getent | BSD-specific NSS query (Apple uses dscacheutil). (login_cap was a phantom — libutil function not a binary; logname is REPLACE via shell_cmds; hostid dropped — not a FreeBSD binary, /etc/rc.d/hostid is a script and we don't run /etc/rc.) | various |
| usr.bin/top, w, vmstat | BSD vmstat/top format | procps top/w/vmstat |
| usr.sbin/devctl, diskinfo, fstyp, gstat, pciconf, crashinfo | FreeBSD-specific newbus/GEOM/PCI/crash tools | various (udev/lspci/...) |
| libexec/save-entropy | FreeBSD entropy daemon | systemd-random-seed |
Net KEEP set: ~25–30 entries combined runtime + utilities. This is srclist-fbsdglue.txt's permanent content on FreeBSD; on Linux these get swapped 1:1 with the Linux equivalents above.
Every other entry from the original FreeBSD-runtime (187 binaries) + FreeBSD-utilities (604 binaries) inventory that's NOT DEFER or DROP. Per-repo mapping:
| Apple repo (v3 roadmap) | Sample entries it covers |
|---|---|
file_cmds (27 binaries) | cat, chflags, chmod, chown, chgrp, cp, dd, df, du, gzip, install, ln, ls, mkdir, mkfifo, mknod, mtree, mv, pax, rm, rmdir, stat, sync, touch, truncate |
shell_cmds (~45) | basename, chroot, date, dirname, echo, env, expr, find, getopt, hexdump, hostname, jot, kill, lastcomm, lockf, logname, mktemp, nice, nohup, pwd, realpath, renice, script, seq, sh, shlock, sleep, stdbuf, tee, test, time, true, false, tty, uname, w, who, xargs, yes, id, su, killall, path_helper, logger |
adv_cmds (15) | cap_mkdb, finger, gencat, last, locale, localedef, lsvfs, pkill, ps, stty, tabs, tty, whois, colldef |
text_cmds (34) | banner, bintrans, cat, col, colrm, column, comm, csplit, cut, ed, expand, fmt, fold, grep, head, join, lam, look, md5, nl, paste, pr, rev, rs, sed, sort, split, tail, tr, ul, unexpand, uniq, unvis, vis, wc |
system_cmds (~50) | arch, at, atrun, accton, chkpasswd, chpass, cpuctl, dmesg, dynamic_pager, fs_usage, gcore, getconf, getty, hostinfo, iosim, iostat, kpgo, latency, login, lskq, lsmp, ltop, mean, memory_pressure, mkfile, mslutil, newgrp, nologin, nvram, pagesize, passwd, proc_uuid_policy, purge, pwd_mkdb, reboot, sa, sc_usage, shutdown, stackshot, sysctl, taskpolicy, vipw, wait4path, zdump, zic, halt(family) |
network_cmds (15) | arp, dnctl, ifconfig, kdumpd, ndp, netstat, ping, ping6, rarpd, route, rtadvd, rtsol, spray, traceroute, traceroute6 |
PowerManagement (~6) | caffeinate, pmset, pmtool, pmconfigd, ioupsd, swd |
DiskArbitration (~4) | diskarbitrationd, autodiskmount, DiskArbitrationAgent, datest |
| Upstream contrib (vendored separately) | usr.bin/bsdtar (libarchive), less, ncurses (tic/tput/clear/…), tcpdump, mandoc/man/manpath, awk (one-true-awk), bmake |
Net REPLACE set: ~175–200 binaries land via the seven sequential Apple-repo ports (#105a–#105g sequencing in §9.2). Until each port lands, FreeBSD-runtime + utilities pkgs stay installed (overlay-overwrite pattern); after all ports land, those pkgs drop entirely in #105g.
~15 entries: bin/ed, bin/getfacl, bin/setfacl, bin/nproc, bin/uuidgen, sbin/comcontrol, sbin/conscontrol, sbin/dumpon, sbin/fsck_msdosfs, sbin/mknod, sbin/mount_fusefs/msdosfs/nullfs, sbin/newfs_msdos, sbin/recoverdisk, sbin/swapon, usr.bin/bzip2-scripts, usr.bin/limits, usr.bin/what, usr.sbin/ip6addrctl, plus the utilities DEFER list (BSM audit, cron/at, NTP suite, NFS bits, on-target compile toolchain, etc.). Re-evaluate when a real consumer surfaces.
Confirmed dead per build.sh inspection or superseded by in-repo daemons:
sbin/adjkerntz (UTC-only), sbin/bsdlabel + sbin/fdisk (GPT-only boot), sbin/ddb (in-kernel), sbin/etherswitchcfg (HW we don't have), sbin/init (launchd PID 1), sbin/mdconfig + mdmfs + sbin/mount_mfs + sbin/mount_cd9660 + sbin/mount_udf + sbin/mount_unionfs (no memdisk/unionfs/UDF path), sbin/routed (no RIP), sbin/savecore (core dumps disabled), bin/hostname (covered by shell_cmds REPLACE actually — reclassify), usr.sbin/service (launchctl owns service lifecycle), usr.sbin/services_mkdb (rc.d-only; flat-file fallback works; no Apple equivalent in any v3 repo), usr.sbin/sysrc (no /etc/rc.conf), plus the utilities DROP list (mail, printer, NIS, UUCP, BSD games, floppy/tape, IPsec, embedded HW, HyperV/Mellanox, sendmail, etc. — ~190 entries).
Every /usr/src dir from FreeBSD-runtime + FreeBSD-utilities, single strict-rule verdict per row. Organized by /usr/src bucket (alphabetical within). LINK aliases collapsed to their source dir.
bin/| /usr/src dir | Verdict | Rationale | Apple repo (if REPLACE) |
|---|---|---|---|
| bin/cat | REPLACE | file ops | file_cmds |
| bin/chflags | REPLACE | file ops | file_cmds |
| bin/chio | DROP | tape changer | — |
| bin/chmod | REPLACE | file ops + ACL | file_cmds |
| bin/cp | REPLACE | file ops + clonefile | file_cmds |
| bin/cpuset | DEFER | CPU pinning niche | — |
| bin/date | REPLACE | shell tool | shell_cmds |
| bin/dd | REPLACE | file ops | file_cmds |
| bin/df | REPLACE | filesystem stats | adv_cmds |
| bin/echo | REPLACE | shell builtin (also standalone) | shell_cmds |
| bin/ed | DEFER | vi covers; ed unused | — |
| bin/expr | REPLACE | shell arithmetic | shell_cmds |
| bin/freebsd-version | KEEP | FreeBSD-only release reporter | — |
| bin/getfacl | DEFER | UFS ACLs unused first iter | — |
| bin/hostname | REPLACE | thin gethostname/sethostname wrapper | shell_cmds |
| bin/kenv | KEEP | FreeBSD-only kernel env (mach.debug_enable, launchd_trace gates) | — |
| bin/kill | REPLACE | signal sender | shell_cmds |
| bin/ln | REPLACE | file ops | file_cmds |
| bin/ls | REPLACE | file listing + ACL display | file_cmds |
| bin/mkdir | REPLACE | file ops | file_cmds |
| bin/mv | REPLACE | file ops | file_cmds |
| bin/nproc | DEFER | nice-to-have for parallel make | — |
| bin/pax | REPLACE | file ops + xattr | file_cmds |
| bin/pkill (incl. pgrep/pwait aliases) | REPLACE | process signal/match | adv_cmds |
| bin/ps | REPLACE | process listing | adv_cmds |
| bin/pwd | REPLACE | shell tool | shell_cmds |
| bin/realpath | REPLACE | file ops | file_cmds |
| bin/rm | REPLACE | file ops | file_cmds |
| bin/rmdir | REPLACE | file ops | file_cmds |
| bin/setfacl | DEFER | UFS ACLs unused first iter | — |
| bin/sh | REPLACE | load-bearing shell | shell_cmds |
| bin/sleep | REPLACE | shell tool | shell_cmds |
| bin/stty | REPLACE | terminal control | adv_cmds |
| bin/sync | REPLACE | file ops | file_cmds (also system_cmds) |
| bin/test (and "[") | REPLACE | shell tool | shell_cmds |
| bin/timeout | REPLACE | test harness uses it | shell_cmds |
| bin/uuidgen | DEFER | hwregd has its own | — |
sbin/| /usr/src dir | Verdict | Rationale | Apple repo (if REPLACE) |
|---|---|---|---|
| sbin/adjkerntz | DROP | UTC-only ISO | — |
| sbin/bsdlabel | DROP | GPT-only boot | — |
| sbin/camcontrol | DEFER | FreeBSD CAM/SCSI; needs lib/libnvmf privatelib prereq (NVMe-over-Fabrics) and not load-bearing for CI (virtio, no CAM) or daily dev. Reclassified from KEEP after iter 2 CI run 26459081598 surfaced the dep; add back if a real consumer surfaces. | — |
| sbin/comcontrol | DEFER | no serial console | — |
| sbin/conscontrol | DEFER | no serial console | — |
| sbin/ddb | DROP | kernel ddb in-kernel; userland unused | — |
| sbin/decryptcore | DROP | encrypted dumps unused | — |
| sbin/devfs | KEEP | FreeBSD devfs.rules subsystem | — |
| sbin/dmesg | REPLACE | kmsg reader | system_cmds |
| sbin/dumpon | DEFER | core dumps disabled | — |
| sbin/etherswitchcfg | DROP | embedded switch HW we don't have | — |
| sbin/fdisk | DROP | MBR; we use GPT | — |
| sbin/fsck | KEEP | FreeBSD UFS fsck driver | — |
| sbin/fsck_ffs | KEEP | FreeBSD UFS | — |
| sbin/fsck_msdosfs | DEFER | FAT USB only | — |
| sbin/init | DROP | launchd is PID 1 | — |
| sbin/ifconfig | REPLACE | network config; lib/libifconfig prereq goes away once Apple's lands | network_cmds |
| sbin/kldconfig, kldload, kldstat, kldunload | KEEP | FreeBSD kld(4) family; mach.ko is loaded via these | — |
| sbin/ldconfig | KEEP | FreeBSD rtld hint cache; libxpc/libmach/libdispatch dlopened via | — |
| sbin/md5 (+27 hash aliases) | REPLACE | hash family (md5/sha1/sha256/sha512/rmd160/skein) | system_cmds |
| sbin/mdconfig, mdmfs | DROP | no memdisk pivot (build.sh:2145) | — |
| sbin/mknod | DEFER | devfs autopopulates | — |
| sbin/mount | KEEP | FreeBSD VFS-specific | — |
| sbin/mount_cd9660 | DROP | no ISO9660 in boot path | — |
| sbin/mount_fusefs | DEFER | no FUSE-by-default | — |
| sbin/mount_mfs | DROP | dead with mdconfig | — |
| sbin/mount_msdosfs | DEFER | FAT USB sticks only | — |
| sbin/mount_nullfs | DEFER | no overlay trick in current build | — |
| sbin/mount_udf | DROP | DVD filesystem; no use case | — |
| sbin/mount_unionfs | DROP | "no unionfs" per build.sh:2145 | — |
| sbin/newfs | KEEP | FreeBSD UFS | — |
| sbin/newfs_msdos | DEFER | FAT only | — |
| sbin/nologin | KEEP | login shell-of-last-resort | — |
| sbin/nos-tun | DROP | obscure tunneling | — |
| sbin/pfilctl | DROP | no firewall | — |
| sbin/ping, ping6 | REPLACE | dev work | network_cmds |
| sbin/recoverdisk | DEFER | data recovery niche | — |
| sbin/reboot (+halt+poweroff+fastboot+fasthalt+nextboot aliases) | REPLACE | system shutdown family | system_cmds |
| sbin/route | REPLACE | route manipulation | network_cmds |
| sbin/routed (+rtquery) | DROP | RIP daemon unused | — |
| sbin/rtsol | REPLACE | IPv6 RA | network_cmds |
| sbin/savecore | DROP | core dumps disabled | — |
| sbin/setkey | DROP | IPsec unused | — |
| sbin/shutdown | REPLACE | login users hit this | system_cmds |
| sbin/swapon (+swapoff+swapctl) | DEFER | no swap configured | — |
| sbin/sysctl | REPLACE | kern.* knobs | system_cmds |
| sbin/tunefs | KEEP | FreeBSD UFS | — |
| sbin/umount | KEEP | FreeBSD VFS | — |
| sbin/zfsbootcfg | DROP | UFS-only boot | — |
usr.bin/ (the long tail)| /usr/src dir | Verdict | Rationale | Apple repo (if REPLACE) |
|---|---|---|---|
| usr.bin/apply | DROP | obscure | — |
| usr.bin/ar, ranlib | DEFER | on-target compile toolchain | — |
| usr.bin/asa | DROP | FORTRAN carriage control | — |
| usr.bin/awk | REPLACE | scripts everywhere | shell_cmds (or contrib/one-true-awk) |
| usr.bin/b64decode/encode, uuencode/uudecode | DROP | one-shot conversion; use python/openssl | — |
| usr.bin/banner, fortune, morse, number, factor, primes, random, msgs, leave, pom, caesar, rot13, strfile | DROP | BSD games/novelty | — |
| usr.bin/basename | REPLACE | shell scripts | shell_cmds |
| usr.bin/bc, dc | DEFER | not load-bearing | — |
| usr.bin/biff, from, mesg, write, wall, mail, mailx, vacation, talk | DROP | no MTA | — |
| usr.bin/bmake, make | DEFER | on-target compile | — |
| usr.bin/brandelf, elfctl, elfdump, etdump | DEFER | binary forensics off-target | — |
| usr.bin/bsdcat | REPLACE | libarchive front-end | contrib/libarchive (upstream vendor) |
| usr.bin/bsdiff, bspatch, bsdcpio, bsdunzip | DROP | unused | — |
| usr.bin/bzip2 + bz*grep/bzless scripts | DEFER | compressed log convenience | — |
| usr.bin/byacc, yacc, lex, flex | DEFER | on-target codegen | — |
| usr.bin/c89, c99 | DEFER | on-target compile | — |
| usr.bin/cal, ncal | DROP | trivia | — |
| usr.bin/calendar | DROP | reminder daemon | — |
| usr.bin/cap_mkdb | REPLACE | termcap-style DB builder | adv_cmds |
| usr.bin/chat | DROP | UUCP/PPP dialer | — |
| usr.bin/chfn, chpass, chsh | DEFER | one root user | — |
| usr.bin/chgrp | REPLACE | group ownership | file_cmds |
| usr.bin/chkey | DROP | Secure RPC | — |
| usr.bin/cksum | REPLACE | checksum tool | text_cmds |
| usr.bin/cmp | REPLACE | file compare | shell_cmds |
| usr.bin/col, colcrt, colrm, column, comm, csplit, cut, expand, fmt, fold, head, join, lam, nl, paste, pr, rev, soelim, split, tail, tee, tr, tsort, ul, unexpand, uniq, wc | REPLACE | text-stream processors | text_cmds (most) / shell_cmds (tee, cut) |
| usr.bin/colldef, mkcsmapper, mkesdb | REPLACE | locale tooling | adv_cmds (colldef) |
| usr.bin/compress | DEFER | legacy | — |
| usr.bin/cpio | DROP | tape archiver unused | — |
| usr.bin/crontab | DROP | launchd StartCalendarInterval covers | — |
| usr.bin/crunchgen, crunchide | DROP | no /rescue/ | — |
| usr.bin/crypt, enigma | DROP | toy crypto | — |
| usr.bin/ctags, indent, file2c, mkstr, xstr, unifdef | DEFER | dev-on-target | — |
| usr.bin/ctlstat | DROP | CAM debug niche | — |
| usr.bin/cu, tip | DROP | modem | — |
| usr.bin/dialog, bsddialog | DROP | TUI installer | — |
| usr.bin/diff, diff3, sdiff | DEFER | not load-bearing | — |
| usr.bin/dtc | DROP | device tree compiler (ARM); we're amd64 | — |
| usr.bin/du | REPLACE | disk usage | adv_cmds |
| usr.bin/ed | DEFER | vi enough | — |
| usr.bin/ee | DROP | use vi | — |
| usr.bin/env | REPLACE | shebang lines | shell_cmds |
| usr.bin/false, true, yes | REPLACE | shell primitives | shell_cmds |
| usr.bin/fetch | KEEP | no direct Apple equivalent (curl/wget would be ports) | — |
| usr.bin/file | KEEP | no Apple equivalent; binary forensics | — |
| usr.bin/find | REPLACE | overlay install + cleanup | shell_cmds |
| usr.bin/finger | REPLACE | user info | adv_cmds |
| usr.bin/fstat, fuser, sockstat, procstat | KEEP | BSD-specific introspection (Apple has lsof/sample, different shape) | — |
| usr.bin/gcore | REPLACE | core dump generator | system_cmds |
| usr.bin/gencat | REPLACE | POSIX catopen | adv_cmds |
| usr.bin/getconf, getopt, hexdump | REPLACE | shell scripting | shell_cmds |
| usr.bin/getent | KEEP | BSD-specific NSS query (Apple uses dscacheutil) | — |
| usr.bin/gprof | DEFER | off-target | — |
| usr.bin/grep (+egrep/fgrep/rgrep/z* aliases) | REPLACE | universal | text_cmds |
| usr.bin/groups, id, whoami | REPLACE | identity | adv_cmds (groups), shell_cmds (id) |
| usr.bin/gzip (+gunzip/gzcat/zcat aliases) | REPLACE | compression | file_cmds |
| usr.bin/host | DEFER | DNS lookup; not load-bearing | — |
| usr.bin/hostid | KEEP | BSD-specific; SMBIOS/syslog use it | — |
| usr.bin/iconv | DEFER | locale conversion | — |
| usr.bin/ident | DROP | RCS keyword extractor | — |
| usr.bin/info, infocmp, infotocap, makewhatis | DEFER | precompute on builder | — |
| usr.bin/ipcrm, ipcs | DEFER | SysV IPC; we use Mach | — |
| usr.bin/jot, seq | REPLACE | numeric sequences | shell_cmds (seq); jot drops |
| usr.bin/kdump, ktrace, ktrdump, truss | KEEP | BSD-specific tracing (Apple has dtrace/sample) | — |
| usr.bin/killall | REPLACE | full-argv match | shell_cmds |
| usr.bin/lastcomm | REPLACE | process accounting | shell_cmds |
| usr.bin/ldd | KEEP | BSD-specific (Apple uses otool -L); essential debug | — |
| usr.bin/less (+lessecho/lesskey/more/lz*/xz*/zstd* family) | REPLACE | pager | contrib (upstream less vendor) |
| usr.bin/limits, lockf, lock | DEFER | launchd handles directly | — |
| usr.bin/locale, localedef | REPLACE | locale machinery | adv_cmds |
| usr.bin/locate (+helpers) | DROP | locate db; not load-bearing | — |
| usr.bin/lockf | DEFER | shell-level locking | — |
| usr.bin/login_cap | KEEP | BSD-specific login.conf hooks; PAM expects login_cap.db | — |
| usr.bin/logger | REPLACE | syslog/ASL bring-up | shell_cmds |
| usr.bin/login | REPLACE | console login | system_cmds |
| usr.bin/logins, logname | REPLACE | login info / current name | shell_cmds (logname); logins DROP |
| usr.bin/look, lorder | DROP | obscure | — |
| usr.bin/lp, lpq, lpr, lprm (printer suite) | DROP | no printer | — |
| usr.bin/lsvfs | REPLACE | VFS table | adv_cmds |
| usr.bin/m4 | DEFER | sendmail-cf only | — |
| usr.bin/man, mandoc, manpath, apropos, whatis | REPLACE | man-page reading | contrib (upstream mandoc vendor) |
| usr.bin/mdo | DROP | doas-alike niche | — |
| usr.bin/mididump, mixer, sndctl | DROP | audio unused | — |
| usr.bin/mkdep, mkfifo, mkimg, mkuzip | REPLACE | mkfifo via file_cmds; rest DEFER/DROP | file_cmds (mkfifo) |
| usr.bin/mktemp | REPLACE | overlay scripts | shell_cmds |
| usr.bin/mt | DROP | tape | — |
| usr.bin/nawk | REPLACE | link to awk | shell_cmds |
| usr.bin/nc | REPLACE | netcat (Apple has it via shell_cmds/adv_cmds) | shell_cmds |
| usr.bin/netstat | REPLACE | network statistics | network_cmds |
| usr.bin/newgrp, nice, nohup, printenv, printf, readlink, renice | REPLACE | shell helpers | shell_cmds (most) / system_cmds (newgrp) |
| usr.bin/ntpq | DEFER | NTP suite | — |
| usr.bin/od | REPLACE | octal dump | text_cmds |
| usr.bin/pargs, penv, proccontrol, protect, pwdx, rctl | DEFER | FreeBSD-specific tooling | — |
| usr.bin/passwd | REPLACE | user password (works with our PAM) | system_cmds |
| usr.bin/patch | DEFER | source mods on-target | — |
| usr.bin/pathchk | REPLACE | POSIX path check | file_cmds |
| usr.bin/perror | DROP | obscure | — |
| usr.bin/pmcstudy | DROP | hwpmc-specific | — |
| usr.bin/posixmqcontrol, posixshmcontrol | DROP | not used | — |
| usr.bin/quota | DROP | no quotas | — |
| usr.bin/revoke | DROP | obscure tty revoke | — |
| usr.bin/rpcgen | DROP | RPC code gen | — |
| usr.bin/rpcinfo | DEFER | NFS-only | — |
| usr.bin/rs | DROP | obscure column reshape | — |
| usr.bin/script | DEFER | terminal capture | — |
| usr.bin/sed | REPLACE | stream editor | text_cmds |
| usr.bin/shar | DROP | obscure shell archive | — |
| usr.bin/showmount | DEFER | NFS-only | — |
| usr.bin/sort | REPLACE | Mach-semaphore parallel sort | text_cmds |
| usr.bin/spray | DROP | Sun-RPC bw test | — |
| usr.bin/stat | REPLACE | file metadata | file_cmds |
| usr.bin/stdbuf | DROP | obscure | — |
| usr.bin/strings | KEEP | binary forensics; no Apple equivalent in v3 | — |
| usr.bin/su | REPLACE | BSM audit-aware | shell_cmds |
| usr.bin/systat, top, vmstat | KEEP | BSD-specific top/vmstat format (Apple's are different shape) | — |
| usr.bin/tcopy | DROP | tape | — |
| usr.bin/tftp | DEFER | netboot debug | — |
| usr.bin/time | REPLACE | command time | shell_cmds |
| usr.bin/touch, truncate | REPLACE | file ops | file_cmds |
| usr.bin/tty | REPLACE | tty name | adv_cmds |
| usr.bin/units | DROP | obscure | — |
| usr.bin/unvis, vis | DROP | obscure | — |
| usr.bin/unzip | DROP | libarchive front-end variant | — |
| usr.bin/uname | REPLACE | system info | shell_cmds |
| usr.bin/usbhidaction, usbhidctl | DROP | USB HID | — |
| usr.bin/w | REPLACE | who-is-on (uptime alias) | adv_cmds |
| usr.bin/wg | DROP | wireguard | — |
| usr.bin/what | DEFER | SCCS-tag inspector | — |
| usr.bin/whereis | DEFER | which covers | — |
| usr.bin/which | REPLACE | command location | shell_cmds |
| usr.bin/whois | REPLACE | whois client | adv_cmds |
| usr.bin/xargs | REPLACE | command chain | shell_cmds |
| usr.bin/xinstall | REPLACE | PROGNAME=install | file_cmds |
| usr.bin/xo, xstr | DEFER | libxo CLI / preprocessor obscure | — |
| usr.bin/zstd (+zstdcat/zstdmt/zstd* aliases) | REPLACE | compression | contrib (upstream zstd) or file_cmds |
usr.sbin/| /usr/src dir | Verdict | Rationale | Apple repo (if REPLACE) |
|---|---|---|---|
| usr.sbin/adduser, rmuser, edquota, quotaon, quotaoff, repquota, quot | DEFER | account mgmt + quota niche | — |
| usr.sbin/arp, ndp, rtadvd, rtadvctl, rtsold | REPLACE | network admin | network_cmds |
| usr.sbin/audit, auditd, auditdistd, auditreduce, praudit | DEFER | BSM stub; expand later | — |
| usr.sbin/authpf, binmiscctl, blacklistd, boot0cfg, btxld, bsdconfig, freebsd-update, etcupdate, mergemaster, sysrc, tzsetup | DROP | install/update/legacy/pf-tied | — |
| usr.sbin/bootparamd, dconschat, rarpd, rmt, rrenumd, route6d, rip6query, ipfwpcap, mountd (NFS server) | DROP | netboot / IPv6 RIP / tape / NFS-server / ipfw | — |
| usr.sbin/boottrace | DEFER | measure launchd startup later | — |
| usr.sbin/camdd, cdcontrol, chkgrp, ckdist, config, dumpcis, fdcontrol, fdformat, fdread, fdwrite, fifolog_*, fwcontrol, gpioctl, hv_kvp_daemon, hv_vss_daemon, i2c, pwm, spi, ifmcstat, iovctl, ipfwpcap, mfiutil, mprutil, mpsutil, mptutil, mrsasutil, mldquery, mptable, mtest, manctl, lptcontrol, lptest, makefs, smbmsg, sesutil, setfib, spkrtest, tcpdrop, tcpsso, uathload, uefisign, uhsoctl, usbconfig, usbdump, wlandebug, wake, zonectl, zzz, sm6_query, prometheus_sysctl_exporter, pstat, keyserv, nscd, getfmac, setfmac, setfsmac, getpmac, setpmac, ugidfw, extattrctl, getextattr, lsextattr, setextattr, rmextattr | DROP | HyperV-host / hw RAID / firewire / wifi-fw / 3G modem / quotas / MAC / IPsec / printer / floppy / embedded HW / etc. | — |
| usr.sbin/cpucontrol, ngctl, nghook, pmc, pmcannotate, pmccontrol, pmcstat, rtprio, trim, vigr, vipw, watch, watchdog, watchdogd, zdump, zic | DEFER | perf / tz / watchdog / netgraph niche | vipw → system_cmds |
| usr.sbin/chown | REPLACE | chown is in file_cmds via chmod_chown.c | file_cmds |
| usr.sbin/chroot | REPLACE | shell helper | shell_cmds |
| usr.sbin/crashinfo | KEEP | FreeBSD-specific post-panic forensics | — |
| usr.sbin/cron, daemon | DROP | launchd replaces (StartCalendarInterval + KeepAlive) | — |
| usr.sbin/devctl, diskinfo, fstyp, gstat, pciconf | KEEP | FreeBSD-specific HW/FS introspection | — |
| usr.sbin/iostat | REPLACE | I/O stats | system_cmds |
| usr.sbin/kldxref | KEEP | FreeBSD kld(4) cache | — |
| usr.sbin/lpc, lpd, lpr (suite), pac, chkprintcap | DROP | printer | — |
| usr.sbin/nologin | KEEP | login shell-of-last-resort | — |
| usr.sbin/ntp-keygen, ntpd, ntpdate, ntpdc, ntptime, sntp | DEFER | NTP suite; launchd-managed approach later | — |
| usr.sbin/pac (printer accounting) | DROP | printer | — |
| usr.sbin/powerd | REPLACE | power mgmt daemon | PowerManagement |
| usr.sbin/pw | KEEP | FreeBSD user/group mgmt (no Apple equivalent — Apple uses dscl) | — |
| usr.sbin/pwd_mkdb | REPLACE | passwd db builder | system_cmds |
| usr.sbin/rpcbind, rpc.statd, rpc.tlsclntd, rpc.tlsservd | DEFER | NFS bits | — |
| usr.sbin/sendmail (suite: editmap, makemap, praliases, mailstats, hoststat, purgestat, mailwrapper) | DROP | no MTA | — |
| usr.sbin/service | DROP | launchctl owns service lifecycle | — |
| usr.sbin/services_mkdb | DROP | rc.d-only; getservbyname flat-file fallback works; no Apple equivalent | — |
| usr.sbin/tcpdump | REPLACE | kernel-vs-userland oracle | contrib (upstream tcpdump vendor) |
| usr.sbin/traceroute, traceroute6 | REPLACE | network debug | network_cmds |
| usr.sbin/zonectl, zzz, wake | DROP | ZFS zones / suspend / WoL unused | — |
libexec/| /usr/src dir | Verdict | Rationale | Apple repo (if REPLACE) |
|---|---|---|---|
| libexec/getty | REPLACE | console login spawn | system_cmds (#105e; subsumes #106) |
| libexec/save-entropy | KEEP | FreeBSD entropy daemon; launchd RandomSeed plist execs it | — |
| libexec/bootpd, rbootd, tftp-proxy, tftpd, comsat, fingerd, ntalkd, phttpget, pppoed, locate.* helpers, ulog-helper, rpc.* helpers | DROP | netboot / mail / talk / NIS / dialup / locate-db unused | — |
| libexec/flua | DEFER | freebsd-lua; some tools may embed | — |
srclist-fbsdglue.txtThe full irreducibly-FreeBSD-only set, formatted for direct paste into the manifest file at the repo root. Used by build.sh at the final PR (#105g/#105h) once all Apple-repo ports have landed and FreeBSD-runtime + FreeBSD-utilities pkgs drop from pkglist-base.txt. Live current state as of 2026-05-26 evening after iter 2 (PR #119) CI iteration:
# srclist-fbsdglue.txt — irreducibly-FreeBSD-only /usr/src dirs.
# Built per-subdir from /usr/src via build.sh step 3a2. Future Linux
# port swaps these 1:1 with Linux equivalents (modprobe/util-linux/
# strace/etc.). Per-line format: <relative path under /usr/src>;
# # for comments; empty lines ignored. Iterated in file order so
# prereq libs can be listed above consumers when needed.
# --- bin/ ---
bin/freebsd-version
bin/kenv
# --- sbin/ kernel-bound + UFS family ---
# (sbin/camcontrol DEFERRED — needs lib/libnvmf privatelib prereq.)
sbin/devfs
sbin/fsck
sbin/fsck_ffs
sbin/kldconfig
sbin/kldload
sbin/kldstat
sbin/kldunload
sbin/ldconfig
sbin/mount
sbin/newfs
sbin/tunefs
sbin/umount
# --- usr.bin/ — debug toolkit DEFERRED, see #120 ---
usr.bin/ldd
# --- usr.sbin/ FreeBSD HW/FS introspection + user mgmt ---
usr.sbin/crashinfo
usr.sbin/devctl
usr.sbin/diskinfo
usr.sbin/fstyp
usr.sbin/gstat
usr.sbin/kldxref
usr.sbin/nologin
usr.sbin/pciconf
usr.sbin/pw
# --- libexec/ ---
libexec/save-entropy
25 entries total (down from initial 44 estimate). Compared to original 425-dir inventory, that's a ~94% trim. The other ~175 entries (REPLACE) come from Apple sources via the seven sequential Apple-repo PRs; the remaining ~190 (DROP) + ~80 (DEFER) never ship.
Iteration log of changes from initial 44 estimate:
sbin/camcontrol → DEFER (iter 2 CI run 26459081598 surfaced lib/libnvmf privatelib prereq; not load-bearing for CI virtio or daily dev)lib/libnvmf → DROP (was iter-2 prereq for camcontrol; both removed together)usr.bin/login_cap → not a /usr/src dir (login_cap is a libutil function, not a binary); removed from estimatesbin/nologin → usr.sbin/nologin (the SOURCE dir is at usr.sbin/; Makefile LINKs to /sbin/nologin at install time)usr.bin/fuser → DROP from manifest (LINK from usr.bin/fstat; binary still appears at /usr/bin/fuser via fstat's Makefile LINKS=). CI iter 2 run 26459388127 surfaced.usr.bin/hostid → DROP (not a FreeBSD binary; /etc/rc.d/hostid is a shell script that reads /etc/hostid UUID into kern.hostuuid sysctl). We don't run /etc/rc (launchd PID 1) and none of our daemons use gethostid(), so functional impact is zero. CI iter 2 run 26459641829 surfaced.usr.bin/fetch, file, fstat, getent, kdump, ktrace, ktrdump, procstat, sockstat, strings, systat, top, truss, vmstat (14 tools). Plus the lib prereqs they triggered: lib/libsysdecode (codegen tables.h for kdump/truss), lib/libelftc (privatelib _pie for strings; CI iter 2 run 26459928204 surfaced). Rationale: nothing in current CI / boot path / Apple-repo port work uses these; each entry forces a per-tool privatelib prereq build chain for marginal benefit. #120 tracks the priority order: fstat+sockstat+procstat trio first, then ktrace+kdump+libsysdecode, then strings+libelftc, then top+vmstat. Add back when an actual debug session demands one (e.g., daemon-port "why is this fd held / which syscall failed" question that ldd alone doesn't answer).For the Linux port (future): this 44-entry file gets renamed to srclist-linuxglue.txt (or similar) and its content swapped 1:1 for Linux equivalents:
bin/freebsd-version → /etc/os-release (no binary)bin/kenv → /proc/cmdline readersbin/camcontrol → lsblk + smartctlsbin/devfs → udev rules toolsbin/fsck, fsck_ffs, tunefs, newfs → e2fsck/tune2fs/mke2fssbin/kld* + kldxref → modprobe/lsmod/rmmod/depmodsbin/ldconfig → glibc ldconfigsbin/mount, umount → util-linux mount/umountusr.bin/fstat, sockstat, fuser → lsof, ss, fuser (procps)usr.bin/ktrace/kdump/truss → straceusr.bin/ldd → glibc lddusr.bin/top/w/vmstat → procps top/w/vmstatusr.bin/file, strings → file + binutils stringsusr.sbin/devctl, diskinfo, gstat, pciconf, fstyp → udevadm, lspci, iostat, blkidusr.sbin/pw → useradd/usermod/groupadd| Verdict | Count (approx) | What it means for the ISO |
|---|---|---|
| KEEP | ~25–30 | Built from /usr/src via srclist-fbsdglue.txt at #105g. Future Linux equivalent table in §9.5.1. |
| REPLACE | ~175–200 | Apple binaries land at canonical paths via #105a-#105f (one Apple repo per PR, overlay pattern). Plus ~5-8 from upstream contrib (bsdtar via libarchive, less, mandoc, tcpdump, zstd). |
| DEFER | ~80–100 | Not in srclist; not shipped. Re-evaluate per-iter when a real consumer surfaces. |
| DROP | ~190–220 | Never ships. Confirmed dead per build.sh inspection or unused-feature category (mail, printer, NIS, UUCP, BSD games, floppy/tape, IPsec, embedded HW, HyperV-host, sendmail, etc.). |
| Total inventoried | ~425 dirs | Combined FreeBSD-runtime + FreeBSD-utilities original inventory |
If we expand the manifest to cover more tools in future tickets, watch for:
lib/ncurses/{tinfo,ncurses}/Makefile via MK* shell scripts + awk + make_keys helper. If /bin/ls or /usr/bin/less stop linking against the pkgbase-installed libtermcapw.a and need a from-source rebuild, this becomes the next prereq pain.lib/libsysdecode first.contrib/: less, gzip, bzip2, xz, zstd, libarchive, mandoc, ldns, ntp, sendmail, tcpdump, dialog, bsddialog, ofed, openbsm, pf, ipfilter, ipfw. These all build fine standalone with their existing Makefile shim under usr.bin/<name>; just be aware that the actual source lives in contrib/ not the wrapper dir.Drafted 2026-05-26 from four parallel research-agent passes across apple-oss-distributions, freebsd/freebsd-src on GitHub, and live pkgbase manifests at pkg.freebsd.org/FreeBSD:14:amd64/base_latest/. Scopes issue #104 + #105. Source data files (pkg manifests, build.sh inspection, Makefile.inc1 phase list) retained in the agent transcripts.