Compiler / Backend Integration with the CosmoOS Build
Status: C0 (deliverable 8). Policy facts come from [PA §1, §3, §6, impl 8] in research/cosmoos-platform-audit.md.
1. Constraints from the CosmoOS repository
- The CosmoOS constitution permits C#/.NET for host development tools (MASTER prompt §50), so a .NET-hosted
novacis allowed in principle. Butdocs/plan.md:767says "introduce another language only for a concrete benefit", andAGENTS.md:14-22restricts work to the owner-chosen 1.2 unit (storage depth). Any Nova change inside the CosmoOS tree requires the owner to choose it as a unit. Until then everything lives in the Nova repository (integrations/cosmoos/). - CI: clang 19.1.7 Debian image, no .NET. The AArch64 job already runs ~51.7 min (median) against a 70 min cap, so any added boot test costs scarce minutes.
- Build invariants B5/B6: generated output lives under
$(OUT), and builds are byte-reproducible.
2. Separation of artefacts
host (.NET) novac ───────────────► generated C (+ nova/rt*.h, runtime .c)
CosmoOS toolchain clang (CosmoOS flags) ─► .o
CosmoOS link ld.lld (user.ld | -r) ─► ELF executable | module .ko (signed)
CosmoOS image mkbootarchive / pkgbuild / mkimage ─► cosmoos.img
CosmoOS tests run_boot_test.py under QEMU (x86-64, AArch64)novac never invokes CosmoOS internals except to query flags. CosmoOS never invokes .NET unless and until the owner approves a build-time generation step.
3. Staged integration plan
| Stage | Where | How generated C reaches CosmoOS | .NET in CosmoOS CI? | Needs owner unit? |
|---|---|---|---|---|
| S0 (C1) | Nova repo only | integrations/cosmoos/c1.sh builds against a local, unmodified CosmoOS checkout: gmake ARCH=<a> libc, then compiles and links Nova output with CosmoOS flags and runs it in QEMU with a separate scratch disk (QEMU_EXTRA) or a release image | no | no (no CosmoOS source change, and nothing committed there) |
| S1 (C1→C3) | CosmoOS ports/nova-<name>/ | checked-in generated C + port file; picked up by the PORT_DIRS wildcard, no Makefile edit; a boot marker NOVATEST: PASS in rc.test + run_boot_test.py | no | yes |
| S2 (C3+) | CosmoOS nova/nova.mk | $(OUT)/nova/%.c generated by $(NOVAC) at build time; a pattern rule as in pkg.mk:18-21 | yes (Dockerfile change) or a pinned NativeAOT novac binary fetched by checksum | yes |
| S3 (C4–C8) | CosmoOS kernel/modules | as S2, plus kernel flags, ANALYSIS_REPORTS gate, module signing | yes | yes, one per component |
Recommendation: S0 for C1, then propose S1 to the owner with the C1 evidence. S1 keeps .NET out of CosmoOS entirely, at the cost of generated C in the tree. To keep that reviewable, the generated C is deterministic, formatted and carries a header: // Generated by novac <version> from <file>.nova (sha256 …). Do not edit.
3.1 What was built: S1 with the sources in tree (2026-10-27)
C9b (#459) put the GPT port's generated C into CosmoOS as S1, with the Nova source still in Nova's repository and integrations/cosmoos/vendor.py writing the C. On 2026-10-27 the owner chose to move the sources into CosmoOS (roadmap 1.2 A5's first PR, CosmoOS #461), between S1 and S2:
- Each
NAME.novasits beside theNAME.cit generates (kernel/block/gpt.nova,kernel/process/cputime.nova). The generated C stays checked in with a banner naming its source, so building CosmoOS still needs no Nova compiler and no .NET. Nova's runtime (kernel/include/nova/rt.h,kernel/nova/nova_rt_core.c) is generated the same way. make nova(CosmoOS'sscripts/nova-gen.py) regenerates it with a pinned novac (NOVAC_VERSION), refusing any other version;make nova-checkcompares. A new port is one line in the script'sPORTS.- CosmoOS's CI job "Nova sources" fetches the pinned release's NativeAOT binary, checked against its SHA-256 (S2's "pinned binary fetched by checksum"), and fails if the checked-in C differs from what its source generates.
- A novac upgrade is a CosmoOS change of its own: bump the pin and the job's hash,
make nova, review, run the matrix. - How to write a port there, for people and AI agents, is CosmoOS's
docs/build/nova.md(linked from itsAGENTS.md): setup, the workflow, the two header models (a hand-written C header that Nova imports, or novac'snova_exports.hwritten under the port's name with its own guard), and the kernel's rules for Nova code.
Nova's repository keeps what tests the compiler against that code: c9.py (the differential test against the C original) and benchmarks/gpt read the sources from a CosmoOS checkout (--cosmoos). The reasons for in tree over Nova's repository or a third repository: one PR per feature, reviewed where it lands; drift caught by CosmoOS's own CI; and the source, the preferred form for modification under the GPL, shipped with the C.
4. Flag source of truth
novac must not copy CosmoOS flags into its own code. Planned mechanism: integrations/cosmoos/flags.sh <arch> <user|kernel|module> extracts the flags for a representative source file from CosmoOS's compile_commands.json (already present in the tree), or from a trivial print-% Make query if the owner adds one. C1 records the exact flags used in its report.
5. Proposed commands (Nova side; none added to CosmoOS yet)
novac build --profile cosmoos-user --target aarch64-cosmoos --emit c -o out/nova/hello hello.nova
integrations/cosmoos/c1.sh --cosmoos ~/dev/CosmoOS --arch x86_64|aarch64 # build+link+QEMU
novac check --profile cosmoos-kernel ... # ownership diagnostics
novac build --explain-allocations ... # M5Possible future CosmoOS Make targets (S2, only if approved): nova, nova-test, nova-check.
6. Reproducibility
novacoutput is a pure function of (sources, compiler version, profile, target, flags). There are no timestamps or absolute paths in the output;#lineuses package-relative paths.- A C1 acceptance item: two consecutive builds produce byte-identical
.cand.elffiles (sha256sum).