Skip to content

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 novac is allowed in principle. But docs/plan.md:767 says "introduce another language only for a concrete benefit", and AGENTS.md:14-22 restricts 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 ​

text
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 ​

StageWhereHow generated C reaches CosmoOS.NET in CosmoOS CI?Needs owner unit?
S0 (C1)Nova repo onlyintegrations/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 imagenono (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.pynoyes
S2 (C3+)CosmoOS nova/nova.mk$(OUT)/nova/%.c generated by $(NOVAC) at build time; a pattern rule as in pkg.mk:18-21yes (Dockerfile change) or a pinned NativeAOT novac binary fetched by checksumyes
S3 (C4–C8)CosmoOS kernel/modulesas S2, plus kernel flags, ANALYSIS_REPORTS gate, module signingyesyes, 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.nova sits beside the NAME.c it 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's scripts/nova-gen.py) regenerates it with a pinned novac (NOVAC_VERSION), refusing any other version; make nova-check compares. A new port is one line in the script's PORTS.
  • 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 its AGENTS.md): setup, the workflow, the two header models (a hand-written C header that Nova imports, or novac's nova_exports.h written 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) ​

text
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 ...                                      # M5

Possible future CosmoOS Make targets (S2, only if approved): nova, nova-test, nova-check.

6. Reproducibility ​

  • novac output is a pure function of (sources, compiler version, profile, target, flags). There are no timestamps or absolute paths in the output; #line uses package-relative paths.
  • A C1 acceptance item: two consecutive builds produce byte-identical .c and .elf files (sha256sum).

Pre-1.0: the language and its tools are still changing.