# How the Kernel-Floor Ratchet Enforces Measured Package Counts in OpenHuman

> Learn how the kernel-floor ratchet enforces measured package counts in OpenHuman. This CI guard prevents bloat in the Rust kernel by tracking dependency metrics and failing builds that exceed set limits.

- Repository: [Tiny Humans/openhuman](https://github.com/tinyhumansai/openhuman)
- Tags: internals
- Published: 2026-08-24

---

**The kernel-floor ratchet is a CI guard that prevents bloat in OpenHuman's always-on Rust kernel by measuring package counts, storing strict upper limits, and failing builds when dependency metrics exceed their caps.**

OpenHuman maintains a deliberately small *kernel* within its Rust binary to ensure fast compile times and minimal attack surface for third-party embedders. The repository implements a **kernel-floor ratchet** mechanism that tracks measured package counts across the kernel profile dependency tree, using shell scripts and strict ceiling values to block unintentional growth before it reaches production.

## What Is the Kernel-Floor Ratchet?

The kernel-floor ratchet is a three-stage enforcement system that protects the minimal dependency graph required for the kernel profile. Unlike the full desktop application (Product profile), which can include heavy crates like `ring` or `zstd-sys`, the kernel must remain lean for agents, CLI tools, and test harnesses. The ratchet ensures that adding new dependencies to this critical path requires explicit justification and documented limit updates.

The mechanism operates through two distinct build lanes:

- **Product profile** – The full desktop application with unrestricted dependencies.
- **Kernel profile** – The minimal in-process set tracked by [`scripts/kernel-floor.sh`](https://github.com/tinyhumansai/openhuman/blob/main/scripts/kernel-floor.sh) and guarded by [`scripts/check-kernel-floor.sh`](https://github.com/tinyhumansai/openhuman/blob/main/scripts/check-kernel-floor.sh).

## How Package Counts Are Measured

The ratchet tracks three specific metrics to detect different types of bloat. In [`scripts/kernel-floor.sh`](https://github.com/tinyhumansai/openhuman/blob/main/scripts/kernel-floor.sh), the measurement logic parses the output of `cargo tree` (or `cargo metadata`) using the kernel feature set (e.g., `flows`), then computes the following:

1. **Total packages** – The complete count of all crates in the resolved dependency graph.
2. **Distinct crate names** – The deduplicated count of unique crate names, preventing duplicate version inflation from silently growing the graph.
3. **Native-toolchain builds** – The number of crates triggering C or C++ compilation steps, identified by inspecting each crate's `links` field or the presence of build scripts.

When you run the measurement script locally, it outputs the current counts in a parseable format:

```bash
$ scripts/kernel-floor.sh flows
304 packages / 281 names / 3 native

```

This output format allows the CI checker to extract integers easily and compare them against stored limits.

## The Ratchet Enforcement Pipeline

The kernel-floor ratchet enforces measured package counts through three coordinated steps:

### Step 1: Counting Current Dependencies

The script [`scripts/kernel-floor.sh`](https://github.com/tinyhumansai/openhuman/blob/main/scripts/kernel-floor.sh) walks the Cargo dependency tree for a specified feature set. It invokes `cargo tree` with the kernel features enabled, deduplicates crate names to compute the unique-name count, and inspects crate metadata to identify native build requirements. This script lives at the repository root and accepts the feature name as an argument (e.g., `flows`).

### Step 2: Storing Baseline Limits

The measured counts for stable kernel baselines are recorded in `scripts/kernel-floor.limits`. This plain-text file stores "maximum allowed" values for each metric and profile combination. Each entry represents a ceiling that cannot be exceeded without a documented justification and deliberate file edit. Lowering a number requires a comment explaining the reduction, ensuring that limit changes are intentional and traceable.

### Step 3: CI Regression Checks

During the `ci-lite` workflow, the script [`scripts/check-kernel-floor.sh`](https://github.com/tinyhumansai/openhuman/blob/main/scripts/check-kernel-floor.sh) reads the current counts from [`kernel-floor.sh`](https://github.com/tinyhumansai/openhuman/blob/main/kernel-floor.sh), looks up the corresponding limits in `kernel-floor.limits`, and aborts the build if any metric exceeds its cap. The failure is explicitly reported at line 460 of [`.github/workflows/ci-lite.yml`](https://github.com/tinyhumansai/openhuman/blob/main/.github/workflows/ci-lite.yml). Contributors can run this check manually during development:

```bash
$ scripts/check-kernel-floor.sh --verbose

# exits 0 if counts are ≤ limits, non-zero otherwise

```

## Why Kernel Package Counts Matter

Tracking **measured package counts** matters because the kernel profile directly influences binary size, compile time, and security attack surface for library embedders. By monitoring three distinct metrics—total packages, unique names, and native builds—the ratchet catches both pure-Rust bloat and the addition of C/C++ build steps that would enlarge the final binary.

Native-toolchain builds receive special attention because they introduce external compiler dependencies and increase build complexity. The ratchet treats each native build as a significant cost, ensuring that adding a crate like `git2` or similar system libraries requires explicit acknowledgment through limit updates.

## Accepting Changes and Updating Limits

When a pull request adds a new dependency to the kernel profile, the author must follow the ratchet protocol:

1. Run `scripts/kernel-floor.sh <feature>` locally to obtain current counts.
2. Verify the new numbers do not exceed the limits in `scripts/kernel-floor.limits`.
3. If the counts exceed limits, either remove the dependency or update the limits file with a comment justifying the increase.

The CI job automatically executes `scripts/check-kernel-floor.sh --verbose`; any breach blocks the PR. This forces contributors to consciously decide whether the dependency is worth the permanent increase in kernel floor size, or whether to find lighter alternatives.

## Summary

- The **kernel-floor ratchet** prevents uncontrolled growth of OpenHuman's always-on Rust kernel by enforcing strict **measured package counts**.
- Three metrics are tracked: total packages, distinct crate names, and native-toolchain builds via [`scripts/kernel-floor.sh`](https://github.com/tinyhumansai/openhuman/blob/main/scripts/kernel-floor.sh).
- Limits are stored in `scripts/kernel-floor.limits` and represent maximum allowable values that only decrease without explicit justification.
- CI enforcement occurs in [`.github/workflows/ci-lite.yml`](https://github.com/tinyhumansai/openhuman/blob/main/.github/workflows/ci-lite.yml) using [`scripts/check-kernel-floor.sh`](https://github.com/tinyhumansai/openhuman/blob/main/scripts/check-kernel-floor.sh), failing builds at line 460 when limits are breached.
- The system distinguishes between the heavy Product profile and the minimal Kernel profile, protecting embeddable library components from bloat.

## Frequently Asked Questions

### What triggers a kernel-floor ratchet failure in CI?

A failure occurs when [`scripts/check-kernel-floor.sh`](https://github.com/tinyhumansai/openhuman/blob/main/scripts/check-kernel-floor.sh) detects that the current count of packages, unique names, or native builds exceeds the corresponding maximum value stored in `scripts/kernel-floor.limits`. This check runs during the `ci-lite` workflow and exits with a non-zero status, blocking the PR until the dependency graph shrinks or limits are deliberately updated with documentation.

### How do I update the package count limits after adding a dependency?

First, run `scripts/kernel-floor.sh <your-feature>` to determine the new counts. Then edit `scripts/kernel-floor.limits`, updating the relevant `max_packages`, `max_names`, or `max_native` values. You must include a comment explaining why the limit changed, such as: `# Added crypto primitives, raising max_packages to 305`. The CI checker allows increases only when the limits file itself is modified with justification.

### Why does the ratchet track native-toolchain builds separately?

Native-toolchain builds (C/C++ compilations) significantly increase build complexity, compile times, and potential security surface. By counting these separately from pure-Rust packages in [`scripts/kernel-floor.sh`](https://github.com/tinyhumansai/openhuman/blob/main/scripts/kernel-floor.sh), the ratchet ensures that adding a crate with system dependencies—such as those linking to `openssl` or `zlib`—requires explicit acknowledgment, preventing "hidden" build costs from entering the kernel profile.

### Where is the ratchet check implemented in the GitHub Actions workflow?

The enforcement logic resides in [`.github/workflows/ci-lite.yml`](https://github.com/tinyhumansai/openhuman/blob/main/.github/workflows/ci-lite.yml) at line 460, where the workflow calls [`scripts/check-kernel-floor.sh`](https://github.com/tinyhumansai/openhuman/blob/main/scripts/check-kernel-floor.sh). This script compares the live output of the kernel dependency counter against the stored limits file, providing verbose output to help contributors identify which specific metric exceeded its ceiling.