SchOS/docs/licensing.md
Nexoniarz 57aff40228 docs: four directories, and a rule for when a thing leaves the roadmap
docs/ was ten files where a plan, a description, a guide and a bug report all
sat next to each other. It is now architecture/ (what SchOS is), plan/ (what it
will be), guides/ (how to work on it) and history/ (why it is like this), with
an index that states the one rule holding it together: when something is
finished it moves from plan/ to architecture/ and is rewritten as a description
of the thing rather than a record of building it.

A ticked checkbox says the work happened. It does not say what the work
*produced*, and six months later the checkbox is all that is left. The network
stack proved the point: finished, verified end to end, and for a month the only
description of it anywhere was a checkbox four levels of indentation deep.

So roadmap.md went from 534 lines to 181 -- nothing deleted, the done work
graduated. Seven subsystems that were finished and undescribed now have
descriptions: boot, kernel, syscalls, filesystem, networking, graphics, usb,
init. Every one ends with "What it does not do", which is the section that pays;
a document listing only strengths is marketing, and the reader who needs it most
is the one about to trip over a limitation nobody wrote down.

schfs.md still opened with "phases 1 through 3 1/2 are done, phase 4 is next"
long after all five had landed. It is a description now, with the phase record
and the hard-won bugs moved to history/.

Three corrections found on the way, all load-bearing:

  * projects/schcom/README.md claimed SCM_RIGHTS was done. There is no
    sendmsg/recvmsg in the kernel at all, and an entire GUI plan rested on it.
  * The root README said "No TCP/IP" months after the stack landed.
  * history/kernel.md sec.7 was marked "in progress" on a problem that process
    groups solved.

Also adds plan/1.0.md, which draws a finish line so the open list stops being
infinite, and marks schwm/ and schde/ superseded: in Wayland the compositor is
the window manager, so that split dissolves rather than being abandoned.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ7Qx8E1q1M1bbCq8QLHS2
2026-09-12 17:13:35 +02:00

10 KiB

Licensing

The one page to check before copying anyone else's code into SchOS.

Referenced from LICENSE, LICENSE.MIT and NOTICE, all three of which pointed here long before this file existed.


1. SchOS is Apache-2.0

Copyright Nexoniarz. See LICENSE.

Apache-2.0 was chosen over MIT/BSD for one reason that actually matters at OS scale: it contains an express patent grant and a patent-retaliation clause. MIT and BSD are silent on patents, which means a contributor can hand you code and later assert a patent over it. For a kernel that is intended to accept outside contributions, that silence is the expensive kind.

What that grant means in practice: Apache-2.0 §2 gives everyone a perpetual, worldwide, irrevocable licence to reproduce, modify, sublicense and distribute SchOS. Any additional restriction stated elsewhere — in a README, a website, or a policy — does not narrow it. The licence text is what holds up.

If restricted distribution is ever genuinely wanted, that is a licence change (a bespoke proprietary licence, or something like BUSL-1.1 with a conversion date), not a wording change, and it means giving up the Apache grant.


2. What can be copied in

Licence Verdict Obligation
Public domain, 0BSD, CC0 Yes None
MIT, ISC Yes Keep the notice
BSD 2-clause Yes Keep the notice
BSD 3-clause Yes Keep the notice; no endorsement claims
BSD 4-clause (advertising) Avoid — see §3 Notice and an acknowledgement in advertising materials
Apache-2.0 Yes Keep NOTICE contents
MPL-2.0 Case by case File-level copyleft; keep those files separate
GPL-2.0-only No —
GPL-3.0 / LGPL-3.0 No for linked code —

Every "yes" above requires an entry in NOTICE. That file is the project's attribution record and the thing that makes the permissive licences actually satisfied rather than merely tolerated.

Why GPL-2.0-only is a hard no

Apache-2.0 imposes conditions GPLv2 treats as "further restrictions" under its §6 — principally the patent-retaliation term. The FSF and the ASF agree on this: Apache-2.0 code and GPL-2.0-only code cannot be combined into one distributable work. It is not a matter of taste or of how carefully the files are kept apart in the tree; it is that the combined binary cannot satisfy both licences at once.

GPL-3.0 fixed this in the other direction (Apache-2.0 is compatible into GPLv3), but that does not help: the result would have to ship under GPLv3, and SchOS does not.

Practical consequence: BSD drivers can be adopted. Linux drivers cannot, ever, no matter how convenient. This is why the USB stack was written from the specification rather than ported.


3. NetBSD in particular

src-trunk/ is a NetBSD checkout kept as reference material and a parts bin (see plan/schapi.md §5). NetBSD is not uniformly licensed, and the difference matters per file:

Template Status
2-clause BSD — modern NetBSD Foundation files Fine
3-clause, "Regents of the University of California" Fine. Berkeley formally rescinded the advertising clause in 1999
4-clause with the advertising clause, non-UC copyright holder Avoid. Berkeley's rescission covers Berkeley's copyright, not other people's

The last row is real, not hypothetical. Measured on this checkout:

sys/kern      26 of  220 files carry the advertising clause
sys/dev      500 of 3565
lib/libc     101 of 1575
sys/net        5 of  180      ← the TCP/IP stack is nearly clean

4-clause is still permissive and still redistributable; the burden is an advertising obligation that accumulates quietly and is tedious to honour properly. Prefer a 2-clause or UC-Regents file. If a 4-clause file is genuinely the right answer, it goes into NOTICE with the full clause quoted.

Check before copying, not after:

grep -l "All advertising materials" <file>

And check whose clause it is

A file can carry several licence blocks from several copyright holders. Finding the advertising clause is only half the check — Berkeley's rescission covers Berkeley's copyright and nobody else's, so the question is always whose clause you found.

Measured on src-trunk, the networking tree:

sys/net        106 files,  5 with the advertising clause
sys/netinet    121 files, 25   "        "         "
sys/netinet6    51 files,  5   "        "         "

Encouraging at first glance — the 25 in sys/netinet are almost all SCTP, DCCP and multicast routing, none of which SchOS needs. ip_input.c, ip_output.c, udp_usrreq.c, if_arp.c, ip_icmp.c, if.c and route.c are all UC 3-clause, i.e. fine.

But tcp_input.c and tcp_output.c are not. Their advertising clause belongs to the WIDE Project (the KAME IPv6 people), whose copyright sits at the top of the file; the UC block is a separate licence further down. Berkeley never spoke for WIDE, so the rescission does not reach it. The two most valuable files in the stack are the two encumbered ones.

That is not fatal — 4-clause is still permissive — but it is exactly the case where a second BSD tree earns its disk space: FreeBSD's TCP has been through a relicensing effort NetBSD's has not, so the same file there may well be 2-clause. Check it the same way before assuming either:

grep -n "Copyright" <file> | head        # who claims it
grep -n -B6 "All advertising" <file>     # whose clause is it

FreeBSD's TCP is clean where NetBSD's is not

Checked, 2026-08-08, exactly that way. Against FreeBSD main: sys/netinet/tcp_input.c contains no advertising clause at all. Its copyright holders are the UC Regents, Swinburne University, Lawrence Stewart, the FreeBSD Foundation and Juniper Networks -- all BSD-2 or BSD-3.

So if BSD networking code is taken, it must come from FreeBSD, not NetBSD, and the specific reason is TCP. This reverses the earlier assumption in docs/plan/roadmap.md that NetBSD was the intended starting point; NetBSD remains the better-written reference to read, but FreeBSD is the one that can be copied from.

The third option: lwIP

Before porting either BSD stack, weigh lwIP against both. Verified 2026-08-08 from its COPYING: 3-clause BSD, Swedish Institute of Computer Science, no advertising clause anywhere in the file. Compatible, one NOTICE entry, done.

The licence is the smaller half of the argument. The larger half is that FreeBSD's sys/netinet is not a library -- tcp_input.c alone is 122 KB and reaches into mbufs, epoch(9), netisr, VNET, uma(9), sockbufs, inpcb hash tables and FreeBSD's locking. Taking it means porting FreeBSD's kernel infrastructure first and finding the TCP somewhere underneath, which is the same conclusion docs/guides/adding-a-driver.md already reached about sys/dev/usb.

lwIP was written for the case SchOS is in: a small operating system with a raw Ethernet driver and no infrastructure to speak of. Its port layer is a handful of files, it has no dependency on the host kernel's allocator or locking, and it brings ARP, IPv4, ICMP, UDP, TCP, DHCP and DNS.

Fonts

Chosen 2026-08-09, both licences checked at source rather than assumed:

Font Where Licence
Roboto desktop, window manager, compositor Apache-2.0
JetBrains Mono terminal, TTY SIL OFL 1.1

Roboto is the same licence as SchOS, so it is the easy case: a NOTICE entry and nothing else.

OFL is permissive and bundling is precisely what it is for, with two conditions worth knowing before anyone subsets or converts a font:

  • The font stays under OFL even inside an Apache-2.0 system. It does not infect anything else; it just cannot be relicensed.
  • It may not be sold on its own. Shipping it as part of an OS is fine.
  • Reserved Font Names. JetBrains Mono declares none -- its copyright line names no reserved name -- so a modified version may keep the name. Most OFL fonts do reserve theirs, and then a derivative must be renamed. Pre-rasterising a font into bitmaps at build time is a modification, so this is not a theoretical point for this project.

4. Things that are deliberately not shipped

Some code is fine to build and run locally and impossible to distribute with SchOS. Keeping the distinction sharp is what stops it eroding:

  • Refrence/ — a FreeBSD checkout (Refrence/freebsd-src), kept as reference material and a parts bin. Never built, never in an image. The directory name is spelled as it is on disk; renaming it is a one-line change if it ever grates.
  • src-trunk/ — a NetBSD checkout, same rules. Currently absent; it was deleted for disk space and can be re-fetched sparsely if needed.
  • dist/ — upstream tarballs and other downloaded blobs. Cached so a rebuild never needs the network; not part of any image, and not all of it is redistributable.

The mechanisms that keep this from eroding, since good intentions have already failed once here:

  • NOTPORTS in ports/Makefile — a port that lives in the tree but is never built by make.
  • RAMDISK_EXCLUDE in the root Makefile — paths kept out of the ramdisk root. This one matters more than it looks: the ramdisk image is linked into the kernel binary, so anything sitting in sysroot/ when that image is built becomes part of a distributable artifact. A GPL-2.0 or non-redistributable file staged there does not merely ride along, it makes the kernel itself undistributable.

A previous acceptance test — a ported 1993 shooter, GPL-2.0 engine on non-redistributable shareware data — was carried under exactly these rules and has since been removed. It is worth recording why it was safe: it was never in PORTS, and its 33 MB of data was excluded from the ramdisk. It is equally worth recording that the safety depended on two separate opt-outs staying correct, which is a lot of standing risk for a test that had stopped finding bugs. See docs/guides/testing.md.


5. Specifications are not code

A published specification carries no copyright over an independent implementation of it. The xHCI, USB, PCI, fbdev and ELF specifications were all read and implemented directly, which is why those drivers have no licence entanglement at all despite equivalents existing in both Linux and BSD.

When a subsystem is small enough to write from the spec, that is usually the cheapest option in the long run — not because copying is hard, but because a copied file is a file to be understood, attributed and maintained forever.