EssayArticle / 001

What I Actually Wanted

The requirements that turned Chartreuse from a reaction against existing Linux systems into a specification with consequences.

The previous post explained why I began building Chartreuse. This one concerns the more difficult question of what I was actually trying to build.

Most people never write down what they require from an operating system. They begin with whatever distribution was available, learn its assumptions, and gradually form preferences through moments of frustration. In doing so, their idea of a better system becomes a collection of reactions to the one already in front of them. The package manager is inconvenient, the init system feels too large, the release cycle moves too quickly, or the software they need exists outside the official repositories.

These complaints may be understandable, but they are not yet a design.

A complaint explains what irritates someone. A requirement explains what they are willing to build, maintain, and sacrifice in order to create something different. Saying that systemd is annoying does not establish an architecture. Saying that I want a supervised init whose mechanism I can understand in an afternoon, and that I am willing to accept the compatibility problems created by that decision, begins to form a real specification.

Chartreuse started with that distinction in mind. Before it was a repository, an installer, or a line of code, it was a list of requirements. The work on Chartreuse is the process of turning those requirements into actual contracts, then accepting the technical and maintenance consequences that follow from them.

A System That Can Sit Still

The first requirement was that the system should be able to sit still.

Stillness does not mean abandonment, frozen software, or a refusal to repair security problems. It means establishing one conservative baseline at a time, then allowing most of the system to remain stable while a smaller and more deliberate group of packages continues to move. Chartreuse describes this as a serial-LTS and selective-rolling model: one primary line, one understandable system state, and regular movement only where that movement has a clear purpose.

The dominant expectation in Linux is often the opposite. Constant movement is treated as evidence of health, while a package that has not recently changed is treated as a possible sign of neglect. This creates a system where updates arrive not only because something is broken or meaningfully improved, but because change itself has become the expected condition.

The wider problem is that a system in constant motion becomes difficult to fully understand. Documentation changes, defaults shift, dependencies gain new responsibilities, and yesterday's knowledge becomes less reliable even when the user's needs have not changed. The machine may remain functional, but the relationship between the person and the system becomes increasingly temporary.

I wanted Chartreuse to resist that pattern. A stable baseline gives the user time to learn why the system behaves as it does, rather than merely learning how to recover from its latest change. As such, stillness becomes more than a release policy. It becomes a form of legibility.

Supervision Without Absorption

The second requirement was supervision without a monolith.

Chartreuse uses the upstream s6 stack: s6-linux-init establishes the boot environment, s6-svscan occupies PID 1, and s6-rc manages service state and dependencies. This was not based on the argument that systemd is evil, because that argument does very little design work. The actual requirement was that the init and supervision mechanism should remain small enough to understand, inspect, and reason about as a collection of focused components.

The attraction of s6 is that supervision remains visible. Processes are supervised by tools built for supervision, service relationships are represented through an explicit graph, and the runtime engine does not need to absorb every adjacent system responsibility in order to remain useful. This creates a stronger separation between mechanism and policy, although it should be noted that the separation also creates one of the most difficult questions in an s6-based distribution.

Upstream s6 gives a distribution a powerful engine, but it does not provide a complete distribution policy. Someone still has to decide where service definitions live, how packages contribute them, how local overrides work, which bundles are enabled, and how a newly compiled service database becomes active. Every s6 distribution must eventually answer these questions.

The common answers tend to fall in two directions. One leaves the user close to the austerity of the upstream tools, where the mechanism is clear but the distribution provides little coordination. The other places a new manager around s6, making the system easier to operate while slowly recreating the centralized authority it was meant to avoid.

Chartreuse is pursuing a third way. The upstream engine remains the engine, while distribution policy lives in package-owned service definitions, explicit bundle membership, composition rules, and visible compile-and-update hooks. In doing so, the system attempts to provide coherent distribution behavior without allowing the convenience layer to become a second service manager.

This decision reaches much further than boot. It shapes packaging, upgrades, local services, administrative overrides, and the boundary between what exists on the filesystem and what becomes active at runtime. For that reason, the service architecture is not a minor implementation detail. It is one of the foundational contracts of the system.

Transactions That Explain Themselves

I also wanted transactional updates without adopting an entire computational religion to obtain them.

The basic transactional idea is correct: a system change should either complete successfully or leave the previous state intact. Updates should be inspectable, atomic, and reversible. A failed package operation should not place the machine somewhere between two coherent states, forcing the administrator to reconstruct what happened from logs and partially modified files.

However, transactional systems often arrive with additional assumptions. Some require the user to adopt a new package language, an unfamiliar filesystem model, or a content-addressed store that changes the way the entire machine is understood. Lighter snapshot systems may preserve a previous state, but their rollback interface can amount to little more than a timestamp and an invitation to jump backward.

My requirement was located between these two approaches.

Chartreuse should continue to use real XBPS packages on a recognizable filesystem. At the same time, supported system changes should produce numbered generations with structured information about what each transaction changed. Before a rollback occurs, the system should explain what the target generation means: which packages will be removed, which versions will be downgraded, which service definitions will return, and whether the selected generation was previously known to be healthy.

This is important because reversibility alone does not create understanding. A rollback that hides its consequences is still an act performed without meaningful information. It may restore the machine, but it does not clarify what state the machine is entering or why that state should be trusted.

Chartreuse therefore treats generation metadata and rollback previews as part of the transaction itself, rather than as optional decoration around a snapshot command. The wider goal is not merely to make system changes reversible. It is to make the history of the system visible enough that the user can account for it.

One Package Discipline

The package manager also needed to remain the only package manager.

This means one primary package format, one build substrate, and one coherent inventory of installed software. Chartreuse does not support Flatpak or AppImage as application-distribution layers, and it does not accept curl | sh installation as a normal answer to missing software. Each of those approaches creates a second path around the system's package discipline, bringing its own update behavior, dependency model, and trust relationships.

The difficulty is that no small distribution can package everything. Once that limitation is acknowledged, the question becomes unavoidable: what happens when the user needs software that the official repositories do not provide?

The usual answer is to step outside the distribution. The user may keep a collection of build scripts, install files permanently under /usr/local, copy binaries into a private directory, or introduce a separate application format whose contents the system package database cannot fully explain. Over time, the machine develops two histories: the one recorded by the distribution and the one remembered by the administrator.

Chartreuse requires a different path. A user should be able to point a supported tool at upstream source and produce a normal local XBPS package, stored in a separate signed overlay repository and installed through the same transactional system used for official software. The result must remain clearly marked as local rather than official, because convenience should not erase the trust boundary between packages reviewed by the distribution and packages built under the user's authority.

This distinction is central. Local packages should participate in the same package database, generation history, rollback mechanism, and service-integration rules as official packages, but they should not inherit an official guarantee merely because the tooling made them easy to build.

In doing so, Chartreuse attempts to place extensibility inside the system's discipline rather than around it. The user remains free to extend the machine, but the extension does not need to become invisible to the mechanisms responsible for explaining and recovering the system.

Trust Boundaries That Remain Visible

I wanted the system's trust boundaries to stay sharp.

Official packages should be signed. Signing keys should not live in Git repositories. Release signing should remain an intentional human operation rather than an invisible side effect of automation. SSH should be the only network-facing service enabled by default, while every additional network service should require an explicit policy decision.

The same principle applies to telemetry. Chartreuse may eventually use a narrow, opt-in package census to understand which locally built applications are common enough to justify official packaging, but that mechanism must have one stated purpose, a previewable report, and a deliberate limit on what it can collect. It should not gradually become machine profiling, behavior analytics, or a broad inventory of someone's system.

None of these requirements are especially exotic when considered individually. The difficulty comes from preserving them over time.

Trust boundaries rarely disappear through one dramatic decision. They erode through convenience: a key is copied into an automated environment, another daemon becomes enabled because a desktop component expects it, or a small reporting feature begins collecting additional fields because the information might be useful later. Each change can appear reasonable by itself, while the combined system becomes more difficult to account for.

With that in mind, Chartreuse treats refusal as part of the architecture. The system should not only document what it trusts. It should also remain clear about what it has chosen not to trust, what it does not enable, and what it will not quietly absorb for compatibility.

A System One Person Can Sustain

The final requirement disciplines all the others: Chartreuse must remain maintainable by one person.

Without this constraint, nearly every operating-system design becomes easy to imagine. The project can promise several architectures, multiple init systems, a giant repository, many desktop environments, rapid updates, extensive compatibility layers, and polished infrastructure for every possible workflow. On paper, this appears ambitious. In practice, each promise becomes a future maintenance obligation.

A system that requires a team I do not have is not a serious design for this project. It is a fantasy whose costs have been moved into the future.

This requirement rules out a giant package universe and a latest-everything desktop promise. It rules out supporting multiple competing service architectures and multiple public release channels merely because other distributions do so. It requires serial focus, a narrow official scope, and a willingness to say no when a new feature would create a permanent responsibility without strengthening the central design.

This does not mean that Chartreuse should remain artificially primitive. It means that every capability must justify the burden it adds. The project can grow, but that growth must remain bounded by what can still be reviewed, repaired, documented, and understood by the person responsible for it.

As such, maintainability is not a secondary concern placed after the technical architecture. It is part of the architecture. A smaller system that remains coherent is more useful than an ambitious system whose packages, policies, and trust relationships slowly decay.

The Shape of the Trade

Together these requirements reveal the larger shape of Chartreuse.

Each one trades breadth for legibility. The official package set is smaller so that its maintenance policy remains meaningful. The service architecture uses fewer hidden layers so that activation and supervision can be traced. The update system records generations so that change has a visible history. Local software remains inside XBPS while retaining a separate trust identity. Default services remain limited so that network exposure is the result of a decision rather than an assumption.

This trade will not suit everyone, and it is not intended to.

Chartreuse is not an attempt to produce a universal Linux distribution or to prove that every other system has made the wrong decisions. It is a specification for a particular kind of machine: one whose contents, behavior, trust relationships, and history can be accounted for by the person operating it.

The work is found in accepting the consequences of that specification. Choosing s6 means building distribution policy around an engine that deliberately does not provide it. Choosing informed transactions means creating metadata, validation, and rollback behavior rather than merely taking snapshots. Choosing one package discipline means supporting local package creation instead of telling users to leave the system whenever the repository is incomplete. Choosing a one-person maintenance boundary means rejecting attractive features that would weaken the project later.

In the end, Chartreuse began with a simple desire: I wanted a system that answered to its design instead of to churn. The requirements above are the attempt to make that desire concrete.

The next part of this series examines the existing Linux landscape against this specification. Several systems satisfy individual requirements, and some come remarkably close, but none satisfies the full conjunction. The interesting question is not simply which feature is missing. It is why these requirements become difficult when they are expected to exist together.