freebsd-apple-userland-cmds — v3 planPorting Apple userland onto freebsd-launchd-mach. Revised 2026-05-26 (v3): the per-tool "port if Apple has integration advantage, skip otherwise" rule is retired. New rule: vendor every Apple userland repo we have open-source for, port all of its binaries, modify as needed to fit FreeBSD. Rationale: anything we don't port from Apple still has to be built from source on the live ISO (FreeBSD-runtime + FreeBSD-utilities are not installed); we'd rather the source live in our src/ tree than be fetched from /usr/src at build time. The same modify-to-fit approach already proved out on OpenPAM (PAM port plan) — vendor + shim layer + patched config.h.
v3 scope at a glance.
bootstrap_cmds, network_cmds, file_cmds, shell_cmds, system_cmds, text_cmds, adv_cmds, PowerManagement, DiskArbitration. ~155 binaries total. All PORT.hdiutil/hdik (Apple-closed; darling-dmg-style fresh-write); diskdev_cmds (mount/fsck/newfs; needs Apple OSS fetch + UFS2 forward-port); kext loader substrate (kextload/kextunload needs XNU OSKext ported into mach.ko)./usr/src gap-filler manifest for now (transitional, see §1.1): kldload/kldunload/kldstat/kldconfig/kldxref, mdconfig/mdmfs, geom family, devfs (rules tool), dumpon/savecore, swapon/swapoff, plus the deferred items above (mount/fsck/newfs)./usr/src gap-filler manifestbootstrap_cmdsfile_cmds auditshell_cmds auditsystem_cmds auditnetwork_cmds audittext_cmds auditadv_cmds audit (NEW in v3)PowerManagement audit (NEW in v3)DiskArbitration audit (NEW in v3)build.sh/System/Library/Tools/, no /usr/local/sbin/, no PATH-shadowing. Apple's ifconfig goes at /sbin/ifconfig.FreeBSD-runtime + FreeBSD-utilities entirely. The conflict-overwrite model (install pkgs intact, then overwrite Apple paths) is rejected — pkg's database silently reverts overwrites on pkg upgrade. Apple-ports + transitional /usr/src-built BSD gap-fillers occupy disjoint paths./usr/src or from src/<apple-repo>/; vendoring into our tree gives us the modify-as-needed lever (proven on OpenPAM).freebsd-shims/ headers, patch config.h for FreeBSD library naming + paths, accept Apple-only feature paths failing gracefully (ioctl returns -1, flag never set). No major rewrites.hdiutil/hdik/diskutil/DiskImages.framework are Apple-closed; mount/fsck/newfs need diskdev_cmds fetched from Apple OSS archive; kextload needs XNU OSKext ported into mach.ko. Each gets a scoping ticket and lands in a later phase (§13)./usr/src manifest until we decide whether to vendor FreeBSD source into src/freebsd-vendored/ or fresh-write Apple-shape equivalents. Tools: kld*, mdconfig/mdmfs, geom, devfs (rules), dumpon/savecore, swapon/swapoff. See §2./usr/src gap-filler manifestUnder v3 the manifest contracts from ~40 entries to the irreducible FreeBSD-kernel-tied set plus the items deferred to scoping tickets. Built per-tool from /usr/src/<dir>/ in the FreeBSD-15 builder chroot via (cd /usr/src/$DIR && make obj && make && make install DESTDIR=$WORK/rootfs MK_MAN=no MK_TESTS=no). Manifest at pkglist-fbsdsrc-manifest.txt in the freebsd-launchd-mach repo.
| Category | /usr/src directories | Why no Apple-vendored replacement (yet) |
|---|---|---|
| Kernel module management | sbin/kldload, sbin/kldunload, sbin/kldstat, sbin/kldconfig, usr.sbin/kldxref | Apple's equivalents (kextload/kextunload/kextstat from IOKitTools) drive a different loader (IOKit OSKext + kernelmanagerd) and parse .kext bundles, not .ko files. Real port requires vendoring XNU OSKext into mach.ko — see §13. |
| Memory disk | sbin/mdconfig, sbin/mdmfs | Apple's hdiutil/hdik + DiskImages.framework are closed-source. Real port = darling-dmg-style fresh-write — see §13. |
| GEOM stack | sbin/geom (gpart/glabel/gnop/gmirror/graid/geli/gjournal/gcache/…) | No Apple analogue exists at any level. CoreStorage was Apple's vaguely-similar block-composition layer but it was never open-sourced and is deprecated for APFS. Future option: vendor FreeBSD source into src/freebsd-vendored/geom/. |
devfs rules tool | sbin/devfs | Both OSes have devfs; only FreeBSD has a ruleset subsystem (devfs.rules(5)). Apple has no equivalent tool to vendor. Future option: vendor FreeBSD source. |
| Kernel dump | sbin/dumpon, sbin/savecore | Apple kernel cores go through CrashReporter, not a dump device. No equivalent binary or model. |
| Swap | sbin/swapon (installs swapoff) | Apple's swap is file-based via dynamic_pager (which IS in system_cmds — we port it). Decommissioning swapon means redesigning the install around swap files + dynamic_pager, not partition swap in /etc/fstab. Deferred until the install-model redesign is scoped. |
| Filesystem mount & check (deferred — scoping ticket §13) | sbin/mount, sbin/umount, sbin/mount_nullfs, sbin/mount_unionfs, sbin/mount_tmpfs, sbin/mount_msdosfs, sbin/mount_cd9660, sbin/fsck, sbin/fsck_ffs, sbin/fsck_msdosfs, sbin/newfs, sbin/newfs_msdos, sbin/tunefs | Apple historically open-sourced these in diskdev_cmds (~2009 era, pre-UFS-removal). Not yet vendored locally; needs Apple OSS archive fetch + UFS2/SU+J forward-port. Sequenced separately from this plan. |
| Boot & init (transitional until Phase I3) | sbin/init | Replaced by launchd-842 as PID 1 at Phase I3; not separately ported from Apple. Drops out once launchd-842 takes over. |
| Tracing / introspection FreeBSD does its own way | (not in manifest — ktrace/kdump/top/vmstat/iostat/ps/pstat/systat/dtrace/dmesg ship via other pkgbase pkgs or are out of scope) | Apple's analogues (fs_usage, sc_usage, latency) DO port from system_cmds under v3 (with kdebug stubs). FreeBSD dtrace stays in parallel for the kernel-tracing role. |
* FreeBSD-rc is dropped separately — from pkglist-base.txt on 2026-05-16 (launchd replaces /etc/rc); not in the manifest.
Bottom line under v3: manifest entries that are FreeBSD-kernel-tied stay (~13 lines, plus the deferred-pending diskdev_cmds rows ~13 more = ~26 lines transitional). All POSIX-equivalent CLI work that v1/v2 had in the manifest (POSIX file ops, POSIX shell tools, sysctl/login/getty) leaves the manifest and gets covered by Apple-vendored repo ports below.
The Apple-userland-cmds port list + the transitional gap-filler manifest are deferred until the high-iteration daemon ports inside freebsd-launchd-mach stabilize. The daemon ports iterate heavily (often 4–6 CI rounds per iter); adding 9-repo userland-cmds churn on top is unnecessary drag.
Order of operations:
ipconfig(8) CLI), mDNSResponder port, notifyd, ASL, DiskArbitration daemon side, any other Phase K daemon work.mig + migcom from bootstrap_cmds (zero conflict; pure addition).FreeBSD-runtime + FreeBSD-utilities from pkglist-base.txt. One PR. Boot will break until step 4 lands.pkglist-fbsdsrc-manifest.txt + the build.sh iteration step (the contracted v3 manifest, ~26 lines). Boot green at the end of this step.| Repo | Binaries | v3 verdict | Key Apple-specific integration to preserve / shim |
|---|---|---|---|
bootstrap_cmds | ~4 files | PORT all | MIG. Pre-req for every MIG-using daemon. |
file_cmds | 27 | PORT all | ACL + xattr + clonefile + fcopyfile preservation across cp/mv/ls/install/gzip/pax. |
shell_cmds | ~45 | PORT all | Open Directory (id, libopendirectory shim), BSM audit (su), KERN_PROCARGS2 (killall). |
system_cmds | ~50 | PORT all | Mach IPC introspection (lsmp/hostinfo/stackshot), IOKit NVRAM (nvram), launchd-coordinated reboot/shutdown, BSM audit (login), kdebug stubs (fs_usage/sc_usage/latency), dynamic_pager swap, getty, sysctl, dmesg. |
network_cmds | 15 | PORT all | SystemConfiguration parity (configd consumes this output), IFSCOPE routing, LQM, IPv6 secure ND, kdumpd launchd-managed-socket-activation worked example. |
text_cmds | 34 | PORT all | sort uses Mach semaphores for parallelism. Rest are POSIX stream processors (pure vendor). |
adv_cmds | 15 | PORT all | NEW in v3. pkill/ps with macOS proc-info layout, stty/tty, locale tools, finger/last/whois, lsvfs, cap_mkdb, gencat, tabs. |
PowerManagement | ~6 | PORT all | NEW in v3. pmset/pmtool/caffeinate/pmconfigd/ioupsd/swd. Drives IOPMLib (which reboot/shutdown also use). Heavy IOKit stubs. |
DiskArbitration | ~4 | PORT all | NEW in v3. diskarbitrationd, autodiskmount, DiskArbitrationAgent, datest. DiskArbitration.framework is the system-service consumer for hdiutil/diskutil events — daemon-side port is independent of those userland tools. |
| Total | ~155 | — | — |
Per-binary audit detail follows in §5–§13. The audit columns ("Apple-stack integration", "Apple-specific feature", file:line citations) are still authoritative as the rationale for what to preserve / shim in each port; the SKIP / PARTIAL pills in those tables are historical (v1/v2 verdicts) and superseded by the all-PORT scoreboard above.
bootstrap_cmds — install table| Apple binary | Source path | FreeBSD path today | Install path | Conflict |
|---|---|---|---|---|
mig | xcodescripts/install-mig.sh | (not present) | /usr/bin/mig | none |
migcom | migcom.tproj/ | (not present) | /usr/libexec/migcom | none |
mig.1, migcom.1 | migcom.tproj/*.1 | (not present) | /usr/share/man/man1/ | none |
Zero conflicts; pure addition. Smoke marker: MIG-BUILD-OK — mig --help exits 0, migcom emits help on stderr.
file_cmds auditNote: SKIP / PARTIAL pills below are v1/v2 audit verdicts; v3 ports all binaries. Audit-rationale columns still apply as porting context.
| Binary | Apple-stack integration | Apple-specific feature | FreeBSD path | v1/v2 verdict |
|---|---|---|---|---|
cp | fcopyfile, clonefile, ACL + xattr (cp/utils.c:138-491) | APFS clonefile COW; resource-fork + ACL preservation | /bin/cp | PORT |
chmod | Apple libacl (chmod_acl.c:121-854) | Extended ACL manipulation | /bin/chmod | PORT |
ls | getxattr, acl_get_link_np, SF_DATALESS | ACL display (-e), xattr count, dataless-file awareness | /bin/ls | PORT |
mv | fcopyfile for ACL+xattr | Cross-FS move preserves permissions+xattr | /bin/mv | PORT |
install | fcopyfile ACL+xattr | ACL preservation in install(1) | /usr/bin/install | PORT |
gzip | fgetattrlist, fsetattrlist, fcopyfile | Preserves ACLs+xattrs across compression | /usr/bin/gzip | PORT |
pax | fcopyfile, setattrlist | Precise timestamp + ACL+xattr in archives | /bin/pax | PORT |
df | getattrlist for ATTR_VOL_SPACEUSED | Volume metadata without traversal | /bin/df | PARTIAL |
du | getattrlist for SF_DATALESS | Accurate dataless-file accounting | /usr/bin/du | PARTIAL |
mtree | libdispatch | GCD-parallel hashing | /usr/sbin/mtree | PARTIAL |
| 17 others chflags, chown, cksum, compress, dd, ipcrm, ipcs, ln, mkdir, mkfifo, mknod, pathchk, rm, rmdir, shar, stat, touch, truncate, xattr | None — pure POSIX | Standard POSIX | various | SKIP |
Driver: Apple's cp/mv/ls/install/gzip/pax preserve ACLs + extended attributes + APFS clonefile semantics through file operations. clonefile(2) is APFS-only; on FreeBSD UFS/ZFS it falls back to byte-copy — benign. xattr: Apple's xattr(2) API diverges from FreeBSD's extattr(2); shim layer maps the calls in our libSystem.
Risks: libacl + libdispatch dependencies. We already ship libdispatch (/usr/lib/system/libdispatch.so); libacl shim needed.
shell_cmds auditNote: SKIP / PARTIAL pills below are v1/v2 audit verdicts; v3 ports all binaries.
| Binary | Apple-stack integration | Apple-specific feature | FreeBSD path | v1/v2 verdict |
|---|---|---|---|---|
id | CoreFoundation + Open Directory | OD-backed identity lookups for enterprise LDAP/NIS | /usr/bin/id | PORT |
su | BSM audit session | Audit-session-aware privilege escalation | /usr/bin/su | PORT |
path_helper | None (file I/O only) | Reads /etc/paths + /etc/paths.d/ to build PATH | (not present) | PARTIAL |
killall | KERN_PROCARGS2 sysctl | Full-argv match vs FreeBSD's truncated ki_comm | /usr/bin/killall | PARTIAL |
| ~40 others basename, chroot, date, dirname, echo, env, expr, false, find, getopt, hexdump, hostname, jot, kill, lastcomm, lockf, logname, mktemp, nice, nohup, printenv, printf, pwd, realpath, renice, script, seq, sh, shlock, sleep, stdbuf, tee, test, time, true, tty, uname, w, who, xargs, yes, … | None | Standard POSIX | various | SKIP |
Risk callout: Apple id requires libopendirectory, which has no FreeBSD equivalent. Ship a no-op libopendirectory shim and let id fall back to /etc/passwd. Real OD work is a separate, far-future phase.
system_cmds auditNote: SKIP / PARTIAL pills below are v1/v2 audit verdicts; v3 ports all binaries.
This is the most Mach-IPC-heavy of the in-scope repos. Many ports depend on new mach.ko traps (see callout below).
| Binary | Apple-stack integration | Apple-specific feature | FreeBSD path | v1/v2 verdict |
|---|---|---|---|---|
lsmp | Mach IPC introspection (task_read_for_pid, mach_port_space_info) | Mach port enumeration — no FreeBSD equivalent | (not present) | PORT |
hostinfo | Mach: host_info HOST_BASIC_INFO, processor sets | Reports Mach kernel version, processor-set state | (not present) | PORT |
nvram | IOKit (IORegistry, IORegistryEntryCreateCFProperty) | Firmware-parameter R/W via IOKit | (not present) | PORT |
stackshot | Mach + stackshot syscall | Kernel stack snapshots | (not present) | PORT |
lskq | EVFILT_MACHPORT in kqueue | Mach-aware kqueue analysis | /usr/bin/lskq | PARTIAL |
reboot | Bootstrap + IOKit kextmanager | launchd-coordinated reboot, kext locking | /sbin/reboot | PARTIAL |
shutdown | IOKit IOPMLib + BSM audit | Power-management-aware shutdown, audit-logged | /sbin/shutdown | PARTIAL |
halt | IOPMLib stubs | Power-management-aware halt | /sbin/halt | SKIP → now PORT |
gcore | Mach-image introspection | Core dumps with Mach thread-state notes | /usr/bin/gcore | PARTIAL |
login | BSM audit | Audit-aware session creation | /bin/login | PARTIAL |
taskpolicy | Mach task_policy_set/get | QoS + CPU-limit management | /usr/bin/taskpolicy | PARTIAL |
getty | BSM audit (modest) | Audit-aware tty login spawn | /usr/libexec/getty | SKIP → now PORT |
sysctl | None significant | POSIX-style sysctl(8); Apple-shape options | /sbin/sysctl | SKIP → now PORT |
dmesg | None significant | kmsg buffer reader | /sbin/dmesg | SKIP → now PORT |
dynamic_pager | Mach + vnode pager | Swap-file pager (Apple's swap model) | (not present) | SKIP → now PORT (also unlocks future swapon retirement) |
fs_usage, sc_usage, latency | kdebug + Mach timing | kdebug-based tracing | various | SKIP → now PORT (with no-op kdebug stubs) |
kpgo, memory_pressure, vm_stat, vm_purgeable_stat | Apple-only kernel features (PGO, jetsam, purgeable VM) | n/a on FreeBSD | various | SKIP → now PORT (stub returns “feature not available” gracefully) |
| ~20 others ac, accton, arch, at, atrun, chkpasswd, chpass, cpuctl, getconf, iosim, iostat, ltop, mean, mkfile, mslutil, newgrp, nologin, pagesize, passwd, proc_uuid_policy, purge, pwd_mkdb, sa, sync, vifs, vipw, wait4path, wordexp-helper, zdump, zic | None or trivial | Standard POSIX / BSD heritage | various | SKIP → now PORT |
Kernel-side mach.ko work this implies.
lsmp → task_read_for_pid, mach_port_space_info, host_processor_sets, processor_set_tasks_with_flavor (4 new traps)hostinfo → host_info HOST_BASIC_INFO flavor + processor info (1 new trap, multiple flavors)stackshot → kernel stackshot syscall (1 new syscall, large)nvram → IOKit NVRAM driver (different track entirely; EFI device-tree walker)dynamic_pager → vnode-backed pager hooks; requires VM-system thinkingfs_usage/sc_usage/latency → kdebug stubs (return empty trace or wire to dtrace; stub-first)The trap-based items fit our existing multiplexer slot 219 pattern. IOKit NVRAM and dynamic_pager are separate, much bigger tracks.
network_cmds auditNote: SKIP / PARTIAL pills below are v1/v2 audit verdicts; v3 ports all binaries.
Highest port ratio in v1/v2 (10/15); under v3 all 15. These tools are the system-of-record for network state that configd reads. Apple-shaped output is required for the SC store.
| Binary | Apple-stack integration | Apple-specific feature | FreeBSD path | v1/v2 verdict |
|---|---|---|---|---|
ifconfig | IFEF_* flags, LQM | AWDL/cellular/companion interface types, LQM quality state | /sbin/ifconfig | PORT |
route | RTF_IFSCOPE parsing | Interface-scoped routes, RTF_PINNED/RTF_IFREF | /sbin/route | PORT |
arp | IFSCOPE, IFNET_LQM_THRESH_* | Interface-scoped ARP for multi-homed mDNS | /usr/sbin/arp | PORT |
ndp | ND6_IFF_* flags, prefix list sysctl | SEND (secure ND), proxy prefixes, NUD state machine | /usr/sbin/ndp | PORT |
ping | IP_NO_IFT_CELLULAR, DSCP marking | Cellular exclusion, QoS class | /sbin/ping | PORT |
ping6 | IPV6_NO_IFT_CELLULAR, DSCP marking | IPv6 variant of ping with cellular/QoS | /sbin/ping6 (symlink) | PORT |
rtadvd | RDNSS/DNSSL + PVD config | IPv6 prefix advertisement with Apple extras | /usr/sbin/rtadvd | PORT |
rtsol | IPv6 router-solicitation daemon | Auto IPv6 prefix solicitation | /usr/sbin/rtsold | PORT |
kdumpd | launchd plist + socket activation | Establishes launchd-managed-daemon pattern | (not present) | PORT |
netstat | LQM thresholds, NSTAT cellular link status | LQM + cellular display | /usr/bin/netstat | PARTIAL |
traceroute | None | None Apple-specific | /usr/sbin/traceroute | SKIP → now PORT |
traceroute6 | None | None Apple-specific | /usr/sbin/traceroute6 | SKIP → now PORT |
dnctl | Apple dummynet control | Apple-specific QoS scheduling | (not present) | SKIP → now PORT (FreeBSD has its own ipfw-dummynet; Apple's dnctl ships as a separate diagnostic tool) |
rarpd | None | Legacy RARP server | (not present) | SKIP → now PORT |
spray | None | Sun-RPC bandwidth measurement | (not present) | SKIP → now PORT |
Driver: SystemConfiguration parity. configd's job is to read ifconfig -a, route -n get, ndp -pr, arp -a, netstat -i output and turn it into the SC store. kdumpd's launchd plist is the worked example for launchd-managed-socket-activation we copy when adding ntpd, mDNSResponder, etc.
text_cmds auditNote: SKIP pill below is v1/v2 audit verdict; v3 ports all binaries.
| Binary | Apple-stack integration | Apple-specific feature | FreeBSD path | v1/v2 verdict |
|---|---|---|---|---|
sort | Mach semaphores | Multi-threaded sort via Mach IPC | /usr/bin/sort | PORT |
| 33 others banner, bintrans, cat, col, colrm, column, comm, csplit, cut, ed, expand, fmt, fold, grep, head, jq, join, lam, look, md5, nl, paste, pr, rev, rs, sed, split, tail, tr, ul, unexpand, uniq, unvis, vis, wc, … | None — POSIX stream processors | Locale and encoding edge cases only | various | SKIP → now PORT |
adv_cmds audit (NEW in v3)Not in v1/v2 plan; added in v3. Sister repo to shell_cmds containing 15 more userland tools, several with Apple-specific integration.
| Binary | Apple-stack integration / note | FreeBSD path | v3 verdict |
|---|---|---|---|
pkill | Mach + macOS proc-info layout | /bin/pkill | PORT |
ps | Mach + macOS proc-info layout; -Z for sandbox label | /bin/ps | PORT |
stty | BSD; Apple keeps minor option additions | /bin/stty | PORT |
tty | POSIX | /usr/bin/tty | PORT |
finger | BSD heritage | /usr/bin/finger | PORT |
last | BSD; reads /var/log/wtmp | /usr/bin/last | PORT |
whois | BSD | /usr/bin/whois | PORT |
locale | Apple locale database layout | /usr/bin/locale | PORT |
localedef | Apple locale database layout | /usr/bin/localedef | PORT |
cap_mkdb | BSD termcap-style DB | /usr/bin/cap_mkdb | PORT |
gencat | POSIX catopen(3) | /usr/bin/gencat | PORT |
genwrap | Apple build helper | /usr/bin/genwrap | PORT |
lsvfs | VFS-mount-table introspection (Apple-shape) | /usr/sbin/lsvfs | PORT |
tabs | POSIX terminal control | /usr/bin/tabs | PORT |
colldef | Locale collation-rule compiler | /usr/bin/colldef | PORT |
Driver: consistency with the other "shell-like" repos. ps/pkill matter most — they read macOS-shape kinfo_proc layout; FreeBSD's layout differs, so without these the rest of the userland gets confused-looking ps output. locale/localedef matter for the locale database to match Apple's expected paths.
PowerManagement audit (NEW in v3)Not in v1/v2 plan; added in v3. Daemon (pmconfigd) + CLIs that drive IOPMLib.
| Binary | Apple-stack integration | Install path | v3 verdict |
|---|---|---|---|
pmset | IOPMLib (config R/W); SCDynamicStore | /usr/bin/pmset | PORT |
pmtool | IOPMLib diagnostics / scheduling | /usr/bin/pmtool | PORT |
caffeinate | IOPMAssertion API (prevent-sleep) | /usr/bin/caffeinate | PORT |
pmconfigd | Long-running daemon, IOKit notification consumer | /usr/libexec/pmconfigd | PORT |
ioupsd | UPS protocol over HID | /usr/libexec/ioupsd | PORT |
swd | System watchdog / panic handler | /usr/libexec/swd | PORT |
Driver: reboot and shutdown (from system_cmds) both link IOPMLib; we already need IOPMLib stubs for those. Porting the PowerManagement repo's CLIs costs little extra given the shared dep, and gives us Apple-shape power UX.
Risk: IOPMLib stubs need to cover the breadth of pmset commands (sleep schedules, hibernate modes, display assertions). Mostly stub-to-no-op acceptable on FreeBSD; real power management can come later as a separate phase.
DiskArbitration audit (NEW in v3)Not in v1/v2 plan; added in v3. Daemon + agent + test tool. Independent of hdiutil/diskutil (those are the CLI consumers; this is the framework + daemon).
| Binary | Apple-stack integration | Install path | v3 verdict |
|---|---|---|---|
diskarbitrationd | IOKit disk-arrival events → mount dispatcher; launchd-managed | /usr/libexec/diskarbitrationd | PORT |
autodiskmount | Auto-mounter (consumes DA events) | /usr/sbin/autodiskmount | PORT |
DiskArbitrationAgent | Per-user agent for DA events | /System/Library/CoreServices/DiskArbitrationAgent | PORT |
datest | DA test harness | /usr/bin/datest | PORT |
Driver: DiskArbitration is the framework Apple-shape userland consumers (Finder, hdiutil, diskutil, etc.) use for mount/unmount/eject coordination. Porting it now means we have the framework ready when hdiutil/diskutil scoping tickets land later.
Risk: needs IOKit disk-arrival events from mach.ko — or a FreeBSD-devd bridge that emits the same notifications. Bridge work is meaningful but tractable.
~155 binaries across 9 repos, ordered for build pipeline integration (full per-binary list in source-tree manifest; summary here):
| Phase | Repo (count) | What lands |
|---|---|---|
| 1 | bootstrap_cmds (4) | mig + migcom + man pages. Zero conflict. |
| 2 | network_cmds (15) | All 15. Heavy ABI-drift risk on ifconfig/route/netstat — Apple struct fields not in FreeBSD will fail gracefully. |
| 3 | file_cmds (27) | All 27. libdispatch + libacl shims. |
| 4 | shell_cmds (~45) | All ~45. libopendirectory shim for id. |
| 5 | adv_cmds (15) | All 15. ps/pkill need kinfo_proc shim layer. |
| 6 | text_cmds (34) | All 34. sort needs Mach semaphores; others are pure POSIX. |
| 7 | system_cmds (~50) | All ~50. Heaviest Mach trap dependency — some tools wait on mach.ko traps landing first (lsmp/hostinfo/stackshot/dynamic_pager). IOPMLib shim covers reboot/shutdown/halt. |
| 8 | PowerManagement (~6) | All ~6. IOPMLib already shimmed from system_cmds work. |
| 9 | DiskArbitration (~4) | All ~4. Daemon + agent + autodiskmount. Needs IOKit disk-arrival event bridge. |
build.shPre-req: all freebsd-launchd-mach daemon ports (configd remaining iters, IPConfiguration iter 7+, mDNSResponder, notifyd, ASL, …) shipped.
pkg install the trimmed pkgbase set (FreeBSD-runtime + FreeBSD-utilities removed; FreeBSD-clibs, FreeBSD-rescue, FreeBSD-ufs, FreeBSD-geom, … remain)./usr/src (~13 lines + ~13 deferred = ~26 lines transitional). Marker FBSDSRC-MANIFEST-OK. Boot test green at this point.bootstrap_cmds; install mig + migcom. Marker MIG-BUILD-OK. May move earlier if a daemon port needs it — pure addition, zero conflict.mig against launchd-842's seven .defs files; cache output.network_cmds (15 binaries). Per-tool smoke markers: NETCMD-IFCONFIG-OK, …file_cmds (27). Markers FILECMD-CP-OK, …shell_cmds (~45). Ship libopendirectory shim; id falls back to /etc/passwd.adv_cmds (15). Ship kinfo_proc-shape shim; ps/pkill read FreeBSD's layout via the shim.text_cmds (34).system_cmds (~50). Defer lsmp/hostinfo/stackshot binaries that need new mach.ko traps; everything else lands now.PowerManagement (~6). IOPMLib shim already in place from system_cmds.DiskArbitration (~4). Needs IOKit disk-arrival event bridge (or stub).mach.ko traps for the Mach-IPC-deep system_cmds binaries (lsmp, hostinfo, stackshot); rebuild those.Three workstreams the v3 plan explicitly defers. Each gets its own scoping ticket in the repo, sequenced after the 9-repo port roadmap stabilizes.
| Workstream | Apple-source status | What deferral means | Scoping ticket scope |
|---|---|---|---|
hdiutil / hdik / DiskImages.framework | Closed-source. Apple never published. | Live ISO uses mdconfig from /usr/src. No hdiutil-shape CLI shipped. | Compare three paths: (a) fresh-write Apple-shape CLI in src/hdiutil/ matching man-page semantics, drives md(4); (b) vendor darling-dmg (GPL-3.0, read-only, FUSE-based); (c) hybrid — fresh-write front-end + darling-dmg-shaped DMG parser. License + scope tradeoff. |
diskdev_cmds (mount/fsck/newfs family) | Apple-open, not vendored locally. Need fetch from Apple OSS archive (~2009 era, pre-UFS-removal). | Live ISO uses FreeBSD mount/fsck/newfs from /usr/src. Manifest carries ~13 transitional rows. | Fetch + vendor + UFS2/SU+J/snapshot forward-port. Largest port of the three. Maybe additionally include Apple's mount(8) front-end with FreeBSD mount_<fs> back-ends as a smaller intermediate step. |
kextload / kext loader substrate | Apple-open (IOKitTools, needs fetching); kernel substrate is XNU OSKext. | Live ISO uses kldload from /usr/src to load mach.ko and all FreeBSD modules. | Vendor XNU OSKext + IOCatalogue + IOKextLib into mach.ko. Vendor kextload/kextunload/kextstat/kmutil from IOKitTools. Decide whether to also repackage existing FreeBSD .ko modules (if_em, ums, …) as .kext bundles, or keep kldload as a parallel loader. |
Worst in ifconfig, netstat, route, arp, ndp, ps, pkill. Apple extends struct ifreq, struct ifmediareq, struct rt_msghdr, kinfo_proc; some Apple ioctls don't exist on FreeBSD. Apple-only feature paths fail gracefully (ioctl returns -1, flag never set).
Aggregated across the 9 repos: libopendirectory (no-op fallback to /etc/passwd; id), IOPMLib (mostly no-op stubs; reboot/shutdown/halt/pmset/caffeinate/pmconfigd), libacl (BSD POSIX.1e bridge; chmod/ls/cp/install/mtree), BSM audit (no-op stub; su/login/shutdown/getty), kdebug (no-op stub; fs_usage/sc_usage/latency), kinfo_proc shim (Apple-shape over FreeBSD's; ps/pkill). Most are <100 LOC each; lean on the OpenPAM-style shim pattern.
system_cmds Tier B lands4 new traps for lsmp + hostinfo + stackshot (port-space introspection, host info flavors, stackshot syscall). All fit the multiplexer slot 219 pattern; ~600 LOC of mach.ko work. nvram needs an IOKit NVRAM driver — separate track. dynamic_pager needs vnode-pager hooks — another separate track.
diskarbitrationd consumes IOKit disk-arrival/removal events. On FreeBSD this needs either (a) a real IOKit event source from mach.ko, or (b) a devd bridge that translates FreeBSD devd events into IOKit-shape notifications. Stub-first: ship the daemon, get it running, file follow-up for the event bridge.
Per-repo build + per-tool smoke marker adds substantially to CI run time once the workstream is active. Mitigation is sequencing (§3): land after the daemon roadmap, not during. Inside the workstream, group per-repo PRs so CI runs full-marker pass once per repo, not per binary.
/usr/src availability on the builderThe transitional manifest assumes /usr/src on the builder chroot. Already there for kmod compiles; just adding new directories.
If we never get to the deferred-scoping tickets, the transitional manifest stays. That's OK — the 9-repo port is independently valuable; deferred items are quality-of-life rather than blocking.
id, login, auth. Stubbed by libopendirectory no-op for now. Separate multi-month effort.kldload persists.hdiutil/diskutil. Deferred to §16 scoping ticket; mdconfig persists.diskdev_cmds. Deferred to §16 scoping ticket.src/freebsd-vendored/. Option for Tier-4 items (geom/devfs-rules/dumpon/savecore) instead of /usr/src manifest carry-over. Not in current scope; revisit after 9-repo port lands..ko modules as .kext bundles. Only relevant if kext-substrate scoping ticket lands and we want full Apple-shape module model.kdebug tracing infrastructure. fs_usage/sc_usage/latency get stubbed for v3; real kdebug or kdebug-over-dtrace is a separate effort.FreeBSD-rc removal. Once launchd-842 is PID 1, its plists own multi-user bring-up. Drop the pkg then.Drafted 2026-05-13 (v1). Revision 2026-05-23 (v2): Option C (drop FreeBSD-runtime + FreeBSD-utilities, build per-tool from /usr/src). Revision 2026-05-26 (v3): retired the per-binary "port if Apple has integration advantage, skip otherwise" rule; new rule is "vendor every Apple userland repo we have open-source for, port all binaries, modify as needed." Scope expanded from 6 to 9 repos (adv_cmds, PowerManagement, DiskArbitration added). Apple-closed-source items (hdiutil/diskutil) and Apple-open-but-not-vendored items (diskdev_cmds, IOKitTools kext loader) split off to §16 scoping tickets. Per-tool SKIP / PARTIAL pills in §6–§10 audit tables are historical (v1/v2) and superseded by the §4 all-PORT scoreboard.