Repository navigation
Expand file tree
/
Copy pathfreebsd-srclist-build-plan.html
More file actions
838 lines (707 loc) · 94.5 KB
/
Copy pathfreebsd-srclist-build-plan.html
File metadata and controls
838 lines (707 loc) · 94.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>srclist build strategy — which /usr/src tools build standalone, which need prereqs</title>
<style>
:root {
--fg: #1a1a1a; --fg-muted: #555; --bg: #fafaf7; --accent: #b8472a;
--accent-soft: #f3e7df; --border: #d8d4c8; --code-bg: #f0ece2;
--table-stripe: #f4efe5; --warn: #8a5a00; --good: #2d6f3b; --bad: #a23030;
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body { font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, sans-serif; color: var(--fg); background: var(--bg); line-height: 1.55; margin: 0; padding: 0; }
.wrap { max-width: 980px; margin: 0 auto; padding: 48px 32px 96px; }
h1 { font-size: 2.1rem; line-height: 1.2; margin: 0 0 8px; letter-spacing: -0.01em; }
h2 { font-size: 1.45rem; margin: 56px 0 12px; padding-top: 18px; border-top: 2px solid var(--border); letter-spacing: -0.005em; }
h3 { font-size: 1.15rem; margin: 32px 0 10px; color: var(--accent); }
p { margin: 0 0 14px; }
ul, ol { margin: 0 0 14px 22px; padding: 0; }
li { margin-bottom: 4px; }
code, pre { font-family: "SF Mono", Menlo, Consolas, monospace; background: var(--code-bg); color: var(--fg); }
code { padding: 1px 5px; border-radius: 3px; font-size: 0.92em; }
pre { padding: 14px 18px; border-radius: 4px; overflow-x: auto; font-size: 0.86rem; line-height: 1.45; margin: 0 0 18px; }
a { color: var(--accent); }
a:hover { text-decoration: underline; }
.lede { font-size: 1.05rem; color: var(--fg-muted); margin-bottom: 32px; }
table { width: 100%; border-collapse: collapse; margin: 14px 0 22px; font-size: 0.91rem; }
th, td { text-align: left; padding: 8px 10px; border: 1px solid var(--border); vertical-align: top; }
th { background: var(--accent-soft); font-weight: 600; }
tr:nth-child(even) td { background: var(--table-stripe); }
.callout { border-left: 3px solid var(--accent); background: var(--accent-soft); padding: 14px 18px; margin: 18px 0 22px; border-radius: 0 4px 4px 0; }
.callout p:last-child { margin-bottom: 0; }
.callout-good { border-left-color: var(--good); background: #e8f1e3; }
.callout-warn { border-left-color: var(--warn); background: #fbf3df; }
.callout-bad { border-left-color: var(--bad); background: #fbe6e6; }
.pill { display: inline-block; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; padding: 2px 7px; border-radius: 10px; margin-right: 6px; }
.pill-good { background: #d6ead0; color: var(--good); }
.pill-warn { background: #f4dfbf; color: var(--warn); }
.pill-bad { background: #f0c8c8; color: var(--bad); }
.toc { background: white; border: 1px solid var(--border); border-radius: 4px; padding: 18px 24px 14px 36px; margin: 0 0 36px; font-size: 0.95rem; }
.toc h2 { margin: 0 0 8px; padding-top: 0; border-top: none; font-size: 1rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--fg-muted); margin-left: -14px; }
.toc ol { margin: 0 0 0 6px; }
.toc a { color: var(--fg); text-decoration: none; }
.toc a:hover { text-decoration: underline; }
.footnote { font-size: 0.85rem; color: var(--fg-muted); border-top: 1px solid var(--border); margin-top: 48px; padding-top: 16px; }
@media (max-width: 600px) { .wrap { padding: 24px 18px 64px; } }
</style>
</head>
<body>
<div class="wrap">
<h1>srclist build strategy — which <code>/usr/src</code> tools build standalone, which need prereqs</h1>
<p class="lede">Deep-dive investigation triggered by CI failure on <a href="https://github.com/pkgdemon/freebsd-launchd-mach/pull/107">PR #107</a> (drop <code>FreeBSD-rescue</code> pkg, build <code>/rescue/</code> from <code>/usr/src</code>): the standalone <code>make -C rescue/rescue</code> failed because <code>rescue/rescue</code>'s crunchgen pulls in <code>lib/libifconfig</code> 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 <code>srclist-rescue.txt</code> and <code>srclist-runtime.txt</code> in <a href="https://github.com/pkgdemon/freebsd-launchd-mach/issues/104">tickets #104</a> / <a href="https://github.com/pkgdemon/freebsd-launchd-mach/issues/105">#105</a>?</p>
<div class="callout callout-good">
<p><strong>TL;DR.</strong> Three findings, in order of importance:</p>
<ul>
<li><strong>Apple has no <code>/rescue/</code> — ever.</strong> 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 <strong>drop FreeBSD-rescue entirely and not replace it</strong>. <a href="https://github.com/pkgdemon/freebsd-launchd-mach/issues/104">Issue #104</a> + <a href="https://github.com/pkgdemon/freebsd-launchd-mach/pull/107">PR #107</a> closed 2026-05-26. See §2.</li>
<li><strong>Strategic shift to Apple-source userland (for Linux portability).</strong> The single rule: <strong>REPLACE everything in an Apple userland-cmds repo</strong> (file_cmds, shell_cmds, adv_cmds, text_cmds, system_cmds, network_cmds, PowerManagement, DiskArbitration); <strong>KEEP only the irreducible FreeBSD-only items</strong> (kld* family, UFS mount/fsck, devfs, ldconfig, pw, kenv, freebsd-version + BSD-specific debug tools fstat/sockstat/ktrace/ldd/…). Whole-repo porting means whole-repo replacement — no "Apple value-add vs Apple-version-is-same" cherry-picking. See §9 strategic shift.</li>
<li><strong>Net under the strict rule:</strong> <code>srclist-fbsdglue.txt</code> = <strong>25 entries</strong> 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 <a href="https://github.com/pkgdemon/freebsd-launchd-mach/issues/120">#120</a> — 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. <strong>Nine sequential PRs</strong> (§9.2): #105a iter 1 (mechanism + minimal; <a href="https://github.com/pkgdemon/freebsd-launchd-mach/pull/118">PR #118 merged</a>), #105a iter 2 (25-entry shippable; <a href="https://github.com/pkgdemon/freebsd-launchd-mach/pull/119">PR #119 in flight</a>), 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.</li>
<li><strong>Sequencing: FreeBSD-glue mechanism FIRST (high risk), Apple-repo ports second (low risk).</strong> The libifconfig prereq that triggered this investigation IS the FreeBSD-glue mechanism risk. Validating that mechanism early surfaces additional landmines (libsysdecode for kdump/truss, etc.) before any Apple-repo work commits. Apple-side pattern is OpenPAM-proven.</li>
<li><strong>No <code>buildworld</code> needed</strong> anywhere. Per-subdir <code>make</code> against pkgbase-installed headers/libs is sufficient. CI budget: trivial — only ~25–30 entries to build from <code>/usr/src</code>, the rest from Apple sources we vendor under <code>src/</code>.</li>
</ul>
</div>
<div class="toc">
<h2>Contents</h2>
<ol>
<li><a href="#question">The investigation question</a></li>
<li><a href="#apple-rescue">Does Apple even have <code>/rescue/</code>? (No.)</a></li>
<li><a href="#data-inventory">Data: complete pkg inventory (agent 3)</a></li>
<li><a href="#data-categorization">Data: per-tool dep categorization (agent 1)</a></li>
<li><a href="#data-infrastructure">Data: FreeBSD build infrastructure (agent 2)</a></li>
<li><a href="#data-dropkeep">Data: drop-or-keep matrix (agent 4)</a></li>
<li><a href="#strategy">Strategy</a></li>
<li><a href="#action-104">Action for #104 (rescue) — closed (drop /rescue/ entirely)</a></li>
<li><a href="#strategic-shift">Strategic shift — Apple-source for Linux portability</a></li>
<li><a href="#strict-verdicts">Strict-rule verdicts (KEEP / REPLACE / DEFER / DROP)</a></li>
<li><a href="#followup-landmines">Follow-up landmines</a></li>
</ol>
</div>
<h2 id="question">1. The investigation question</h2>
<p>PR #107 (proof-of-concept for ticket #104) failed CI with this error:</p>
<pre><code>lib/libifconfig/libifconfig_sfp.h:33:10: fatal error:
'libifconfig_sfp_tables.h' file not found
*** Error code 1
Stop.</code></pre>
<p>That header is <strong>generated at lib build time</strong> by <code>sfp.lua</code> in <code>lib/libifconfig/Makefile</code>. Standalone <code>make -C rescue/rescue</code> doesn't trigger the prerequisite <code>lib/libifconfig</code> build, so the header never exists in <code>${OBJTOP}/lib/libifconfig/</code> when the crunchgen step needs it.</p>
<p>The question this investigation answers: <strong>is this prereq pattern an outlier, or pervasive?</strong> If pervasive, the manifest-driven build mechanism in <code>srclist-rescue.txt</code> / <code>srclist-runtime.txt</code> needs significant scaffolding (full <code>buildworld</code> prologue, etc.). If outlier, we can drop the offending tools and keep the simple per-subdir <code>make</code> pattern.</p>
<p>Four parallel research agents inventoried four orthogonal facets:</p>
<ol>
<li><strong>Per-tool dep categorization</strong> across a curated 48-tool sample (agent 1)</li>
<li><strong>FreeBSD build infrastructure</strong> — what <code>buildworld</code> does and how long it costs (agent 2)</li>
<li><strong>Complete pkg inventory</strong> — every binary in FreeBSD-runtime/utilities/rescue mapped to <code>/usr/src</code> dirs (agent 3)</li>
<li><strong>Drop-or-keep matrix</strong> — which specific tools force prereq libs (agent 4)</li>
</ol>
<h2 id="apple-rescue">2. Does Apple even have <code>/rescue/</code>? (No.)</h2>
<p>This question wasn't part of the original investigation but came up reviewing the data. The answer reframes ticket #104 significantly.</p>
<h3>2.1. Apple's recovery model</h3>
<p>macOS has never had a <code>/rescue/</code> directory. Apple's recovery story is a <strong>separate Recovery partition (recoveryOS)</strong> — an entire stripped-down macOS image living on its own APFS volume in the same container. Boot paths:</p>
<table>
<tr><th>Mechanism</th><th>How it works</th></tr>
<tr><td><strong>Cmd+R at boot</strong> (Intel Macs)</td><td>Boots into the local Recovery partition's recoveryOS. Provides Disk Utility, Terminal, Safari, Reinstall macOS, Time Machine restore.</td></tr>
<tr><td><strong>Cmd+Option+R</strong> (Intel Macs)</td><td>Internet Recovery — downloads recoveryOS over network.</td></tr>
<tr><td><strong>Long-press Power button</strong> (Apple Silicon)</td><td>Brings up Startup Options menu including Recovery.</td></tr>
<tr><td><strong>Single-user mode</strong> (<code>boot -s</code>, Intel only)</td><td>Boots normal macOS but drops to <code>/bin/sh</code> before launchd starts services. Uses <strong>regular <code>/bin</code> and <code>/sbin</code></strong>, not a separate rescue dir.</td></tr>
<tr><td><strong>Safe Boot</strong> (Shift at boot)</td><td>Normal macOS with extension loading restricted.</td></tr>
</table>
<p>Crucially: <strong>no statically-linked emergency-tools directory exists on macOS at any path.</strong> If <code>/bin/sh</code> or <code>/sbin/mount</code> 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 <code>/rescue/</code>" is BSD-only.</p>
<h3>2.2. Why FreeBSD has <code>/rescue/</code></h3>
<p>FreeBSD's <code>/rescue/</code> is a single statically-linked multi-call binary built via <code>crunchgen</code> that ships every essential tool name as a symlink (ls, cp, mv, sh, mount, fsck, kldload, etc.). The rationale: if <code>/usr</code> is unmountable or <code>/lib</code> is corrupted, <code>/rescue/</code> still works because nothing it does requires shared libraries.</p>
<p>Worth noting: <strong>FreeBSD's single-user mode also drops to <code>/bin/sh</code> first</strong> (just like macOS), and only escalates to <code>/rescue/sh</code> if <code>/bin/sh</code> can't execute (e.g., <code>/lib/libc.so.7</code> missing). The path of recovery is layered: shared-lib tools first, statically-linked rescue tools as fallback.</p>
<h3>2.3. What we actually need for <code>freebsd-launchd-mach</code></h3>
<p>We're building a live ISO that boots in QEMU for CI testing and on real hardware as a dev/research environment. We're <strong>not</strong> building a production OS where someone's data hangs on recovering from a corrupted /lib. The actual failure modes we care about:</p>
<ul>
<li><strong>CI boot test fails</strong> → we read the QEMU console + serial log; no in-VM recovery needed</li>
<li><strong>Dev machine boots to broken state</strong> → rebuild and reflash; the ISO is throwaway</li>
<li><strong>Real recovery story</strong> → not load-bearing; users who need it can keep a FreeBSD live USB around (which has its own /rescue/)</li>
</ul>
<p>So per architectural rule 3 ("don't invent things Apple doesn't do"), and per practical need: <strong>we don't need <code>/rescue/</code> at all</strong>.</p>
<h3>2.4. Implication for ticket #104</h3>
<p>The original framing of #104 ("Drop FreeBSD-rescue pkg; build /rescue/ from /usr/src") is solving the wrong problem. The right framing is: <strong>drop FreeBSD-rescue pkg; don't replace it</strong>. <code>/rescue/</code> simply doesn't exist on our ISO. Single-user mode (if anyone invokes it) falls through to <code>/bin/sh</code> from FreeBSD-runtime (ticket #105 will continue to provide that via <code>bin/sh</code> in <code>srclist-runtime.txt</code>).</p>
<p>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 <code>bin/echo</code> from src) as a smaller proof-of-concept, then move directly to #105.</p>
<div class="callout callout-good">
<p><strong>Updated recommendation for #104:</strong> close PR #107 in favor of a simpler one that just drops the <code>FreeBSD-rescue</code> pkgbase line and adjusts run.sh + boot-test.sh to expect <code>/rescue/</code> 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.</p>
</div>
<h2 id="data-inventory">3. Data: complete pkg inventory (agent 3)</h2>
<p>Inventoried live from <code>pkg.freebsd.org/FreeBSD:14:amd64/base_latest/</code> pkgbase manifests on 2026-05-26.</p>
<table>
<tr><th>Pkg</th><th>Binaries</th><th>Distinct /usr/src dirs</th><th>Notes</th></tr>
<tr><td><code>FreeBSD-runtime</code></td><td>187</td><td>~96</td><td>Includes 27 LINK aliases of <code>sbin/md5</code> (md5sum, sha1, sha256, etc.) + reboot family (halt/poweroff/fastboot) + ln/link, pkill family, etc. After collapsing LINKs: ~96 distinct dirs.</td></tr>
<tr><td><code>FreeBSD-utilities</code></td><td>604</td><td>~330</td><td>The long tail. ~245 <code>usr.bin/*</code>, ~70 <code>usr.sbin/*</code>, ~15 <code>libexec/*</code>, plus ~20 <code>contrib/</code> consumers (less, gzip, bzip2, xz, zstd, libarchive, mandoc, ldns, ntp, sendmail, tcpdump, dialog, …).</td></tr>
<tr><td><code>FreeBSD-rescue</code></td><td>148</td><td>0 new</td><td>All 148 files in <code>/rescue/</code> are hardlinks of one crunchgen multi-call binary (<code>rescue/rescue</code>). Every source dir is already in runtime or utilities — no new src dirs needed.</td></tr>
<tr><td colspan="2"><strong>Combined runtime + utilities (the scope of <code>srclist-runtime.txt</code>):</strong></td><td><strong>~400 dirs</strong></td><td>791 binaries</td></tr>
</table>
<p>Rescue contributing zero new dirs is a useful finding: once <code>srclist-runtime.txt</code> covers runtime + utilities, we have everything we need to also re-build the rescue crunchgen.</p>
<h2 id="data-categorization">4. Data: per-tool dep categorization (agent 1)</h2>
<p>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.</p>
<table>
<tr><th>Category</th><th>Count</th><th>%</th><th>Build pattern</th><th>Examples</th></tr>
<tr><td><strong>A — Leaf (pure libc)</strong></td><td>25</td><td>52%</td><td><code>make -C dir obj && make && make install</code> works trivially. No LIBADD, no generated headers.</td><td>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), ...</td></tr>
<tr><td><strong>B — Lib-dependent (prebuilt libs in pkgbase)</strong></td><td>22</td><td>46%</td><td>Standalone <code>make</code> works because libs are already in <code>/usr/lib</code> from pkgbase clibs / utilities / etc.</td><td>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), ...</td></tr>
<tr><td><strong>C — .PATH into sibling source</strong></td><td>8</td><td>17% (overlap with B)</td><td>Works fine if full <code>/usr/src</code> checkout is present (it is, via src.txz). No buildworld needed.</td><td>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)</td></tr>
<tr><td><strong>D — Crunchgen with lib-build prereq</strong></td><td>1</td><td>2%</td><td><strong>Fails standalone.</strong> Crunchgen pulls in <code>libifconfig.a</code> via <code>CRUNCH_LIBS+= ${OBJTOP}/lib/libifconfig/libifconfig.a</code> AND a <code>-I ${OBJTOP}/lib/libifconfig</code> include path that depends on the generated <code>libifconfig_sfp_tables.h</code>.</td><td><code>rescue/rescue</code> (the only one)</td></tr>
<tr><td><strong>E — Full <code>buildworld</code> required</strong></td><td>0</td><td>0%</td><td>n/a</td><td>(none in the inventory)</td></tr>
</table>
<p><strong>Result: 47 of 48 tools (98%) build standalone with <code>make -C dir obj && make && make install DESTDIR=...</code> against a stock FreeBSD-runtime target plus a full <code>/usr/src</code> checkout.</strong> Only <code>rescue/rescue</code> requires a prereq step.</p>
<h2 id="data-infrastructure">5. Data: FreeBSD build infrastructure (agent 2)</h2>
<p>From <code>Makefile.inc1</code> + freebsd-launchd-mach's own build.sh / GitHub Actions inspection.</p>
<table>
<tr><th>Build approach</th><th>Wall time on 4-vCPU VM</th><th>Notes</th></tr>
<tr><td>Full <code>make buildworld</code></td><td>45–90 min</td><td>Cold cache (vmactions reality — no <code>/usr/obj</code> populated). The <code>_cross-tools</code> phase (rebuilding clang+lld+lldb) is the single biggest cost at 8–15 min.</td></tr>
<tr><td>Stacked <code>WITHOUT_*</code> knobs (CLANG+LLD+LLDB+TESTS+MAN+LIB32+NLS+PROFILE+GAMES) + <code>WITHOUT_CLEAN</code></td><td>20–30 min</td><td>Floor. Still over our 15-min CI budget.</td></tr>
<tr><td><code>SUBDIR_OVERRIDE=lib/libifconfig make buildworld</code></td><td>~15 min</td><td>Still runs <code>_cross-tools</code> prologue. Saves <code>everything</code> phase but not bootstrap.</td></tr>
<tr><td><strong>Per-subdir <code>make -C lib/libifconfig obj && make</code></strong></td><td><strong>~30 sec</strong></td><td>Uses host's clang + headers + libc already in <code>/usr/lib</code>. Just builds that one lib's <code>.a</code> + populates its obj dir with the generated header. This is the right pattern for one-off prereqs.</td></tr>
<tr><td><strong>Per-subdir <code>make -C bin/cp obj && make && make install</code> (leaf)</strong></td><td><strong>~5–15 sec</strong></td><td>The existing <code>build.sh</code> step 3a2 pattern. Works for every Category A / B / C tool.</td></tr>
</table>
<p><strong>Recommendation from agent 2:</strong> stay on the leaf-only pattern (already validated by step 3a2 for <code>rescue/rescue</code>). 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.</p>
<h2 id="data-dropkeep">6. Data: drop-or-keep matrix (agent 4)</h2>
<h3>5.1. Generated-header libs in <code>/usr/src/lib/</code></h3>
<p>The actual landmines — libs whose Makefile runs code-gen at build time, producing headers that external consumers need:</p>
<table>
<tr><th>Lib</th><th>Generator</th><th>Generated headers</th><th>External consumers in our scope</th></tr>
<tr><td><code>lib/libifconfig</code></td><td><code>sfp.lua</code> (src.lua.mk)</td><td><code>libifconfig_sfp_tables.h</code>, <code>libifconfig_sfp_tables_internal.h</code></td><td><strong><code>sbin/ifconfig</code></strong>, <strong><code>rescue/rescue</code></strong> crunchgen</td></tr>
<tr><td><code>lib/libpcap</code></td><td>yacc/bison</td><td><code>tokdefs.h</code> from <code>grammar.h</code></td><td><strong><code>sbin/ipf</code></strong> (rescue), tcpdump (utilities), many others outside scope</td></tr>
<tr><td><code>lib/libsysdecode</code></td><td><code>mktables</code> sh + <code>mkioctls</code></td><td><code>tables.h</code>, <code>tables_linux.h</code>, <code>ioctl.c</code></td><td><code>kdump</code>, <code>truss</code> (utilities; not load-bearing)</td></tr>
<tr><td><code>lib/ncurses/{tinfo,ncurses}</code></td><td>sh + awk MK* scripts</td><td>term.h, curses.h, init_keytry.h, nomacros.h, hashsize.h, parametrized.h (6 headers)</td><td><strong>None in our srclist scope</strong> — <code>ls</code> and <code>less</code> link against the <em>installed</em> <code>libtermcapw.a</code> from pkgbase clibs, not requiring rebuild.</td></tr>
<tr><td>libfetch, libedit, libsm*, libypclnt</td><td>(internal codegens)</td><td>(internal headers)</td><td>None — codegen is intra-lib, builds in a single <code>make</code> pass.</td></tr>
</table>
<h3>5.2. Drop-or-keep for FreeBSD-rescue's crunchgen</h3>
<table>
<tr><th>Sub-tool</th><th>Source dir</th><th>Generated-header dep</th><th>Decision</th><th>Why</th></tr>
<tr><td><code>ifconfig</code></td><td>sbin/ifconfig</td><td><strong>libifconfig</strong></td><td><span class="pill pill-bad">DROP</span></td><td>Emergency-mode rescue rarely needs full ifconfig. Apple's <code>network_cmds/ifconfig</code> in v3 plan replaces /sbin/ifconfig later anyway.</td></tr>
<tr><td><code>ipf</code></td><td>sbin/ipf/ipf</td><td><strong>libpcap</strong></td><td><span class="pill pill-bad">DROP</span></td><td>Packet filter not needed in single-user/emergency shell.</td></tr>
<tr><td>All other ~70 crunchgen entries</td><td>various</td><td>None (verified)</td><td><span class="pill pill-good">KEEP</span></td><td>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.</td></tr>
</table>
<p><strong>Net rescue change:</strong> patch <code>rescue/rescue/Makefile</code> to remove ~7 lines (the <code>ifconfig</code> entry + the <code>MK_IPFILTER</code> ipf block + the <code>CRUNCH_LIBS+= libifconfig.a</code> + the <code>CRUNCH_BUILDOPTS+= -I ${OBJTOP}/lib/libifconfig</code> + the <code>CRUNCH_LIBS_ifconfig+= ${LIBNV}</code>). After that, crunchgen has no external lib-build prereqs.</p>
<h3>5.3. Drop-or-keep for FreeBSD-runtime</h3>
<p>Of 96 distinct <code>/usr/src</code> dirs in FreeBSD-runtime, exactly <strong>one</strong> binary force the libifconfig prereq:</p>
<table>
<tr><th>Installed path</th><th>/usr/src dir</th><th>Generated-header LIBADD</th><th>Decision</th><th>Why</th></tr>
<tr><td><code>/sbin/ifconfig</code></td><td>sbin/ifconfig</td><td><strong>libifconfig</strong></td><td><span class="pill pill-bad">DROP</span> from srclist-runtime.txt</td><td>Apple <code>network_cmds/ifconfig</code> replacement on roadmap. Same rationale as rescue's <code>ifconfig</code>.</td></tr>
<tr><td>All other 95 dirs</td><td>various</td><td>None</td><td><span class="pill pill-good">KEEP</span></td><td>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.</td></tr>
</table>
<p><strong>Net runtime change:</strong> <code>srclist-runtime.txt</code> will list ~95 dirs (instead of 96); <code>/sbin/ifconfig</code> stays missing on the ISO until ticket #106's first per-tool Apple swap (or until <code>network_cmds/ifconfig</code> port lands as a separate per-Apple-repo ticket later in the v3 plan).</p>
<h3>5.4. FreeBSD-utilities (the 330-dir long tail)</h3>
<p>Agent 4 spot-checked the utilities list. Two more potential concerns surfaced:</p>
<table>
<tr><th>Installed path</th><th>/usr/src dir</th><th>Concern</th><th>Decision</th></tr>
<tr><td><code>/usr/bin/kdump</code>, <code>/usr/bin/truss</code></td><td>usr.bin/{kdump,truss}</td><td>LIBADD <code>libsysdecode</code> (has codegen)</td><td><span class="pill pill-warn">drop or keep</span> — not load-bearing for boot. Drop unless someone needs them.</td></tr>
<tr><td>(others)</td><td>various</td><td>None confirmed</td><td><span class="pill pill-good">KEEP</span></td></tr>
</table>
<p><strong>Conclusion: the universe of "tools with generated-header lib prereqs" is essentially {<code>ifconfig</code>, <code>ipf</code>, <code>kdump</code>, <code>truss</code>, tcpdump (libpcap)} across all three pkgs.</strong> Everything else builds clean per-subdir.</p>
<h2 id="strategy">7. Strategy</h2>
<p>The data + the Apple-shape reframing (§2) settle the question decisively:</p>
<ol>
<li><strong>Drop <code>/rescue/</code> entirely.</strong> 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.</li>
<li><strong>Stay on the leaf-only manifest pattern</strong> for #105's runtime + utilities work — the <code>build.sh</code> step 3a2 wiring is right; just point it at a different srclist file.</li>
<li><strong>Drop <code>/sbin/ifconfig</code> from <code>srclist-runtime.txt</code></strong> — matches the existing Apple-userland-cmds v3 plan (network_cmds replacement).</li>
<li><strong>Decide on <code>kdump</code>/<code>truss</code></strong> in utilities — drop unless someone needs them; otherwise add <code>lib/libsysdecode</code> as a prereq entry.</li>
<li><strong>Watch for ncurses</strong> if anything new starts needing it. Not currently a problem; would become one if we start manifesting against headers we don't have.</li>
<li><strong>Slim the manifest aggressively for #105's first iter.</strong> ~425 entries is too many for our CI budget. Trim to the boot/login-critical subset (~50 entries) for the first PR; add the long tail in subsequent iters.</li>
</ol>
<h2 id="action-104">8. Action for #104 (rescue) — revised in light of §2</h2>
<p>Close PR #107 (the "build /rescue/ from src" approach) and open a simpler PR:</p>
<ol>
<li><strong>Keep <code>FreeBSD-rescue</code> commented out in <code>pkglist-base.txt</code></strong> (as PR #107 already did).</li>
<li><strong>Delete <code>srclist-rescue.txt</code></strong> — we don't need it; the manifest mechanism gets proven in #105 instead.</li>
<li><strong>Delete the build.sh step 3a2</strong> entirely.</li>
<li><strong>Update run.sh</strong>: change the <code>RESCUE-SRC-OK</code> check to instead verify <code>/rescue/</code> 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.</li>
<li><strong>Update boot-test.sh</strong>: remove the <code>RESCUE-SRC-OK</code> expect block (or change to <code>RESCUE-ABSENT-OK</code> matching the run.sh change).</li>
<li><strong>Document in commit message + ticket update</strong>: ticket #104's framing of "build /rescue/ from src" was wrong; the right answer is to drop /rescue/ entirely per rule 3 (don't invent things Apple doesn't do).</li>
</ol>
<p>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.</p>
<p><strong>Proof-of-concept for the manifest mechanism</strong> (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 (<code>bin/echo</code> or <code>usr.bin/yes</code>) via a one-entry manifest — that exercises the build.sh wiring without engaging the rescue/crunchgen prereq problem.</p>
<h2 id="strategic-shift">9. Strategic shift — Apple-source userland for Linux portability</h2>
<div class="callout callout-bad">
<p><strong>Major reframing (2026-05-26 evening):</strong> 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 <strong>future Linux portability</strong> — 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.).</p>
<p>So: <strong>port the Apple userland-cmds repos now</strong>, alongside #105, and only ship from <code>srclist-fbsdglue.txt</code> 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.</p>
</div>
<div class="callout callout-good">
<p><strong>The single rule that drives every classification:</strong></p>
<ul>
<li><strong>REPLACE</strong> = entry is in an Apple userland-cmds repo we're porting (file_cmds, shell_cmds, adv_cmds, text_cmds, system_cmds, network_cmds, PowerManagement, DiskArbitration). The whole repo gets vendored + ported — we never cherry-pick binaries from within a repo. Same build cost as FreeBSD-source; gets us closer to Linux portability.</li>
<li><strong>KEEP</strong> = entry has no Apple equivalent at all — either kernel-bound platform glue (kld*, UFS fsck, mount, devfs, ldconfig) or BSD-specific debug tooling with no Apple analogue (fstat, sockstat, procstat, ktrace, ldd, etc.). FreeBSD-source forever; becomes Linux-equivalent later (modprobe/util-linux/strace/lsof/...) on the Linux port.</li>
<li><strong>DEFER</strong> = useful eventually but not first-iter; not in <code>srclist-fbsdglue.txt</code> for now.</li>
<li><strong>DROP</strong> = irrelevant to our use case; never ships.</li>
</ul>
<p>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.</p>
</div>
<h3>9.0. Irreducibly FreeBSD-only on the current ISO (becomes Linux-specific later)</h3>
<p>Re-auditing the original 47-KEEP list under the strict "is there an Apple counterpart?" test, only <strong>~13 entries</strong> are truly FreeBSD-only:</p>
<table>
<tr><th>/usr/src dir</th><th>Why FreeBSD-only</th><th>Linux equivalent (future)</th></tr>
<tr><td>bin/freebsd-version</td><td>FreeBSD release version reporter</td><td><code>lsb_release</code> / <code>/etc/os-release</code></td></tr>
<tr><td>bin/kenv</td><td>FreeBSD-only kernel environment</td><td><code>/proc/cmdline</code> + custom parsing</td></tr>
<tr><td>sbin/camcontrol</td><td>FreeBSD CAM/SCSI control</td><td><code>lsblk</code> + <code>smartctl</code></td></tr>
<tr><td>sbin/devfs</td><td>FreeBSD devfs.rules subsystem</td><td><code>udev</code> / systemd-udev rules</td></tr>
<tr><td>sbin/fsck</td><td>FreeBSD UFS fsck driver</td><td><code>e2fsck</code> / <code>fsck.ext4</code></td></tr>
<tr><td>sbin/mount, umount</td><td>FreeBSD VFS mount</td><td>util-linux <code>mount</code>/<code>umount</code></td></tr>
<tr><td>sbin/kldconfig, kldload, kldstat, kldunload, usr.sbin/kldxref</td><td>FreeBSD kld(4) module family</td><td><code>modprobe</code>/<code>lsmod</code>/<code>rmmod</code>/<code>depmod</code> (kmod)</td></tr>
<tr><td>sbin/ldconfig</td><td>FreeBSD rtld hint cache</td><td>glibc <code>ldconfig</code> (different binary, same purpose)</td></tr>
<tr><td>usr.sbin/pw</td><td>FreeBSD user/group mgmt</td><td><code>useradd</code>/<code>usermod</code>/<code>groupadd</code></td></tr>
</table>
<p>That's the entire "must-stay-platform-source" set: <strong>~13 entries in <code>srclist-fbsdglue.txt</code></strong> 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.</p>
<h3>9.1. Per-srcdir reclassifications — old KEEP entries that flip to REPLACE under the strict rule</h3>
<p>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:</p>
<table>
<tr><th>Apple repo</th><th>KEEP entries that should be REPLACE</th></tr>
<tr><td><code>file_cmds</code></td><td>bin/cat, chflags, dd, ln, mkdir, realpath, rm, rmdir, sync, usr.bin/install</td></tr>
<tr><td><code>shell_cmds</code></td><td>bin/echo, expr, pwd, sh, sleep, test, date, usr.bin/mktemp, env, uname, logger</td></tr>
<tr><td><code>adv_cmds</code></td><td>bin/df, du, kill, pgrep, stty, groups, id</td></tr>
<tr><td><code>text_cmds</code></td><td>bin/tr</td></tr>
<tr><td><code>system_cmds</code></td><td>sbin/md5 (27 hash aliases → Apple md5/shasum family), usr.bin/passwd, usr.sbin/pwd_mkdb</td></tr>
<tr><td>upstream contrib (vendor directly, not via FreeBSD pkg)</td><td>usr.bin/bsdtar (libarchive), less, ncurses</td></tr>
</table>
<p>Combined with the original 21 already-REPLACE entries: <strong>~34 KEEP-now entries reclassified to REPLACE</strong>. Everything except the 13-entry FreeBSD-glue set gets sourced from Apple repos (or upstream contrib for libarchive/less/ncurses).</p>
<h3>9.2. Sequencing strategy — validate <code>srclist-fbsdglue.txt</code> mechanism FIRST, then Apple-repo ports</h3>
<p>Two patterns are in flight:</p>
<ul>
<li><strong>Apple-repo overlay-overwrite</strong> — OpenPAM iter-3-proven. Install Apple binaries at canonical paths overlaying FreeBSD's; <code>pkg set -A 0 FreeBSD-runtime FreeBSD-utilities FreeBSD-pam-lib</code> blocks autoremove. <strong>Low risk.</strong></li>
<li><strong><code>srclist-fbsdglue.txt</code> per-subdir <code>/usr/src</code> builds</strong> — just had PR #107 fail on the libifconfig prereq. <strong>High risk — the actual unknown.</strong> Other generated-header libs (<code>libsysdecode</code> for kdump/truss, etc.) may surface similar prereqs.</li>
</ul>
<p>Therefore: <strong>validate the FreeBSD-glue mechanism as iter 1, before committing to six months of Apple-repo ports built on top of it.</strong></p>
<table>
<tr><th>PR</th><th>What lands</th><th>Risk</th></tr>
<tr><td><strong>#105a iter 1</strong></td><td><strong>srclist-fbsdglue.txt mechanism + minimal entries (~10-11).</strong> Boot-critical leaf binaries only: <code>kld*</code> family, <code>mount</code>, <code>umount</code>, <code>fsck</code>, <code>devfs</code>, <code>ldconfig</code>, <code>kenv</code>, <code>freebsd-version</code>. 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 <code>FBSDGLUE-MIN-OK</code>. <strong>This is the iter that validates the mechanism.</strong></td><td><span class="pill pill-bad">HIGH</span> — mechanism unproven post-#107 failure</td></tr>
<tr><td><strong>#105a iter 2</strong></td><td><strong>Expand <code>srclist-fbsdglue.txt</code> to the full 44 entries</strong> (§9.6.6 ready-to-paste). Includes codegen-prereq cases (<code>kdump</code>/<code>truss</code> link <code>libsysdecode</code>, which has its own <code>mktables</code>-generated headers — same shape as libifconfig prereq from PR #107). Add <code>lib/libsysdecode</code> as a prereq entry above kdump/truss in the manifest. Validate ordered-manifest semantics work.</td><td>Medium</td></tr>
<tr><td><strong>#105b</strong></td><td><strong>file_cmds port</strong> — 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. <code>pkg set -A 0</code> applied. CI markers per binary. First Apple-repo port via overlay pattern.</td><td>Low</td></tr>
<tr><td><strong>#105c</strong></td><td><strong>shell_cmds port</strong> — ~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/…</td><td>Low</td></tr>
<tr><td><strong>#105d</strong></td><td><strong>adv_cmds port</strong> — 15 binaries. /bin/ps and /bin/pkill (Apple <code>kinfo_proc</code> layout shim). Also: stty, tty, finger, last, whois, locale, localedef, cap_mkdb, gencat, tabs, lsvfs.</td><td>Low-Medium (kinfo_proc shim)</td></tr>
<tr><td><strong>#105e</strong></td><td><strong>text_cmds port</strong> — 34 binaries. sort (Mach semaphores) + grep/sed/tr/wc/tail/head/uniq/comm/cut/paste/… (pure POSIX vendor).</td><td>Low</td></tr>
<tr><td><strong>#105f</strong></td><td><strong>system_cmds port</strong> — ~50 binaries. The big one: getty, login, sysctl, dmesg, halt/shutdown/reboot, dynamic_pager, hash family (md5/sha1/sha256/… 27 aliases), passwd, pwd_mkdb. <strong>Subsumes ticket #106</strong> (getty swap) entirely.</td><td>Medium (mach.ko traps for lsmp/hostinfo/stackshot)</td></tr>
<tr><td><strong>#105g</strong></td><td><strong>network_cmds port</strong> — 15 binaries: ifconfig, ping, ping6, route, arp, ndp, rtadvd, rtsol, netstat, traceroute, traceroute6, kdumpd. <strong>Resolves the libifconfig prereq permanently</strong> — Apple's ifconfig replaces FreeBSD's at /sbin/ifconfig.</td><td>Low-Medium (struct ABI drift)</td></tr>
<tr><td><strong>#105h</strong></td><td><strong>Final pkg drop</strong> — comment out FreeBSD-runtime + FreeBSD-utilities + FreeBSD-pam-lib lines in pkglist-base.txt. Trivial 3-line PR. <strong>Closes #103</strong> (pam-lib phantom).</td><td>Trivial</td></tr>
</table>
<p><strong>Why this ordering is better than "Apple repos first":</strong></p>
<ul>
<li>The libifconfig prereq problem that triggered this entire investigation IS the FreeBSD-glue mechanism risk. Validating that mechanism FIRST surfaces additional landmines (libsysdecode, libpcap, ncurses, etc.) before any Apple-repo work commits.</li>
<li>#105a iter 1 with just ~10 leaf entries is small + ships fast — quick validation cycle.</li>
<li>#105a iter 2 expands to the full 44 including codegen-prereq cases — proves the mechanism scales.</li>
<li>Apple-repo ports (#105b–#105g) then proceed on solid foundation. If any Apple-port PR has issues, they're isolated to that repo's shim/build work, not entangled with mechanism validation.</li>
<li><strong>Ticket #106 (getty swap)</strong> becomes redundant since system_cmds (#105f) includes getty. Close #106 with a redirect to #105f.</li>
</ul>
<h3>9.3. First-iter PR scope — aggressive drop+defer</h3>
<p>Concretely for <strong>#105a (file_cmds port, the first PR)</strong>:</p>
<ul>
<li>Vendor <code>apple-oss-distributions/file_cmds</code> into <code>src/file_cmds/</code> at a pinned tag</li>
<li>Build all 27 binaries (no half-port; whole-repo). Most are leaf POSIX (no Apple-stack deps); cp/mv/ls/install/gzip/pax/mtree need libdispatch (already shipped) + libacl shim</li>
<li>Install at Apple-canonical paths: /bin/cp, /bin/ls, /bin/cat, etc. (overlay-overwriting FreeBSD-runtime's same paths)</li>
<li><code>pkg set -A 0 FreeBSD-runtime FreeBSD-utilities</code> applied right after pkg install (mirrors the OpenPAM iter-3 pattern at build.sh:175-198)</li>
<li><strong>Nothing else changes</strong>: pkglist-base.txt keeps FreeBSD-runtime/utilities; no srclist mechanism introduced; no /usr/src builds from manifest</li>
<li>CI markers per binary or per logical group: <code>FILECMD-CP-OK</code> (verify Apple cp via clonefile attempt or Apple-specific behavior), <code>FILECMD-LS-OK</code> (verify -e flag for ACL display works), etc.</li>
</ul>
<p>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.</p>
<p><strong>The srclist mechanism (and srclist-rescue.txt's failed shape from PR #107) is no longer load-bearing.</strong> It's only needed for the final ~13-entry fbsdglue manifest at #105g, which is tiny and trivial.</p>
<h2 id="strict-verdicts">9.5. Strict-rule verdicts — consolidated runtime + utilities</h2>
<p>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.</p>
<h3>9.5.1. KEEP — truly FreeBSD-only (will become Linux-only later)</h3>
<table>
<tr><th>/usr/src dir</th><th>Why no Apple equivalent</th><th>Linux equivalent (future)</th></tr>
<tr><td>bin/freebsd-version</td><td>FreeBSD release reporter</td><td><code>/etc/os-release</code></td></tr>
<tr><td>bin/kenv</td><td>FreeBSD kernel env interface</td><td><code>/proc/cmdline</code></td></tr>
<tr><td>sbin/camcontrol <em>(deferred 2026-05-26 — see §9.6.2)</em></td><td>FreeBSD CAM/SCSI</td><td><code>lsblk</code> + <code>smartctl</code></td></tr>
<tr><td>sbin/devfs</td><td>FreeBSD devfs.rules subsystem</td><td><code>udev</code></td></tr>
<tr><td>sbin/fsck</td><td>FreeBSD UFS fsck driver (UFS2 + SU+J port "too much work" per user)</td><td><code>fsck.ext4</code> / <code>e2fsck</code></td></tr>
<tr><td>sbin/kldconfig, kldload, kldstat, kldunload</td><td>FreeBSD kld(4)</td><td><code>modprobe</code>/<code>lsmod</code>/<code>rmmod</code></td></tr>
<tr><td>sbin/ldconfig</td><td>FreeBSD rtld hint cache</td><td>glibc ldconfig</td></tr>
<tr><td>sbin/mount, umount</td><td>FreeBSD VFS</td><td>util-linux mount/umount</td></tr>
<tr><td>usr.sbin/kldxref</td><td>FreeBSD kld(4) cache</td><td><code>depmod</code></td></tr>
<tr><td>usr.sbin/pw</td><td>FreeBSD user/group mgmt</td><td><code>useradd</code>/<code>groupadd</code></td></tr>
<tr><td colspan="3"><em>FreeBSD-specific debug tools (no Apple analogue):</em></td></tr>
<tr><td>usr.bin/fstat, sockstat, procstat</td><td>FreeBSD-specific process/socket introspection (Apple uses <code>lsof</code> + <code>sample</code>). <em>(fuser is a LINK from usr.bin/fstat — binary appears at /usr/bin/fuser via fstat's Makefile LINKS=.)</em></td><td><code>lsof</code> / <code>ss</code> / <code>fuser</code> (procps)</td></tr>
<tr><td>usr.bin/ktrace, kdump, truss, ktrdump</td><td>FreeBSD ktrace/truss (Apple uses dtrace/sample)</td><td><code>strace</code></td></tr>
<tr><td>usr.bin/ldd</td><td>FreeBSD-specific rtld query (Apple uses <code>otool -L</code>)</td><td><code>ldd</code> (glibc)</td></tr>
<tr><td>usr.bin/getent</td><td>BSD-specific NSS query (Apple uses dscacheutil). <em>(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.)</em></td><td>various</td></tr>
<tr><td>usr.bin/top, w, vmstat</td><td>BSD vmstat/top format</td><td>procps top/w/vmstat</td></tr>
<tr><td>usr.sbin/devctl, diskinfo, fstyp, gstat, pciconf, crashinfo</td><td>FreeBSD-specific newbus/GEOM/PCI/crash tools</td><td>various (udev/lspci/...)</td></tr>
<tr><td>libexec/save-entropy</td><td>FreeBSD entropy daemon</td><td>systemd-random-seed</td></tr>
</table>
<p><strong>Net KEEP set:</strong> ~25–30 entries combined runtime + utilities. This is <code>srclist-fbsdglue.txt</code>'s permanent content on FreeBSD; on Linux these get swapped 1:1 with the Linux equivalents above.</p>
<h3>9.5.2. REPLACE — covered by Apple userland-cmds v3 ports</h3>
<p>Every other entry from the original FreeBSD-runtime (187 binaries) + FreeBSD-utilities (604 binaries) inventory that's NOT DEFER or DROP. Per-repo mapping:</p>
<table>
<tr><th>Apple repo (v3 roadmap)</th><th>Sample entries it covers</th></tr>
<tr><td><code>file_cmds</code> (27 binaries)</td><td>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</td></tr>
<tr><td><code>shell_cmds</code> (~45)</td><td>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</td></tr>
<tr><td><code>adv_cmds</code> (15)</td><td>cap_mkdb, finger, gencat, last, locale, localedef, lsvfs, pkill, ps, stty, tabs, tty, whois, colldef</td></tr>
<tr><td><code>text_cmds</code> (34)</td><td>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</td></tr>
<tr><td><code>system_cmds</code> (~50)</td><td>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)</td></tr>
<tr><td><code>network_cmds</code> (15)</td><td>arp, dnctl, ifconfig, kdumpd, ndp, netstat, ping, ping6, rarpd, route, rtadvd, rtsol, spray, traceroute, traceroute6</td></tr>
<tr><td><code>PowerManagement</code> (~6)</td><td>caffeinate, pmset, pmtool, pmconfigd, ioupsd, swd</td></tr>
<tr><td><code>DiskArbitration</code> (~4)</td><td>diskarbitrationd, autodiskmount, DiskArbitrationAgent, datest</td></tr>
<tr><td>Upstream contrib (vendored separately)</td><td>usr.bin/bsdtar (libarchive), less, ncurses (tic/tput/clear/…), tcpdump, mandoc/man/manpath, awk (one-true-awk), bmake</td></tr>
</table>
<p><strong>Net REPLACE set:</strong> ~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.</p>
<h3>9.5.3. DEFER — useful eventually but not first iter</h3>
<p>~15 entries: <code>bin/ed</code>, <code>bin/getfacl</code>, <code>bin/setfacl</code>, <code>bin/nproc</code>, <code>bin/uuidgen</code>, <code>sbin/comcontrol</code>, <code>sbin/conscontrol</code>, <code>sbin/dumpon</code>, <code>sbin/fsck_msdosfs</code>, <code>sbin/mknod</code>, <code>sbin/mount_fusefs/msdosfs/nullfs</code>, <code>sbin/newfs_msdos</code>, <code>sbin/recoverdisk</code>, <code>sbin/swapon</code>, <code>usr.bin/bzip2-scripts</code>, <code>usr.bin/limits</code>, <code>usr.bin/what</code>, <code>usr.sbin/ip6addrctl</code>, 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.</p>
<h3>9.5.4. DROP — never ships</h3>
<p>Confirmed dead per build.sh inspection or superseded by in-repo daemons:</p>
<p><code>sbin/adjkerntz</code> (UTC-only), <code>sbin/bsdlabel</code> + <code>sbin/fdisk</code> (GPT-only boot), <code>sbin/ddb</code> (in-kernel), <code>sbin/etherswitchcfg</code> (HW we don't have), <code>sbin/init</code> (launchd PID 1), <code>sbin/mdconfig</code> + <code>mdmfs</code> + <code>sbin/mount_mfs</code> + <code>sbin/mount_cd9660</code> + <code>sbin/mount_udf</code> + <code>sbin/mount_unionfs</code> (no memdisk/unionfs/UDF path), <code>sbin/routed</code> (no RIP), <code>sbin/savecore</code> (core dumps disabled), <code>bin/hostname</code> (covered by shell_cmds REPLACE actually — reclassify), <code>usr.sbin/service</code> (launchctl owns service lifecycle), <code>usr.sbin/services_mkdb</code> (rc.d-only; flat-file fallback works; no Apple equivalent in any v3 repo), <code>usr.sbin/sysrc</code> (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).</p>
<h2 id="complete-table">9.6. Complete per-srcdir verdict table</h2>
<p>Every <code>/usr/src</code> dir from FreeBSD-runtime + FreeBSD-utilities, single strict-rule verdict per row. Organized by <code>/usr/src</code> bucket (alphabetical within). LINK aliases collapsed to their source dir.</p>
<h3>9.6.1. <code>bin/</code></h3>
<table>
<tr><th>/usr/src dir</th><th>Verdict</th><th>Rationale</th><th>Apple repo (if REPLACE)</th></tr>
<tr><td>bin/cat</td><td><span class="pill pill-warn">REPLACE</span></td><td>file ops</td><td>file_cmds</td></tr>
<tr><td>bin/chflags</td><td><span class="pill pill-warn">REPLACE</span></td><td>file ops</td><td>file_cmds</td></tr>
<tr><td>bin/chio</td><td><span class="pill pill-bad">DROP</span></td><td>tape changer</td><td>—</td></tr>
<tr><td>bin/chmod</td><td><span class="pill pill-warn">REPLACE</span></td><td>file ops + ACL</td><td>file_cmds</td></tr>
<tr><td>bin/cp</td><td><span class="pill pill-warn">REPLACE</span></td><td>file ops + clonefile</td><td>file_cmds</td></tr>
<tr><td>bin/cpuset</td><td><span class="pill pill-neutral">DEFER</span></td><td>CPU pinning niche</td><td>—</td></tr>
<tr><td>bin/date</td><td><span class="pill pill-warn">REPLACE</span></td><td>shell tool</td><td>shell_cmds</td></tr>
<tr><td>bin/dd</td><td><span class="pill pill-warn">REPLACE</span></td><td>file ops</td><td>file_cmds</td></tr>
<tr><td>bin/df</td><td><span class="pill pill-warn">REPLACE</span></td><td>filesystem stats</td><td>adv_cmds</td></tr>
<tr><td>bin/echo</td><td><span class="pill pill-warn">REPLACE</span></td><td>shell builtin (also standalone)</td><td>shell_cmds</td></tr>
<tr><td>bin/ed</td><td><span class="pill pill-neutral">DEFER</span></td><td>vi covers; ed unused</td><td>—</td></tr>
<tr><td>bin/expr</td><td><span class="pill pill-warn">REPLACE</span></td><td>shell arithmetic</td><td>shell_cmds</td></tr>
<tr><td>bin/freebsd-version</td><td><span class="pill pill-good">KEEP</span></td><td>FreeBSD-only release reporter</td><td>—</td></tr>
<tr><td>bin/getfacl</td><td><span class="pill pill-neutral">DEFER</span></td><td>UFS ACLs unused first iter</td><td>—</td></tr>
<tr><td>bin/hostname</td><td><span class="pill pill-warn">REPLACE</span></td><td>thin gethostname/sethostname wrapper</td><td>shell_cmds</td></tr>
<tr><td>bin/kenv</td><td><span class="pill pill-good">KEEP</span></td><td>FreeBSD-only kernel env (mach.debug_enable, launchd_trace gates)</td><td>—</td></tr>
<tr><td>bin/kill</td><td><span class="pill pill-warn">REPLACE</span></td><td>signal sender</td><td>shell_cmds</td></tr>
<tr><td>bin/ln</td><td><span class="pill pill-warn">REPLACE</span></td><td>file ops</td><td>file_cmds</td></tr>
<tr><td>bin/ls</td><td><span class="pill pill-warn">REPLACE</span></td><td>file listing + ACL display</td><td>file_cmds</td></tr>
<tr><td>bin/mkdir</td><td><span class="pill pill-warn">REPLACE</span></td><td>file ops</td><td>file_cmds</td></tr>
<tr><td>bin/mv</td><td><span class="pill pill-warn">REPLACE</span></td><td>file ops</td><td>file_cmds</td></tr>
<tr><td>bin/nproc</td><td><span class="pill pill-neutral">DEFER</span></td><td>nice-to-have for parallel make</td><td>—</td></tr>
<tr><td>bin/pax</td><td><span class="pill pill-warn">REPLACE</span></td><td>file ops + xattr</td><td>file_cmds</td></tr>
<tr><td>bin/pkill (incl. pgrep/pwait aliases)</td><td><span class="pill pill-warn">REPLACE</span></td><td>process signal/match</td><td>adv_cmds</td></tr>
<tr><td>bin/ps</td><td><span class="pill pill-warn">REPLACE</span></td><td>process listing</td><td>adv_cmds</td></tr>
<tr><td>bin/pwd</td><td><span class="pill pill-warn">REPLACE</span></td><td>shell tool</td><td>shell_cmds</td></tr>
<tr><td>bin/realpath</td><td><span class="pill pill-warn">REPLACE</span></td><td>file ops</td><td>file_cmds</td></tr>
<tr><td>bin/rm</td><td><span class="pill pill-warn">REPLACE</span></td><td>file ops</td><td>file_cmds</td></tr>
<tr><td>bin/rmdir</td><td><span class="pill pill-warn">REPLACE</span></td><td>file ops</td><td>file_cmds</td></tr>
<tr><td>bin/setfacl</td><td><span class="pill pill-neutral">DEFER</span></td><td>UFS ACLs unused first iter</td><td>—</td></tr>
<tr><td>bin/sh</td><td><span class="pill pill-warn">REPLACE</span></td><td>load-bearing shell</td><td>shell_cmds</td></tr>
<tr><td>bin/sleep</td><td><span class="pill pill-warn">REPLACE</span></td><td>shell tool</td><td>shell_cmds</td></tr>
<tr><td>bin/stty</td><td><span class="pill pill-warn">REPLACE</span></td><td>terminal control</td><td>adv_cmds</td></tr>
<tr><td>bin/sync</td><td><span class="pill pill-warn">REPLACE</span></td><td>file ops</td><td>file_cmds (also system_cmds)</td></tr>
<tr><td>bin/test (and "[")</td><td><span class="pill pill-warn">REPLACE</span></td><td>shell tool</td><td>shell_cmds</td></tr>
<tr><td>bin/timeout</td><td><span class="pill pill-warn">REPLACE</span></td><td>test harness uses it</td><td>shell_cmds</td></tr>
<tr><td>bin/uuidgen</td><td><span class="pill pill-neutral">DEFER</span></td><td>hwregd has its own</td><td>—</td></tr>
</table>
<h3>9.6.2. <code>sbin/</code></h3>
<table>
<tr><th>/usr/src dir</th><th>Verdict</th><th>Rationale</th><th>Apple repo (if REPLACE)</th></tr>
<tr><td>sbin/adjkerntz</td><td><span class="pill pill-bad">DROP</span></td><td>UTC-only ISO</td><td>—</td></tr>
<tr><td>sbin/bsdlabel</td><td><span class="pill pill-bad">DROP</span></td><td>GPT-only boot</td><td>—</td></tr>
<tr><td>sbin/camcontrol</td><td><span class="pill pill-neutral">DEFER</span></td><td>FreeBSD CAM/SCSI; needs lib/libnvmf privatelib prereq (NVMe-over-Fabrics) and not load-bearing for CI (virtio, no CAM) or daily dev. <em>Reclassified from KEEP after iter 2 CI run 26459081598 surfaced the dep; add back if a real consumer surfaces.</em></td><td>—</td></tr>
<tr><td>sbin/comcontrol</td><td><span class="pill pill-neutral">DEFER</span></td><td>no serial console</td><td>—</td></tr>
<tr><td>sbin/conscontrol</td><td><span class="pill pill-neutral">DEFER</span></td><td>no serial console</td><td>—</td></tr>
<tr><td>sbin/ddb</td><td><span class="pill pill-bad">DROP</span></td><td>kernel ddb in-kernel; userland unused</td><td>—</td></tr>
<tr><td>sbin/decryptcore</td><td><span class="pill pill-bad">DROP</span></td><td>encrypted dumps unused</td><td>—</td></tr>
<tr><td>sbin/devfs</td><td><span class="pill pill-good">KEEP</span></td><td>FreeBSD devfs.rules subsystem</td><td>—</td></tr>
<tr><td>sbin/dmesg</td><td><span class="pill pill-warn">REPLACE</span></td><td>kmsg reader</td><td>system_cmds</td></tr>
<tr><td>sbin/dumpon</td><td><span class="pill pill-neutral">DEFER</span></td><td>core dumps disabled</td><td>—</td></tr>
<tr><td>sbin/etherswitchcfg</td><td><span class="pill pill-bad">DROP</span></td><td>embedded switch HW we don't have</td><td>—</td></tr>
<tr><td>sbin/fdisk</td><td><span class="pill pill-bad">DROP</span></td><td>MBR; we use GPT</td><td>—</td></tr>
<tr><td>sbin/fsck</td><td><span class="pill pill-good">KEEP</span></td><td>FreeBSD UFS fsck driver</td><td>—</td></tr>
<tr><td>sbin/fsck_ffs</td><td><span class="pill pill-good">KEEP</span></td><td>FreeBSD UFS</td><td>—</td></tr>
<tr><td>sbin/fsck_msdosfs</td><td><span class="pill pill-neutral">DEFER</span></td><td>FAT USB only</td><td>—</td></tr>
<tr><td>sbin/init</td><td><span class="pill pill-bad">DROP</span></td><td>launchd is PID 1</td><td>—</td></tr>
<tr><td>sbin/ifconfig</td><td><span class="pill pill-warn">REPLACE</span></td><td>network config; lib/libifconfig prereq goes away once Apple's lands</td><td>network_cmds</td></tr>
<tr><td>sbin/kldconfig, kldload, kldstat, kldunload</td><td><span class="pill pill-good">KEEP</span></td><td>FreeBSD kld(4) family; mach.ko is loaded via these</td><td>—</td></tr>
<tr><td>sbin/ldconfig</td><td><span class="pill pill-good">KEEP</span></td><td>FreeBSD rtld hint cache; libxpc/libmach/libdispatch dlopened via</td><td>—</td></tr>
<tr><td>sbin/md5 (+27 hash aliases)</td><td><span class="pill pill-warn">REPLACE</span></td><td>hash family (md5/sha1/sha256/sha512/rmd160/skein)</td><td>system_cmds</td></tr>
<tr><td>sbin/mdconfig, mdmfs</td><td><span class="pill pill-bad">DROP</span></td><td>no memdisk pivot (build.sh:2145)</td><td>—</td></tr>
<tr><td>sbin/mknod</td><td><span class="pill pill-neutral">DEFER</span></td><td>devfs autopopulates</td><td>—</td></tr>
<tr><td>sbin/mount</td><td><span class="pill pill-good">KEEP</span></td><td>FreeBSD VFS-specific</td><td>—</td></tr>
<tr><td>sbin/mount_cd9660</td><td><span class="pill pill-bad">DROP</span></td><td>no ISO9660 in boot path</td><td>—</td></tr>
<tr><td>sbin/mount_fusefs</td><td><span class="pill pill-neutral">DEFER</span></td><td>no FUSE-by-default</td><td>—</td></tr>
<tr><td>sbin/mount_mfs</td><td><span class="pill pill-bad">DROP</span></td><td>dead with mdconfig</td><td>—</td></tr>
<tr><td>sbin/mount_msdosfs</td><td><span class="pill pill-neutral">DEFER</span></td><td>FAT USB sticks only</td><td>—</td></tr>
<tr><td>sbin/mount_nullfs</td><td><span class="pill pill-neutral">DEFER</span></td><td>no overlay trick in current build</td><td>—</td></tr>
<tr><td>sbin/mount_udf</td><td><span class="pill pill-bad">DROP</span></td><td>DVD filesystem; no use case</td><td>—</td></tr>
<tr><td>sbin/mount_unionfs</td><td><span class="pill pill-bad">DROP</span></td><td>"no unionfs" per build.sh:2145</td><td>—</td></tr>
<tr><td>sbin/newfs</td><td><span class="pill pill-good">KEEP</span></td><td>FreeBSD UFS</td><td>—</td></tr>
<tr><td>sbin/newfs_msdos</td><td><span class="pill pill-neutral">DEFER</span></td><td>FAT only</td><td>—</td></tr>
<tr><td>sbin/nologin</td><td><span class="pill pill-good">KEEP</span></td><td>login shell-of-last-resort</td><td>—</td></tr>
<tr><td>sbin/nos-tun</td><td><span class="pill pill-bad">DROP</span></td><td>obscure tunneling</td><td>—</td></tr>
<tr><td>sbin/pfilctl</td><td><span class="pill pill-bad">DROP</span></td><td>no firewall</td><td>—</td></tr>
<tr><td>sbin/ping, ping6</td><td><span class="pill pill-warn">REPLACE</span></td><td>dev work</td><td>network_cmds</td></tr>
<tr><td>sbin/recoverdisk</td><td><span class="pill pill-neutral">DEFER</span></td><td>data recovery niche</td><td>—</td></tr>
<tr><td>sbin/reboot (+halt+poweroff+fastboot+fasthalt+nextboot aliases)</td><td><span class="pill pill-warn">REPLACE</span></td><td>system shutdown family</td><td>system_cmds</td></tr>
<tr><td>sbin/route</td><td><span class="pill pill-warn">REPLACE</span></td><td>route manipulation</td><td>network_cmds</td></tr>
<tr><td>sbin/routed (+rtquery)</td><td><span class="pill pill-bad">DROP</span></td><td>RIP daemon unused</td><td>—</td></tr>
<tr><td>sbin/rtsol</td><td><span class="pill pill-warn">REPLACE</span></td><td>IPv6 RA</td><td>network_cmds</td></tr>
<tr><td>sbin/savecore</td><td><span class="pill pill-bad">DROP</span></td><td>core dumps disabled</td><td>—</td></tr>
<tr><td>sbin/setkey</td><td><span class="pill pill-bad">DROP</span></td><td>IPsec unused</td><td>—</td></tr>
<tr><td>sbin/shutdown</td><td><span class="pill pill-warn">REPLACE</span></td><td>login users hit this</td><td>system_cmds</td></tr>
<tr><td>sbin/swapon (+swapoff+swapctl)</td><td><span class="pill pill-neutral">DEFER</span></td><td>no swap configured</td><td>—</td></tr>
<tr><td>sbin/sysctl</td><td><span class="pill pill-warn">REPLACE</span></td><td>kern.* knobs</td><td>system_cmds</td></tr>
<tr><td>sbin/tunefs</td><td><span class="pill pill-good">KEEP</span></td><td>FreeBSD UFS</td><td>—</td></tr>
<tr><td>sbin/umount</td><td><span class="pill pill-good">KEEP</span></td><td>FreeBSD VFS</td><td>—</td></tr>
<tr><td>sbin/zfsbootcfg</td><td><span class="pill pill-bad">DROP</span></td><td>UFS-only boot</td><td>—</td></tr>
</table>
<h3>9.6.3. <code>usr.bin/</code> (the long tail)</h3>
<table>
<tr><th>/usr/src dir</th><th>Verdict</th><th>Rationale</th><th>Apple repo (if REPLACE)</th></tr>
<tr><td>usr.bin/apply</td><td><span class="pill pill-bad">DROP</span></td><td>obscure</td><td>—</td></tr>
<tr><td>usr.bin/ar, ranlib</td><td><span class="pill pill-neutral">DEFER</span></td><td>on-target compile toolchain</td><td>—</td></tr>
<tr><td>usr.bin/asa</td><td><span class="pill pill-bad">DROP</span></td><td>FORTRAN carriage control</td><td>—</td></tr>
<tr><td>usr.bin/awk</td><td><span class="pill pill-warn">REPLACE</span></td><td>scripts everywhere</td><td>shell_cmds (or contrib/one-true-awk)</td></tr>
<tr><td>usr.bin/b64decode/encode, uuencode/uudecode</td><td><span class="pill pill-bad">DROP</span></td><td>one-shot conversion; use python/openssl</td><td>—</td></tr>
<tr><td>usr.bin/banner, fortune, morse, number, factor, primes, random, msgs, leave, pom, caesar, rot13, strfile</td><td><span class="pill pill-bad">DROP</span></td><td>BSD games/novelty</td><td>—</td></tr>
<tr><td>usr.bin/basename</td><td><span class="pill pill-warn">REPLACE</span></td><td>shell scripts</td><td>shell_cmds</td></tr>
<tr><td>usr.bin/bc, dc</td><td><span class="pill pill-neutral">DEFER</span></td><td>not load-bearing</td><td>—</td></tr>
<tr><td>usr.bin/biff, from, mesg, write, wall, mail, mailx, vacation, talk</td><td><span class="pill pill-bad">DROP</span></td><td>no MTA</td><td>—</td></tr>
<tr><td>usr.bin/bmake, make</td><td><span class="pill pill-neutral">DEFER</span></td><td>on-target compile</td><td>—</td></tr>
<tr><td>usr.bin/brandelf, elfctl, elfdump, etdump</td><td><span class="pill pill-neutral">DEFER</span></td><td>binary forensics off-target</td><td>—</td></tr>
<tr><td>usr.bin/bsdcat</td><td><span class="pill pill-warn">REPLACE</span></td><td>libarchive front-end</td><td>contrib/libarchive (upstream vendor)</td></tr>
<tr><td>usr.bin/bsdiff, bspatch, bsdcpio, bsdunzip</td><td><span class="pill pill-bad">DROP</span></td><td>unused</td><td>—</td></tr>
<tr><td>usr.bin/bzip2 + bz*grep/bzless scripts</td><td><span class="pill pill-neutral">DEFER</span></td><td>compressed log convenience</td><td>—</td></tr>
<tr><td>usr.bin/byacc, yacc, lex, flex</td><td><span class="pill pill-neutral">DEFER</span></td><td>on-target codegen</td><td>—</td></tr>
<tr><td>usr.bin/c89, c99</td><td><span class="pill pill-neutral">DEFER</span></td><td>on-target compile</td><td>—</td></tr>
<tr><td>usr.bin/cal, ncal</td><td><span class="pill pill-bad">DROP</span></td><td>trivia</td><td>—</td></tr>
<tr><td>usr.bin/calendar</td><td><span class="pill pill-bad">DROP</span></td><td>reminder daemon</td><td>—</td></tr>
<tr><td>usr.bin/cap_mkdb</td><td><span class="pill pill-warn">REPLACE</span></td><td>termcap-style DB builder</td><td>adv_cmds</td></tr>
<tr><td>usr.bin/chat</td><td><span class="pill pill-bad">DROP</span></td><td>UUCP/PPP dialer</td><td>—</td></tr>
<tr><td>usr.bin/chfn, chpass, chsh</td><td><span class="pill pill-neutral">DEFER</span></td><td>one root user</td><td>—</td></tr>
<tr><td>usr.bin/chgrp</td><td><span class="pill pill-warn">REPLACE</span></td><td>group ownership</td><td>file_cmds</td></tr>
<tr><td>usr.bin/chkey</td><td><span class="pill pill-bad">DROP</span></td><td>Secure RPC</td><td>—</td></tr>
<tr><td>usr.bin/cksum</td><td><span class="pill pill-warn">REPLACE</span></td><td>checksum tool</td><td>text_cmds</td></tr>
<tr><td>usr.bin/cmp</td><td><span class="pill pill-warn">REPLACE</span></td><td>file compare</td><td>shell_cmds</td></tr>
<tr><td>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</td><td><span class="pill pill-warn">REPLACE</span></td><td>text-stream processors</td><td>text_cmds (most) / shell_cmds (tee, cut)</td></tr>
<tr><td>usr.bin/colldef, mkcsmapper, mkesdb</td><td><span class="pill pill-warn">REPLACE</span></td><td>locale tooling</td><td>adv_cmds (colldef)</td></tr>
<tr><td>usr.bin/compress</td><td><span class="pill pill-neutral">DEFER</span></td><td>legacy</td><td>—</td></tr>
<tr><td>usr.bin/cpio</td><td><span class="pill pill-bad">DROP</span></td><td>tape archiver unused</td><td>—</td></tr>
<tr><td>usr.bin/crontab</td><td><span class="pill pill-bad">DROP</span></td><td>launchd StartCalendarInterval covers</td><td>—</td></tr>
<tr><td>usr.bin/crunchgen, crunchide</td><td><span class="pill pill-bad">DROP</span></td><td>no /rescue/</td><td>—</td></tr>
<tr><td>usr.bin/crypt, enigma</td><td><span class="pill pill-bad">DROP</span></td><td>toy crypto</td><td>—</td></tr>
<tr><td>usr.bin/ctags, indent, file2c, mkstr, xstr, unifdef</td><td><span class="pill pill-neutral">DEFER</span></td><td>dev-on-target</td><td>—</td></tr>
<tr><td>usr.bin/ctlstat</td><td><span class="pill pill-bad">DROP</span></td><td>CAM debug niche</td><td>—</td></tr>
<tr><td>usr.bin/cu, tip</td><td><span class="pill pill-bad">DROP</span></td><td>modem</td><td>—</td></tr>
<tr><td>usr.bin/dialog, bsddialog</td><td><span class="pill pill-bad">DROP</span></td><td>TUI installer</td><td>—</td></tr>
<tr><td>usr.bin/diff, diff3, sdiff</td><td><span class="pill pill-neutral">DEFER</span></td><td>not load-bearing</td><td>—</td></tr>
<tr><td>usr.bin/dtc</td><td><span class="pill pill-bad">DROP</span></td><td>device tree compiler (ARM); we're amd64</td><td>—</td></tr>
<tr><td>usr.bin/du</td><td><span class="pill pill-warn">REPLACE</span></td><td>disk usage</td><td>adv_cmds</td></tr>
<tr><td>usr.bin/ed</td><td><span class="pill pill-neutral">DEFER</span></td><td>vi enough</td><td>—</td></tr>
<tr><td>usr.bin/ee</td><td><span class="pill pill-bad">DROP</span></td><td>use vi</td><td>—</td></tr>
<tr><td>usr.bin/env</td><td><span class="pill pill-warn">REPLACE</span></td><td>shebang lines</td><td>shell_cmds</td></tr>
<tr><td>usr.bin/false, true, yes</td><td><span class="pill pill-warn">REPLACE</span></td><td>shell primitives</td><td>shell_cmds</td></tr>
<tr><td>usr.bin/fetch</td><td><span class="pill pill-good">KEEP</span></td><td>no direct Apple equivalent (curl/wget would be ports)</td><td>—</td></tr>
<tr><td>usr.bin/file</td><td><span class="pill pill-good">KEEP</span></td><td>no Apple equivalent; binary forensics</td><td>—</td></tr>
<tr><td>usr.bin/find</td><td><span class="pill pill-warn">REPLACE</span></td><td>overlay install + cleanup</td><td>shell_cmds</td></tr>
<tr><td>usr.bin/finger</td><td><span class="pill pill-warn">REPLACE</span></td><td>user info</td><td>adv_cmds</td></tr>
<tr><td>usr.bin/fstat, fuser, sockstat, procstat</td><td><span class="pill pill-good">KEEP</span></td><td>BSD-specific introspection (Apple has lsof/sample, different shape)</td><td>—</td></tr>
<tr><td>usr.bin/gcore</td><td><span class="pill pill-warn">REPLACE</span></td><td>core dump generator</td><td>system_cmds</td></tr>
<tr><td>usr.bin/gencat</td><td><span class="pill pill-warn">REPLACE</span></td><td>POSIX catopen</td><td>adv_cmds</td></tr>
<tr><td>usr.bin/getconf, getopt, hexdump</td><td><span class="pill pill-warn">REPLACE</span></td><td>shell scripting</td><td>shell_cmds</td></tr>
<tr><td>usr.bin/getent</td><td><span class="pill pill-good">KEEP</span></td><td>BSD-specific NSS query (Apple uses dscacheutil)</td><td>—</td></tr>
<tr><td>usr.bin/gprof</td><td><span class="pill pill-neutral">DEFER</span></td><td>off-target</td><td>—</td></tr>
<tr><td>usr.bin/grep (+egrep/fgrep/rgrep/z* aliases)</td><td><span class="pill pill-warn">REPLACE</span></td><td>universal</td><td>text_cmds</td></tr>
<tr><td>usr.bin/groups, id, whoami</td><td><span class="pill pill-warn">REPLACE</span></td><td>identity</td><td>adv_cmds (groups), shell_cmds (id)</td></tr>
<tr><td>usr.bin/gzip (+gunzip/gzcat/zcat aliases)</td><td><span class="pill pill-warn">REPLACE</span></td><td>compression</td><td>file_cmds</td></tr>
<tr><td>usr.bin/host</td><td><span class="pill pill-neutral">DEFER</span></td><td>DNS lookup; not load-bearing</td><td>—</td></tr>
<tr><td>usr.bin/hostid</td><td><span class="pill pill-good">KEEP</span></td><td>BSD-specific; SMBIOS/syslog use it</td><td>—</td></tr>
<tr><td>usr.bin/iconv</td><td><span class="pill pill-neutral">DEFER</span></td><td>locale conversion</td><td>—</td></tr>
<tr><td>usr.bin/ident</td><td><span class="pill pill-bad">DROP</span></td><td>RCS keyword extractor</td><td>—</td></tr>
<tr><td>usr.bin/info, infocmp, infotocap, makewhatis</td><td><span class="pill pill-neutral">DEFER</span></td><td>precompute on builder</td><td>—</td></tr>
<tr><td>usr.bin/ipcrm, ipcs</td><td><span class="pill pill-neutral">DEFER</span></td><td>SysV IPC; we use Mach</td><td>—</td></tr>
<tr><td>usr.bin/jot, seq</td><td><span class="pill pill-warn">REPLACE</span></td><td>numeric sequences</td><td>shell_cmds (seq); jot drops</td></tr>
<tr><td>usr.bin/kdump, ktrace, ktrdump, truss</td><td><span class="pill pill-good">KEEP</span></td><td>BSD-specific tracing (Apple has dtrace/sample)</td><td>—</td></tr>
<tr><td>usr.bin/killall</td><td><span class="pill pill-warn">REPLACE</span></td><td>full-argv match</td><td>shell_cmds</td></tr>
<tr><td>usr.bin/lastcomm</td><td><span class="pill pill-warn">REPLACE</span></td><td>process accounting</td><td>shell_cmds</td></tr>
<tr><td>usr.bin/ldd</td><td><span class="pill pill-good">KEEP</span></td><td>BSD-specific (Apple uses otool -L); essential debug</td><td>—</td></tr>
<tr><td>usr.bin/less (+lessecho/lesskey/more/lz*/xz*/zstd* family)</td><td><span class="pill pill-warn">REPLACE</span></td><td>pager</td><td>contrib (upstream less vendor)</td></tr>
<tr><td>usr.bin/limits, lockf, lock</td><td><span class="pill pill-neutral">DEFER</span></td><td>launchd handles directly</td><td>—</td></tr>
<tr><td>usr.bin/locale, localedef</td><td><span class="pill pill-warn">REPLACE</span></td><td>locale machinery</td><td>adv_cmds</td></tr>
<tr><td>usr.bin/locate (+helpers)</td><td><span class="pill pill-bad">DROP</span></td><td>locate db; not load-bearing</td><td>—</td></tr>
<tr><td>usr.bin/lockf</td><td><span class="pill pill-neutral">DEFER</span></td><td>shell-level locking</td><td>—</td></tr>
<tr><td>usr.bin/login_cap</td><td><span class="pill pill-good">KEEP</span></td><td>BSD-specific login.conf hooks; PAM expects login_cap.db</td><td>—</td></tr>
<tr><td>usr.bin/logger</td><td><span class="pill pill-warn">REPLACE</span></td><td>syslog/ASL bring-up</td><td>shell_cmds</td></tr>
<tr><td>usr.bin/login</td><td><span class="pill pill-warn">REPLACE</span></td><td>console login</td><td>system_cmds</td></tr>
<tr><td>usr.bin/logins, logname</td><td><span class="pill pill-warn">REPLACE</span></td><td>login info / current name</td><td>shell_cmds (logname); logins DROP</td></tr>
<tr><td>usr.bin/look, lorder</td><td><span class="pill pill-bad">DROP</span></td><td>obscure</td><td>—</td></tr>
<tr><td>usr.bin/lp, lpq, lpr, lprm (printer suite)</td><td><span class="pill pill-bad">DROP</span></td><td>no printer</td><td>—</td></tr>
<tr><td>usr.bin/lsvfs</td><td><span class="pill pill-warn">REPLACE</span></td><td>VFS table</td><td>adv_cmds</td></tr>
<tr><td>usr.bin/m4</td><td><span class="pill pill-neutral">DEFER</span></td><td>sendmail-cf only</td><td>—</td></tr>
<tr><td>usr.bin/man, mandoc, manpath, apropos, whatis</td><td><span class="pill pill-warn">REPLACE</span></td><td>man-page reading</td><td>contrib (upstream mandoc vendor)</td></tr>
<tr><td>usr.bin/mdo</td><td><span class="pill pill-bad">DROP</span></td><td>doas-alike niche</td><td>—</td></tr>
<tr><td>usr.bin/mididump, mixer, sndctl</td><td><span class="pill pill-bad">DROP</span></td><td>audio unused</td><td>—</td></tr>
<tr><td>usr.bin/mkdep, mkfifo, mkimg, mkuzip</td><td><span class="pill pill-warn">REPLACE</span></td><td>mkfifo via file_cmds; rest DEFER/DROP</td><td>file_cmds (mkfifo)</td></tr>
<tr><td>usr.bin/mktemp</td><td><span class="pill pill-warn">REPLACE</span></td><td>overlay scripts</td><td>shell_cmds</td></tr>
<tr><td>usr.bin/mt</td><td><span class="pill pill-bad">DROP</span></td><td>tape</td><td>—</td></tr>
<tr><td>usr.bin/nawk</td><td><span class="pill pill-warn">REPLACE</span></td><td>link to awk</td><td>shell_cmds</td></tr>
<tr><td>usr.bin/nc</td><td><span class="pill pill-warn">REPLACE</span></td><td>netcat (Apple has it via shell_cmds/adv_cmds)</td><td>shell_cmds</td></tr>
<tr><td>usr.bin/netstat</td><td><span class="pill pill-warn">REPLACE</span></td><td>network statistics</td><td>network_cmds</td></tr>
<tr><td>usr.bin/newgrp, nice, nohup, printenv, printf, readlink, renice</td><td><span class="pill pill-warn">REPLACE</span></td><td>shell helpers</td><td>shell_cmds (most) / system_cmds (newgrp)</td></tr>
<tr><td>usr.bin/ntpq</td><td><span class="pill pill-neutral">DEFER</span></td><td>NTP suite</td><td>—</td></tr>
<tr><td>usr.bin/od</td><td><span class="pill pill-warn">REPLACE</span></td><td>octal dump</td><td>text_cmds</td></tr>
<tr><td>usr.bin/pargs, penv, proccontrol, protect, pwdx, rctl</td><td><span class="pill pill-neutral">DEFER</span></td><td>FreeBSD-specific tooling</td><td>—</td></tr>
<tr><td>usr.bin/passwd</td><td><span class="pill pill-warn">REPLACE</span></td><td>user password (works with our PAM)</td><td>system_cmds</td></tr>
<tr><td>usr.bin/patch</td><td><span class="pill pill-neutral">DEFER</span></td><td>source mods on-target</td><td>—</td></tr>
<tr><td>usr.bin/pathchk</td><td><span class="pill pill-warn">REPLACE</span></td><td>POSIX path check</td><td>file_cmds</td></tr>
<tr><td>usr.bin/perror</td><td><span class="pill pill-bad">DROP</span></td><td>obscure</td><td>—</td></tr>
<tr><td>usr.bin/pmcstudy</td><td><span class="pill pill-bad">DROP</span></td><td>hwpmc-specific</td><td>—</td></tr>
<tr><td>usr.bin/posixmqcontrol, posixshmcontrol</td><td><span class="pill pill-bad">DROP</span></td><td>not used</td><td>—</td></tr>
<tr><td>usr.bin/quota</td><td><span class="pill pill-bad">DROP</span></td><td>no quotas</td><td>—</td></tr>
<tr><td>usr.bin/revoke</td><td><span class="pill pill-bad">DROP</span></td><td>obscure tty revoke</td><td>—</td></tr>
<tr><td>usr.bin/rpcgen</td><td><span class="pill pill-bad">DROP</span></td><td>RPC code gen</td><td>—</td></tr>
<tr><td>usr.bin/rpcinfo</td><td><span class="pill pill-neutral">DEFER</span></td><td>NFS-only</td><td>—</td></tr>
<tr><td>usr.bin/rs</td><td><span class="pill pill-bad">DROP</span></td><td>obscure column reshape</td><td>—</td></tr>
<tr><td>usr.bin/script</td><td><span class="pill pill-neutral">DEFER</span></td><td>terminal capture</td><td>—</td></tr>
<tr><td>usr.bin/sed</td><td><span class="pill pill-warn">REPLACE</span></td><td>stream editor</td><td>text_cmds</td></tr>
<tr><td>usr.bin/shar</td><td><span class="pill pill-bad">DROP</span></td><td>obscure shell archive</td><td>—</td></tr>
<tr><td>usr.bin/showmount</td><td><span class="pill pill-neutral">DEFER</span></td><td>NFS-only</td><td>—</td></tr>
<tr><td>usr.bin/sort</td><td><span class="pill pill-warn">REPLACE</span></td><td>Mach-semaphore parallel sort</td><td>text_cmds</td></tr>
<tr><td>usr.bin/spray</td><td><span class="pill pill-bad">DROP</span></td><td>Sun-RPC bw test</td><td>—</td></tr>
<tr><td>usr.bin/stat</td><td><span class="pill pill-warn">REPLACE</span></td><td>file metadata</td><td>file_cmds</td></tr>
<tr><td>usr.bin/stdbuf</td><td><span class="pill pill-bad">DROP</span></td><td>obscure</td><td>—</td></tr>
<tr><td>usr.bin/strings</td><td><span class="pill pill-good">KEEP</span></td><td>binary forensics; no Apple equivalent in v3</td><td>—</td></tr>
<tr><td>usr.bin/su</td><td><span class="pill pill-warn">REPLACE</span></td><td>BSM audit-aware</td><td>shell_cmds</td></tr>
<tr><td>usr.bin/systat, top, vmstat</td><td><span class="pill pill-good">KEEP</span></td><td>BSD-specific top/vmstat format (Apple's are different shape)</td><td>—</td></tr>
<tr><td>usr.bin/tcopy</td><td><span class="pill pill-bad">DROP</span></td><td>tape</td><td>—</td></tr>
<tr><td>usr.bin/tftp</td><td><span class="pill pill-neutral">DEFER</span></td><td>netboot debug</td><td>—</td></tr>
<tr><td>usr.bin/time</td><td><span class="pill pill-warn">REPLACE</span></td><td>command time</td><td>shell_cmds</td></tr>
<tr><td>usr.bin/touch, truncate</td><td><span class="pill pill-warn">REPLACE</span></td><td>file ops</td><td>file_cmds</td></tr>
<tr><td>usr.bin/tty</td><td><span class="pill pill-warn">REPLACE</span></td><td>tty name</td><td>adv_cmds</td></tr>
<tr><td>usr.bin/units</td><td><span class="pill pill-bad">DROP</span></td><td>obscure</td><td>—</td></tr>
<tr><td>usr.bin/unvis, vis</td><td><span class="pill pill-bad">DROP</span></td><td>obscure</td><td>—</td></tr>
<tr><td>usr.bin/unzip</td><td><span class="pill pill-bad">DROP</span></td><td>libarchive front-end variant</td><td>—</td></tr>
<tr><td>usr.bin/uname</td><td><span class="pill pill-warn">REPLACE</span></td><td>system info</td><td>shell_cmds</td></tr>
<tr><td>usr.bin/usbhidaction, usbhidctl</td><td><span class="pill pill-bad">DROP</span></td><td>USB HID</td><td>—</td></tr>
<tr><td>usr.bin/w</td><td><span class="pill pill-warn">REPLACE</span></td><td>who-is-on (uptime alias)</td><td>adv_cmds</td></tr>
<tr><td>usr.bin/wg</td><td><span class="pill pill-bad">DROP</span></td><td>wireguard</td><td>—</td></tr>
<tr><td>usr.bin/what</td><td><span class="pill pill-neutral">DEFER</span></td><td>SCCS-tag inspector</td><td>—</td></tr>
<tr><td>usr.bin/whereis</td><td><span class="pill pill-neutral">DEFER</span></td><td>which covers</td><td>—</td></tr>
<tr><td>usr.bin/which</td><td><span class="pill pill-warn">REPLACE</span></td><td>command location</td><td>shell_cmds</td></tr>
<tr><td>usr.bin/whois</td><td><span class="pill pill-warn">REPLACE</span></td><td>whois client</td><td>adv_cmds</td></tr>
<tr><td>usr.bin/xargs</td><td><span class="pill pill-warn">REPLACE</span></td><td>command chain</td><td>shell_cmds</td></tr>
<tr><td>usr.bin/xinstall</td><td><span class="pill pill-warn">REPLACE</span></td><td>PROGNAME=install</td><td>file_cmds</td></tr>
<tr><td>usr.bin/xo, xstr</td><td><span class="pill pill-neutral">DEFER</span></td><td>libxo CLI / preprocessor obscure</td><td>—</td></tr>
<tr><td>usr.bin/zstd (+zstdcat/zstdmt/zstd* aliases)</td><td><span class="pill pill-warn">REPLACE</span></td><td>compression</td><td>contrib (upstream zstd) or file_cmds</td></tr>
</table>
<h3>9.6.4. <code>usr.sbin/</code></h3>
<table>
<tr><th>/usr/src dir</th><th>Verdict</th><th>Rationale</th><th>Apple repo (if REPLACE)</th></tr>
<tr><td>usr.sbin/adduser, rmuser, edquota, quotaon, quotaoff, repquota, quot</td><td><span class="pill pill-neutral">DEFER</span></td><td>account mgmt + quota niche</td><td>—</td></tr>
<tr><td>usr.sbin/arp, ndp, rtadvd, rtadvctl, rtsold</td><td><span class="pill pill-warn">REPLACE</span></td><td>network admin</td><td>network_cmds</td></tr>
<tr><td>usr.sbin/audit, auditd, auditdistd, auditreduce, praudit</td><td><span class="pill pill-neutral">DEFER</span></td><td>BSM stub; expand later</td><td>—</td></tr>
<tr><td>usr.sbin/authpf, binmiscctl, blacklistd, boot0cfg, btxld, bsdconfig, freebsd-update, etcupdate, mergemaster, sysrc, tzsetup</td><td><span class="pill pill-bad">DROP</span></td><td>install/update/legacy/pf-tied</td><td>—</td></tr>
<tr><td>usr.sbin/bootparamd, dconschat, rarpd, rmt, rrenumd, route6d, rip6query, ipfwpcap, mountd (NFS server)</td><td><span class="pill pill-bad">DROP</span></td><td>netboot / IPv6 RIP / tape / NFS-server / ipfw</td><td>—</td></tr>
<tr><td>usr.sbin/boottrace</td><td><span class="pill pill-neutral">DEFER</span></td><td>measure launchd startup later</td><td>—</td></tr>
<tr><td>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</td><td><span class="pill pill-bad">DROP</span></td><td>HyperV-host / hw RAID / firewire / wifi-fw / 3G modem / quotas / MAC / IPsec / printer / floppy / embedded HW / etc.</td><td>—</td></tr>
<tr><td>usr.sbin/cpucontrol, ngctl, nghook, pmc, pmcannotate, pmccontrol, pmcstat, rtprio, trim, vigr, vipw, watch, watchdog, watchdogd, zdump, zic</td><td><span class="pill pill-neutral">DEFER</span></td><td>perf / tz / watchdog / netgraph niche</td><td>vipw → system_cmds</td></tr>
<tr><td>usr.sbin/chown</td><td><span class="pill pill-warn">REPLACE</span></td><td>chown is in file_cmds via chmod_chown.c</td><td>file_cmds</td></tr>
<tr><td>usr.sbin/chroot</td><td><span class="pill pill-warn">REPLACE</span></td><td>shell helper</td><td>shell_cmds</td></tr>
<tr><td>usr.sbin/crashinfo</td><td><span class="pill pill-good">KEEP</span></td><td>FreeBSD-specific post-panic forensics</td><td>—</td></tr>
<tr><td>usr.sbin/cron, daemon</td><td><span class="pill pill-bad">DROP</span></td><td>launchd replaces (StartCalendarInterval + KeepAlive)</td><td>—</td></tr>
<tr><td>usr.sbin/devctl, diskinfo, fstyp, gstat, pciconf</td><td><span class="pill pill-good">KEEP</span></td><td>FreeBSD-specific HW/FS introspection</td><td>—</td></tr>
<tr><td>usr.sbin/iostat</td><td><span class="pill pill-warn">REPLACE</span></td><td>I/O stats</td><td>system_cmds</td></tr>
<tr><td>usr.sbin/kldxref</td><td><span class="pill pill-good">KEEP</span></td><td>FreeBSD kld(4) cache</td><td>—</td></tr>
<tr><td>usr.sbin/lpc, lpd, lpr (suite), pac, chkprintcap</td><td><span class="pill pill-bad">DROP</span></td><td>printer</td><td>—</td></tr>
<tr><td>usr.sbin/nologin</td><td><span class="pill pill-good">KEEP</span></td><td>login shell-of-last-resort</td><td>—</td></tr>
<tr><td>usr.sbin/ntp-keygen, ntpd, ntpdate, ntpdc, ntptime, sntp</td><td><span class="pill pill-neutral">DEFER</span></td><td>NTP suite; launchd-managed approach later</td><td>—</td></tr>
<tr><td>usr.sbin/pac (printer accounting)</td><td><span class="pill pill-bad">DROP</span></td><td>printer</td><td>—</td></tr>
<tr><td>usr.sbin/powerd</td><td><span class="pill pill-warn">REPLACE</span></td><td>power mgmt daemon</td><td>PowerManagement</td></tr>
<tr><td>usr.sbin/pw</td><td><span class="pill pill-good">KEEP</span></td><td>FreeBSD user/group mgmt (no Apple equivalent — Apple uses dscl)</td><td>—</td></tr>
<tr><td>usr.sbin/pwd_mkdb</td><td><span class="pill pill-warn">REPLACE</span></td><td>passwd db builder</td><td>system_cmds</td></tr>
<tr><td>usr.sbin/rpcbind, rpc.statd, rpc.tlsclntd, rpc.tlsservd</td><td><span class="pill pill-neutral">DEFER</span></td><td>NFS bits</td><td>—</td></tr>
<tr><td>usr.sbin/sendmail (suite: editmap, makemap, praliases, mailstats, hoststat, purgestat, mailwrapper)</td><td><span class="pill pill-bad">DROP</span></td><td>no MTA</td><td>—</td></tr>
<tr><td>usr.sbin/service</td><td><span class="pill pill-bad">DROP</span></td><td>launchctl owns service lifecycle</td><td>—</td></tr>
<tr><td>usr.sbin/services_mkdb</td><td><span class="pill pill-bad">DROP</span></td><td>rc.d-only; getservbyname flat-file fallback works; no Apple equivalent</td><td>—</td></tr>
<tr><td>usr.sbin/tcpdump</td><td><span class="pill pill-warn">REPLACE</span></td><td>kernel-vs-userland oracle</td><td>contrib (upstream tcpdump vendor)</td></tr>
<tr><td>usr.sbin/traceroute, traceroute6</td><td><span class="pill pill-warn">REPLACE</span></td><td>network debug</td><td>network_cmds</td></tr>
<tr><td>usr.sbin/zonectl, zzz, wake</td><td><span class="pill pill-bad">DROP</span></td><td>ZFS zones / suspend / WoL unused</td><td>—</td></tr>
</table>
<h3>9.6.5. <code>libexec/</code></h3>
<table>
<tr><th>/usr/src dir</th><th>Verdict</th><th>Rationale</th><th>Apple repo (if REPLACE)</th></tr>
<tr><td>libexec/getty</td><td><span class="pill pill-warn">REPLACE</span></td><td>console login spawn</td><td>system_cmds (#105e; subsumes #106)</td></tr>
<tr><td>libexec/save-entropy</td><td><span class="pill pill-good">KEEP</span></td><td>FreeBSD entropy daemon; launchd RandomSeed plist execs it</td><td>—</td></tr>
<tr><td>libexec/bootpd, rbootd, tftp-proxy, tftpd, comsat, fingerd, ntalkd, phttpget, pppoed, locate.* helpers, ulog-helper, rpc.* helpers</td><td><span class="pill pill-bad">DROP</span></td><td>netboot / mail / talk / NIS / dialup / locate-db unused</td><td>—</td></tr>
<tr><td>libexec/flua</td><td><span class="pill pill-neutral">DEFER</span></td><td>freebsd-lua; some tools may embed</td><td>—</td></tr>
</table>
<h3>9.6.6. Ready-to-paste <code>srclist-fbsdglue.txt</code></h3>
<p>The full irreducibly-FreeBSD-only set, formatted for direct paste into the manifest file at the repo root. Used by <code>build.sh</code> at the final PR (#105g/#105h) once all Apple-repo ports have landed and FreeBSD-runtime + FreeBSD-utilities pkgs drop from <code>pkglist-base.txt</code>. <strong>Live current state as of 2026-05-26 evening</strong> after iter 2 (PR #119) CI iteration:</p>
<pre><code># 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
</code></pre>
<p><strong>25 entries total</strong> (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.</p>
<p><strong>Iteration log of changes from initial 44 estimate:</strong></p>
<ul>
<li><code>sbin/camcontrol</code> → DEFER (iter 2 CI run 26459081598 surfaced <code>lib/libnvmf</code> privatelib prereq; not load-bearing for CI virtio or daily dev)</li>
<li><code>lib/libnvmf</code> → DROP (was iter-2 prereq for camcontrol; both removed together)</li>
<li><code>usr.bin/login_cap</code> → not a /usr/src dir (login_cap is a libutil function, not a binary); removed from estimate</li>
<li><code>sbin/nologin</code> → <code>usr.sbin/nologin</code> (the SOURCE dir is at usr.sbin/; Makefile LINKs to /sbin/nologin at install time)</li>
<li><code>usr.bin/fuser</code> → DROP from manifest (LINK from <code>usr.bin/fstat</code>; binary still appears at /usr/bin/fuser via fstat's Makefile LINKS=). CI iter 2 run 26459388127 surfaced.</li>
<li><code>usr.bin/hostid</code> → DROP (not a FreeBSD binary; <code>/etc/rc.d/hostid</code> is a shell script that reads <code>/etc/hostid</code> UUID into <code>kern.hostuuid</code> sysctl). We don't run <code>/etc/rc</code> (launchd PID 1) and none of our daemons use <code>gethostid()</code>, so functional impact is zero. CI iter 2 run 26459641829 surfaced.</li>
<li><strong>BSD-debug toolkit → DEFER (<a href="https://github.com/pkgdemon/freebsd-launchd-mach/issues/120">#120</a>)</strong>: <code>usr.bin/fetch</code>, <code>file</code>, <code>fstat</code>, <code>getent</code>, <code>kdump</code>, <code>ktrace</code>, <code>ktrdump</code>, <code>procstat</code>, <code>sockstat</code>, <code>strings</code>, <code>systat</code>, <code>top</code>, <code>truss</code>, <code>vmstat</code> (14 tools). Plus the lib prereqs they triggered: <code>lib/libsysdecode</code> (codegen tables.h for kdump/truss), <code>lib/libelftc</code> (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. <strong>#120</strong> 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 <code>ldd</code> alone doesn't answer).</li>
</ul>
<p><strong>For the Linux port (future):</strong> this 44-entry file gets renamed to <code>srclist-linuxglue.txt</code> (or similar) and its content swapped 1:1 for Linux equivalents:</p>
<ul>
<li><code>bin/freebsd-version</code> → <code>/etc/os-release</code> (no binary)</li>
<li><code>bin/kenv</code> → <code>/proc/cmdline</code> reader</li>
<li><code>sbin/camcontrol</code> → <code>lsblk</code> + <code>smartctl</code></li>
<li><code>sbin/devfs</code> → <code>udev</code> rules tool</li>
<li><code>sbin/fsck</code>, <code>fsck_ffs</code>, <code>tunefs</code>, <code>newfs</code> → <code>e2fsck</code>/<code>tune2fs</code>/<code>mke2fs</code></li>
<li><code>sbin/kld*</code> + <code>kldxref</code> → <code>modprobe</code>/<code>lsmod</code>/<code>rmmod</code>/<code>depmod</code></li>
<li><code>sbin/ldconfig</code> → glibc <code>ldconfig</code></li>
<li><code>sbin/mount</code>, <code>umount</code> → util-linux <code>mount</code>/<code>umount</code></li>
<li><code>usr.bin/fstat</code>, <code>sockstat</code>, <code>fuser</code> → <code>lsof</code>, <code>ss</code>, <code>fuser</code> (procps)</li>
<li><code>usr.bin/ktrace</code>/<code>kdump</code>/<code>truss</code> → <code>strace</code></li>
<li><code>usr.bin/ldd</code> → glibc <code>ldd</code></li>
<li><code>usr.bin/top</code>/<code>w</code>/<code>vmstat</code> → procps <code>top</code>/<code>w</code>/<code>vmstat</code></li>
<li><code>usr.bin/file</code>, <code>strings</code> → <code>file</code> + binutils <code>strings</code></li>
<li><code>usr.sbin/devctl</code>, <code>diskinfo</code>, <code>gstat</code>, <code>pciconf</code>, <code>fstyp</code> → <code>udevadm</code>, <code>lspci</code>, <code>iostat</code>, <code>blkid</code></li>
<li><code>usr.sbin/pw</code> → <code>useradd</code>/<code>usermod</code>/<code>groupadd</code></li>
</ul>
<h3>9.6.7. Final tallies under strict rule</h3>
<table>
<tr><th>Verdict</th><th>Count (approx)</th><th>What it means for the ISO</th></tr>
<tr><td><span class="pill pill-good">KEEP</span></td><td>~25–30</td><td>Built from <code>/usr/src</code> via <code>srclist-fbsdglue.txt</code> at #105g. Future Linux equivalent table in §9.5.1.</td></tr>
<tr><td><span class="pill pill-warn">REPLACE</span></td><td>~175–200</td><td>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).</td></tr>
<tr><td><span class="pill pill-neutral">DEFER</span></td><td>~80–100</td><td>Not in srclist; not shipped. Re-evaluate per-iter when a real consumer surfaces.</td></tr>
<tr><td><span class="pill pill-bad">DROP</span></td><td>~190–220</td><td>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.).</td></tr>
<tr><td><strong>Total inventoried</strong></td><td><strong>~425 dirs</strong></td><td>Combined FreeBSD-runtime + FreeBSD-utilities original inventory</td></tr>
</table>
<h2 id="followup-landmines">11. Follow-up landmines</h2>
<p>If we expand the manifest to cover more tools in future tickets, watch for:</p>
<ul>
<li><strong>libncurses chain.</strong> Six generated headers across <code>lib/ncurses/{tinfo,ncurses}/Makefile</code> via MK* shell scripts + awk + make_keys helper. If <code>/bin/ls</code> or <code>/usr/bin/less</code> stop linking against the pkgbase-installed <code>libtermcapw.a</code> and need a from-source rebuild, this becomes the next prereq pain.</li>
<li><strong>libsysdecode</strong> (kdump, truss) — if these are wanted, plan to also build <code>lib/libsysdecode</code> first.</li>
<li><strong>libpcap</strong> (tcpdump, ipfw, dhclient sometimes) — same pattern. Tcpdump is in FreeBSD-utilities; dhclient is in FreeBSD-rescue's crunchgen but doesn't actually link libpcap directly (only ipf does via the BPF filter compiler).</li>
<li><strong>libypclnt</strong> — NIS client codegen; irrelevant unless we start needing NIS interop.</li>
<li><strong>contrib/ vendored sources.</strong> Many usr.bin entries pull from <code>contrib/</code>: 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 <code>usr.bin/<name></code>; just be aware that the actual source lives in <code>contrib/</code> not the wrapper dir.</li>
</ul>
<p class="footnote">Drafted 2026-05-26 from four parallel research-agent passes across <code>apple-oss-distributions</code>, <code>freebsd/freebsd-src</code> on GitHub, and live pkgbase manifests at <code>pkg.freebsd.org/FreeBSD:14:amd64/base_latest/</code>. Scopes <a href="https://github.com/pkgdemon/freebsd-launchd-mach/issues/104">issue #104</a> + <a href="https://github.com/pkgdemon/freebsd-launchd-mach/issues/105">#105</a>. Source data files (pkg manifests, build.sh inspection, Makefile.inc1 phase list) retained in the agent transcripts.</p>
</div>
</body>
</html>