#+TITLE: RNT
#+html: <img alt="the RNT logo" style="width=15%" src="./images/logo.png" /><br>
#+html: <a href="https://builtwithnix.org"><img alt="built with nix" src="https://builtwithnix.org/badge.svg" /></a><br>
#+html: <a href="https://github.com/dont-rely-on-nulls/RNT"><img alt="AGPLv3 License" src="https://img.shields.io/badge/License-AGPL%20v3-blue.svg" /></a>
* About
RNT is an experimental database kernel inspired by the object-management model of the Windows NT kernel. The project explores what database internals look like when relations, tuples, transactions, namespaces, permissions, cursors, and handles are treated as explicit runtime-managed objects. /RNT stands for "Relations, Not Tables"/
The goal is a small, understandable runtime where database state is accessed through uniform paths, guarded by explicit security checks, and managed through visible lifecycle rules. The codebase is still early, so several classes define architectural boundaries before they define complete behavior.
* Motivation
The NT kernel is a good model for a dedicated database kernel for three reasons.
**The object manager.** NT's OB gives every kernel resource a named path in a hierarchical namespace, a security descriptor, and a uniform open and close lifecycle enforced through handles. A database kernel has the same requirements: relations, transactions, cursors, and namespaces all need to be located by path, checked for access, and cleaned up when the last handle closes. Rather than building those mechanisms independently for each database concept, this project borrows the NT object manager's shape directly. The result is a single, consistent runtime model instead of a collection of loosely related subsystems.
**Physical backends as drivers.** NT device drivers expose a narrow dispatch table. The kernel routes I/O through it without knowing whether the device is a local disk, a USB key, or a network adapter. Storage backends in a database kernel follow the same pattern. SQLite and an in-memory store both satisfy the same interface here. A remote backend like etcd is just another driver, but it brings its own concerns: network latency, connection management, and the possibility of partial failure. The driver boundary keeps those concerns inside the backend module and out of the rest of the kernel.
**Clients as environment subsystems.** NT supports Win32, POSIX, and OS/2 as environment subsystems layered above a common native API. Each subsystem translates its own conventions into native NT system calls; the kernel itself knows nothing about Win32 or POSIX. A database client works the same way. A PostgreSQL wire adapter, a MySQL wire adapter, or an HTTP/JSON interface each translates its protocol into kernel-level operations: handle opens, cursor iterations, VM plan evaluations. The kernel never sees SQL syntax or protocol framing. Adding a new wire protocol means implementing a new translation layer, not touching the kernel.
* Design Direction
- Object management: database objects are registered, located, and referenced through a central registry.
- Permissions: access checks are kept separate from object lookup so security policy can evolve independently.
- Identity and lifecycle: opening, closing, monitoring, pinning, cleanup, and contention are modeled as runtime responsibilities.
- Handles: authorized access is explicit, which makes ownership, accounting, and cleanup visible.
- Cursors and VM: retrieval is designed around pull-based cursors and a split between terminating first-order logic and higher-order logic execution.
- Storage: tuples are content-addressed. Each one is stored under the SHA256 digest of its serialized bytes. The physical layer is a pluggable KV backend (=IStorageBackend=); the current implementation uses SQLite.
* Current Status
The open-handle pipeline is wired end-to-end and cursors pull tuples lazily from the storage backend one page at a time through the Tarski FOL engine. The active backend (=SqliteBackend=) keeps a single =kv(hash, value)= table for content-addressed tuple data. Relation membership is tracked by a sorted Merkle B-tree (=Merkle=) whose nodes are stored in the same KV table; only the root hash per relation is held in memory. =InMemoryBackend= provides the same interface for tests.
An =extern "C"= API (=RNT_C_API.h=) exposes the full manager pipeline to OCaml via ctypes, enabling Sakura to use this kernel as its storage and query execution layer.
Several manager features are still being designed: dual ref counting, type callbacks, trie-based object lookup, and the namespace reparse layer. These are specified in header comments.
* Building
** GNU/Linux with Nix
The supported build path is the Nix development shell on GNU/Linux. It provides
GCC, CMake, Ninja, SQLite, PicoSHA2 headers, Catch2, Doxygen, Graphviz, and GDB.
#+begin_src shell
nix develop
cmake --preset gnu-debug
cmake --build out/build/gnu-debug
ctest --test-dir out/build/gnu-debug --output-on-failure
#+end_src
A release build uses =--preset gnu-release=. CI builds the package with =nix build=,
which also runs the test suite.
* Documentation
API documentation is generated with Doxygen. The root =Doxyfile= reads the public headers, source files, and the documentation main page in =docs/mainpage.dox=.
#+begin_src shell
nix develop --command doxygen Doxyfile
#+end_src
Generated HTML is written to =docs/generated/html=.
The comments in the public headers are part of the design record. Keep architectural notes close to the declarations they explain so Doxygen can publish them with the API reference.
The repository also includes a GitHub Actions workflow that publishes the generated Doxygen HTML to GitHub Pages on pushes to =master=. In the repository settings, configure Pages to use =GitHub Actions= as its source.
* License
RNT is free software licensed under the GNU Affero General Public License v3.0.
See =LICENSE= for the full terms.
Copyright (C) 2026 RNT contributors, and Don't Rely on Nulls.
Maintainers: Marcos Magueta & Estevan Castilho.