RADpm Reference
RADpm is the RADPx-OS package model: signed .radpm archives described by machine-readable
JSON indexes that RadBuild reads to resolve and stage packages into generated root filesystems.
This page documents the on-disk schema and packaging model that the published indexes currently
express only by example.
What RADpm Is
RADpm is the RADPx-OS package system. A package is a .radpm archive (a tar archive that
unpacks into a rootfs/ tree and/or standard top-level directories such as bin,
etc, lib, usr) plus a JSON metadata record. The metadata records
are gathered into a package index and an optional packagegroup index
per suite and component.
The radpm tool (source: RADLib/tools/radpm/radpm.cpp) reads these indexes and
supports the commands list, resolve, verify, install,
and cache-toolchain. In the current release line RadBuild is the installer: it resolves
package metadata and stages package archives into generated RADPx root filesystems. In-OS package
management is not enabled yet.
Indexes live under a fixed repository layout. For a repository root, suite, and component the tool
derives the paths radpm/dists/<suite>/main/packages.json and
radpm/dists/<suite>/main/packagegroups.json (see indexLocation() in
radpm.cpp). The default suite is experimental; stable is also
published. A repository may also be pointed directly at a single .json index file, or at
an http(s):// base URL.
Package Index Schema (radpm-package-index)
The package index is a JSON object. Top-level fields observed in the published indexes
(radpm/dists/<suite>/main/packages.json):
schema— string identifier, always"radpm-package-index". Present in every index; a format marker.schema_version— integer, currently1. Present in every index.repository— human-readable repository name (e.g."RadicalPackages RADPx Package Repository"). Theradpmtool reads this into the repository provider field (default"unknown"), which then supplies each package's default provider.suite— the suite the index belongs to ("stable"or"experimental"). Informational in the file; the tool takes the active suite from its--suiteoption rather than this field.component— component name, currently always"main". Present in the file; not consumed by the tool.packages— array of package records (see below). Empty arrays are valid; the stable index currently ships"packages": [].signing_key— optional/observed, index level. A GPG key fingerprint for the index as a whole. Present in the experimental index; the tool parsessigning_keyonly on individual package records, not at index level, so at index level it is descriptive metadata.signature— optional/observed, index level. URL of a detached ASCII-armored signature over the index file (e.g.packages.json.asc). Present in the experimental index; not consumed by the tool.
Package Record Fields
Each entry of packages is an object. The following fields are parsed by
parsePackage() in radpm.cpp:
name— package name (required; the tool errors on a record with no name).version— package version string, e.g."0.1.0-crimson","0.2.0-radpx"(required).suite— suite for this package; defaults to the repository suite when omitted.architecture— target architecture slug. Observed values:radpx-any(architecture-independent) andradpx-x86_64.summary— one-line human description.dependencies— array of package names (or provided virtual names) this package requires. Used byresolve/verifyto report unmet dependencies.provides— array of virtual names this package satisfies. A dependency is considered met if some selected package'snameor one of itsprovidesentries matches. Example:radpx-ncursesprovideslibncurses,libtinfo,libradpxc, etc.archive— location of the.radpmarchive: an absolutehttp(s)URL or a path relative to the index. May benull/absent for pure metadata packages. On resolve the tool computes an absolutearchive_locationfrom this.sha256— hex SHA-256 of the archive. This is the integrity check the tool actually enforces:installrunssha256sumon the downloaded archive and fails on mismatch. May benull/absent when there is no archive.bytes— integer archive size in bytes (default0).docs— documentation reference for the package. Observed values are relative doc paths ("docs/radpx-os/0.1.4/api/","docs/radlib/0.2.0/api/") or a portal page ("radpx-os.html").signature— optional. URL of a detached ASCII-armored signature over the archive (the archive URL with a.ascsuffix). May benull/absent. See GPG Signing below.signing_key— optional. GPG key fingerprint that signed the archive. May benull/absent. Every signed package in the experimental index uses fingerprintF3731ADBB37AFA120A7D5EBD20B2754CF3894789.provider— optional. Provider name; defaults to the repository'srepositoryvalue when omitted (the current records omit it and inherit the default).repository_url— optional. Provider repository URL; defaults to the repository root when omitted.supported_kernel_versions— optional/observed. Array of version-range strings, e.g.[">=0.1.0 <0.3.0"]. Present on every current package record but not parsed byradpm.cpp; treat it as advisory metadata rather than an enforced constraint.
Packagegroups
A packagegroup is a named, versioned set of package names that are meant to be selected together. RADPx OS images should select packagegroups first and add explicit packages only when needed: packagegroups keep terminal, desktop, networking, and SDK selections reproducible while still letting the resolver report missing dependencies. Selecting a group adds all of its member package names to the resolve set.
Packagegroup Index (radpm-packagegroup-index)
radpm/dists/<suite>/main/packagegroups.json is optional (repositories without it still
load). Top-level fields mirror the package index — schema
("radpm-packagegroup-index"), schema_version, repository,
suite, component, and an index-level signing_key (observed) — plus:
packagegroups— array of group entries. Each entry either carries the full group inline, or points to a separate descriptor file viadescriptor(a path relative to the index) orurl. When adescriptor/urlis present the tool loads that file and reads the full group from it; the inlinename/version/provider/summaryfields in the index entry act as a preview.
Packagegroup Descriptor (radpm-packagegroup)
Each descriptor file (e.g. packagegroups/radpx-terminal-base.json) is parsed by
parseGroupDescriptor():
schema—"radpm-packagegroup";schema_version—1(present in file, not parsed).name— group name (required), e.g.radpx-terminal-base.version— group version (required), e.g."0.2.0-beta.1".provider— optional. Provider name; defaults to the repository provider.repository_url— optional. Provider repository URL; defaults to the repository root.summary— one-line human description.packages— array of member package names.docs— documentation reference (observed:"radpx-os.html#packagegroups").
Published experimental groups: radpx-terminal-base, radpx-desktop-base,
radpx-networking, and radpx-dev-sdk.
GPG Signing
RADpm artifacts are signed with the RadicalPackages archive key, fingerprint
F3731ADBB37AFA120A7D5EBD20B2754CF3894789. The public key is committed at
keys/radical-packages-archive-key.asc (ASCII-armored) and
keys/radical-packages-archive-key.gpg (dearmored); the private key is never committed.
Signatures are detached and ASCII-armored (.asc). Each signed package record carries a
signature URL alongside its archive — the archive URL with a .asc suffix — and
a signing_key fingerprint. The experimental package index also carries an index-level
signature (over packages.json) and signing_key, and each
packagegroup index carries an index-level signing_key.
Note on enforcement: the radpm tool records and passes through these signing fields but does
not itself invoke GPG. The integrity check it enforces on install is the sha256
of each downloaded archive. Signature verification with the archive key is therefore a separate,
operator-driven step against the published .asc files. (The same key also clear-signs and
detach-signs the parallel Debian/APT channels — InRelease and Release.gpg — via
scripts/stage_github_release_apt_repo.py.)
Resolve Output (radpm-lock)
radpm resolve/verify emit a lock object that radpm install consumes.
It is generated output rather than index schema, but documents how the fields above are used. Fields:
schema ("radpm-lock"), schema_version, repository,
suite, index, selected_packages,
selected_packagegroups, packages (each resolved package record plus a computed
archive_location), diagnostics, and ok. On a missing package or
unmet dependency the tool instead emits a radpm-error object and exits non-zero.
Example: A Real Package Record
Drawn verbatim from radpm/dists/experimental/main/packages.json (the
radpx-ncurses record), showing an architecture-specific, signed package with virtual
provides:
{
"name": "radpx-ncurses",
"version": "0.1.0-experimental",
"suite": "experimental",
"architecture": "radpx-x86_64",
"summary": "RADPx ncurses/tinfo shared runtime and development headers for x86_64 terminal applications.",
"dependencies": [
"radpx-core"
],
"provides": [
"libncurses",
"libncursesw",
"libtinfo",
"libradpxc",
"radpx-terminal-ui-dev"
],
"supported_kernel_versions": [
">=0.1.0 <0.3.0"
],
"archive": "https://github.com/Radical-Computer-Technologies/RadicalPackages/releases/download/radpx-os-0.1.4-beta.1/radpx-ncurses_0.1.0-experimental_radpx-x86_64.radpm",
"sha256": "853b76699f78622fbe7877e4685128e802a96cd7e371479addbe47ef013ed714",
"bytes": 607457,
"docs": "radpx-os.html",
"signature": "https://github.com/Radical-Computer-Technologies/RadicalPackages/releases/download/radpx-os-0.1.4-beta.1/radpx-ncurses_0.1.0-experimental_radpx-x86_64.radpm.asc",
"signing_key": "F3731ADBB37AFA120A7D5EBD20B2754CF3894789"
}
The enclosing index adds the object header and, in the experimental suite, index-level
signing_key and signature fields:
{
"schema": "radpm-package-index",
"schema_version": 1,
"repository": "RadicalPackages RADPx Package Repository",
"suite": "experimental",
"component": "main",
"packages": [ /* ...records... */ ],
"signing_key": "F3731ADBB37AFA120A7D5EBD20B2754CF3894789",
"signature": "https://github.com/Radical-Computer-Technologies/RadicalPackages/releases/download/radpx-os-0.1.4-beta.1/packages.json.asc"
}
Example: A Packagegroup Descriptor
From radpm/dists/experimental/main/packagegroups/radpx-terminal-base.json:
{
"schema": "radpm-packagegroup",
"schema_version": 1,
"name": "radpx-terminal-base",
"version": "0.2.0-beta.1",
"provider": "RadicalPackages",
"repository_url": "https://github.com/Radical-Computer-Technologies/RadicalPackages",
"summary": "Core RADPx terminal image package set with RADLib, ncurses, and vim-tiny.",
"packages": [
"radpx-core",
"radlib",
"radpx-ncurses",
"radpx-vim-tiny"
],
"docs": "radpx-os.html#packagegroups"
}