Codegeist OS is the workspace for a NixOS-based personal desktop that integrates a catalog-selected local language model, the Codegeist CLI, and accelerator- backed local speech while keeping AI execution separate from the normal human user.
The project defines an operating system in which AI-assisted actions are constrained by operating-system identity, policy, approval, and auditable system boundaries. Access to human data, credentials, devices, processes, networks, and privileged operations must be granted deliberately and remain revocable.
codegeist-llm owns logical language-model selection, training, provenance,
evaluation, runtime-variant production, and release artifacts. codegeist owns
the CLI and its native releases. This repository owns the current direct
integration pins and operating-system isolation. It will also own the planned
generic catalog that connects LLM and speech variants to hardware profiles and
their lifecycle, updates, rollback, and recovery.
The first integration milestone is intentionally narrow:
- NixOS with classic stable Nix interfaces, not experimental Nix Flakes.
- Separate x86_64 and aarch64 UEFI desktop images. The current installer target uses Hyprland; broader desktop and architecture profiles remain planned.
- A model-free bootstrap VM and a production live-ISO closure with no GGUF or
speech-model bytes. The installed x86_64 system receives one model through a
mandatory Calamares download, while standard target packages derived from the
pinned Nixpkgs revision come from
cache.nixos.org. - A broad hardware-profile contract for CPU and independently verified Intel, AMD, NVIDIA, and Qualcomm accelerators. The RTX A2000 12GB remains the first planned CUDA reference profile, not a measured or universal requirement.
- One approved logical language-model release with multiple cataloged variants for formats, quantizations, system architectures, backends, and resource envelopes.
- SafeTensors as the canonical training output and quantized GGUF as the OS runtime-variant format where appropriate.
- A native llama.cpp server exposing one OpenAI-compatible loopback API.
- A shared future catalog for German STT, anonymous diarization, and fixed-voice TTS variants, with model payloads also excluded from the base ISO.
- Anonymous speaker diarization that assigns transcript segments to file-local
labels such as
SPEAKER_00, without identifying people. - Matching preinstalled Codegeist Linux native releases for each supported system architecture.
- Architecture-specific QEMU VMs and installer ISOs built from reviewed NixOS profiles.
codegeist --versionin the model-free bootstrap and a configured localaskpath under the locked paired Geist identity in the installed system.
The current x86_64 output is one raw codegeist-os-x86_64.iso. LightDM
auto-logs the live nixos account into Openbox solely to run the Codegeist
OS-branded Calamares installer; neither component is part of the installed
desktop. Calamares generates a minimal Hyprland target with greetd/tuigreet,
Waybar, Fuzzel, Foot, Thunar, NetworkManager, PipeWire, notifications, Polkit,
and essential Wayland tools. Installation requires cache.nixos.org for
standard target closures and Hugging Face for the fixed 1.1 GB
codegeist-llm Q4_K_M GGUF. The ISO contains no GGUF bytes. The alpha live
environment keeps only C/POSIX and US English locale data.
The current raw image uses xz SquashFS and measures 1,821,573,120 bytes, below
the 2,000,000,000-byte release limit. Target-module evaluation and hybrid BIOS,
UEFI, MBR, and GPT boot metadata were checked. The separate graphical driver
verifies Calamares installation, the fixed model download, reboot, greetd
authentication, Hyprland, Foot, visible copied target modules, and one real
geist "What is Codegeist?" response through local llama.cpp. Physical USB boot
and physical hardware remain unverified.
The generated target configures native llama.cpp to load
/var/lib/codegeist/model.gguf with context 4096 and expose its
OpenAI-compatible API at 127.0.0.1:11434. /etc/codegeist/codegeist.yml
directs Codegeist to that endpoint using the gpt-5-mini alias required by
Codegeist 0.5.0. Calamares downloads the model after nixos-install, requires
exactly 1,107,408,672 bytes, and does not verify a checksum.
The generated human account receives only geist; the wrapper is configured to
run codegeist ask as a locked, non-login
<username>-geist system user. The two accounts share the private primary group
<username>-geist with group-writable newly created files. The installer is
configured for this one pinned model but does not rank hardware or offer model
selection.
Generic catalog selection, alternate-model acquisition, offline package import,
persistent model lifecycle and recovery, live microphone capture, speaker
identification, voice cloning, desktop control, privileged actions, and a general
human approval interface remain later milestones.
- The architecture and cross-repository artifact contracts are documented.
- NixOS
26.05.7006.445d861c6d31is pinned directly innix/artifacts.nix, and classicnix-buildattributes build the Codegeist package, x86_64 UEFI headless and VNC bootstrap runners, the Geist wrapper, the payload-free Openbox/LightDM Calamares ISO, the network-dependent graphical installer driver, and the wrapper and bootstrap tests. - The bootstrap creates a locked non-login
codegeist-aisystem user, keeps its home and empty workspace private, disables SSH and sudo, and does not add a human-facing Codegeist command to the system PATH. - The UEFI test boots through OVMF and systemd-boot, reaches
multi-user.target, and verifies Codegeist0.5.0metadata commands under the AI UID in a private-network systemd unit. - The production ISO configures the branded Calamares welcome, model disclosure, progress page, account, hostname, and required Hyprland target. It builds as one payload-free hybrid image under the release-size limit. The separate graphical driver proves installation, reboot, greetd authentication, Hyprland, Foot, and visible target-module presence, then requires one non-empty local Geist response.
- The Calamares-generated target defines one native llama.cpp service on loopback. The one-shot request proves that it starts and serves the installed model. The unit currently runs as root without filesystem hardening, and its unauthenticated loopback API remains accessible to all local processes.
- The generated target policy creates a private
<username>-geistgroup shared by the human and locked<username>-geistsystem accounts. The Geist account has no password, login shell, orwheelmembership. ANOPASSWD:NOSETENVsudo rule permits only the immutable internal Geist command; arbitrary passwordless commands as the Geist account remain denied. The human home is0750, login umask is007, and the internal command also uses umask0007so both accounts can update group-shared project files. Logs and sessions remain inside the Geist account's private0700home. geist one twoexecutescodegeist ask "one two"as<username>-geistwhile preserving the current directory. The immutable wrapper directs Codegeist'sLOG_FILEto/var/lib/geist/<username>/logs/codegeist.logandCODEGEIST_SESSION_DIRECTORYto/var/lib/geist/<username>/.codegeist, and disables Spring shell history so application state is not created in the human workspace. The rawcodegeistcommand is not added to the human PATH. The wrapper contract is tested independently, and the installer driver verifies its installed llama.cpp path withgeist "What is Codegeist?". The separate bootstrap VM remains model-free and exercises only Codegeist metadata commands.- Aarch64, the generic variant catalog, hardware ranking and model selection, model-manager lifecycle and recovery, external package import, speech, accelerator profiles, hardened human desktop policy, rollback, and recovery outputs remain target decisions rather than implemented guarantees.
- The generated target passes one native CPU-inference request. No response-quality, repeated-request, load, failure-recovery, accelerator, or physical-hardware gate is implemented yet.
- Human approval, audit, rollback, and recovery remain design requirements, not implemented security controls.
- Codegeist
v0.5.0is sufficient for the bootstrap metadata smoke but its Linux archive requires anx86-64-v3CPU, omits the documented license file, and carries an optionallibinstrument.sodependency on an absentlibjli.so. The Nix package pins the later repository 0BSD license separately and permits only that unused instrumentation dependency; a corrected upstream archive is required before a stable or production OS release. - This repository is public through its GitHub mirror. Do not commit private planning material, credentials, personal data, model weights, or restricted artifacts.
Eligible x86_64 alpha tags are built and published as GitHub prereleases at
github.com/codegeist-ai/codegeist-os/releases.
A successful release contains one raw ISO and SHA256SUMS. Immutable alpha tags
originate in the authoritative Gitea repository, are mirrored to GitHub, and trigger
the GitHub-hosted build in .github/workflows/release.yml; locally built images are
not uploaded into this release path. If the release page is empty, no alpha has
completed that publication gate yet.
Download both files into one directory and verify the ISO before writing it:
sha256sum --check SHA256SUMSThe files are unsigned. A matching SHA-256 detects download corruption but does not
authenticate the publisher. Review the release notes for the required
cache.nixos.org and Hugging Face installation access, x86-64-v3 CPU baseline,
known upstream limitations, and current test scope.
To write an ISO to a USB drive, identify the complete target device carefully with
lsblk, unmount any of its mounted partitions, set ISO_FILE to the downloaded
release filename, and replace /dev/sdX below with that device. This command
irreversibly overwrites the selected device:
ISO_FILE=codegeist-os-v0.1.0-alpha.1-x86_64.iso
sudo dd \
if="$ISO_FILE" \
of=/dev/sdX \
bs=4M \
conv=fsync \
status=progressPhysical USB boot and physical hardware remain unverified. These artifacts are experimental prereleases, not stable or production releases.
The Calamares-generated human account receives geist, which accepts the complete
prompt as ordinary shell arguments:
geist Explain this projectThe wrapper joins those arguments with spaces and executes the equivalent of
codegeist ask "Explain this project" as <username>-geist. It does not use
eval, request arbitrary environment preservation through sudo -E, or permit a
different command. The paired account cannot log in. Because both accounts share
the private <username>-geist group, the process can access every path whose
group mode allows it, not only the current directory. It preserves that caller
directory but keeps logs and Codegeist sessions under /var/lib/geist/<username> and disables
Spring shell history. Codegeist reads /etc/codegeist/codegeist.yml and reaches
the local llama.cpp OpenAI-compatible endpoint.
Use the Taskfile shortcuts from the repository root:
task build
task test
task check
task start
task start-vnc
task record-installer-demotask build builds the Openbox/LightDM Calamares ISO whose closure excludes the
GGUF. Installation requires the Nixpkgs cache for standard target closures and
Hugging Face for the mandatory model download.
task build-bootstrap builds the Codegeist and Geist packages plus both
model-free VM runners. task test runs the wrapper and unattended bootstrap
tests, while task check builds the ISO and bootstrap outputs before running
those tests. task start builds the model-free bootstrap VM when needed and
starts QEMU on the serial console. Additional QEMU arguments can be forwarded after
--, for example:
task start -- -snapshotFor graphical testing, start the same UEFI VM with a localhost-only VNC server:
task start-vncConnect a VNC client to vnc://127.0.0.1:5900. To use another local display and
port, pass a Task variable; display :1 maps to TCP port 5901:
task start-vnc VNC_DISPLAY=127.0.0.1:1The VNC endpoint has no password because it is a local development interface.
Keep it bound to 127.0.0.1; do not expose it on 0.0.0.0 or a remote network.
The dedicated VNC runner uses tty0 as the primary kernel console, so firmware,
systemd-boot, kernel messages, and the final login prompt remain visible in the
VNC client instead of switching to the serial-only headless console.
task record-installer-demo is the separate network-dependent graphical
installer workflow. It completes Calamares with the fixed model download,
reboots, authenticates through greetd, reaches Hyprland, launches Foot, and
visibly checks both copied target modules before running
geist "What is Codegeist?" and requiring a non-empty response. The recorder
publishes docs/assets/installer/codegeist-os-installer.gif only after
test-complete and media validation. This is not part of task build,
task test, or task check and does not verify response quality, repeated
requests, failure recovery, physical USB boot, or physical hardware.
The VM itself has no login credential. Use task reset-vm-state to delete its
mutable disk and EFI variables, task clean to remove only build result links,
or task clean-all for both. Run task --list for the complete command list.
Run task reset-vm-state after changing a VM profile: an existing QCOW2 overlay
keeps the immutable backing image from the moment that overlay was created.
All generated workspace artifacts stay under target/:
target/
codegeist
geist
iso
installer-driver
installer-demo/
installer-vnc-output/
vm
vm-vnc
test
test-geist-wrapper
vm-state/
headless/
installer-vnc/
vnc/
The tasks delegate to these classic build attributes:
nix-build -A packages.x86_64.codegeist -o target/codegeist
nix-build -A packages.x86_64.geist -o target/geist
nix-build -A images.x86_64.iso -o target/iso
nix-build -A images.x86_64.vm -o target/vm
nix-build -A images.x86_64.vmVnc -o target/vm-vnc
nix-build -A tests.x86_64.bootstrap -o target/test
nix-build -A tests.x86_64.geistWrapper -o target/test-geist-wrapper
nix-build -A tests.x86_64.installerDriver -o target/installer-driverThe VM runner can also be started directly with:
NIX_DISK_IMAGE=./target/vm-state/headless/codegeist-os.qcow2 \
NIX_EFI_VARS=./target/vm-state/headless/codegeist-os-efi-vars.fd \
./target/vm/bin/run-codegeist-os-vmThe bootstrap VM deliberately has no login credential. Mutable VM disks, EFI
variables, generated images, and build links stay under ignored target/ and
outside Git.
docs/architecture.mddefines the selected Version 1 system architecture and identity boundaries.docs/base-system-selection.mdrecords the NixOS decision and the stable Nix, no-Flakes policy.docs/artifact-contract.mddefines image inputs, the shared LLM and speech catalog, hardware profiles, external test bundles, fixtures, and per-system Codegeist releases.docs/build-workflow.mddefines the independent model, CLI, bootstrap VM, payload-free ISO, graphical installer/recorder, inference-reliability, external-bundle, and hardware-profile verification flow.docs/feature-demos.mddefines how successful feature workflows become local full recordings and curated repository-owned GIFs.docs/speech-model-evaluation.mdrecords the local TTS/STT hardware smoke, candidate models, diarization research, licenses, and first accelerator-profile direction.docs/security.mddefines least-privilege, isolation, artifact, audit, disablement, and recovery requirements.
.devcontainer/ and .opencode/ are Git submodules that track the release
branches of the shared Codegeist development and agent kits. Initialize them
from this repository with:
git submodule update --init .devcontainer .opencoderefs/codegeist/ and refs/codegeist-llm/ are read-only source-reference
submodules that track main on the public GitHub repositories. They support
cross-repository review and contract work without making either mutable source
tree an OS build input. Normal VM and ISO builds must continue to consume only
reviewed native releases, manifests, catalogs, and hashes from
docs/artifact-contract.md.
Initialize all workspace submodules with:
git submodule update --init \
.devcontainer .opencode refs/codegeist refs/codegeist-llmUpdating a reference submodule changes a real parent-repository gitlink and must
be reviewed explicitly. Both reference repositories track main, but the parent
repository always records a concrete commit.
Gitea at git.codegeist.ai is the primary write target. GitHub at
github.com/codegeist-ai/codegeist-os is a public push mirror of Git refs.
Issues, pull requests, secrets, permissions, and other platform state are not
automatically synchronized.
Development environments should trust the certificate authority used by the Gitea deployment and keep Git TLS verification enabled. Installing that CA in the environment trust store is the required long-term fix.
This repository currently carries an explicit temporary exception in
.codegeist/Dockerfile: GIT_SSL_NO_VERIFY=true disables certificate
verification for every Git HTTPS request made inside the rebuilt devcontainer,
including non-Gitea hosts. It does not provide Gitea authentication and does not
affect host-side submodule initialization before the container starts. Never put
a Gitea token in a remote URL, Dockerfile, environment committed to Git, or other
tracked file. Remove the exception as soon as the Gitea CA is trusted.
Codegeist OS-owned repository material is available under the Zero Clause BSD
License (0BSD) in LICENSE. Third-party packages, firmware, drivers, models,
voices, fixtures, and other artifacts retain their own terms. Their complete
distribution rights still require review before an OS release is published.
