xim index

Luban Packages

Rendered from docs/12-luban-packages.md in the index repository — one source of truth, no second copy to drift.

Luban's editions, policies and boot profiles are ordinary recipes in this index: the xpkg format is unchanged, the data is in the recipe, and only libs/luban.lua writes files. What Luban is, and how editions are used, is in xlings's Luban docs.

The luban: namespace

What is official and made for Luban is published in the luban namespace: editions (luban:core, luban:desktop), desktop components (luban:labwc, luban:lxqt, luban:kde, luban:xdesk), the Qt runtime, the tool sets, and the bundles built for them. General software stays in xim (fish, mesa, a kernel), and so do the programs a user runs on a host (xim:luban, xim:luban-os). Anyone may depend on a luban: package -- any SubOS, any system: the namespace says who publishes it, not who may use it.

A short name in luban is a name in this namespace: --edition desktop is luban:desktop, --desktop kde is luban:kde. Adding an official desktop is adding its recipe here; nothing in luban or the Luban OS app lists them.

xim, luban, subos and config are reserved: index-compat.json declares them (namespaces.reserved), and a client that knows the field takes packages in them from this index only -- a recipe elsewhere that says namespace = "luban" is refused, naming its index and file. The rule is the client's and generic: any index may reserve its own namespaces the same way.

The published subos:luban-* editions and xim:labwc-desktop are frozen: kept, resolved as before (instances and older editions name them), never updated. Their successors declare replaces = "<old name>", which a client honours from the same index only.

The kinds

Kind type Namespace Version Written by
an edition subos luban (frozen ones: subos) the release date, YYYY.M.D.N luban.edition({id, variant, versions, files})
a desktop component (luban:labwc, luban:foot) package luban upstream's, -rN for this index's build the recipe; luban_component places it
a composite (luban:compositor, luban:xdesk) or a tool set (luban:tools-dev) package luban the release date, or what it composes its deps, its session and configuration
a policy subos-policy xim the release date luban.policy(json)
a boot profile package xim the release date luban.boot(json)
upstream software (kernels, limine, busybox, ...) package xim upstream's, -rN when rebuilt the recipe

Each component says, in a comment, the form it takes and why (a bundle, a runtime, a composite of atomic packages): the name and its conventions (a session file, X-Luban-Shell, its checks, the default terminal) stay when the form changes.

An edition's manifest

A luban: edition writes its manifest from a table (luban.manifest): its keys in a fixed order, replaces the frozen edition it succeeds, and a luban object -- what a reader that knows Luban is told about it:

Key Meaning
luban.settings what it presets (mode, enter, desktop, login_shell): below what the person sets; also written to the root's usr/share/luban/settings.json, which an older luban reads
luban.os how it names itself (name, version): a distribution based on Luban says its own name
luban.requires what it needs of whoever reads or runs it (opencaps names, root-layout>=2); a reader that lacks one says so before making it
manifest = {
    subos_kind = "rootfs", min_client = "2026.10.18.1",
    from = "luban:core@2026.10.18.1", replaces = "subos:luban-desktop",
    abi = { kernel = "linux", libc = "gnu" },
    packages = { "luban:xdesk@2026.10.18.1", "luban:foot@1.27.0-r1" },
    luban = { settings = { mode = "machine", enter = "desktop", desktop = "xdesk-classic" } },
    workspace = {},
}

The rules

  1. A published version's output never changes. tests/fixtures/luban-published.json records the sha256 and mode of every file each published version writes, and tests/test_luban_published.py compares. When a version merges to main, add it: LUBAN_PUBLISHED_ADD=pkgs/l/<recipe>.lua@<version> pytest -k add_published. The fixture only grows.
  2. An edition using a field newer clients read sets min_client. A new field is designed so an older client ignoring it is still safe (an ignored boot.profile falls back to boot.kernel).
  3. Every edition froms an official layer (except nano) and states its abi.
  4. A new edition names only luban-init; xlings-init stays for published versions.
  5. Tools that move fast are not pinned (an agent CLI): subos new installs the newest and records it in the instance, and luban upgrade moves it. Every other package is pinned exactly.
  6. A preview edition (status = "preview") has no short name in luban. A desktop is not an edition: an edition presets one, and luban new --desktop chooses another (luban-desktop in a package's categories offers it).
  7. An edition is built for the architectures it declares. archs lists only what was booted and tested; each package it pins exists for each of them, and scripts/test-luban-editions.sh runs on x86_64 and aarch64.