← Back · NextBSD research · follows the system-path layout spike (the layout decision was tabled; this is the narrower, agreed slice)

NextBSD path-domain conformance — adopt the gershwin four-domain layout

Coverage plan for a bounded, agreed change: make NextBSD's filesystem paths obey gershwin's four-domain model (/System/Library, /Local/Library, /Network/Library, ~/Library) instead of Apple's convention where the bare /Library is the Local domain. Concretely: every bare /Library/X becomes /Local/Library/X; everything already under /System/Library stays. This doc is the org-wide audit result (all 9 nextbsd-redux repos inspected) and the exact change surface. Status: implemented in nextbsd-userland#19 (33 sites, grep-clean, CI-gated) — this page is now the decision record behind that PR.

Scope resolved — one repo The Darwin userland source is currently byte-identical in nextbsd-userland/src and nextbsd/src (the ISO builder compiles its own copy). But nextbsd/src is slated for removal when the ISO is redone (a future PR), so it is not touched by this change. The rename lands only in nextbsd-userland/src — a single-repo, single-PR job. The earlier "edit both in lockstep" concern is retired along with nextbsd/src.

Contents

  1. The target: gershwin's four domains & the one rename rule
  2. Org-wide coverage matrix (all 9 repos)
  3. The double-repo problem (nextbsd vs nextbsd-userland)
  4. The rename surface: behavioral sites by subsystem
  5. Path-by-path mapping (and the judgment calls)
  6. Risk, atomicity & the two strlen constants
  7. What explicitly stays put
  8. How this reconciles with the tabled spike
  9. Open decisions
  10. Appendix: full change surface (file:line, ×2 repos)

1. The target: gershwin's four domains & the one rename rule

The gershwin tools-make FilesystemLayout roots resources in four domains. NextBSD adopts the same shape, so there is exactly one mechanical rule for the OS side:

DomainRoot (gershwin)MeaningNextBSD action
System/System/LibraryOS-providedunchanged — already correct everywhere
Local/Local/Librarythis machine, admin-installedbare /Library/X/Local/Library/X
Network/Network/Librarynetwork-sharedunused today — reserve, no change
User~/Libraryper-userunchanged — already matches

The rule: a path is a rename candidate iff it starts with a bare /Library/ (Apple's Local domain). Anything already qualified — /System/Library, ~/Library, /var/…/Library — is left alone. The audit below applies exactly this filter across the org.

2. Org-wide coverage matrix (all 9 repos)

Every repository in the nextbsd-redux org was inspected (fresh shallow clones of ground truth, not local checkouts), scoped strictly to the freebsd-launchd-mach variant. Result: the rename surface is confined to the two repos that carry the Darwin userland source. Six repos are already clean; one is out of scope by rule.

RepoVerdictDetail
nextbsd-userlandCHANGEAuthoritative source of the candidates — 33 bare-/Library hits ⇒ ~12 runtime-behavioral across 6 subsystems (rest are comments/docs/man/tests). Overlay ships only /System/Library.
nextbsdskipISO builder — compiles its own byte-identical copy of the same src/ tree (5,382 files), but src/ is slated for removal when the ISO is redone (future PR). Not touched here. Build scripts only ever create /System/Library.
nextbsd-freebsd-compatcleanOnly /System/Library/Libraries (Lever B, System domain). No bare /Library.
nextbsd-pkgcleanOnly /System/Library/Extensions (kext staging, System domain).
nextbsd-kernel-modulescleanKexts placed only into /System/Library/Extensions. Zero bare /Library.
nextbsd-kernelcleanZero /Library of any kind; the mach kernel overlay has none.
nextbsd-kernel-toolchaincleanZero /Library.
nextbsd-redux.github.iocleanZero /Library.
freebsd-srcout of scopeUpstream fork, edit-forbidden by hard rule. NextBSD-authored delta is CI-only (.github/workflows); any /Library is vendored heimdal/clang. (Caveat: GitHub code-search cannot index forks, so this rests on the authored delta being CI-only.)

3. The double-repo question — resolved to one

The audit exposed that the Darwin userland source lives in two repos, which is why "it might not be just one repo" was the right instinct to check. But the decision resolves it cleanly to a single target:

nextbsd-userland/srcthe target

  • The go-forward Darwin layer; the CI cross-build and the userland-repo split destination.
  • The rename lands here, and only here.

nextbsd/srcbeing removed

  • The current ISO builder compiles this copy (make -C src/launchd/src…), byte-identical today.
  • Slated for deletion when the ISO is redone (a future PR). Editing it would be throwaway work — skip it.

So the earlier lockstep worry is moot: there is one edit, in one repo. The transient window where the shipped ISO still builds the old nextbsd/src strings is acceptable — the affected dirs are empty third-party slots (below), and that tree is on its way out regardless.

4. The rename surface: behavioral sites by subsystem

~12 runtime-behavioral sites (paths actually used at runtime), across six subsystems, all in nextbsd-userland/src. Comments/docs/man-pages/help-strings/tests (~21 more) are cosmetic — update for consistency, but they don't affect behavior.

SubsystemSite (nextbsd-userland/src)LiteralKind
launchd (PID 1)src/launchd/src/launchd_plist_scan.c:265"/Library/LaunchDaemons"boot scan dir
launchdsrc/launchd/support/launchctl.c:4122"/Library/StartupItems"bootstrap dir create/chmod
SCPreferencessrc/libSystemConfiguration/SCPreferences.c:35PREFS_DEFAULT_DIR "/Library/Preferences/SystemConfiguration"SC state store (ComputerName / DiskArb; ties to #358)
CoreFoundationsrc/libCoreFoundation/CFKnownLocations.c:38,46CFSTR("/Library/Preferences")CFPreferences "Any-user"/computer domain
CoreFoundationsrc/libCoreFoundation/CFXMLPreferencesDomain.c:241strncmp(cpath, "/Library/Preferences", 20)root-owned-write special-case strlen 20
CoreFoundationsrc/libCoreFoundation/CFBundle_Resources.c:1245CFSTR("/Library/Spotlight")bundle-path compare (vestigial — see mapping)
kext_toolssrc/kext_tools/kext.subproj/bootfiles.h:69,73kLibraryExtensionsDir "/Library/Extensions"; kBootConfig ".../com.apple.Boot.plist"aux kext dir + boot config
kext_toolssrc/kext_tools/kext.subproj/OSKextPrivate.h:57_kOSKextLibraryExtensionsFolder "/Library/Extensions"aux kext folder
syslog / ASLsrc/syslog/aslcommon/asl_common.c:53PATH_LIBRARY_LOGS "/Library/Logs/"log-path prefix test strlen 14
syslog / ASLsrc/syslog/aslcommon/asl_common.h:32_PATH_CRASHREPORTER "/Library/Logs/CrashReporter"crash-log dir

5. Path-by-path mapping (and the judgment calls)

Most sites are a clean Local-domain rename. Four deserve an explicit decision rather than a blind rewrite — they're Apple-vestigial or semantically debatable under a BSD+launchd system.

Bare path→ ProposedConfidenceNote
/Library/LaunchDaemons/Local/Library/LaunchDaemonscleanThe Local-domain daemon slot. Core of the change.
/Library/Preferences/Local/Library/PreferencescleanComputer/Local prefs domain.
/Library/Preferences/SystemConfiguration/Local/Library/Preferences/SystemConfigurationcleanSC store incl. com.apple.Boot.plist.
/Library/Extensions/Local/Library/ExtensionscleanAuxiliary kext dir (distinct from System /System/Library/Extensions, which stays).
/Library/StartupItems/Local/Library/StartupItems or dropdecideDeprecated Apple legacy (pre-launchd). Rename for consistency, or delete the dead bootstrap-create entirely.
/Library/Logs, /Library/Logs/CrashReporter/Local/Library/Logs, /Local/Library/Logs/CrashReporterdecidedASL log location. Chosen: /Local/Library/Logs (domain-consistent), not /var/log. Update asl_common.c/.h + the 14 constant (now 20 for "/Local/Library/Logs/").
/Library/Spotlightleave / inertn/aNextBSD has no Spotlight; it's a bundle-path comparison that never matches. Rename only for tidiness.
/Library/Managed Preferencescomment onlyn/aMDM reference in a shim comment; no runtime path.

6. Risk, atomicity & the two strlen constants

7. What explicitly stays put

To keep scope honest: nothing under /System/Library changes. That includes the Lever B rtld path /System/Library/Libraries (compat build.yml), kext placement /System/Library/Extensions (pkg, kernel-modules, nextbsd), and the 11 shipped system daemon plists in /System/Library/LaunchDaemons. The Network domain (/Network/Library) and User domain (~/Library) are already conformant and untouched. This plan is only the bare-/Library/Local/Library slice.

8. How this reconciles with the tabled spike

The layout spike weighed keeping the domains (Option A) vs. moving NextBSD off /System to POSIX (Option B), and noted that bare /Library does not collide with Gershwin. Tabling that decision and doing this instead is a deliberate lean toward Option A's spirit: rather than vacate the Apple shape, make NextBSD rigorously obey gershwin's domain model. Note the trade this accepts: moving into /Local/Library places NextBSD's Local-domain resources in the same domain Gershwin uses for its admin installs — which is what the Local domain is for (shared, this-machine, admin-installed), so it's coherent, but it is the opposite move from the spike's "vacate for clean separation." Worth remembering if the /System question is untabled later.

9. Open decisions

  1. resolved Which repo: only nextbsd-userland/src. nextbsd/src is being removed when the ISO is redone (future PR), so it is not touched — single-repo, single-PR.
  2. resolved ASL logs: /Local/Library/Logs (+ /Local/Library/Logs/CrashReporter), not /var/log. Update asl_common.c/.h and the length constant 1420.
  3. resolved StartupItems: rename to /Local/Library/StartupItems (not deleted) — launchctl.c:4122.
  4. resolved SCPreferences store: /Local/Library/Preferences/SystemConfiguration (domain-consistent, not /var/db) — matches the all-domain direction; coordinate with #358.
  5. resolved Spotlight / Managed Preferences: rewrite for tidiness (no vestigial /Library strings left behind).
  6. resolved Cosmetic refs: update all ~21 comments/docs/man-pages/help-strings/tests too — zero bare /Library remaining, grep-clean.
  7. resolved README: the PR documents the canonical four-domain locations in nextbsd-userland/README.md (System-path-layout section).
  8. Sequencing — one atomic PR (single repo). Deferred to implementation — planning only for now.

Net Every open decision is closed toward full four-domain consistency: all bare /Library/X/Local/Library/X, behavioral and cosmetic, in one nextbsd-userland PR that also lands a README location reference. The only path that had a live POSIX alternative and stays POSIX is — none: even ASL logs and the SC store go domain.

10. Appendix: full change surface (file:line, nextbsd-userland/)

All in nextbsd-userland/src (nextbsd/src is being removed, not edited). Behavioral (must edit for correct paths):

src/launchd/src/launchd_plist_scan.c:265      "/Library/LaunchDaemons"
src/launchd/support/launchctl.c:4122          "/Library/StartupItems"
src/libSystemConfiguration/SCPreferences.c:35 PREFS_DEFAULT_DIR "/Library/Preferences/SystemConfiguration"
src/libCoreFoundation/CFKnownLocations.c:38   CFSTR("/Library/Preferences")
src/libCoreFoundation/CFKnownLocations.c:46   CFSTR("/Library/Preferences")
src/libCoreFoundation/CFXMLPreferencesDomain.c:241  strncmp(cpath,"/Library/Preferences",20)   << also 20 -> 26
src/libCoreFoundation/CFBundle_Resources.c:1245     CFSTR("/Library/Spotlight")
src/kext_tools/kext.subproj/bootfiles.h:69    kLibraryExtensionsDir "/Library/Extensions"
src/kext_tools/kext.subproj/bootfiles.h:73    kBootConfig ".../Library/Preferences/SystemConfiguration/com.apple.Boot.plist"
src/kext_tools/kext.subproj/OSKextPrivate.h:57  _kOSKextLibraryExtensionsFolder "/Library/Extensions"
src/syslog/aslcommon/asl_common.c:53          PATH_LIBRARY_LOGS "/Library/Logs/"           << also PATH_LIBRARY_LOGS_LEN 14 (:54)
src/syslog/aslcommon/asl_common.h:32          _PATH_CRASHREPORTER "/Library/Logs/CrashReporter"

Cosmetic (comments / docs / man / help-string / test — update for consistency, no behavior change):

src/launchd/src/launchd_plist_scan.c:7,222,260   src/launchd/src/launchd_plist_scan.h:11
src/launchd/support/launchctl.c:2571             src/launchd/freebsd-shims/NSSystemDirectories.h:6,12
src/libCoreFoundation/CFKnownLocations.c:32      src/libSystemConfiguration/SCDynamicStoreKeys.c:62
src/libSystemConfiguration/SystemConfiguration/SCPreferences.h:93
src/kext_tools/kext.subproj/OSKextPrivate.h:50   src/syslog/aslcommon/asl_common.c:468
src/syslog/freebsd-shims/configuration_profile.h:5
src/hostnamed/hostnameprefset.c:8,112 (help)     src/hostnamed/hostnamed.c:8   src/hostnamed/prefs_monitor.c:6
src/libxpc/xpc/connection.h:96                   src/mDNSResponder/mDNSShared/mDNSResponder.8:100,104
tests/boot-test.sh:1145

Audit method: fresh shallow clones of all 9 nextbsd-redux repos, grep for /Library minus domain-qualified forms, classified behavioral vs cosmetic, scoped to the freebsd-launchd-mach variant. nextbsdnextbsd-userland source identity verified by diff; nextbsd/build.sh confirmed to compile src/. freebsd-src excluded from edits by hard rule (upstream fork). Implemented in nextbsd-userland#19.