Files
SUB-OS/docs/CONTRIBUTING.md
T
subhobhai943andClaude Opus 4.8 a0cd95cdc9 docs: add Contributing, Security, and Roadmap docs; link them from the README
Create docs/CONTRIBUTING.md (build/verify workflow, coding style, kernel
gotchas, commit & PR conventions), docs/SECURITY.md (supported versions,
private vulnerability reporting, documented caveats), and docs/ROADMAP.md
(shipped in v1.0.0 plus near/mid/long-term plans). Add a Documentation and
Contributing section to the README pointing at all four docs.

Note: used the conventional CONTRIBUTING.md / SECURITY.md filenames (in
docs/) so GitHub auto-detects them as community-health files.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
2026-08-30 22:10:28 +05:30

6.8 KiB

SUB-OS logo

Contributing to SUB-OS

Thanks for your interest in SUB-OS — a multi-architecture, modular monolithic, Linux-compatible operating system written from scratch in C, C++17, Assembly, freestanding Rust (no_std), and the native SUB Language. This guide covers how to build, the conventions we follow, and how to get a change merged.


Table of Contents


Ground rules

  • Verify before you claim. Nothing is "done" until it builds and boots. Every crypto primitive and codec is tested against a reference vector (RFC or a PIL-generated fixture) before it enters the kernel. Hold new code to the same bar.
  • No libc, no POSIX host. The kernel is freestanding. No floating point in kernel space (-mno-sse); all math is integer.
  • Small, reviewable changes. One feature or fix per pull request, with a clear description of what you verified and how.
  • Be kind. Assume good faith, keep discussion technical, and respect reviewers' time.

Development environment

The project targets x86_64, aarch64, and armv8i (AArch32). On a Debian/ Ubuntu host, install the toolchains and emulators:

sudo apt update
sudo apt install build-essential g++ nasm qemu-system-x86 qemu-system-arm \
                 gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu \
                 gcc-arm-linux-gnueabihf binutils-arm-linux-gnueabihf \
                 rustc cargo dialog python3

For the freestanding Rust layer:

rustup target add x86_64-unknown-none

The x86_64 kernel is normally built with an x86_64-elf- cross toolchain. A stock x86_64-linux-gnu- GCC also works — pass it via CROSS_COMPILE=.


Building

SUB-OS uses a Linux-style Kconfig + Kbuild flow. The version/codename lives at the top of the Makefile (VERSION/PATCHLEVEL/SUBLEVEL/EXTRAVERSION/ NAME) and in include/init/version.h — keep the two in sync when you bump a release.

# Configure (interactive) or pick an architecture preset:
make configure                       # or: make menuconfig
make x86_64_defconfig                # x86_64 (Intel / AMD)
make aarch64_defconfig               # 64-bit ARM (Cortex-A57)
make armv8i_defconfig                # 32-bit ARM (Cortex-A15)

# Build:
make                                 # builds the configured/default ARCH
make ARCH=aarch64                    # or target one explicitly

Always make clean when switching ARCH. Object files from another architecture link into a "file in wrong format" error otherwise.


Running & verifying

make run                 # x86_64 disk image in QEMU
make run-gui             # windowed graphical desktop
make run-fullscreen      # fullscreen desktop
make run-vnc             # headless: VNC on localhost:5900
make ARCH=aarch64 run    # ARM targets

Default login is SUB / SUB. Pass nogui, text, emergency, or single on the kernel command line to boot to the TTY instead of the desktop.

Headless verification (what CI and reviewers use): boot with -serial file:serial.log -monitor unix:mon.sock,server,nowait -display none, drive the login over the monitor sendkey interface, and capture the screen with screendump. For a code path with no UI, add a temporary CLI applet under userland/lazybox/ that exercises it over serial, verify, then revert the temporary hook.

When you submit a change, state plainly what you ran and what you saw — build output, boot log excerpt, screenshot, or reference-vector comparison.


Coding style

  • C: freestanding C11. Match the surrounding file — 4-space indent, K&R braces, snake_case for functions and variables, SCREAMING_SNAKE for macros/constants. Keep comment density and idiom consistent with the module you're editing.
  • Assembly: per-arch under arch/<arch>/. .S files run through cpp, so no nested /* ... */ comments.
  • Rust: no_std, no allocator assumptions beyond what the kernel provides.
  • C++: freestanding C++17, no exceptions/RTTI, no host STL.
  • Headers: public interfaces in include/, with an include guard.
  • No new external dependencies in kernel space.

Kernel gotchas

These bite newcomers — internalize them before touching the relevant subsystem:

  • printk/vsprintf are minimal. Supported conversions are c s d i u o x X p % only — no length modifiers (l, ll) and no field width. Cast to int / unsigned / void* at the call site.
  • list_del() NULLs both links, so list_empty() is not a reliable "is this node still queued?" test after a delete — inspect the links directly.
  • Preemption is armed after boot. A context switch must never run while a plain spinlock is held: wrap such sections with sched_preempt_disable/enable (as printk does). weave_lock sections use arch_irq_save/restore so the timer tick cannot fire inside them.
  • Dead tasks/stacks are not reclaimed yet. Prefer one long-lived worker thread over spawning a task per request.
  • Network checksums are byte-wise on purpose — word-at-a-time reads get reordered around the caller's hdr->checksum = 0 store under -O2.
  • Ethernet frames are padded to 60 bytes — trim payloads to the IP total_length, never the frame length.

Commit & PR conventions

  • Commit messages follow Conventional-Commits-style prefixes: feat(scope): …, fix(scope): …, build: …, docs: …, release(vX.Y.Z): …. Write the subject in the imperative and add a body explaining what changed and what you verified.
  • Branch off main for your work; open a pull request against main.
  • One logical change per PR. Rebase/squash noisy WIP commits before review.
  • CI must pass (build + kernel verification) before merge.
  • In the PR description, include: what the change does, which architectures you built, and how you verified boot behaviour.

Reporting bugs

Open a GitHub issue with:

  1. Architecture and how you built (defconfig, ARCH, toolchain).
  2. Exact command that reproduces it.
  3. What you expected vs. what happened — paste the serial log and, for the desktop, attach a screendump.
  4. The commit SHA (git rev-parse --short HEAD).

For security-sensitive reports, do not open a public issue — follow the Security Policy instead.


Happy hacking. 🐉