git mirror - github.com/owenewans/holy - branch master
clone: https://src.holypkg.eu/holy/

file llm.txt

holy.conf.5 source=holy version=development sha256=e4a579af5be8f10bddb18a78414b1aaaacf3a8b6ed5198cb5d19ccede91b7706
HOLY.CONF(5)			  File Formats			    HOLY.CONF(5)

NAME
     holy.conf - Holy source configuration format

STATUS
     This  page describes the syntax checker and source identity registration. A
     registered holy-http source can mirror one explicitly pinned or  explicitly
     accepted unsigned current index through holypkg sync. A registered holy-git
     source uses a pinned commit and index digest. A source with an Ed25519 pub-
     lic  key  verifies	 signed generations. General multi-source resolution and
     full disk installation are not implemented; the restricted local  data/sta-
     tic-ELF transaction uses separate commands.

SYNOPSIS
     holypkg config check FILE

DESCRIPTION
     Input  must  be  UTF-8. Each record contains a key and whitespace-separated
     arguments. Double quotes retain spaces. A hash sign at the start of a token
     begins a comment outside quotes. Escapes are backslash-quote,  double-back-
     slash,  backslash-n,  backslash-t,	 backslash-r and backslash-x followed by
     two hexadecimal digits. NUL is rejected.  The parser does not run shell ex-
     pansion.

     Sections are [general], [resolver], [source NAME], [rule  NAME],  [install]
     and  [disk]. [install-plan], [disk-plan] and [disk-finalize-plan] are emit-
     ted by holyinstall and are not user config	 sections.   Include  takes  one
     path relative to the containing file. Repeated scalar keys within a section
     are  errors with both source locations. The source repo and resolver prefer
     and install artifact keys are lists and can repeat. Recursive includes  are
     rejected.	The checker validates lexical and structural syntax; it does not
     yet  validate  rule  references. It checks that source parents exist and do
     not form cycles.  It rejects userinfo in URL  authorities	without	 echoing
     credentials  in  diagnostics.  It validates key names, argument counts, and
     the scripts, trust, ask-sources and prefer values. The alias local	 is  re-
     served and cannot name a source.

     Each  populated  source section requires type and at least one url or repo.
     Repository names within one source must be distinct.  Each	 populated  rule
     requires  consumer,  require and provider. Empty values are rejected. These
     checks do not prove that a repository is reachable or its packages can  re-
     solve.

     For  holy-http  and holy-git, "public-key PATH" names an Ed25519 PEM public
     key. The path is relative to the file containing that  entry.  source  plan
     reads  it	and  freezes the raw 32-byte public key in the reviewed registry
     plan; source apply does not reopen the PEM file.  "public-key-ed25519  HEX"
     supplies  those bytes as 64 lowercase hex digits. Only one form is allowed.
     trust require needs a key for either native source type. A	 configured  key
     requires  signed  catalogs	 for sync, binding and later source queries even
     when trust is warn. Private signing keys are not configuration inputs.

     [install] accepts one root directory and ordered artifact	SHA-256	 entries
     for  holyinstall's pre-mounted-root package transaction. The first artifact
     is the explicit package. The installer checks required fields, digest  syn-
     tax  and  duplicate  artifacts before planning. See holyinstall(8).  An ad-
     dressable accept-arch list can approve placement of selected artifacts with
     a different target architecture. The frozen plan retains each approval.  An
     accept-privileged list confirms the exact artifact hashes whose setuid exe-
     cutables have been reviewed. holyinstall records  these  decisions	 in  its
     frozen  plan  and	passes	them  to  holypkg.   The  list key "source ARTI-
     FACT_SHA256 SOURCE_ID" associates a selected local artifact with an  active
     registered	 origin.  The installed instance retains the source ID and alias
     snapshot; metadata inside the archive grants no source authority.

     [disk] accepts one image path and layout gpt-ext4. The  disk  plan	 accepts
     regular  image  files, not block devices. Its fixed plan schema forbids in-
     clude.  The installer's text menu can save [disk] alongside  [install]  and
     prepare  the  disk	 plan  independently  of  package selection. See holyin-
     stall(8).

EXAMPLE
     [general]
     arch x86_64
     scripts ask
     [source arch]
     type pacman
     repo core "https://mirror.example/arch/$repo/os/$arch"

FILES
     /etc/holy.conf is the proposed system path. The checker takes  an	explicit
     file.

SOURCE IDENTITIES
     The source plan command reads this syntax, including includes, and proposes
     a registry replacement. The source apply command consumes that frozen plan;
     it	 does  not  reread the configuration. See holypkg(8) for the command se-
     quence.

     The current source ID is SHA-256 of a canonical, sorted  representation  of
     type,  url	 and repo records. Alias, parent, family, priority, trust policy
     and public key are excluded. Renaming an alias preserves the  ID.	Changing
     an endpoint, backend type or repository name creates another ID and retains
     the  previous definition as inactive history.  Readding the same definition
     reactivates its existing ID. Equivalent URL spellings and mirrors	are  not
     automatically identified as one source.

     Registration  requires  endpoints with a scheme followed by :// and rejects
     URL userinfo, queries, fragments and  whitespace.	Plans  therefore  cannot
     carry  those credential forms. Two aliases with the same definition require
     a decision.  Registration neither contacts a repository  nor  verifies  its
     signatures.  Set  installation  can  bind local artifacts to registered IDs
     through explicit --source associations. The registry  stores  parent  as  a
     source-id,	 separate  from the endpoint-derived identity. Renaming a parent
     alias retains the relationship.  Parent preference applies when add discov-
     ers a missing native provider; it does not replace the child's URL with the
     parent's URL.

     Optional family NAME groups sources  for  dependency  preference.	Optional
     priority  SIGNED_INTEGER ranks candidates within the same preference group;
     a larger number wins. The default priority is zero. Family and priority are
     policy, not part of source identity. A changed policy is recorded by source
     apply.  holypkg source show ALIAS displays the policy after apply.

     A registered APK source uses type apk and one or more repo NAME HTTPS_BASE/
     entries. holypkg apk sync names the repo, obtains its  APKINDEX.tar.gz  and
     writes  a	source-id-bearing  catalog  and	 target-root binding. public-key
     points to an RSA PEM public key for APK sources; source  plan  freezes  its
     SHA-256  fingerprint.   trust  require  needs that key and a valid APKINDEX
     signature. The matching key file is supplied to  apk  sync	 and  apk  fetch
     through  --public-key.  Fetch verifies the bound APK package signature with
     the same registered key. See holypkg(8) for  the  digest  confirmation  and
     fetch sequence.

     A	registered  APT source uses type apt and one url HTTPS_BASE/. public-key
     points to a binary OpenPGP keyring; source plan freezes its SHA-256.  trust
     require  needs  that key. holypkg apt sync-source requires the same keyring
     and records the stable source-id in its signed catalog and	 database  bind-
     ing.  Queries  and	 fetches can select it with source, suite, component and
     index architecture; they recheck the current registry. The keyring	 is  se-
     lected  by	 the  user; adding a source does not import public keys from the
     network.  The --inrelease option selects a clearsigned  InRelease;	 without
     it sync-source uses Release and Release.gpg.

     A	registered  RPM-MD source uses type rpm-md and one url HTTPS_BASE/, with
     no repo entries. The base is the repository root that  serves  repodata/re-
     pomd.xml.	holypkg sync RPM_MD_SOURCE takes an explicit repomd --sha256 pin
     and records the source-id in the catalog it writes. No repository signature
     is checked, so trust require is not available for this backend.  Query, ca-
     pability lookup and fetch select the source by alias and recheck the regis-
     tered url and source-id against the stored catalog.

     A registered XBPS source uses type xbps and one url HTTPS_BASE/. public-key
     points to an RSA PEM public key; source plan freezes  the	SHA-256	 finger-
     print  of its public-key encoding. trust require needs that key. xbps sync-
     source checks the selected key against the registry and the index metadata.
     It also requires an explicit repodata  SHA-256  pin.  Source-aware	 queries
     check  the catalog's source-id, URL and recorded key fingerprint. Fetch re-
     quires the same key file and verifies the package	.sig2  signature.  sync-
     source  also  binds  the catalog's conversion digest under the target data-
     base; later queries can select that binding by source and	index  architec-
     ture.

Holy				 September 2026			    HOLY.CONF(5)
holygetiso.8 source=holy version=development sha256=ce2b437d781e75a9085de2dc946c063c161232d47a077ba02d4e3fdfa7fed88b
HOLYGETISO(8)		      System Administration		   HOLYGETISO(8)

NAME
     holygetiso - build and boot-test a Holy image from explicit inputs

SYNOPSIS
     holygetiso [--check] CONFIG
     holygetiso --export-inputs IMAGE_OUTPUT DIRECTORY

DESCRIPTION
     The current command drives the repository's bootstrap-image builder. Run it
     from  the	Holy  source  directory	 after make. It accepts local or pinned-
     source core inputs and pinned native source packages for additional  appli-
     cations.  It rejects unknown sections, keys, duplicate scalar keys, missing
     input paths and malformed quoting. It uses the holy.conf lexer;  configura-
     tion  text is not executed by a shell. A top-level "include PATH" reads an-
     other config relative to the containing file. Include cycles and  duplicate
     scalar keys across files fail.

     The  builder  packages the core inputs, asks holyinstall and holypkg to in-
     stall them into a separate root, generates	 the  documentation  bundle  and
     initramfs, creates an ISO, then runs the QEMU boot contract. The output di-
     rectory must not exist. A successful exit requires a boot-tested image; the
     build  log,  install preview, frozen plan, package hashes and VM report re-
     main there.  The command writes one expanded effective config with resolved
     input paths.  Its SHA-256 is included in build.record before the boot  plan
     is	 hashed.  The  builder	copies	those exact bytes into output/inputs/im-
     age.conf and  rejects  a  change  between	validation  and	 copying.   With
     --check,  the  command  validates	the  config and existing input paths and
     prints the effective config hash, target architecture, profile  and  output
     path without starting a build.

     --export-inputs  copies the inputs, normalized packages, sealed native mir-
     rors, build record and frozen plans from an existing build	 output	 into  a
     new  directory.   It  checks  the	input  lock and source/install/boot plan
     hashes before copying.  SHA256SUMS records each copied file and is	 checked
     before the command succeeds.  The bundle preserves the exact package inputs
     for inspection or a repeated experiment. host-tools.jsonl names each direct
     executable	 used  by the builder, its canonical path and SHA-256; the build
     record binds that file. The bundle does  not  include  the	 host  compiler,
     QEMU,  firmware,  their dependency closure or the Holy source checkout. The
     destination must not exist.

CONFIGURATION
     Paths are resolved relative to the config file. Existing input  paths  must
     resolve at startup. The output path names a new directory; the ISO is writ-
     ten as holy-ARCH.iso inside it. Supported sections and keys follow.

     [image]
	    Required: arch (i686 or x86_64), output, kernel-version, limine-dir,
	    static-holypkg,  static-holyinstall, static-cc, profile (static-core
	    or dual-libc), root-storage (ram, ext4  or	gpt-ext4).   Choose  one
	    kernel-image  local path or kernel-package ALIAS:PACKAGE from an ac-
	    tive pinned source. The source package must be  named  linux,  match
	    kernel-version and target architecture, use libc nolibc, and contain
	    boot/vmlinuz.  The builder preserves that .holy and source ID in the
	    install plan, and checks the  extracted  x86  kernel  header  before
	    building   the   image.    make  bootstrap-kernel  can  create  that
	    linux.holy from a selected local x86 kernel image  and  an	optional
	    modules  staging tree. Its result enters an image through an explic-
	    itly  configured  source   catalog.	   If	the   package	contains
	    usr/lib/modules/KERNEL_VERSION/kernel/drivers/net/dummy.ko	and  its
	    modules.dep entry, the builder packages a static module probe.  QEMU
	    requires  the  guest  to  load dummy and find it in /proc/modules on
	    each boot.	Without that module the report marks  kernel-module-load
	    untested.  Optional: glibc-cc, musl-cc, libc-boot-state, network-re-
	    covery,  install-test and install-firmware. Their supported combina-
	    tions are documented in holy-image(7).  boot-test  accepts	required
	    (default) or build-only. The dual-libc profile requires musl-cc.

     [packages]
	    Required:  busybox,	 dinit and mdevd. The dual-libc profile also re-
	    quires glibc and musl. An installer test requires doas and	storage-
	    tools. Each value is a local .holy path or a pinned source reference
	    where  supported.  The builder records original and normalized arti-
	    fact hashes separately. Repeated "add PATH"	 entries  install  addi-
	    tional local .holy packages in the same frozen set plan. Their orig-
	    inal  archives  remain in output/inputs and the build record identi-
	    fies each hash.  An "add ALIAS:PACKAGE" entry fetches a named  pack-
	    age	 from  a pinned native source. The builder resolves requirements
	    against all configured sealed catalogs in  a  temporary  root,  then
	    copies selected .holy artifacts into inputs and binds each source ID
	    in	holyinstall's  frozen set plan. A unique exact provider can come
	    from another source. Other explicit "add ALIAS:PACKAGE" entries  be-
	    come  candidates for the current package; unresolved ambiguity stops
	    the build. The busybox, dinit, mdevd, glibc and musl  fields  accept
	    local  artifacts  or ALIAS:PACKAGE from a pinned source. The builder
	    records the source ID and original digest, then normalizes each core
	    artifact into a new unsigned Holy package. On an x86_64 builder tar-
	    geting i686, the resolver's x86 placement decision is  recorded  for
	    each  selected  x86	 artifact. This does not claim that the host can
	    execute the i686 image. Doas and storage-tools fields require  local
	    artifacts.	 Added	packages  must	target the image architecture or
	    noarch; x86 packages are also accepted in an x86_64 image. Duplicate
	    package names fail	before	plan  generation.  The	package	 manager
	    checks payload ownership and dependencies.

     make  source-ready-core  accepts  OUTPUT,	SOURCE_ALIAS, SOURCE_URL and the
     five *_PACKAGE input paths.  It copies  the  bootstrap  archives,	rebuilds
     their  manifests  with root ownership inside a user namespace, and writes a
     sealed unsigned native repository plus core-source.conf for inclusion in an
     image config. build.record links each new artifact digest to  its	original
     digest.  SOURCE_URL  is  provenance  for this local repository; the command
     does not publish files at that URL. This step requires user namespaces  and
     does not sign the resulting artifacts.

     [resolver]
	    Optional  "answers	PATH"  selects a holy-answers-1 file with source
	    decisions keyed by consumer artifact hash and requirement  ID.  "an-
	    swers-sha256  DIGEST" is required with it. holygetiso checks the di-
	    gest during config validation, then the builder copies the	file  to
	    output/inputs/resolver-answers  and	 checks	 the digest again before
	    using it. The build record and  exported  input  lock  include  that
	    copy.  An  answer  naming a source that does not offer the exact re-
	    quirement fails in holypkg; a changed consumer hash cannot reuse  an
	    old answer. An unresolved choice stops the build with status 3.

     [source NAME]
	    Each  used	native source requires type holy-http or holy-git, "url"
	    and "index-sha256" with the exact lowercase digest of  the	selected
	    generation.	  holy-http uses an HTTPS directory URL ending in slash.
	    holy-git also requires "commit" with a full lowercase Git object ID.
	    The builder records the commit in build.record and	checks	it  when
	    fetching  or  importing a mirror.  "ca-file" names an optional local
	    CA file. "mirror PATH" selects an existing sealed  snapshot	 for  an
	    offline  build.  Its source ID, URL and index must match the config-
	    ured source and pin. The builder copies  and  revalidates  it  under
	    output/mirrors.  "embed-mirror  yes" also includes the entire sealed
	    catalog in the image root at  /var/cache/holypkg/image-mirrors/NAME.
	    The	 source	 binding  uses	that root-relative location so fetch can
	    find it after the image boots. The	default	 is  no:  only	selected
	    packages  enter the image cache, and the user syncs the source after
	    boot to obtain its current catalog.	 mirror and  ca-file  cannot  be
	    combined.	"trust	require"  with	"public-key  PATH"  verifies  an
	    Ed25519-signed catalog.  holygetiso resolves the PEM  path	relative
	    to	its containing config file and freezes the raw public key in the
	    effective config and source plan. Changing the key bytes changes the
	    effective config hash. A signed offline mirror must	 carry	a  valid
	    signature for that key. The key is checked again when a bound mirror
	    is	queried.   The	image config uses the holy.conf lexer but index-
	    sha256 is specific to holygetiso. The builder registers  all  listed
	    sources and keeps the verified mirrors in output/mirrors. Its record
	    binds  source  IDs	and index digests. An index digest is a pin, not
	    publisher signature evidence.

     [docs]
	    Exactly    one    "include	  installed-man-pages"	  and	 "output
	    /usr/share/holy/llm.txt"  are  required.  holypkg docs reads the in-
	    stalled root and generates this file from its selected man pages.

STATUS
     The command returns 0 after a boot-tested build, 2 for  invalid  config,  6
     for missing inputs or host requirements, and 1 for other failures. The out-
     put build.record says "result incomplete" when a build fails after the out-
     put  directory  is created. If QEMU is missing, or boot-test is build-only,
     the builder writes "result untested" after producing the image and	 returns
     6.	 A successful process exit alone does not certify hardware, a desktop or
     all packages named in the Holy specification.

LIMITS
     This  bootstrap  command supports holy-http and holy-git sources. For addi-
     tional packages it uses holypkg's native resolver in a temporary root  with
     every  pinned mirror bound. The resolver can select a unique exact provider
     from another source. Explicitly listed packages from other	 sources  become
     candidate	providers;  unresolved	ambiguity  stops  the build. The builder
     copies only selected artifacts and their source IDs into the final	 install
     plan.   Boot core packages may come from a pinned native source. Full pack-
     age policy and a portable export of build tools remain  open.  The	 command
     stays in-tree while the source checkout provides build tools and profiles.

SEE ALSO
     holy-image(7), holypkg(8), holyinstall(8), holy.conf(5)

Holy				 September 2026			   HOLYGETISO(8)
holy-image.7 source=holy version=development sha256=cb82d96f230ddf9a651274a721ddf2bfbf5737808ecb10aaa69c8a002d5843f9
HOLY-IMAGE(7)			 System Overview		   HOLY-IMAGE(7)

NAME
     holy-image - image build and libc recovery boot tests

BUILD
     make  bootstrap-kernel packages an existing x86 kernel image as linux.holy.
     KERNEL_IMAGE, KERNEL_VERSION, ARCH and OUTPUT select its inputs and output;
     MODULES_DIR optionally names a staging tree for that release.  The	 builder
     checks  the x86 boot header, matches every .ko to modules.dep, verifies the
     package and scans each module's architecture and vermagic. It  records  the
     input  and	 artifact  hashes. This target packages an existing kernel; QEMU
     boot acceptance belongs to holygetiso.

     make bootstrap-image builds a live ISO and runs its QEMU  boot  test.  ARCH
     defaults  to  x86_64.  ARCH=i686 supports BIOS optical ISOs with ROOT_STOR-
     AGE=ram or ext4 and an independently bootable BIOS GPT disk with ROOT_STOR-
     AGE=gpt-ext4.  IMAGE_BOOT_TEST=build-only produces the image without a QEMU
     run, records "result untested" and returns 6. If the selected  QEMU  binary
     is	 missing,  the builder takes the same path. Neither case counts as a re-
     lease boot gate.  The i686 ISO boots through El Torito; it is not a  hybrid
     USB  image.   The	i686 profile requires an i686 kernel and matching static
     BusyBox, dinit, mdevd, holypkg and C compiler inputs.  The	 builder  checks
     package  and  executable  architectures  before installation. The dual-libc
     profile also requires matching i686 glibc and musl runtime packages  and  C
     compilers.	  The  GPT profile has no i686 UEFI loader; its tested boot path
     is BIOS.  IMAGE_PROFILE defaults to dual-libc; static-core	 explicitly  se-
     lects  the	 earlier  profile  without dynamic libraries. LIBC_BOOT_STATE is
     present by default.  For dual-libc, glibc, musl or both remove  those  run-
     time  payloads  and their loader links before creating initramfs, while re-
     taining installed records and cached  LIBC_BOOT_STATE=remove-both	requires
     an	 ext4 or gpt-ext4 dual-libc root. The first guest boot runs both dynamic
     probes, then holypkg removes both runtime packages with an explicit broken-
     dependency decision and reboots. Static BusyBox, dinit and holypkg	 run  on
     the second boot, report broken providers, install the same two cached .holy
     artifacts through reviewed plans and repeat the probes. The QEMU report re-
     quires   both  boot  contracts  and  an  unchanged	 read-only  base  image.
     ROOT_STORAGE defaults to ram. ext4 selects a persistent recovery  test  for
     dual-libc	and  requires  mke2fs and qemu-img. The kernel must include ext4
     and virtio-blk, and the BusyBox package must include switch_root, sync  and
     reboot.   gpt-ext4 selects an independently bootable GPT disk with the same
     ext4 recovery contract.  It  additionally	requires  sfdisk,  mkfs.fat  and
     mtools;  xorriso  is  only required for ISO profiles.  NETWORK_RECOVERY de-
     faults to off. The explicit fixture value requires a  dual-libc  RAM  image
     with  LIBC_BOOT_STATE=both.  The  builder omits both libc archives from the
     guest cache, retains copies for a local HTTPS fixture, and packages a  gen-
     erated  test  CA. The guest assigns the fixture address with static BusyBox
     ip, downloads both archives with static holypkg and verifies their	 SHA-256
     digests before missing-only repair. The test CA key stays in the build out-
     put  and is not included in the image or documentation bundle.  The follow-
     ing make variables are required:

     STATIC_HOLYPKG
	    Previously built musl-static holypkg executable.

     STATIC_HOLYINSTALL
	    Previously built musl-static  holyinstall  executable.  The	 builder
	    checks its architecture and nolibc runtime, packages it with holyin-
	    stall(8),  and the guest calls its disk subcommand on the disposable
	    QEMU target and tests package plan/apply in a separate target root.

     STORAGE_TOOLS_PACKAGE
	    Native musl-static package with sfdisk,  mkfs.fat,	mke2fs	and  the
	    Limine  command,  required by INSTALL_TEST=1. make bootstrap-storage
	    builds it from pinned util-linux, dosfstools, e2fsprogs  and  Limine
	    inputs.

     DOAS_PACKAGE
	    Native  musl-static	 OpenDoas  package with a root-owned setuid exe-
	    cutable, required by INSTALL_TEST=1. The guest stages  it  from  the
	    live cache and installs it in the reviewed holyinstall set plan with
	    approval bound to the artifact SHA-256.

     STATIC_CC
	    Path to the musl C compiler driver for the early init helper.

     BUSYBOX_PACKAGE, DINIT_PACKAGE, MDEVD_PACKAGE
	    Native .holy outputs of the matching bootstrap targets.

     GLIBC_PACKAGE, MUSL_PACKAGE
	    For	 dual-libc, the native bootstrap libc packages with private lit-
	    eral loader paths. bootstrap-glibc and  bootstrap-musl  produce  the
	    tested input layouts.

     GLIBC_CC, MUSL_CC
	    Compilers  for the two dynamic C fixtures. GLIBC_CC defaults to gcc;
	    MUSL_CC must name a musl compiler. The image build checks their  ac-
	    tual  runtime requirements against the selected libc payloads before
	    installation.

     KERNEL_IMAGE, KERNEL_VERSION
	    Local Linux kernel image and its expected  uname  release.	The  se-
	    lected  kernel  must  include initramfs/gzip, devtmpfs, proc, sysfs,
	    tmpfs, devpts and serial console  support.	The  local  kernel-image
	    profile  includes  no kernel modules.  The initramfs excludes kernel
	    modules. A source kernel package may install modules in the	 rootfs;
	    the	 dummy.ko  fixture  is	loaded	during	the QEMU boot probe when
	    present with its matching modules.dep entry.

     LIMINE_DIR
	    Directory containing limine-bios.sys, limine-bios-cd.bin and limine-
	    uefi-cd.bin. x86_64 also requires BOOTX64.EFI. Use the matching host
	    limine tool.

     OUTPUT
	    New output directory. Existing directories are refused.

     Host tools include unshare with user namespaces,  a  C  toolchain,	 dracut,
     xorriso,  Limine,	GNU  file  tools,  gzip,  cpio, Python 3 and QEMU.  DRA-
     CUT_BASE selects dracut's helper directory; the default is	 /usr/lib64/dra-
     cut.  Compilation	and  installation run as mapped root in a user namespace
     owned by the ordinary caller. Host root invocation is refused.

INPUTS AND ROOT
     The builder snapshots the selected native packages, normalizes numeric own-
     ership to root and directory  modes  to  0755,  regenerates  manifests  and
     records  the  parent  hashes and normalization in origin. These are new un-
     signed local artifacts. The original archives remain in inputs/.	For  the
     older  BusyBox  bootstrap	package,  its  embedded-musl  license  moves  to
     usr/share/licenses/busybox/musl.COPYRIGHT, with  the  mapping  recorded  in
     origin.  The dynamic musl package owns its own license file.

     The static core binary, selected kernel, Limine data and Holy boot configu-
     ration  also become native packages. The holy-base metapackage requires the
     resulting eight packages, including holyinstall.  INSTALL_TEST=1  also  se-
     lects  the doas package and records its setuid approval. The dual-libc pro-
     file adds the two runtime packages and two C  probe  packages.  holyinstall
     asks  holypkg  to	resolve	 the  selected set, writes install.preview and a
     frozen install.plan, then applies that plan with one writer  lock	and  one
     generation	 change	 into  root/. The preview records selected providers and
     requirements; the plan records artifacts and architecture	approvals.   The
     builder  prepares the profile's directories first. It does not extract for-
     eign distro roots or modify the host package database.

     For ROOT_STORAGE=ext4, mke2fs copies that prepared root into a 512 MiB  raw
     root.ext4 without mounting it on the host. Limine passes holy.root=/dev/vda
     and  holy.rootfstype=ext4.	 holy-init mounts the disk, moves runtime mounts
     and executes BusyBox switch_root followed by dinit. The ISO still	provides
     kernel  and  initramfs; this is not yet an independently installed bootable
     disk.

     ROOT_STORAGE=gpt-ext4 creates a new 1 GiB	regular	 disk.raw.  The	 builder
     uses holyinstall disk plan/apply and includes the reviewed plan hash in the
     boot  plan.  The  GPT contains a 1 MiB BIOS Boot partition, a 256 MiB FAT32
     ESP and a 765 MiB ext4 root. It verifies the partition layout,  copies  the
     kernel,  initramfs	 and  Limine configuration to the ESP, reads those files
     back and compares their bytes. It	then  uses  holyinstall	 disk  finalize-
     plan/apply	 to bind the ESP, root and disk images by SHA-256 before copying
     their bytes into the partitions. The finalize  journal  records  the  write
     stages.  Limine BIOS stages use partition 1; on x86_64 the UEFI loader uses
     EFI/BOOT/BOOTX64.EFI. The kernel mounts /dev/vda3. Host filesystems are not
     mounted and physical disks are not accepted as output.

     The GPT profile passes holy.esp=/dev/vda2. holy-init mounts that FAT parti-
     tion at /boot before starting dinit, using	 nosuid,nodev,noexec  and  masks
     matching the kernel package's file and directory modes. The kernel must in-
     clude vfat, the default FAT codepage and NLS charset. The boot probe checks
     the  mount,  kernel/initramfs/config  presence  and a plan-bound write that
     survives reboot.  Installed package checking validates the	 mounted  kernel
     payload  against  its recorded manifest. This exposes the actual boot files
     to subsequent operations; coordinated kernel/initramfs update  transactions
     remain to be implemented.

     The profile installs merged-/usr links, a locked root account and the dinit
     services boot, console, mdevd, coldplug and holy-test. mdevd reports readi-
     ness  through a pipe before synchronous coldplug starts. The fixture checks
     that coldplug applied the /dev/null permission rule. This is device-manager
     coverage, not client libudev compatibility.

INITRAMFS AND ISO
     The private dracut module copies the installed root with  preserved  owner-
     ship and file contents. dracut includes only the Holy module, with no host-
     only configuration, host runtime dependencies, microcode or kernel modules.
     The  builder points dracut's sysroot at the installed root. It extracts the
     finished initramfs, compares payload bytes, modes and  symlinks  with  that
     root,  and	 checks	 each ELF with holypkg. Only dracut's module list, build
     parameters and generated loader caches may be additional files.  The  audit
     rejects  unexpected loader aliases. dracut uses ldconfig -X so package sym-
     links remain unchanged. The audit also rejects non-static ELF  outside  the
     five  declared  libc  and probe paths in dual-libc; static-core rejects all
     non-static ELF. The prior package-set scan validates the  libc/probe  graph
     and payload manifests. Omitted files are listed in the build record and re-
     main absent from the image until guest recovery.  holy-init mounts the live
     runtime  filesystems  and	executes  dinit.   Limine  loads  the kernel and
     initramfs from the ISO. The default entry selects the  guest  test	 service
     with  holy.test=1.	 Remove	 that argument in Limine's entry editor to reach
     the BusyBox console service.

     The  output  includes  packages/,	inputs/,  root/,  initramfs.img,   holy-
     ARCH.iso, build.log, build.record, root-check.record, a frozen plan and its
     boot-plan	SHA-256.  The record lists artifact hashes and the build result.
     Input retention permits repeating an experiment; bit-identical  ISO  repro-
     duction is not established.

INSTALLER VM FIXTURE
     INSTALL_TEST=1  selects an x86_64 static-core RAM ISO whose default service
     installs the selected base artifacts on a separate	 QEMU  guest  disk.  The
     runner  creates  a	 blank, read-only 1 GiB raw disk and attaches a writable
     qcow2 overlay to the guest. The live guest uses  holyinstall  to  partition
     that  disk,  create  FAT32	 and ext4 filesystems, and install Limine's BIOS
     stage. Its static storage tools come from STORAGE_TOOLS_PACKAGE, which  the
     builder  installs into the live image but excludes from the installed base.
     The guest mounts the target root, stages its local .holy archives,	 reviews
     and applies one holyinstall package plan containing doas and its setuid ap-
     proval. When the live image has configured sources, the guest registers the
     same  source  IDs	in  the target root, copies embedded pinned mirrors, and
     binds source-attributed artifacts in that plan. It verifies  the  installed
     source  records before declaring the package set committed. The source con-
     fig remains at /etc/holy.conf on the installed disk. It generates	the  in-
     stalled  man bundle, and copies kernel, initramfs and Limine files from the
     ISO to the ESP. The runner shuts down that guest after serial success mark-
     ers, then forks the installed overlay  for	 separate  BIOS	 and  UEFI  disk
     boots. Both guests check dinit, BusyBox, holypkg, package state, documenta-
     tion  and the mounted ESP. The install-test image contains a disposable lo-
     cal user and a static login probe. Each installed boot checks rejection  of
     an	 incorrect  password and an authenticated shell with UID 10001. The same
     PTY probe enters the password requested by doas and checks UID 0  from  the
     policy's selected BusyBox command. The fixture account and scoped doas.conf
     are  only	present	 when  INSTALL_TEST=1. The UEFI boot uses fresh writable
     firmware variables.

     The holy-install-vm-7 report records each QEMU command, observed and  miss-
     ing serial markers, serial hashes, ISO and disk hashes, the guest disk-plan
     hash,  base-image	integrity and checks reached by the guest. The i686 BIOS
     install-to-disk fixture passed under QEMU/TCG. Its report lists the account
     menu, PAM/NSS, network and i686  UEFI  as	untested.  INSTALL_FIRMWARE=bios
     runs  only	 BIOS and records UEFI as untested; the x86_64 default both mode
     requires UEFI_CODE and UEFI_VARS, which default to the local QEMU edk2  im-
     ages.  This  fixture verifies package installation and boot from a separate
     disk; it does not claim the whole interactive installer acceptance	 matrix.
     Run  an  existing fixture ISO with make check-install-vm ARCH=i686 ISO=FILE
     BOOT_PLAN=SHA256 for i686, or omit ARCH for x86_64. The i686  install  fix-
     ture  requires  a BusyBox package with chown, login, getty, su, passwd, ad-
     duser and addgroup applets.

QEMU
     make check-qemu ARCH=x86_64 ISO=FILE BOOT_PLAN=SHA256 runs the  test  sepa-
     rately.   IMAGE_PROFILE  defaults	to dual-libc. LIBC_BOOT_STATE must match
     the image's declared initial state. The runner requires  the  corresponding
     recovery  markers;	 a  static-only	 boot  cannot  pass  a	dual-libc  test.
     ARCH=i686 chooses qemu-system-i386 and requires an i686 guest  image.   The
     builder  reads  the  x86  kernel  boot header and rejects a kernel with the
     other target architecture before it creates an image.   REPORT_DIR	 chooses
     an existing report parent directory, defaulting to the system temporary di-
     rectory.  QEMU_TIMEOUT  bounds  each boot in seconds (1..600, default 120).
     QEMU_PROBE_TIMEOUT	 bounds	 each  guest  stage   (1..600,	 defaulting   to
     QEMU_TIMEOUT).  The guest emits stage-start markers; a repeated marker does
     not renew its deadline. The runner tracks repeated stages within each boot;
     the report names the boot and stage that ran or timed out.	 QEMU_ACCEL=auto
     selects usable KVM or TCG; kvm and tcg force the accelerator, with unavail-
     able KVM returning 6.

     FIRMWARE=bios  is	the  default.  FIRMWARE=uefi  requires	 UEFI_CODE   and
     UEFI_VARS.	  The  runner  copies both firmware inputs and gives the guest a
     new writable VARS file. It copies and hashes the ISO before starting  QEMU.
     Networking	 is  disabled by default, and no host writable disks or directo-
     ries are attached.	 For NETWORK_RECOVERY=fixture, the runner creates a pri-
     vate network namespace, raises its loopback, serves the  two  frozen  arti-
     facts  over HTTPS and connects QEMU user networking only to that namespace.
     Its host has no external route.  The guest uses 10.0.2.15/24, resolves fix-
     ture.holy.test through the fixture DNS server and fetches both archives  by
     that  HTTPS  name.	 The  report  records  DNS  queries, the CA and artifact
     hashes, HTTP requests and recovery markers.  This fixture does not	 test  a
     public CA bundle or external network access.

     ROOT_DISK supplies a self-contained regular raw or qcow2 disk image for the
     persistent dual-libc test. An external qcow2 backing chain is rejected. The
     runner  copies  the  input to a read-only base, creates a qcow2 overlay and
     attaches only that overlay through virtio-blk. It verifies the copied  base
     hash after QEMU exits and records the overlay hash. QEMU_KEEP=1 retains the
     overlay  and copied inputs for inspection. The default removes those tempo-
     rary files after writing the report and serial log. Copying a live input is
     marked unverified for consistency; the caller must provide a stopped  image
     or	 stable	 snapshot  for	a precise trial. ROOT_IMAGE alone remains an op-
     tional report input and does not attach a disk.

     The guest verifies that / is  ext4,  completes  recovery  and  its	 package
     probes,  records  the  plan  ID under /var/lib/holy-boot-test/reboot, calls
     static sync and requests reboot. On the second boot it requires  that  wit-
     ness and intact restored libc; it repeats PID 1, shell, device, dynamic/IPC
     and  package  probes  without  another  libc  repair. The runner keeps each
     boot's markers separate, rejects repeated or out-of-order boot numbers  and
     requires  both complete contracts. Each boot has its own QEMU_TIMEOUT dead-
     line. RAM tests still use one boot and QEMU's no-reboot mode.

     Guest markers must confirm the expected plan and architecture, dinit as PID
     1 by /proc/1/exe, a BusyBox shell probe, mdevd/coldplug and a complete  lo-
     cal  two-package  dependency-set install/check/remove, including refusal to
     remove the referenced provider first. The guest checks  the  critical  exe-
     cutables' static ELF classification. For static-core it also checks absence
     of	 the  four  expected  dynamic loaders. For dual-libc it verifies the de-
     clared initial presence/absence of	 the  runtime  files,  diagnoses  broken
     providers,	 reads	the  local LZ4 archives and executes missing-only repair
     inside the guest. It runs allocation, thread and  clock  probes  with  each
     libc,  checks  both standard loader links and exchanges data through a pipe
     in both directions between the two ABIs.  KERNEL_VERSION  additionally  re-
     quires  the  matching release marker. A failure marker overrides pass mark-
     ers.  The runner sends QMP quit after the probes or a boot	 timeout,  waits
     up to five seconds, then kills a process which did not exit. Process launch
     or exit status alone cannot pass a boot test.

     Each  run	retains	 serial.log,  QEMU output, a text report and report.json
     (holy-qemu-report-2). Reports include argv,  accelerator,	firmware,  input
     hashes,  elapsed  time, stage deadlines, exit reason and per-marker status.
     The report records whether temporary inputs and the  writable  overlay  re-
     main.   Persistent	 tests additionally record both boot results, the first-
     boot completion time, root storage type  and  whether  the	 read-only  base
     stayed  intact.   The  probe  list	 records  each	stage's elapsed time and
     pass/fail/unknown status.	Optional KERNEL_IMAGE, INITRAMFS and  ROOT_IMAGE
     inputs  add  their	 hashes.  They identify caller-supplied files, not guest
     measurements of running code.

   Retained recovery matrix
     make check-recovery-matrix REPORT=NEW_FILE REPORTS="REPORT_PATHS" validates
     eight retained QEMU report.json files: present, glibc, musl and  both  ini-
     tial  states, each under BIOS and UEFI. Each case must contain two complete
     ext4 boots. The validator checks  per-boot	 serial	 evidence  and	reported
     checks,  including	 PID  1	 identity after reboot. It rehashes the retained
     ISO, raw root, recovery overlay and UEFI code snapshots. BIOS and UEFI runs
     of each initial state must use the same plan, ISO and raw root. Missing  or
     duplicate cases, changed snapshots and incomplete second boots fail the ma-
     trix.

     The  command  creates  a  new holy-recovery-matrix-1 JSON report containing
     each input report and  serial  hash,  image  identities,  acceleration  and
     elapsed time.  The output must not exist. Run the guest tests before invok-
     ing  this command; the validator reads retained evidence and does not start
     new VMs. Local hashes bind the retained files, not	 an  authenticated  pub-
     lisher. Preserve each run directory alongside the summary for revalidation.

COVERAGE
     BOOT_MEDIA=disk  selects  standalone  disk	 boot in the QEMU runner and re-
     quires ROOT_DISK. ISO must be empty; the runner attaches  no  CD-ROM.  Each
     run  uses	its own qcow2 overlay and records boot_media, two boot contracts
     and the unchanged copied base. gpt-ext4 produces disk.raw, disk.plan, disk-
     layout.json and limine.conf instead of an ISO. BIOS and UEFI  remain  sepa-
     rate test runs.

     The  bootstrap  glibc  package  currently contains libc.so.6 and its loader
     with licenses, not the complete SDK, locale archive, NSS modules or  auxil-
     iary  glibc libraries. The reference image still needs the installer, ordi-
     nary networking and public CA packaging. The ext4 fixture uses an ISO  ker-
     nel; gpt-ext4 loads its kernel and initramfs from the disk's ESP. Both test
     recovery  followed	 by reboot on a persistent root overlay. The GPT builder
     is not the interactive installer. Kernel updates still require  integration
     with ESP contents and the generated initramfs.  Those gates remain separate
     from  this	 boot result. The glibc/musl/both damage fixtures retain package
     records; remove-both exercises package removal and reinstallation	after  a
     persistent	 reboot.   The	repository  documentation  bundle  contains Holy
     pages. The image builder uses holypkg docs after its package transaction to
     generate /usr/share/holy/llm.txt from the installed man sources,  including
     dinit.   This  generated  file is separate from package-owned source pages;
     its SHA-256 is recorded in the frozen image plan and /etc/holy/docs.sha256.
     The output directory retains llm.txt and docs.record with the coverage sum-
     mary. Packages without man pages and unsupported page encodings  appear  in
     that bundle.

     On	 each  boot, the guest verifies the shipped bundle's digest and regener-
     ates it with static holypkg after any libc recovery. It compares  the  com-
     plete  contents,  normalizing  only the final summary's database generation
     because package transactions between boots advance that counter. A documen-
     tation failure fails the boot contract. The bundle contains attributed roff
     sources rather than rendered upstream text. QEMU virtual devices do not es-
     tablish physical GPU support.

     make  check-image-docs  IMAGE_DIRECTORY=DIRECTORY	 tests	 an   ext4/dual-
     libc/both build's documentation failures. It copies root.ext4 into two dis-
     posable  disks,  changes  the  generated  bundle  in  one and the installed
     holypkg man source in the other, then boots each through the  original  ISO
     under  BIOS/TCG.  Both guests must stop the boot contract at the documenta-
     tion stage. The original root image's hash must remain unchanged. The  fix-
     ture requires debugfs and the QEMU tools; it never edits the original image
     or mounts a host disk.

HARDWARE
     make  check-hardware  runs outside QEMU against a physical NVIDIA GPU using
     Nouveau and Mesa NVK. It checks the kernel driver and DRM render node,  se-
     lects  the	 NVK Vulkan device, presents 30 frames with vkcube, and measures
     OpenGL frames with glxgears. glxinfo must report an accelerated NVIDIA ren-
     derer. lspci, vulkaninfo, vkcube, glxinfo,	 glxgears,  timeout,  a	 display
     session and a writable render node are required.

     The default HARDWARE_SCOPE=holy requires a valid installed Holy database on
     the  running  system. Missing inputs return 6. REPORT defaults to out/hard-
     ware.json; the holy-hardware-1 JSON records probe commands, output, elapsed
     times, driver selection and frame	counts.	 A  failure  returns  1.   HARD-
     WARE_SCOPE=host  permits  a  diagnostic  probe  on another distribution and
     marks release_gate=false. A host result cannot certify Holy's  packages  or
     boot  image.  The frame probes establish presentation and an FPS count, not
     pixel-correct rendering or broader game compatibility.

SOURCES
     Limine  configuration  and	 ISO   layout:	 https://github.com/limine-boot-
     loader/limine/blob/v12.x/CONFIG.md	   and	 https://github.com/limine-boot-
     loader/limine/blob/v12.x/USAGE.md.	      dracut	  module      interface:
     https://github.com/dracut-ng/dracut-ng/blob/main/man/dracut.modules.7.adoc.
     QEMU  block device and backing-file options: https://www.qemu.org/docs/mas-
     ter/system/invocation.html.

SEE ALSO
     holy-init(8), holypkg(8)

Holy				 September 2026			   HOLY-IMAGE(7)
holy-init.8 source=holy version=development sha256=d3a6d3e0068c68f2c3a615b25f6cd5479a5ce1cc25827a9ebc764f2156e7d268
HOLY-INIT(8)		      System Administration		    HOLY-INIT(8)

NAME
     holy-init - prepare live runtime mounts and execute dinit

DESCRIPTION
     holy-init runs as PID 1 from a live initramfs. It mounts devtmpfs, attaches
     standard  descriptors to /dev/console, makes mount propagation private, and
     mounts proc, sysfs, tmpfs at /run and /tmp, and a new devpts instance.   It
     then executes /sbin/init, supplied as a link to dinit by the image profile.
     dinit  retains  PID 1. Mount and exec failures print a diagnostic and leave
     the process waiting for intervention; they do not report a successful boot.

     The boot profile uses /etc/dinit.d,  a  control  socket  at  /run/dinitctl,
     PATH=/usr/bin  and	 HOME=/root.  The  default  service  is	 boot.	An exact
     holy.test=1 kernel argument selects holy-test instead. Other  kernel  words
     are not interpreted as shell code.

     Calling  holy-init outside PID 1 returns 2 before mounting anything.  With-
     out holy.root it boots an in-memory live  root.  holy.root=/dev/DEVICE  se-
     lects  an	ext4 disk root; holy.rootfstype=ext4 is the supported filesystem
     selector. Empty or repeated holy.root  arguments  are  errors.  The  helper
     waits  up	to 30 seconds for the block device, mounts it at /newroot, veri-
     fies that the target init is executable and moves /dev, /proc,  /sys,  /run
     and  /tmp	there.	 It  then executes the static BusyBox switch_root applet
     with the dinit argv.  The process retains PID 1. Failure does not fall back
     to the RAM root.  Device discovery must be available through built-in  ker-
     nel drivers/devtmpfs.

     holy.esp=/dev/DEVICE  mounts a FAT ESP at /boot within the disk root before
     switch_root. It requires holy.root and a real block device;  empty	 or  re-
     peated  ESP  arguments  fail. The boot directory must be a directory, not a
     symlink.  The mount uses nosuid,nodev,noexec,  root  ownership,  file  mode
     0644 and directory mode 0755. The kernel must provide vfat and its required
     NLS  tables.  Failure leaves the boot incomplete rather than using a hidden
     rootfs copy.  Encrypted roots, UUID discovery, modules and	 other	filesys-
     tems are not yet implemented by this helper.

BUILD
     make  builds holy-init with the configured C99 compiler. make static builds
     it with the selected musl toolchain. The image builder also compiles it us-
     ing its explicit STATIC_CC input and verifies static ELF classification.

SEE ALSO
     holy-image(7), holypkg(8)

Holy				 September 2026			    HOLY-INIT(8)
holyinstall.8 source=holy version=development sha256=4688af7110d201daacae2a11b7e11c935d8eb000991eed9feb9913f0583b0ddf
HOLYINSTALL(8)		     System Manager's Manual		  HOLYINSTALL(8)

NAME
     holyinstall  -  prepare a disk or image and install packages to an existing
     Holy root

SYNOPSIS
     holyinstall --menu --config FILE --plan NEW_FILE [--holypkg FILE]
     holyinstall --config FILE --plan NEW_FILE [--holypkg FILE]
     holyinstall --apply PLAN [--holypkg FILE]
     holyinstall disk plan --config FILE --output NEW_PLAN
     holyinstall disk show --plan PLAN
     holyinstall disk apply --plan PLAN --confirm IMAGE_OR_DEVICE
     holyinstall disk finalize-plan --disk-plan	 PLAN  --esp  FILE  --root-image
     FILE --output NEW_PLAN
     holyinstall disk finalize-apply --plan PLAN --confirm IMAGE

DESCRIPTION
     holyinstall  supports a disk-image preparation stage and a separate package
     transaction for a pre-mounted root. Disk preparation does not mount the im-
     age or connect it to the package transaction.  The target must already con-
     tain an initialized holypkg database and cached are dependency  candidates.
     It invokes holypkg with argv, without a shell.  The default manager path is
     /usr/bin/holypkg.	It must be Holy's C package manager; the separate Slack-
     ware converter named holypkg does not implement this transaction interface.
     The  caller  must	already have permission to modify the target; this stage
     does not invoke doas.

     --menu opens a numbered text menu on a terminal. It shows the current root,
     package count and selected disk image. It edits the root  and  disk  image,
     and  opens	 a package list with add, delete and back actions. Preview calls
     the same holypkg planner as config-driven mode. Save  writes  a  normalized
     config atomically.	 Prepare plan writes the same frozen plan as noninterac-
     tive  mode.  Install  shows the root, set hash and artifact count, then re-
     quires the literal answer yes.  Abort and end-of-input leave the target un-
     changed before apply. Without a TTY, --menu exits with status 3.  The  text
     menu  accepts  [install]  and  [disk];  it	 rejects other sections to avoid
     silently discarding them on save.

     The menu saves [disk] in the same config as [install]. It creates	a  sepa-
     rate disk plan at PACKAGE_PLAN.disk, shows the exact image path, GPT geome-
     try  and  the  plan's first and last MiB hashes. It asks for that full path
     before formatting. Disk selection may be left unset while working on  pack-
     ages. Disk planning and package installation remain separate steps; select-
     ing an image does not mount it as the package target.

     Planning  runs  holypkg  db  plan-set  read-only.	It  prints  the selected
     providers and requirements, then creates a new plan file  with  mode  0600.
     The  plan	binds the SHA-256 of the effective parsed config, canonical tar-
     get-root path, target directory device/inode, ordered  artifact  identities
     and holypkg set hash. An existing plan file is not overwritten. Apply reads
     only  the	fixed  plan  schema; it never reopens the user config or its in-
     cludes under elevated privileges. It  verifies  the  target  directory  and
     passes  the  recorded  set hash to holypkg db apply-set.  holypkg rejects a
     changed database generation, artifact, ownership or dependency result.  Ap-
     ply retains holypkg's incomplete transaction journal if mutation fails.

     The config uses the holy.conf lexer, including relative includes and quoted
     paths. A minimal config is:

	    [install]
	    root "/mnt/holy"
	    artifact SHA256_OF_ROOT_PACKAGE
	    artifact SHA256_OF_DEPENDENCY_CANDIDATE
	    accept-arch SHA256_OF_CONFIRMED_CROSS_ARCH_PACKAGE
	    accept-privileged SHA256_OF_REVIEWED_SETUID_PACKAGE
	    source SHA256_OF_SELECTED_PACKAGE REGISTERED_SOURCE_ID

     SHA256 values must be lowercase. The root path cannot be /. Config comments
     do	 not change the effective-config hash. Changes to parsed values or arti-
     fact order require a new plan. The plan must be reviewed before apply;  the
     config is no longer consulted at that step.

     accept-arch  names	 an artifact already selected in [install]. It preserves
     an explicit architecture-placement decision in plan format 2.  Preview  and
     apply  pass the same approval to holypkg. It permits placement; it does not
     claim the target executable can run on the host. The text menu toggles this
     decision in the package list and shows accepted artifacts before  installa-
     tion.

     accept-privileged	names  a  selected  artifact whose setuid executable and
     full payload the caller has reviewed.  Plan  format  3  records  its  exact
     SHA-256  and  apply  passes  the  same decision to holypkg. Without the ap-
     proval, planning returns decision-required. The package menu  toggles  this
     decision separately from architecture placement. A changed artifact needs a
     new approval and plan.

     source  associates	 one  selected artifact with an active registered source
     ID.  The target database must already contain that registration. Plan  for-
     mat 4 freezes each artifact-to-source binding and passes it to holypkg dur-
     ing  both	planning  and  apply.  Unknown	sources,  duplicate bindings and
     changed source registries fail before package mutation. The text  menu  can
     set or clear a source ID and keeps the binding when saving config.

DISK PREPARATION
     The  disk command accepts a regular file or a block disk of at least 1 GiB.
     The supported layout is GPT with a 1 MiB BIOS boot	 partition,  a	256  MiB
     FAT32  ESP and an ext4 root partition. Image mode uses sfdisk, mkfs.fat and
     mke2fs, and requires losetup to confirm that the image is not attached to a
     loop device.  A minimal image config is:

	    [disk]
	    image "/tmp/holy.img"
	    layout gpt-ext4

     Create the image before  planning,	 for  example  with  truncate.	Planning
     prints  the  exact	 image	path,  device/inode identity, size and partition
     geometry. It hashes the first and last MiB and writes a new mode-0600 plan.
     Apply requires --confirm to equal the canonical image path in that plan. It
     checks the identity and both hashes again, then  records  prepared,  parti-
     tioning  and  formatting stages in PLAN.journal. An existing journal blocks
     another apply.  The show command prints the saved geometry without changing
     the image.	 After an interrupted stage, inspect the image and  journal  be-
     fore starting a new plan. The command does not silently repeat a format op-
     eration.

     For  a  block disk, use device instead of image in [disk]. Planning records
     the disk node, block-device  number,  size,  serial,  first  and  last  MiB
     hashes,  and  SHA-256  of	the  four  static  tools  used by apply: sfdisk,
     mkfs.fat, mke2fs and Limine. Apply requires the exact device path as --con-
     firm and rechecks those inputs before mutation. It holds an exclusive  disk
     descriptor,  writes the GPT, asks the kernel to reread the partition table,
     checks the partition geometry, formats FAT32 and  ext4,  and  installs  the
     Limine  BIOS stage. The journal records each stage. This operation destroys
     existing partitions and filesystems. It does not mount the new root or  in-
     stall packages.

     Disk  preparation	destroys  existing image contents. It does not mount the
     partitions or generate an initramfs. The finalize-plan command  requires  a
     committed	disk  preparation  journal, a valid GPT, an exact-size ESP image
     and an exact-size ext4 root image. It records the full SHA-256, device, in-
     ode and size of the disk, both input images and /usr/bin/limine  in  a  new
     mode-0600	plan.  Review  that  plan before applying it. Finalize-apply re-
     quires the exact disk path as --confirm  and  rechecks  all  inputs  before
     changing the disk. It copies the two images into their partitions, verifies
     the written bytes, installs the Limine BIOS stage and verifies GPT. The ad-
     jacent  journal records each stage. A changed input requires a new plan; an
     existing finalize journal requires inspection before recovery. The	 command
     does  not configure UEFI, mount the partitions or prove the image can boot.
     Boot and account menus and the full interactive install  acceptance  matrix
     remain pending.

     The  optional  install VM fixture described in holy-image(7) gives the live
     guest a blank disk. holyinstall creates the GPT  and  filesystems	and  in-
     stalls  the  Limine  BIOS stage inside that guest before applying a package
     plan to its root. The runner then boots the installed disk through BIOS and
     UEFI.

EXIT STATUS
     0 means the requested step completed. 1 means an operational error. 2 means
     invalid arguments, config or plan. Disk apply returns 3 for a changed image
     or missing confirmation, 5 for an existing journal or failed mutation,  and
     6	for  a	missing	 image, tool or available capability. holypkg statuses 3
     through 6 propagate from the package transaction.

SEE ALSO
     holypkg(8), holy.conf(5), holy-image(7)

								  HOLYINSTALL(8)
holy-package.5 source=holy version=development sha256=c1e0877db91580d7382074adbb37c3c6bc6ea0b94f647763f08d6937bdba2700
HOLY-PACKAGE(5)			  File Formats			 HOLY-PACKAGE(5)

NAME
     holy-package - prototype native archive and payload manifest

DESCRIPTION
     A	.holy  archive	is  a  POSIX tar/PAX stream compressed as a standard LZ4
     frame.  HOLY/meta contains one key and one value  per  line.  The	required
     fields  are  format  (holy-package-1), name, version, release, os, arch and
     libc. An unknown requires-feature field fails inspection.	Optional  x-ver-
     sion-family  records  the version comparator family and is a scalar: dupli-
     cates fail inspection.  The current resolver supports  constrained	 package
     requirements for pacman, Debian and explicitly tagged Holy native versions.
     It	 compares  versions within the consumer's declared family; unknown fami-
     lies remain inspectable but cannot acquire guessed version semantics.   Un-
     versioned file requirements match exact nondirectory paths in verified pay-
     load manifests. Declared file claims alone do not establish file ownership.
     Unversioned  command requirements match executable payloads in the standard
     bin directories. Links must resolve to an executable in the same  artifact;
     declared command claims alone do not prove one exists.  Native packages opt
     in with x-version-family holy. Their version and release use decimal compo-
     nents  separated  by dots, with an optional lowercase prerelease suffix in-
     troduced by hyphen or tilde, such as 7.3-rc4. Invalid Holy	 native	 version
     or release fields fail inspection. Native comparison treats absent trailing
     numeric  components  as zero, compares numbers without fixed-width overflow
     and places prereleases before final versions.   Pacman  imports  store  the
     complete  foreign epoch:version-release in version, and use release for the
     native artifact revision.

     The inspector accepts os=linux or windows, arch=x86, x86_64 or noarch,  and
     libc=glibc,  musl	or nolibc. noarch requires nolibc. These checks validate
     declared metadata values; they do not scan ELF files to prove ABI or  prove
     that a purported noarch payload has no machine code.

     The  separate  holypkg  scan command examines regular ELF payload files and
     each hardlink path, and rejects known arch/libc tag mismatches.  The  basic
     info and verify commands do not perform this ABI check.

     The scanner accepts ET_EXEC without PT_INTERP and PT_DYNAMIC as nolibc, and
     ET_DYN  requiring	libc.so.6  as  glibc evidence, including its basename in
     literal DT_NEEDED paths. Architecture-specific musl loader	 or  libc  names
     and  the native libc.musl-x86_64.so.1 / libc.musl-i386.so.1 SONAMEs provide
     musl classification evidence.  The	 native	 libc.so.6  and	 matching  glibc
     loader  SONAMEs  classify those glibc runtime files. A generic libc.so name
     does not.	Foreign import writes a SONAME capability only after  reading  a
     classified	 ET_DYN	 payload  file and records that file as evidence. It re-
     jects ELF files whose runtime remains unknown. A plugin without  such  evi-
     dence needs classification and review before a package can pass scan.

     The  scanner accepts an ET_REL kernel module only under usr/lib/modules/RE-
     LEASE/kernel/ with a .ko suffix, matching package architecture, libc=nolibc
     and a .modinfo vermagic release matching its path.	 It does not treat  mod-
     ule symbols as userspace providers. Other ET_REL objects remain unknown for
     ABI classification.

     The  archive  contains  one  regular file at each of HOLY/meta, HOLY/files,
     HOLY/deps, HOLY/provides, HOLY/hooks, HOLY/origin and  HOLY/transform.  The
     inspector	checks	their presence and type. Empty metadata placeholders can
     pass this structural check; it does not  validate	dependency,  capability,
     hook  or  origin  content.	 The separate requirements and provides commands
     parse supported subsets of HOLY/deps and HOLY/provides.

     The prototype verifier reads HOLY/files. For each regular payload file  un-
     der DATA/, one manifest line contains twelve whitespace-separated tokens:
     file PATH MODE OWNER GROUP UID GID SIZE SHA256 FLAGS XATTRS HARDLINK-GROUP
     MODE  is  octal;  UID,  GID and SIZE are decimal. PATH is relative to DATA.
     SHA256 has 64 hexadecimal digits. FLAGS accepts none,  config,  mutable  or
     config,mutable  for  regular  files. The verifier rejects flags on directo-
     ries, symlinks and hardlinks. Installed checks still compare mutable  files
     with  their  manifest;  update policy for their local changes is not imple-
     mented. XATTRS=-.	Independent files use HARDLINK-GROUP=-. A  symlink  uses
     one  additional  TARGET  token, SIZE=0 and SHA256=-. A hardlinked file uses
     TYPE=hardlink, a group identifier in HARDLINK-GROUP and  one  extra  TARGET
     token  naming  a  regular	file  in DATA.	The target file carries the same
     group identifier. SIZE and SHA256 describe the target content. The verifier
     rejects chained hardlinks and checks mode, UID and GID against the	 target.
     A	directory  uses	 the same twelve tokens as a file, with TYPE=dir, SIZE=0
     and SHA256=-. The verifier rejects symlink targets that escape the root  by
     lexical  traversal.  The text lexer follows holy.conf(5), so quotes and es-
     capes can preserve spaces in paths. Every archived	 directory  except  DATA
     itself  needs  a  manifest	 record.  The  verifier does not support special
     files, ACLs or extended attributes. The verifier rejects DATA entries  that
     carry archive xattrs or ACLs, even if HOLY/files says XATTRS=-. The planned
     full format includes those attributes.

     The narrow database apply command installs approved data, native static ELF
     files  and	 relative symlinks into existing or explicitly declared safe di-
     rectories. Symlinks require mode 0777 and the caller's  numeric  ownership.
     The transaction records their targets, checks them without following links,
     and  removes only intact owned entries. Direct hardlinks share the verified
     regular target's inode; one regular anchor belongs to each named group. In-
     stallation defers hardlinks until regular	payload	 files	exist,	indepen-
     dently of archive order. Absolute symlink installation remains unsupported.
     Cached  updates  preserve	hardlink groups across content and mode changes,
     member additions/removals, anchor moves and group splits/merges.  The  file
     plan  names  a reserved staging link for each new group; recovery validates
     both content and inode relationships.  The pack command writes and verifies
     this archive format from a prepared tree  of  regular  files,  directories,
     symlinks  and hardlinks. It selects a deterministic regular anchor for each
     inode group; manifest generate uses the same selection.  The verifier  does
     not  verify dependencies, signatures, symbolic owner names or the installed
     filesystem. A full format implementation must verify file ownership, links,
     xattrs, hooks, origin and transaction semantics before accepting  an  arti-
     fact for installation.

FOREIGN IMPORT RECORDS
     The  pacman and Debian importers preserve original package metadata beneath
     HOLY/foreign/pacman and HOLY/foreign/deb. HOLY/origin binds  these	 records
     to	 the  exact  original archive hash and retains original field values and
     line numbers. The source-name field is provenance, not authority to  assign
     a trusted installed source-id.

     A	requirement  of kind foreign preserves an unsupported source expression.
     The current solver reports unsupported semantics instead of  dropping  that
     requirement.   Foreign  hooks may be skipped by an explicit artifact-scoped
     --skip-hooks decision during set installation. The installed  package  then
     carries  hooks-state  with the hash of HOLY/hooks and reports installed-un-
     configured in check. Native postinstall records can be  reviewed  and  exe-
     cuted  through db configure-plan and db configure-apply. A completed hooks-
     state retains the same hash. Foreign script execution, preinstall,	 editing
     and service consent remain unimplemented.	For a reviewed update preserving
     a	modified  config,  the	installed  instance  keeps  the	 exact	archived
     HOLY/files as package-files. Its files record describes the preserved  pub-
     lic file and the new PATH.holy-new. config-state binds the source artifact,
     raw  manifest hash, installed manifest hash and transaction plan hash.  The
     archive  digest  and  local  installed  manifest  digest  remain  distinct.
     HOLY/transform  records  changes already applied to the normalized payload;
     installation never executes that record. Archive verification does not  au-
     thorize hook execution.

     The  AppImage converter records family appimage with the converter holy-ap-
     pimage-1, the original image hash, the entry  point  and  mode  extract  in
     HOLY/origin.   Its	  payload   keeps   the	 whole	extracted  AppDir  under
     /usr/lib/holy/private/NAME/appdir/, a  link  to  it  at  /usr/lib/holy/pri-
     vate/NAME/usr/bin/NAME.appimage  and a generated launcher at /usr/bin/NAME;
     the launcher is a script, so the package names an	interpreter  requirement
     like  any	other  script.	HOLY/transform	records	 the private layout, the
     launcher, the rewritten desktop entry, the path  view  a  link  needs,  the
     dropped image-level sandbox and the absence of a desktop database hook. The
     version, arch and libc are read from the payload rather than assumed, and a
     converted package therefore carries the requirements that payload implies.

     The  Snap converter records family snap with the converter holy-snap-1, the
     original image hash, the manifest version, the command and mode extract  in
     HOLY/origin. Its payload keeps the whole snap root under /usr/lib/holy/pri-
     vate/NAME/snap/	  with	    the	     image     at     /usr/lib/holy/pri-
     vate/NAME/usr/bin/NAME.snap and a generated launcher at /usr/bin/NAME;  the
     launcher  is a script, so the package names an interpreter requirement like
     any other script. HOLY/transform records the private layout, the  launcher,
     the  base	requirement, the dropped confinement, each dropped plug, and the
     recorded hooks, environment names and command-chain entries. The  base  the
     manifest names becomes a package requirement on that name, because the run-
     time  a  snap  store mounts has to come from a source on this system; a su-
     perblock states no runtime, so that requirement names no  libc.  The  name,
     version,  arch  and  libc are read from the manifest and the payload rather
     than assumed.

     The Scoop importer records family scoop with  the	converter  holy-scoop-1,
     the  manifest  digest,  the  artifact  URL, its digest and mode artifact in
     HOLY/origin.  Its	payload	 carries  the  verified	 artifact  whole   under
     /usr/lib/holy/private/NAME/,  with	 the  directory the manifest declares as
     extract_dir replacing the first component of every archive member path, and
     the manifest  copy	 sits  in  the	output	directory  beside  the	package.
     HOLY/transform  records  the private path, the extract_dir, the program the
     manifest names and that the installer was dropped without a  Wine	require-
     ment.   Each  dependency of the manifest becomes one package requirement on
     the app name, and HOLY/hooks stays empty because nothing runs at install.

     The WinGet importer records family winget with the converter  holy-winget-1
     through  the  same	 writer, so its payload, its private path, its transform
     record and its empty HOLY/hooks match the Scoop package: only the	manifest
     fields, the requirement ids and the report wording name the catalog instead
     of the bucket.

     The  Nix closure importer records family nix with the converter holy-nix-1,
     the capture digest, the store path, its hash and mode closure in  HOLY/ori-
     gin.  It  emits one package per store path, each keeping its own store path
     whole under /usr/lib/holy/private/NAME/store/STORE_PATH/. A store path that
     states  an	 entry	point  also  carries  a	  link	 at   /usr/lib/holy/pri-
     vate/NAME/usr/bin/NAME  and  a  generated launcher at /usr/bin/NAME, so the
     package names an interpreter requirement like any other script. HOLY/trans-
     form records the private layout, the launcher, the absent store  view,  the
     dropped  store  daemon  and the reference count. Each reference the capture
     declares to a store path it carries becomes one package requirement on that
     name; a reference to a store path it does not carry becomes  a  requirement
     whose  original  field is the store hash and which names no architecture or
     runtime. Nix states no version, so every package records version 0 and  the
     store  hash is its identity in x-nix-store-hash. HOLY/hooks stays empty be-
     cause nothing runs at install.

     The Solus eopkg importer records family  eopkg  with  the	converter  holy-
     eopkg-1,  the artifact digest, the original version, the original architec-
     ture, the PiSi  format,  the  install  tar	 digest	 and  mode  artifact  in
     HOLY/origin, and it writes x-eopkg-format, x-source-arch and x-eopkg-compo-
     nent   into   the	 metadata.   The   install   tar   travels  whole  under
     /usr/lib/holy/private/NAME/eopkg/, since a Solus layout is recorded  rather
     than  claimed.  HOLY/transform  records the private layout, the install tar
     digest, the dropped install script and COMAR object, the dropped delta  and
     the  untrusted signature. Each runtime dependency becomes one exact package
     requirement whose original field is  the  releaseFrom  value  the	metadata
     states,  or  - when it states none, since a distribution release is a prop-
     erty of the repository rather than of the dependency. A SONAME the	 payload
     needs  and	 does  not provide becomes a SONAME requirement, and the package
     name is provided as a package capability. HOLY/hooks  stays  empty	 because
     nothing runs at install.

INSTALLED GRAPH
     New  local installations use holy-instance-4 state, or holy-instance-5 when
     an explicit non-native architecture placement decision was	 accepted.  Ver-
     sion  5  adds  an	architecture record with the reviewed host and unchanged
     target. The decision is scoped to that artifact hash and does  not	 certify
     execution.	 The  state  includes a graph SHA-256; the graph file uses holy-
     resolution-1 with scope artifact-candidates, a root  artifact,  sorted  se-
     lected  artifact  hashes and selected requirement edges.  Each edge records
     consumer hash, requirement ID, provider hash, path, kind and  target  using
     the holy.conf lexer. The plan hash includes these canonical bytes.

     Database  operations reject a missing, modified, writable or symlink graph.
     Legacy holy-instance-1 entries remain readable without a graph.  Their  ab-
     sence  of	recorded provider choices does not establish dependency correct-
     ness.

     Source-associated installations also preserve the source fields  introduced
     in holy-instance-3. State records the registered source-id and SHA-256 of a
     separate  source  record  containing that ID and the alias at installation.
     The graph and reason fields retain their version-2	 semantics.  The  source
     record  is	 manager-owned	state, not copied from the package. The database
     rejects absent, changed, writable or symlink source records  and  disagree-
     ment  between the record and state. Renaming or deactivating the registered
     source does not rewrite installed origin records.	Check,	removal,  orphan
     analysis  and  missing-only repair preserve this identity without requiring
     the source to remain active.

     New records include a provides file copied from HOLY/provides and bind  its
     SHA-256  in  state. Empty provides is valid. Missing, modified, writable or
     symlink provides records invalidate the database. Installed package aliases
     can be located from these records; read-only database checks do not require
     the archive cache. Constructing an installation plan still	 requires  veri-
     fied cached artifacts.  Legacy holy-instance-1/2/3 records remain readable.
     Alias  discovery  for  a  legacy record reads its verified cached artifact;
     missing cache returns unavailable instead of silently treating unknown  ca-
     pabilities as absent.

     The set installation interface supports package names and declared aliases,
     scoped  pacman version constraints and native dynamic packages with literal
     absolute interpreter and DT_NEEDED provider paths.	 It records explicit/de-
     pendency reasons. General loader search, automatic	 ELF  rewriting	 remains
     unimplemented.  Slot  conflicts compare source-id, name, os, arch and libc;
     distinct artifacts in different slots may coexist with compatible file own-
     ership. Reviewed cached update plans can  replace	one  source-bound  slot;
     registering  the same artifact in multiple slots remains unsupported. Miss-
     ing-only cache repair preserves the installed graph and refuses changed  or
     partial files.

SEE ALSO
     holypkg(8), holy.conf(5)

Holy				 September 2026			 HOLY-PACKAGE(5)
holypkg.8 source=holy version=development sha256=8a486bc1f72410be12715f5b013dd33cfd354899ec6305f479c944480d2915a5
HOLYPKG(8)		      System Administration		      HOLYPKG(8)

NAME
     holypkg - Holy local package tooling prototype

SYNOPSIS
     holypkg  add  local:FILE  [--candidate local:FILE ...] [--choose ID=SHA256]
     [--associate-source ALIAS] [--associate  SHA256=ALIAS  ...]  [--accept-arch
     SHA256  ...]  [--accept-privileged	 SHA256	 ...]  [--skip-hooks SHA256 ...]
     [--root DIRECTORY] [--yes] [--noninteractive]
     holypkg add SOURCE:PACKAGE [--catalog MIRROR]  [--candidate  SOURCE:PACKAGE
     ...]   [--candidate-provider   SOURCE:KIND:NAME   ...]   [--candidate-local
     SOURCE=FILE.holy ...] [--choose ID=SHA256] [--answers FILE]  [--accept-arch
     SHA256  ...] [--accept-privileged SHA256 ...] [--root DIRECTORY] [--prepare
     | --yes] [--noninteractive]
     holypkg up SOURCE:PACKAGE [--prepare] [--output NEW_FILE]	[--catalog  MIR-
     ROR]  [--choose  SHA256] [--arch ARCH] [--libc LIBC] [--accept-arch SHA256]
     [--accept-privileged SHA256] [--root DIRECTORY] [--yes] [--noninteractive]
     holypkg apply PLAN --sha256 PLAN_SHA256 [--root DIRECTORY]
     holypkg import INPUT  --source  NAME	 --format  pacman|rpm|deb|slack-
     ware|apk|xbps|appimage|snap|scoop|winget|nix|eopkg|pkgbuild
     |void|aports|slackbuild|rpmspec|debian|gentoo|pacstall|flatpak|home-
     brew|guix
	  --output NEW_DIRECTORY [--public-key FILE (apk only)]
     holypkg build RECIPE --output NEW_DIRECTORY  [--environment  host|clean|vm]
     [--work NEW_DIRECTORY] [--jobs N] [--yes] [--noninteractive] [--keep]
     holypkg	   convert	 PKGBUILD|APKBUILD|NAME.SlackBuild|NAME.spec|de-
     bian|NAME.ebuild|NAME.pacscript|NAME.rb|NAME.scm|NAME.json|TEMPLATE
     --source NAME --output NEW_DIRECTORY
     holypkg apt index Packages[.gz|.xz|.zst] --sha256 HASH --source NAME --base
     HTTPS_BASE/ --output NEW_DIRECTORY
     holypkg apt sync HTTPS_URL --sha256 HASH --source NAME  --base  HTTPS_BASE/
     --output NEW_DIRECTORY [--ca-file FILE]
     holypkg  apt  sync-signed	HTTPS_BASE/  SUITE  COMPONENT ARCH --source NAME
     --keyring FILE --output NEW_DIRECTORY  [--inrelease]  [--files]  [--ca-file
     FILE]
     holypkg  apt  sync-source	ALIAS  SUITE  COMPONENT	 ARCH  --root  DIRECTORY
     --keyring FILE --output NEW_DIRECTORY  [--inrelease]  [--files]  [--ca-file
     FILE]
     holypkg apt bind ALIAS SUITE COMPONENT INDEX_ARCH CATALOG --root DIRECTORY
     holypkg  apt search QUERY --catalog DIRECTORY [--source ALIAS --root DIREC-
     TORY]
     holypkg apt search QUERY --source ALIAS --suite SUITE --component COMPONENT
     --index-arch ARCH --root DIRECTORY
     holypkg apt info PACKAGE --catalog DIRECTORY [--source ALIAS --root  DIREC-
     TORY]
     holypkg apt info PACKAGE --source ALIAS --suite SUITE --component COMPONENT
     --index-arch ARCH --root DIRECTORY
     holypkg apt fetch NAME VERSION ARCH --catalog DIRECTORY --output NEW_DIREC-
     TORY  [--source  ALIAS --root DIRECTORY] [--ca-file FILE] [--import] [--re-
     quire-file /PATH]
     holypkg apt fetch NAME VERSION ARCH --source ALIAS --suite	 SUITE	--compo-
     nent  COMPONENT  --index-arch  ARCH --root DIRECTORY --output NEW_DIRECTORY
     [--ca-file FILE] [--import] [--require-file /PATH]
     holypkg appimage inspect INPUT
     holypkg appimage extract INPUT --output NEW_DIRECTORY
     holypkg snap inspect INPUT
     holypkg snap extract INPUT --output NEW_DIRECTORY
     holypkg apk  index	 APKINDEX.tar.gz  --source  NAME  --base  URL/	--output
     NEW_DIRECTORY
     holypkg apk verify-index FILE --public-key FILE
     holypkg  apk  sync	 SOURCE	 REPO  --root  DIRECTORY  --output NEW_DIRECTORY
     [--sha256 HASH | --accept-unsigned	 HASH]	[--ca-file  FILE]  [--public-key
     FILE]
     holypkg  apk  bind	 SOURCE REPO CATALOG --root DIRECTORY [--accept-unsigned
     HASH] [--public-key FILE]
     holypkg apk search QUERY [--catalog DIRECTORY | --source SOURCE --repo REPO
     --root DIRECTORY]
     holypkg apk info PACKAGE [--catalog DIRECTORY | --source SOURCE --repo REPO
     --root DIRECTORY]
     holypkg apk providers soname:NAME [--catalog DIRECTORY  |	--source  SOURCE
     --repo REPO --root DIRECTORY]
     holypkg apk fetch-provider soname:NAME ARCH --output NEW_DIRECTORY [--cata-
     log  DIRECTORY  |	--source  SOURCE --repo REPO --root DIRECTORY] [--sha256
     HASH] [--ca-file FILE] [--public-key FILE]
     holypkg apk fetch NAME VERSION ARCH --output NEW_DIRECTORY	 [--catalog  DI-
     RECTORY  |	 --source  SOURCE  --repo REPO --root DIRECTORY] [--sha256 HASH]
     [--ca-file FILE] [--public-key FILE] [--import]  [--require-soname	 SONAME]
     [--require-file /PATH]
     holypkg  xbps index REPODATA --sha256 HASH --source NAME --base HTTPS_BASE/
     --output NEW_DIRECTORY [--public-key FILE]
     holypkg xbps sync HTTPS_BASE/ ARCH --sha256  HASH	--source  NAME	--output
     NEW_DIRECTORY [--ca-file FILE] [--public-key FILE]
     holypkg xbps sync-source ALIAS ARCH --root DIRECTORY --sha256 HASH --output
     NEW_DIRECTORY [--ca-file FILE] [--public-key FILE]
     holypkg  xbps  search|info QUERY --catalog DIRECTORY [--source ALIAS --root
     DIRECTORY]
     holypkg xbps search|info QUERY --source ALIAS --index-arch ARCH --root  DI-
     RECTORY
     holypkg xbps providers SONAME --catalog DIRECTORY
     holypkg  xbps  providers SONAME --source ALIAS --index-arch ARCH --root DI-
     RECTORY
     holypkg xbps fetch NAME VERSION ARCH --catalog DIRECTORY  --output	 NEW_DI-
     RECTORY  [--ca-file FILE] [--public-key FILE] [--source ALIAS --root DIREC-
     TORY] [--import] [--require-soname SONAME]
     holypkg xbps fetch NAME  VERSION  ARCH  --source  ALIAS  --index-arch  ARCH
     --root  DIRECTORY	--output  NEW_DIRECTORY	 [--ca-file  FILE] [--public-key
     FILE] [--import] [--require-soname SONAME]
     holypkg repo mirror HTTPS_BASE/ --sha256 INDEX_SHA256  --output  NEW_DIREC-
     TORY [--public-key PUBLIC_KEY.pem] [--ca-file FILE]
     holypkg repo seal DIRECTORY [--key PRIVATE_KEY.pem]
     holypkg repo verify DIRECTORY --key PUBLIC_KEY.pem
     holypkg source plan --config FILE --root DIRECTORY
     holypkg source apply PLAN --sha256 HASH --root DIRECTORY
     holypkg source list --root DIRECTORY
     holypkg source show ALIAS --root DIRECTORY
     holypkg source catalog bind ALIAS MIRROR [--root DIRECTORY]
     holypkg  sync  SOURCE [--root DIRECTORY] [--output NEW_DIRECTORY] [--sha256
     INDEX_SHA256 | --accept-unsigned INDEX_SHA256] [--commit GIT_COMMIT] [--ca-
     file FILE]
     holypkg sync APK_SOURCE [--repo REPO] --output NEW_DIRECTORY [--root DIREC-
     TORY] [--sha256 HASH | --accept-unsigned HASH] [--ca-file FILE]  [--public-
     key FILE]
     holypkg  sync  XBPS_SOURCE --arch ARCH --sha256 HASH --output NEW_DIRECTORY
     [--root DIRECTORY] [--ca-file FILE] [--public-key FILE]
     holypkg sync APT_SOURCE --suite SUITE  --component	 COMPONENT  --index-arch
     ARCH --keyring FILE --output NEW_DIRECTORY [--root DIRECTORY] [--inrelease]
     [--files] [--ca-file FILE]
     holypkg orphan [--root DIRECTORY] [--json]
     holypkg conflict [--root DIRECTORY] [--json]
     holypkg  index  [--root  DIRECTORY] [--path PATH | --capability KIND --name
     NAME] [--json]
     holypkg run SOURCE:PACKAGE [--root DIRECTORY] [--arch ARCH]  [--libc  LIBC]
     [--auto-view] [--view PUBLIC=PRIVATE ...] -- COMMAND [ARGS...]
     holypkg docs --root DIRECTORY --output FILE
     holypkg config check FILE
     holypkg info local:FILE
     holypkg  info  SOURCE:PACKAGE  [--repo  REPO]  [--arch ARCH] [--suite SUITE
     --component COMPONENT --index-arch ARCH] [--catalog MIRROR] [--root  DIREC-
     TORY]
     holypkg search QUERY [--source SOURCE] [--repo REPO] [--arch ARCH] [--suite
     SUITE  --component COMPONENT --index-arch ARCH] [--file] [--fuzzy] [--cata-
     log MIRROR] [--root DIRECTORY]
     holypkg verify local:FILE
     holypkg manifest local:FILE
     holypkg requirements local:FILE
     holypkg requirements local:FILE --json
     holypkg provides local:FILE
     holypkg provides local:FILE --json
     holypkg solve local:ROOT [local:CANDIDATE ...]
     holypkg  solve   local:ROOT   [local:CANDIDATE   ...]   --choose	REQUIRE-
     MENT_ID=SHA256 [--json]
     holypkg solve local:ROOT [local:CANDIDATE ...] --json
     holypkg fetch local:FILE --output DIRECTORY
     holypkg fetch local:FILE --extract --output DIRECTORY
     holypkg  fetch  SOURCE:PACKAGE [--catalog MIRROR] --output DIRECTORY [--ex-
     tract] [--root DIRECTORY]
     holypkg fetch APK_SOURCE:PACKAGE  --version  VERSION  --arch  ARCH	 [--repo
     REPO]  --output  NEW_DIRECTORY  [--catalog	 DIRECTORY]  [--root  DIRECTORY]
     [--ca-file FILE] [--public-key FILE] [--sha256 HASH] [--import] [--require-
     soname SONAME] [--require-file /PATH]
     holypkg fetch XBPS_SOURCE:PACKAGE --version VERSION  --arch  ARCH	--output
     NEW_DIRECTORY  [--catalog	DIRECTORY]  [--root  DIRECTORY] [--ca-file FILE]
     [--public-key FILE] [--import] [--require-soname SONAME]
     holypkg fetch APT_SOURCE:PACKAGE  --version  VERSION  --arch  ARCH	 --suite
     SUITE   --component  COMPONENT  --index-arch  ARCH	 --output  NEW_DIRECTORY
     [--catalog DIRECTORY] [--root DIRECTORY] [--ca-file FILE] [--import] [--re-
     quire-file /PATH]
     holypkg fetch https://URL --sha256	 SHA256	 --output  DIRECTORY  [--ca-file
     FILE]
     holypkg pack DIRECTORY --output FILE.holy
     holypkg manifest generate DIRECTORY --output FILE
     holypkg split TREE --output NEW_FILE [--split OUTPUT GLOB ...] [--debug]
     holypkg elf FILE [--build-id]
     holypkg check local:FILE --root DIRECTORY
     holypkg check local:FILE --root DIRECTORY --json
     holypkg  check  [SOURCE:PACKAGE]  [--root	DIRECTORY] [--arch ARCH] [--libc
     LIBC] [--json]
     holypkg files SOURCE:PACKAGE [--root DIRECTORY] [--arch ARCH] [--libc LIBC]
     holypkg why SOURCE:PACKAGE [--root DIRECTORY] [--arch ARCH]  [--libc  LIBC]
     [--json]
     holypkg owner PATH [--root DIRECTORY]
     holypkg  repair  SOURCE:PACKAGE  [--root  DIRECTORY]  [--arch ARCH] [--libc
     LIBC] [--plan PLAN_SHA256]
     holypkg rm SOURCE:PACKAGE [--root DIRECTORY] [--arch  ARCH]  [--libc  LIBC]
     [--yes] [--accept-broken]
     holypkg elf FILE
     holypkg scan local:FILE
     holypkg preview local:FILE --root DIRECTORY
     holypkg preview local:FILE --root DIRECTORY --json
     holypkg cache stage local:FILE --root DIRECTORY
     holypkg cache verify SHA256 --root DIRECTORY
     holypkg cache list --root DIRECTORY
     holypkg cache clean SHA256 --root DIRECTORY [--yes [--accept-unavailable]]
     holypkg db init --root DIRECTORY
     holypkg db status --root DIRECTORY
     holypkg db status --root DIRECTORY --json
     holypkg db reserve SHA256 --root DIRECTORY
     holypkg db cancel --root DIRECTORY
     holypkg db recover --root DIRECTORY
     holypkg db recover --abort-empty --root DIRECTORY
     holypkg db recover --continue --root DIRECTORY
     holypkg db recover --finish-apply --root DIRECTORY
     holypkg db preflight --root DIRECTORY
     holypkg db preflight --root DIRECTORY --json
     holypkg db plan --root DIRECTORY
     holypkg db approve PLAN_SHA256 --root DIRECTORY
     holypkg db recheck --root DIRECTORY
     holypkg db apply --root DIRECTORY
     holypkg  db plan-set ROOT_SHA256 [CANDIDATE_SHA256...] [--choose ID=SHA256]
     [--source ARTIFACT=SOURCE_ID ...]	[--accept-arch	SHA256	...]  [--accept-
     privileged SHA256 ...] [--skip-hooks SHA256 ...] --root DIRECTORY
     holypkg   db   apply-set	PLAN_SHA256   ROOT_SHA256  [CANDIDATE_SHA256...]
     [--choose	ID=SHA256]  [--source  ARTIFACT=SOURCE_ID  ...]	  [--accept-arch
     SHA256  ...]  [--accept-privileged	 SHA256	 ...]  [--skip-hooks SHA256 ...]
     --root DIRECTORY
     holypkg db recover --finish-set|--continue-set --root DIRECTORY
     holypkg db configure-plan SHA256 --root DIRECTORY
     holypkg db configure-apply PLAN_SHA256 SHA256 --root DIRECTORY
     holypkg db configure-recover SHA256 --retry --root DIRECTORY
     holypkg db repair-plan SHA256 --root DIRECTORY
     holypkg db plan-update  OLD_SHA256	 NEW_SHA256  [--accept-arch  NEW_SHA256]
     [--accept-privileged NEW_SHA256] --root DIRECTORY
     holypkg  db  apply-update	PLAN_SHA256 OLD_SHA256 NEW_SHA256 [--accept-arch
     NEW_SHA256] [--accept-privileged NEW_SHA256] --root DIRECTORY
     holypkg  rollback	TRANSACTION  [--root  DIRECTORY]  [--apply  PLAN_SHA256]
     [--accept-arch ARTIFACT_SHA256] [--accept-privileged ARTIFACT_SHA256]
     holypkg db recover --update --root DIRECTORY
     holypkg db repair SHA256 --plan PLAN_SHA256 --root DIRECTORY
     holypkg db recover --repair --root DIRECTORY
     holypkg db check SHA256 --root DIRECTORY
     holypkg db check --all --root DIRECTORY
     holypkg db check SHA256|--all --root DIRECTORY --json
     holypkg db rm SHA256 [--accept-broken] --root DIRECTORY
     holypkg db owner PATH --root DIRECTORY
     holypkg repo index DIRECTORY
     holypkg repo list DIRECTORY
     holypkg repo requirements DIRECTORY NAME
     holypkg repo search DIRECTORY NAME
     holypkg repo search DIRECTORY NAME --fuzzy
     holypkg repo search-file DIRECTORY ABSOLUTE_PATH
     holypkg repo search-file DIRECTORY NAME_OR_PATH --fuzzy
     holypkg repo solve DIRECTORY NAME [--json]
     holypkg repo solve DIRECTORY NAME --choose REQUIREMENT_ID=SHA256 [--json]
     holypkg repo providers DIRECTORY KIND NAME
     holypkg repo providers DIRECTORY KIND NAME --json
     holypkg repo seal DIRECTORY
     holypkg repo fetch DIRECTORY SHA256 --output DIRECTORY

DESCRIPTION
   Local pacman, RPM, Debian, Slackware, APK and XBPS binary import
     import  snapshots	a local pacman tar archive, RPM v4 or v6 package, Debian
     .deb, Slackware package, APK v2 or XBPS package, retains its exact bytes as
     NEW_DIRECTORY/original and creates verified LZ4-frame  .holy  outputs.  The
     output  directory	must not exist. --format selects the adapter explicitly;
     --source records provenance only and grants no registered	source	identity
     or	 trust.	  The  command	does  not install files or execute package code.
     Without an explicit APK public key, each output records verification=unver-
     ified. An explicit key verifies the APK signature but does not grant a reg-
     istered source identity.

     --format rpm uses librpm to read the header and payload of v4 and v6  pack-
     ages.   It	 verifies  each	 supported  file  digest  before  packaging with
     libarchive.  The importer checks header and  payload  file	 lists,	 records
     config  flags  and original provenance, and splits observed ELF ABI groups.
     The resolver compares RPM epoch, version and release with a dedicated  lib-
     solv RPM comparator. Ordinary versioned Requires and Provides use that com-
     parator.  Automatic self config-file and rpmlib requirements remain in ori-
     gin  rather  than	becoming  runtime  dependencies.  Conflicts,  Obsoletes,
     scriptlets, triggers and file capabilities require further conversion  sup-
     port.   Local  import does not verify RPM signatures. Builds without librpm
     return status 6 for this format.

     build compiles a local holy-recipe(5) manifest. It fetches	 every	declared
     source  under  its	 pinned digest, unpacks archives into HOLY_SRC, runs the
     reviewed phase steps with absolute HOLY_* paths, and packs	 one  .holy  per
     declared  output.	Every output is grouped by the ABI facts of the files it
     receives, so one build can produce a noarch nolibc document output and sep-
     arate ABI libraries. Requirements come from  declared  depend  records  and
     from  the	DT_NEEDED  entries  of the built payload; provides come from the
     payload SONAMEs.  The result is an ordinary artifact that a later	transac-
     tion  installs.  A	 split-step  output  receives its own staging tree under
     HOLY_SPLIT_DEST, so a payload requirement and a  hook  script  are	 written
     only into the output that carries their file. An unpack step runs after the
     manager has extracted every source, so it may move or reshape that content.
     See holy-recipe(5) for the manifest, phases, split rules and build environ-
     ments.

     rpm  index	 reads a local repomd.xml and its primary archive after checking
     the explicit SHA-256 of repomd.xml. The parser  accepts  only  the	 primary
     data  type, one sha256 checksum and one relative location. It records pack-
     age name, epoch, version, release, architecture, archive SHA-256, size  and
     repository	 href.	 rpm  sync  retrieves repomd.xml and the primary archive
     over HTTPS with the same required hash, then  converts  them.  The	 catalog
     stores that normalized row set.  The converter also builds a digest-checked
     capabilities  index  from	the primary.xml rpm:provides entries. File-index
     coverage is unavailable; dependency coverage stays	 partial  because  file-
     based  requirements need payload scan. Search and info read the catalog af-
     ter rechecking the repomd, primary, catalog and capabilities  digests.  rpm
     providers CAPABILITY returns exact, source-attributed candidate hints with-
     out  downloading  every archive. The claim remains unverified until the se-
     lected payload is imported and its ELF files are checked. An  absent  match
     means  no	declared hint in this index, not proof that the source lacks the
     capability. rpm fetch selects an exact name/EVR/architecture, downloads the
     archive, checks size and SHA-256, and can import it with the same converter
     as --format rpm. The standalone index/sync source name  records  provenance
     but does not register a source-id.

     A	registered  RPM-MD  source  uses  type	rpm-md	and one url HTTPS_BASE/.
     holypkg sync  RPM_MD_SOURCE  requires  an	explicit  repomd  --sha256  pin,
     records the registry source-id in the conversion record and binds the cata-
     log  under the target database. The common fetch RPM_MD_SOURCE:PACKAGE com-
     mand takes --version and --arch, checks the bound catalog and  the	 current
     registry, and downloads through the same verifier. A missing version or ar-
     chitecture	 returns  decision-required  (3). An explicit --catalog must re-
     solve to the bound catalog directory. Changing the	 registered  url  leaves
     the  earlier  binding invalid, so search and fetch report coverage unavail-
     able until a new sync succeeds. No repository signature is checked: verifi-
     cation stays hash-pinned, and trust require needs a key this  backend  does
     not implement.

     --format  deb  reads  the	Debian ar members debian-binary, control.tar and
     data.tar in order, including supported compressed variants. It retains con-
     trol files beneath HOLY/foreign/deb and each control field with its  source
     line  in  HOLY/origin. Debian maintainer scripts remain review-required and
     never run during import. Debian conffiles paths must name	regular	 payload
     files.  The importer records them with the config manifest flag and rejects
     missing, duplicate or unsafe paths. Modified installed config files  report
     changed-config.   Cached updates preserve a modified config when both pack-
     age versions mark it config.  Comma-separated Depends entries become  pack-
     age  requirements. OR alternatives remain one requirement with version con-
     straints on each  branch.	The  solver  records  the  selected  branch  and
     provider in the installed graph. Constraints use Debian ordering, including
     epoch,  tilde  and revision, only against providers in the deb version fam-
     ily. Architecture qualifiers, Pre-Depends and other  unsupported  relation-
     ships remain attributed foreign requirements that require an explicit deci-
     sion  in  the  current  solver.  The automatic cross-source provider search
     checks every branch of a missing OR group.	 It  stages  indexed  candidates
     from  the	chosen	source; the solver then checks each branch's version and
     requests a choice if several providers remain valid.  Simple Provides names
     and exact version claims become package capabilities; an  unversioned  vir-
     tual  claim  does not satisfy a versioned dependency. Unsupported or dupli-
     cate claims remain foreign requirements. The converter  supports  Architec-
     ture  all,	 amd64	and  i386;  it checks observed ELF machines against that
     claim and returns status 3 for unknown or mismatched payloads. It does  not
     verify  Debian  signatures.   When control/md5sums is present, the importer
     verifies each listed regular payload file before  writing	native	outputs.
     MD5  detects  payload  mismatch  here;  it does not authenticate the source
     archive.  make check-deb exercises valid and malformed ar members,	 codecs,
     dependencies, inactive hooks and native install/check/remove in a temporary
     root.   The  Debian reader accepts a numeric 2.x debian-binary version with
     following version-file lines, ignores additional ar members after data.tar,
     and checks that the control/data compression matches its member suffix. The
     version file is limited to 4096 bytes.

     apt index accepts a local Debian Packages index with  an  explicit	 SHA-256
     pin.  It  keeps the compressed source bytes in original and parses Package,
     Version, Architecture, Filename, Size,  SHA256,  Depends,	Pre-Depends  and
     Provides.	 Duplicate  package/version/architecture  entries, unsafe paths,
     missing hashes, empty indexes and malformed stanzas  fail	conversion.  The
     catalog records its source name, HTTPS base URL, pin and package count. The
     source name is provenance, not a registered source-id. The output directory
     must  not exist.  apt sync downloads Packages over HTTPS into private stag-
     ing, checks its explicit SHA-256 pin and creates the same local catalog. It
     does not authenticate the Debian Release/InRelease	 signature.   apt  sync-
     signed  downloads	dists/SUITE/Release,  Release.gpg  and COMPONENT/binary-
     ARCH/Packages.gz over HTTPS. It runs gpgv with the selected keyring, checks
     the Suite or Codename, any Valid-Until deadline, and the signed SHA256  and
     size  of Packages.gz. It stages the catalog beside the output and publishes
     it only after all checks pass. The catalog keeps Release, Release.gpg,  the
     selected  keyring	and  a proof record. Search, info and fetch recheck that
     proof; deleting it makes the signed catalog invalid. gpgv	is  an	external
     requirement  for this mode and the selected keyring is trusted for this op-
     eration. The command does not register that keyring as a source-id	 or  im-
     plement  the  full APT repository policy. Signed catalog fetch receipts use
     verification=release-gpgv-user-key. Missing Valid-Until is accepted.  --in-
     release selects dists/SUITE/InRelease instead of Release  and  Release.gpg.
     gpgv  checks  the	signature; a strict clearsign reader extracts the signed
     text. Only that text supplies the index hash and suite policy.  The catalog
     keeps InRelease, the extracted Release, the keyring  and  a  proof	 record.
     Queries  recheck  the signature. Fetch receipts use verification=inrelease-
     gpgv-user-key. Selection is explicit; a failed InRelease fetch or signature
     does not fall back to detached Release.gpg.  --files also downloads  COMPO-
     NENT/Contents-ARCH.gz.  Sync  checks  its	signed Release SHA-256 and size,
     gzip stream and expanded size before publication. The catalog  records  the
     compressed	 file  and  its	 proof. Catalog reads recheck the file hash, re-
     trieval time and partial coverage status. A missing signed	 Contents  entry
     fails this requested sync.	 apt sync-source reads an active type apt source
     from  the	target-root registry. Its public-key is a binary OpenPGP keyring
     whose SHA-256 is frozen by source plan. The supplied --keyring  must  match
     that  fingerprint. Sync checks the source again before publication, records
     its stable source-id and writes a binding in the target database. apt  bind
     can  replace a binding for a previously verified catalog.	The binding keys
     source-id, suite, component and index architecture. Search, info and  fetch
     resolve  these  coordinates  without  --catalog.  Each operation checks the
     stored catalog path, index,  Release  proof  and  current	source	URL/key.
     Alias renames preserve the binding; a changed source URL or key invalidates
     it.   With	 an  explicit  --catalog,  --source and --root check the catalog
     against the registered source without changing its binding. The package ar-
     chitecture in apt fetch is distinct from --index-arch.

     The common sync APT_SOURCE command uses the  signed  Release  verifier  and
     binds its result. It requires suite, component, index architecture, keyring
     and output. --inrelease selects a clearsigned Release; --files includes the
     signed Contents index. Common search, info and fetch require the same three
     catalog  coordinates and verify the binding. Common fetch also requires the
     package version and architecture; --import and --require-file keep the  APT
     payload checks. A supplied --catalog must resolve to the bound directory.

     apt search and apt info read the catalog and recheck its original index di-
     gest.  Search  matches package name substrings; info requires an exact name
     and returns decision-required if several versions or  architectures  match.
     apt  search  /PATH	 --file looks up an exact file path in the verified Con-
     tents index and prints matching indexed package names. Without --files cov-
     erage is unavailable and status 6 is returned. An absent match  in	 partial
     coverage is unknown and also returns 6.  Contents is a source hint; the im-
     ported  package  payload must still be checked before a file requirement is
     satisfied.	 apt fetch selects an exact name, version and  Debian  architec-
     ture,  downloads the listed Filename over HTTPS, and checks its SHA-256 and
     Size. The output retains the original .deb and a  selection  receipt.  With
     --import,	it invokes the local Debian converter and checks the native out-
     put identity. The converter checks the downloaded DEB hash	 after	staging,
     then records the selected index hash, source URL and verification result in
     each  .holy  origin. Signed catalogs also record keyring and Release signa-
     ture hashes. Direct local DEB import remains unverified. Index  and  selec-
     tion receipts say pinned-unverified when only an external pin is available.
     The  signed path uses the separately selected keyring and Release.gpg. Reg-
     istered operations include a checked source-id in their selection	receipt.
     With  --import  --require-file  /PATH, fetch checks that Contents names the
     selected package, then verifies the exact nondirectory path in the imported
     receipt. The option requires --import.  It does not install packages.  make
     check-apt	covers	local and HTTPS indexes, tampering, TLS fetch, hash mis-
     match and import identity.

     --format slackware reads a .txz, .tgz, .tbz or .tlz tar package and  checks
     its  compression  against	the filename suffix. It parses the name-version-
     arch-build filename from the right, preserves the build tag as  the  native
     release,  and  retains  install/  files  under HOLY/foreign/slackware.  in-
     stall/doinst.sh is recorded as a review-required shell hook and is not  run
     during conversion. Unknown install/ control files become attributed foreign
     requirements.  Official  Slackware	 packages need not declare dependencies;
     the  importer  does  not  invent  them.  It  accepts  noarch,  x86_64   and
     i386/i486/i586/i686 source architecture labels, then separates observed ELF
     arch/libc outputs.	 An unknown or contradictory claim returns status 3. The
     Slackware	version family has no automatic comparator yet, so update choice
     requires review.  make check-slackware covers codecs, links, scripts,  path
     rejection,	 mixed	ELF outputs and install/check/remove of a converted data
     package.

     --format apk reads two or three concatenated gzip members from  an	 APK  v2
     package.  It  retains .PKGINFO, optional signatures and control scripts be-
     neath HOLY/foreign/apk.  When  .PKGINFO  contains	datahash,  the	importer
     checks  its SHA-256 against the compressed data member before creating out-
     puts. With --public-key FILE, the importer snapshots an RSA  PEM  key,  re-
     quires datahash and a signature member, and verifies the signature over the
     compressed	 control member. The key filename must match the .SIGN key name.
     The conversion receipt and each output origin record the algorithm and pub-
     lic-key SHA-256. The caller must establish the key's  authenticity	 outside
     the  import  command. Unversioned package, so:SONAME and cmd:COMMAND depen-
     dencies become exact requirements. Package constraints using the  supported
     APK v2 number, letter, suffix and revision grammar use APK version ordering
     only  against  APK-family providers. Unknown version forms, namespaced ver-
     sioned requirements and other unsupported tokens retain their original  ex-
     pressions as foreign requirements. APK virtual provides, install-if and re-
     places  also  require review because their selection and file-ownership se-
     mantics differ from Holy's simple capabilities. Scripts  remain  review-re-
     quired  and  do not run during import. The importer accepts noarch, x86 and
     x86_64 claims and checks observed ELF machines. It rejects	 truncated  gzip
     members,  extra members and unsafe paths. make check-apk covers these cases
     and installs/checks/removes a converted data package in a	temporary  root.
     make check-apk-version covers comparisons against Alpine apk-tools 2.14.12.

     --format  xbps  reads  a  Void  XBPS  tar	package,  parses props.plist and
     files.plist with libplist, and checks payload file size and SHA-256 against
     the file list.  It compares symlink targets by their resolved  path  inside
     the  target  root;	 a  relative  archive target and the equivalent absolute
     files.plist target match.	It preserves the original property lists beneath
     HOLY/foreign/xbps and records unverified provenance for a direct local  im-
     port.  Package  revision becomes the shlib-requires become arch/libc-scoped
     SONAME  requirements.  Simple  run_depends	 of   the   form   name<version,
     name<=version,  name>version  or name>=version become package requirements.
     Holy compares their versions only against XBPS-family providers with  Dewey
     component	order and the _N revision.  Complex ranges, globs, exact package
     strings and other XBPS-specific relations	remain	attributed  foreign  re-
     quirements.  Provides are preserved in origin metadata without creating de-
     pendencies. INSTALL and  REMOVE  scripts  remain  review-required.	 Unknown
     file-list fields, unsupported architecture, and ELF/architecture contradic-
     tions  stop  conversion. make check-xbps-import covers a generated package,
     ELF-derived SONAME capabilities, dependency selection  and	 malformed  file
     lists;  make  check-xbps-version  checks  component  and revision ordering.
     These do not test the full Void package range.

     xbps index reads a local $ARCH-repodata archive after checking its explicit
     SHA-256. xbps sync retrieves the named architecture's repodata  over  HTTPS
     with  the same required hash. The catalog stores package name, version, ar-
     chitecture, archive SHA-256 and size. Search and info read the catalog  af-
     ter  checking  its digest and the retained repodata. File-index coverage is
     marked unavailable. The converter also builds a digest-checked capabilities
     index from	 XBPS  shlib-provides.	xbps  providers	 SONAME	 returns  exact,
     source-attributed	candidate  hints  without downloading every archive. The
     claim remains unverified until the selected payload is imported and its ELF
     files are checked. An absent match means no declared hint	in  this  index,
     not  proof	 that  the  source  lacks the library. The standalone index/sync
     source name records provenance but does not  register  a  source-id.  sync-
     source  reads  an	active	type  xbps source from the target-root registry,
     checks its URL and selected key, and records its  source-id.   Source-aware
     search/info/fetch check that source-id and the URL against the current reg-
     istry.  sync-source  binds	 the verified conversion digest and catalog path
     under the target database lock. Search, info  and	fetch  can  select  that
     binding  by source alias and index architecture; changed conversion records
     or catalog bytes fail validation. Bindings survive alias renames  that  re-
     tain  the	same  source-id. A catalog inside the target root is stored as a
     root-relative path, so moving that root with its cache preserves the  bind-
     ing.  With	 --public-key  FILE, index requires that the supplied RSA public
     key match index-meta.plist and records its SHA-256 fingerprint. The  caller
     must  establish  the  key's authenticity independently.  The repodata still
     requires an explicit SHA-256 pin; index-meta.plist alone is not trusted au-
     thority for a new key.

     The common sync XBPS_SOURCE command takes --arch and an  explicit	repodata
     --sha256.	It  verifies the registered source and key, then binds the cata-
     log.  The common fetch  XBPS_SOURCE:PACKAGE  command  takes  --version  and
     --arch,  checks  the  bound  catalog  and registered key, and uses the same
     archive verifier and optional import as xbps fetch. A  missing  version  or
     architecture  returns decision-required (3). An explicit --catalog must re-
     solve to the bound catalog directory; a copied unbound catalog is rejected.

     xbps fetch selects an exact name/version/arch from that catalog,  downloads
     the  archive  over HTTPS, checks size and SHA-256, and compares props.plist
     identity with the selected record. With --public-key FILE, fetch  also  re-
     quires  the index's key fingerprint, retrieves the .sig2 sidecar and checks
     its RSA SHA-256 signature over the archive bytes. The receipt distinguishes
     hash-pinned from rsa-sha256. With --import,  fetch	 converts  the	verified
     archive  into  .holy outputs under NEW_DIRECTORY/converted and checks their
     identity. The converter checks the archive hash  again  after  staging  and
     records  hash-pinned  or  rsa-sha256 in each output origin. A signed output
     also records the public key and signature SHA-256. Fetched	 outputs  retain
     the  selected repodata SHA-256 and credential-free source URL. A direct im-
     port remains unverified and has no asserted repository  generation.   --re-
     quire-soname requires --import and checks exact SONAME claims from the con-
     verted  ELF payload; an index hint alone does not satisfy it.  The complete
     fetch receipt records source-id for a checked source binding,  whether  im-
     port  ran,	 and  any verified SONAME. Import failure leaves the archive and
     incomplete output without a complete fetch receipt. Fetch does not	 install
     or	 execute the package. The current transport limits one archive to 1 GiB;
     larger indexed objects return status 6.  An explicit import of the	 fetched
     digest-named  file creates .holy outputs.	make check-xbps-index covers in-
     dex parsing, HTTPS sync/fetch, registered source checks, RSA signature ver-
     ification, conversion and failure cases on a local fixture server. Key  en-
     rollment and automatic provider discovery remain open.

     The apk index command snapshots a local APKINDEX.tar.gz, separates its gzip
     signature	and  data members, and publishes a sorted local catalog with the
     original bytes, source alias, base URL  and  SHA-256.  It	checks	required
     package  identity	fields and duplicate name/version/arch slots. The source
     alias is provenance, not a registered source-id. A publisher  signature  is
     retained in the original input; direct apk index conversion records unveri-
     fied  status.   Package  coverage is complete for the supplied index, while
     file coverage is unavailable. apk search matches a	 package-name  substring
     and  apk  info selects an exact name; multiple versions require a decision.
     Queries verify the catalog hash recorded at conversion. apk  fetch	 obtains
     the  indexed  APK	over  HTTPS,  checks its recorded size and Q1 SHA-1 com-
     pressed-control checksum, then  compares  .PKGINFO	 identity  and	optional
     datahash with the compressed data member. --sha256 adds a full artifact di-
     gest supplied by the caller. The output contains the original APK and a se-
     lection  receipt with index/catalog hashes.  For a bound source with a con-
     figured RSA key, apk fetch requires --public-key,	checks	its  fingerprint
     against  the  registered  key, and verifies the APK signature over the com-
     pressed control member. The receipt records index and package  verification
     separately.  Direct  fetch without a bound keyed source records the package
     signature as unverified.  apk sync reads an  active  type	apk  source  and
     named   repo  from	 the  registered  source  definitions.	It  fetches  AP-
     KINDEX.tar.gz over HTTPS. A configured RSA public-key freezes the key  fin-
     gerprint  in  the	source registry. Sync requires the matching --public-key
     file and verifies the  signed  compressed	index  member  using  RSA/SHA-1,
     RSA/SHA-256 or RSA/SHA-512 according to the .SIGN filename.  The public-key
     filename  must  match  the signature key name. trust require needs this key
     and a valid signature. Without a configured key, --sha256 pins index bytes;
     --accept-unsigned confirms the downloaded digest after a  decision-required
     response.	trust  ignore  permits	an  unpinned  index. Its catalog records
     source-id and repo. apk fetch --root requires  that  exact	 catalog  to  be
     bound, checks its source-id, alias, repo and URL against the active defini-
     tion, and checks again before publishing the package.  If the alias changed
     while  the	 source-id stayed the same, --source names the current alias for
     this check.  apk sync also records an atomic catalog binding under the tar-
     get database.  apk bind replaces that binding  for	 a  previously	verified
     catalog. A source with a configured key must supply it through --public-key
     so	 bind can verify the original index signature again; the binding records
     the verification and key fingerprint. Without a configured key, trust  warn
     requires  --accept-unsigned  with	the exact index digest. Search, info and
     fetch can use the bound catalog by source and  repo.  Readers  compare  its
     saved  index  and	catalog hashes, and reject changed source definitions. A
     catalog inside the target root uses a root-relative binding so the root can
     be moved.

     The common sync APK_SOURCE command calls the same APK  verifier  and  binds
     its  result.  A single configured repository is selected when --repo is ab-
     sent; multiple repositories require  --repo  and  return  decision-required
     (3). APK sync requires --output. --commit applies only to holy-git sources.

     Direct  fetch  without  --root  records source-binding unchecked. Fetch and
     sync do not install files. apk providers soname:NAME searches exact so:NAME
     entries in the hash-bound SONAME index generated from APKINDEX. Each result
     is an index hint. Use fetch --import --require-soname NAME	 to  verify  the
     actual  ELF  before  selecting a provider.	 fetch-provider soname:NAME ARCH
     chooses the sole indexed candidate for that architecture, fetches	and  im-
     ports  it, then checks the exact ELF SONAME. Multiple candidates return de-
     cision-required before download; use apk fetch with an  explicit  name  and
     version to choose one. A false index claim fails after import and leaves no
     complete  selection receipt. Source-bound fetch still checks the registered
     source, key and  index  generation.   With	 --import,  fetch  converts  the
     checked  archive  into  .holy outputs under NEW_DIRECTORY/converted, checks
     each output's name, version and architecture,  and	 rechecks  the	original
     SHA-256  after  staging.  Signed packages are verified again during import.
     The output origin records the selected index hash and fetched artifact URL;
     its verification field describes the package signature, not the index  sig-
     nature.  --require-soname	requires --import and checks exact SONAME claims
     derived from the imported ELF payload. An index claim alone cannot	 satisfy
     it. --require-file checks one exact nondirectory payload path from the con-
     verted  manifest.	Both requirements need --import and can be combined. Im-
     port failure leaves the original and an incomplete output	without	 a  com-
     plete  selection receipt. The APK binding is separate from the native cata-
     log and general dependency resolver. make check-apk-index covers signed and
     unsigned fixtures, duplicate entries, truncated gzip, traversal and catalog
     tampering.	 make check-apk-fetch covers HTTPS, full digest,  size,	 control
     checksum  and  package  signatures.  The verified index identifies packages
     through APK v2 Q1 SHA-1 checksums. For a package selected from  a	verified
     index,  fetch requires keyed source also requires the package signature and
     matching public-key filename.

     The importer reads .PKGINFO identities, full epoch/version/release strings,
     package relations and original field values. It preserves .PKGINFO, .BUILD-
     INFO, .MTREE, .INSTALL and .CHANGELOG beneath HOLY/foreign/pacman.	 Numeric
     and  symbolic  ownership,	modes,	symlinks and supported hardlinks survive
     conversion.  The native installer still requires  supported  ownership  and
     object semantics.

     A	single	observed  ELF ABI receives common data in the same output. Mixed
     ELF  architectures	 or  libc  classes  receive  separate  outputs	plus   a
     noarch/nolibc  common-data	 output.  Source  architecture remains x-source-
     arch; observed payload facts determine output tags. Unknown ELF,  unclassi-
     fied  executable  formats,	 static library archives and pacman backup paths
     require a decision, status 3.  Source packages require  a	recipe	importer
     and are not treated as binary packages.

     Package  dependencies  retain  constraints and original expressions. Pacman
     package version constraints use the comparator described below. Unsupported
     SONAME relations, conflicts, replacements and unknown metadata  fields  be-
     come foreign requirements; the current solver reports decision-required for
     a	selected  output that carries them.  Optional and build requirements re-
     main in attributed origin records.	 An .INSTALL script  remains  review-re-
     quired. The current installer refuses its nonempty hooks record. Split out-
     puts  also	 require  scoped dependency and resolved requirements before in-
     stallation. HOLY/transform records changes already	 made  to  the	packaged
     payload;  the installer does not execute it.  Conversion success alone does
     not establish that an application can be installed or launched.

     The conversion receipt binds the original SHA-256 to every output filename,
     SHA-256 and arch/libc pair. The importer publishes it only after completing
     all outputs. A failed conversion retains the  original  and  any  completed
     outputs;  without a complete receipt the output set is incomplete. Existing
     output files are not overwritten. Origin metadata records	the  format-spe-
     cific  converter identity; executable build attestation and publisher veri-
     fication remain unimplemented.

     Libarchive supplies tar and built-in gzip, bzip2,	XZ,  Zstandard	and  LZ4
     codecs  when  available in the selected build. APK v2 member boundaries use
     zlib. A missing codec returns status 6 and does not invoke an external  de-
     coder.  The  static dependency profile builds all five codecs with musl and
     rejects a libarchive configuration missing any of them. Import uses  anony-
     mous  spool  files	 instead of extracting foreign paths on the host. It re-
     jects duplicate paths, unsafe links, non-directory	 ancestors,  unsupported
     special  nodes,  ACLs  and xattrs. Limits are 1 GiB compressed input, 1 GiB
     per entry, 4 GiB payload spool, 100000 entries and 1 MiB .PKGINFO or Debian
     control. Debian control.tar also has a  16	 MiB  outer  member  limit;  the
     data.tar.lzma  legacy variant uses libarchive's LZMA filter when available.
     The native writer verifies outputs through	 /proc/self/fd	before	publica-
     tion.

     make  check-pacman	 runs  parser and archive fixtures, including a retained
     .PKGINFO from Arch gzip 1.15-1, malformed archives, hooks that must not ex-
     ecute, mixed ELF outputs and installation of a converted data package in  a
     temporary	root.  make check-static-import STATIC_HOLYPKG=FILE verifies the
     six tar/codec paths, including truncated compressed inputs,  in  a	 private
     mount/PID	namespace and a chroot containing the client, inputs, /tmp and a
     private /proc. It installs, checks and removes each converted fixture with-
     out dynamic libc or decoder executables. The test requires	 doas,	unshare,
     mount,  chroot,  Python, readelf and host zstd/lz4 commands to create input
     fixtures. These host compressors are not available inside the chroot.

     make check-pacman also runs 92 attributed version comparisons  from  pacman
     7.1.0,  plus  scoped candidate selection, mixed-family rejection, installa-
     tion and rejection of updates that violate	 an  installed	consumer's  con-
     straint.

     The  reference  metadata  format  is https://alpm.archlinux.page/specifica-
     tions/PKGINFO.5.html.

   Pinned HTTPS catalog mirrors
     repo mirror downloads one explicit catalog generation into a new local  di-
     rectory.  HTTPS_BASE  must end with slash and contain no credentials, query
     or fragment. The command requests index.INDEX_SHA256,  checks  its	 digest,
     parses the entire supported holy-index-prototype-1/2 catalog, and downloads
     its  packages by their recorded hashes. It URL-escapes each filename as one
     path component. The common HTTPS transport validates certificates,	 permits
     at	 most  five  redirects	and refuses credential-bearing redirect targets.
     --ca-file selects a fixture or private repository CA.

     The mirror verifies every archive, payload, known ABI,  dependency	 record,
     identity,	size  and indexed capability claim before sealing its local cur-
     rent pointer. The final sealed index must still match INDEX_SHA256. A trun-
     cated, duplicate, forged or unavailable object cannot publish a usable cat-
     alog.  Index transfers are limited to 16 MiB and  package	transfers  to  1
     GiB,  each	 with  the common five-minute deadline including redirects. This
     operation downloads the entire selected catalog, rather  than  resolving  a
     single package.

     The  new  directory  contains  the original filenames, index, index.DIGEST,
     current and mirror-origin. The latter records the base URL,  pinned  digest
     and digest-pinned-unsigned verification status. repo list/search/providers,
     repo  solve  and repo fetch operate on the resulting local snapshot without
     network access. A valid empty catalog is supported. Existing output  direc-
     tories are refused. Download or validation errors leave partial files with-
     out  a  current pointer; a new attempt uses a new output directory.  An I/O
     failure during final pointer publication can require inspection of current,
     as with repo seal. Success prints only the sealed index digest.

     The caller supplies the digest. Without --public-key, this command does not
     verify a publisher signature. With --public-key, it verifies the signed in-
     dex against that PEM key before downloading packages. It does not	activate
     a	configured source, assign source-id or install packages. Configured sync
     with a pinned digest is described below.  Successful return is  0;	 invalid
     arguments	return	2, conflicting hashes or catalog contents 4, unavailable
     TLS/network inputs 6, and local filesystem errors 1. The directory	 remains
     private to its owner until that owner chooses to share it.

   Installed documentation
     holypkg  docs --root DIRECTORY --output FILE creates a new holy-docs-1 bun-
     dle from the selected root's installed manifests.	It  holds  the	database
     shared  lock,  rejects  pending transactions and visits artifacts in digest
     order.  It includes regular man sources  beneath  usr/share/man,  including
     localized subdirectories, after comparing each opened file's SHA-256 to its
     installed	manifest.  It  refuses symlinked parent directories and reads no
     configs, origin URLs, passwords or files outside the installed man list.

     Each page records its name, section, path, package name/version,  installed
     source-id and artifact and source-file hashes. Local delivery has source-id
     "-" unless explicitly associated with a registered source.	 Same-name pages
     retain separate attributed records.  Sources remain roff text; this command
     does  not	run  a	formatter or interpret roff directives. It decodes gzip,
     bzip2, xz and zstd with built-in libarchive filters when compiled	in,  and
     never invokes a decompression helper.  Hardlinked manual names retain sepa-
     rate  attributed pages after inode-group checks.  The compressed source di-
     gest identifies the original file. Symlink aliases are checked without fol-
     lowing them and listed as references rather than expanded.

     missing-man identifies packages with no included regular page.  omitted-man
     lists  unsupported page names/codecs. The final summary records generation,
     package/page/alias counts and missing/omitted coverage. A successful bundle
     can contain those explicit omissions; inclusion does not assess a	manual's
     semantic  completeness.  Sources  and  manifests  are limited to 16 MiB per
     file; decoded pages are limited to 64 MiB.	 Empty	or  NUL-containing  page
     bodies fail.

     The  command  builds a temporary file beside FILE and publishes without re-
     placing an existing output. Invalid or changed man files return 4;	 pending
     transactions  return  5; output and database I/O failures return 1. Failure
     leaves existing output untouched. It requires neither root nor network. For
     image roots whose manifests use UID 0, run inside	the  builder's	matching
     user  namespace.	HOLY_DOCS_CHROOT=1  sh tests/installed-docs.sh ./holypkg
     additionally exercises the static binary and gzip decoding in  a  libc-free
     chroot using host doas.

   Bootstrap source retrieval
     make  fetch-sources  INPUTS=DIRECTORY  SOURCES="NAME  ..." obtains selected
     pinned archives from profiles/static-sources. make	 fetch-bootstrap-sources
     uses  profiles/bootstrap-sources  for BusyBox, dinit, mdevd, skalibs, glibc
     and musl.cc cross compilers. Omitting SOURCES selects the	whole  manifest.
     The fetcher accepts HTTPS and HTTPS redirects, verifies SHA-256 before pub-
     lishing  each  file, and checks existing files before reuse. A wrong digest
     stops the command without replacing that file. A failed download leaves  no
     published	archive. The resulting INPUTS directory feeds the bootstrap tar-
     gets; fetching alone does not install a package.

   Bootstrap shell package
     The repository target make bootstrap-busybox ARCH=i686|x86_64 INPUTS=DIREC-
     TORY OUTPUT=DIRECTORY builds a small BusyBox package with static musl link-
     age. The default is x86_64; i686 requires multilib GCC and records	 package
     architecture   x86.   INPUTS   must  contain  musl-1.2.5.tar.gz  and  busy-
     box-1.37.0.tar.bz2 from their upstream release URLs.   KERNEL_HEADERS  must
     name  installed  Linux  UAPI headers with linux and asm subdirectories. The
     builder records a digest of those headers and searches them after the  musl
     headers  when  compiling  network applets.	 The build checks pinned SHA-256
     digests before unpacking, uses GCC and upstream make builds,  and	installs
     the  build toolchain only in a temporary directory.  OUTPUT must not exist.
     Its absolute path must use ASCII letters, digits, underscore, dot, slash or
     hyphen. JOBS controls build parallelism, default 2.  The optional GCC  flag
     -fno-link-libatomic  disables the host compiler's automatic libatomic link-
     age when that flag is available; the musl link otherwise uses only the  se-
     lected static libraries.

     Outputs  include  busybox.holy, build.log, build.record, busybox.config, an
     applet list, ELF inspection and shell probe records.  Source  URLs,  source
     hashes,  compiler	version,  config  hash,	 artifact  hash, exit status and
     elapsed seconds are recorded. Upstream BusyBox and musl copyright files ac-
     company the payload.  The package contains /usr/bin/busybox; invoke applets
     as busybox APPLET.	 The configuration is profiles/busybox-bootstrap.config.
     It includes  ash,	basic  file  utilities,	 mount	tools,	ip,  udhcpc  and
     nslookup. The separate static-network fixture verifies interface setup, DNS
     and HTTPS with a local CA; the default boot image still has networking dis-
     abled.   LFS  is  enabled for musl's 64-bit file offsets on i686 as well as
     x86_64.  The manifest records the builder's numeric UID/GID. This is a  lo-
     cal  bootstrap  experiment,  not an official base image or a general recipe
     engine.

     make check-bootstrap-busybox BUSYBOX_PACKAGE=FILE installs the package in a
     disposable root with prepared directories, runs its shell there  with  doas
     and chroot --userspec, checks files and removes the package. Noninteractive
     doas  must	 be  available. The chroot has no dynamic libc directories. This
     fixture approves non-native placement by exact artifact hash. For x86 pack-
     ages it also requires qemu-i386 and runs the shell with  its  pentium2  CPU
     model. This tests the static shell; host holypkg still runs outside the ch-
     root.  Boot,  static holypkg and full libc recovery require separate accep-
     tance tests.

   Host build
     The core, the package manager and the installer are C99, and the  build  is
     make  with	 the  ordinary	CC,  CPPFLAGS,	CFLAGS, LDFLAGS and LDLIBS. make
     CC=tcc, make CC=gcc and make CC=clang each compile it,  and  make	check-cc
     proves  it:  the  target compiles the core with tcc, gcc and clang in turn,
     packs a package with the result, verifies it and lists  its  payload,  then
     restores  the  default  build.  A	missing toolchain returns 6 instead of a
     green run, and a toolchain that breaks the C99 build fails the target  with
     its own compiler output.

   Static core build
     make  bootstrap-mdevd  ARCH=i686|x86_64  INPUTS=DIRECTORY	OUTPUT=DIRECTORY
     builds a musl-static mdevd 0.1.8.2 package with skalibs 2.15.1.0.	The  de-
     fault  is	x86_64.	  STATIC_PREFIX	 may select a completed make static-deps
     toolchain for the same architecture; i686 requires it. The build copies and
     hashes its build.record and records the compiler wrapper hash. INPUTS  con-
     tains  mdevd-0.1.8.2.tar.gz  and  skalibs-2.15.1.0.tar.gz from the upstream
     GitHub tag archives, plus	x86_64-linux-musl-cross.tgz  from  musl.cc  when
     STATIC_PREFIX  is	omitted.  The  script  checks  pinned  hashes of private
     copies, builds with upstream configure/make, and records compiler	version,
     both  configurations,  ELF facts and artifact hash.  OUTPUT must be new and
     use ASCII letters, digits, underscore, dot, slash or hyphen. JOBS	defaults
     to	 2.  Upstream  licenses	 and  HTML  documentation accompany the package;
     docs.record reports missing man pages. No service or mdev.conf  is	 enabled
     by	 this  bootstrap build. Execline directives and external command helpers
     require additional packages and configuration.

     make check-bootstrap-mdevd MDEVD_PACKAGE=FILE installs the artifact into  a
     disposable	 root through the reviewed database plan. In a libc-free chroot,
     mdevd parses a valid configuration with symbolic root user/group names  and
     rejects  an  invalid  regular expression with status 2. Host doas, unshare,
     chroot and timeout provide a private network  namespace  and  a  ten-second
     limit.  The  command runs with the caller's UID/GID; host /dev and /sys are
     absent. The fixture then checks and removes the  installed	 package.   This
     covers  installation, static configuration parsing and removal. Uevent han-
     dling, coldplug, dinit integration and client libudev compatibility  remain
     separate acceptance cases.

     make  bootstrap-dinit  ARCH=i686|x86_64  INPUTS=DIRECTORY	OUTPUT=DIRECTORY
     builds dinit 0.22.1 as a musl-static native package, including its C++ run-
     time. The default target is x86_64. Inputs are dinit-0.22.1.tar.gz from the
     upstream  GitHub  tag   and   the	 pinned	  i686-linux-musl-cross.tgz   or
     x86_64-linux-musl-cross.tgz from musl.cc. The script copies and hashes both
     archives  before  use;  an updated archive at the same URL is rejected.  It
     runs upstream make check, includes upstream  man  pages  and  license,  and
     records  compiler version, configuration, ELF facts and package hash. Capa-
     bilities support is disabled in this bootstrap profile. This package  build
     does  not	establish  PID	1 boot acceptance; that requires the image test.
     OUTPUT must be new.

     make check-bootstrap-dinit DINIT_PACKAGE=FILE  BUSYBOX_PACKAGE=FILE  stages
     both packages and installs them through approved database plans into a dis-
     posable chroot without dynamic libc directories. It checks command and man-
     page  links,  static ELF classification, starts a scripted service, queries
     its STARTED state through the control socket, requests shutdown and  checks
     the  stop-command	effect.	  The  service	manager	 runs  with the caller's
     UID/GID in user mode. Host doas, chroot, mknod and	 timeout  are  required;
     the  fixture  supplies  only /dev/null and enforces a 20-second timeout. It
     prints the tested package hashes.	For i686 it verifies dinit  under  qemu-
     i386  with	 the  pentium2 CPU model.  After service shutdown it checks both
     installed manifests and removes both packages through  the	 database.  This
     covers  package  installation,  service control and the static C++ runtime.
     PID 1 boot remains a separate test.

     make static-deps ARCH=x86_64|i686	INPUTS=DIRECTORY  OUTPUT=DIRECTORY  KER-
     NEL_HEADERS=DIRECTORY builds musl dependencies for the selected target from
     the  pinned  archives listed with URLs and SHA-256 digests in profiles/sta-
     tic-sources. It copies and verifies inputs	 before	 unpacking.  The  caller
     supplies  Linux userspace headers with linux, asm and asm-generic subdirec-
     tories. Their installed copies receive a hash inventory. GCC, make,  CMake,
     autotools, libtool, Perl and archive tools are host build requirements. The
     multilib  GCC installation must supply libgcc for the selected target. JOBS
     controls parallelism, default 2. ARCH defaults to x86_64; i686 uses the x86
     package architecture, not the x32 ABI.  The compiler  wrapper  selects  the
     target machine and linker emulation. The bootstrap compiles and runs a sta-
     tic  probe,  checking  ELF class, machine and pointer width before building
     dependencies. The builder must execute the target for these configure/probe
     steps. Compiler flags and probe evidence are retained.

     The output is a new private prefix containing static libarchive/LZ4,  zlib,
     XZ, Zstandard, bzip2, libelf, libsolv, curl and OpenSSL, plus build compat-
     ibility  libraries.   Its	musl toolchain includes a private dynamic loader
     for upstream configure probes; the final holypkg link uses -static. No host
     libc is replaced.	Source manifests, build logs, library hashes, exit  sta-
     tus  and  elapsed	seconds	 remain in the prefix. Archive decoding includes
     gzip, LZ4, XZ, Zstandard and bzip2; the native writer still emits only  LZ4
     frames.

     make  static  STATIC_DEPS=DIRECTORY checks the completed dependency prefix,
     cleans existing object files and builds holypkg  with  its	 musl  compiler.
     make  check-static-target ARCH=i686|x86_64 STATIC_HOLYPKG=FILE MUSL_CC=FILE
     checks the static client's ELF class and machine, then runs it  under  QEMU
     user emulation. The selected CPU is pentium2 for i686 or qemu64 for x86_64.
     The  test builds a static C payload with that compiler and exercises native
     packing, installation, check, execution and removal. Its JSON report  binds
     client  and  package  hashes  and records coverage. This is a userspace ISA
     test; kernel boot, dynamic libc and physical hardware have separate  accep-
     tance gates.

     make check-static-core STATIC_HOLYPKG=FILE BUSYBOX_PACKAGE=FILE copies that
     binary  into a disposable root without dynamic libc directories. Inside the
     chroot, holypkg verifies and caches the supplied BusyBox package, installs,
     checks and removes it twice using the cached artifact. The original package
     is removed after caching. A BusyBox shell probe runs  after  each	install.
     doas  creates the chroot and drops to the caller's numeric UID/GID.  For an
     ELF32 i686 client, the fixture uses setarch i686 so the  process  sees  the
     i686  host	 personality  while the x86_64 kernel executes it. This does not
     test booting an i686 kernel.  Both artifact hashes are printed on	success.
     This  verifies  the  local	 static package path; removal and restoration of
     real dynamic libc packages, network recovery and dinit boot  still	 require
     their own tests.

     Passing  DINIT_PACKAGE=FILE  to check-static-core also installs, checks and
     removes the complete dinit package, including its	symlinks,  with	 holypkg
     running  inside  that libc-free chroot. The fixture removes the input after
     caching and reports the tested artifact hash. Service control is covered by
     check-bootstrap-dinit.

     make  check-static-network	 STATIC_HOLYPKG=FILE  BUSYBOX_PACKAGE=FILE   RE-
     PORT=FILE	tests that static client in a libc-free chroot with private net-
     work namespace, local DNS and HTTPS fixtures, and a generated test	 CA.  It
     verifies  real  DNS queries, certificate rejection, digest rejection, down-
     loading and native archive verification. The client drops to  the	caller's
     UID/GID.  The  fixture creates no external route and supplies no proxy cre-
     dentials. Python, OpenSSL, unshare, chroot and noninteractive doas are host
     test tools. The packaged static BusyBox ip applet raises the fixture  loop-
     back  from inside the libc-free chroot. Physical network recovery remains a
     separate test.

     The holy-static-network-test-1 JSON report records architecture, host  ker-
     nel,  input and fixture hashes, CA hash, per-command argv/status/time/logs,
     observed DNS query types, completed coverage and unexecuted  cases.  A  dy-
     namic  binary fails the libc-free probe. REPORT defaults to out/static-net-
     work.json. No VM image is involved, so its report field is null.  Temporary
     keys and rootfs are removed after the test.

   Package operations
     The  config  check	 command  checks  source  and rule configuration without
     changing the system. General package installation, foreign	 import,  source
     sync  and multi-source resolution are not available yet. This executable is
     independent of the separate owenewans/holypkg project.

     Pinned HTTPS fetch downloads  one	native	.holy  into  an	 existing,  non-
     writable-	by-others  output  directory.  It  requires an expected SHA-256,
     HTTPS including redirects, certificate validation and an URL without embed-
     ded user/password.	 The downloader checks each redirect target  before  re-
     questing  it  and refuses credentials in redirect URLs. --ca-file selects a
     trusted CA file for a private test or source. The command limits the entire
     redirect chain to 1 GiB and five minutes, verifies the  completed	archive,
     then  publishes  SHA256.holy  without  replacing an existing object. If the
     name exists, it compares the stored bytes with the expected  digest.  HTTP,
     unknown certificates, wrong digests and malformed archives cannot publish a
     new  object. This fetch does not assign source-id, verify a repository sig-
     nature, install files or run hooks. General foreign  binary  fetch	 remains
     separate.

     Pack reads a prepared tree containing only HOLY/ and DATA/. HOLY/ must con-
     tain  exactly  meta,  files, deps, provides, hooks, origin and transform as
     ordinary files. DATA/ may contain directories, ordinary files, symlinks and
     direct hardlinks. The writer rejects extended attributes. It  records  file
     modes  and	 numeric  ownership, fixes archive timestamps to zero and orders
     directory entries by name. It writes a POSIX PAX tar compressed as	 an  LZ4
     frame to a temporary file alongside the destination, verifies the completed
     artifact,	checks	known  ELF  ABI	 facts and supported dependency/provider
     records, and publishes it only when the destination does  not  exist.  Pack
     neither  generates	 HOLY/files  nor infers ABI facts. A mismatched manifest
     fails without publishing a package; recipes and foreign conversion are sep-
     arate work.

     Manifest generate reads DATA/ below DIRECTORY and writes HOLY/files records
     to a new output path outside the input tree. It emits directories and ordi-
     nary files, symlinks and  hardlinks  in  sorted  traversal	 order,	 numeric
     UID/GID, modes, sizes, link targets and SHA-256 digests for ordinary files.
     Symbolic  owner/group names are placeholders; the numeric values remain the
     source tree's ownership. The command refuses  xattrs,  escapes  paths  with
     whitespace	 or  non-ASCII	bytes,	and does not replace an existing output.
     Copy the generated file to HOLY/files and run pack; neither command  infers
     package arch/libc or dependencies from arbitrary data files.  Both commands
     inventory regular files by device and inode before writing.  For each inode
     shared  by	 multiple  DATA paths, the bytewise smallest path is the regular
     anchor. Other names are direct hardlinks to it, including when tree traver-
     sal visits an alias first. The group identifier is the SHA-256 of	the  an-
     chor's  archive path, independent of host inode numbers. Links outside DATA
     are not archived; a file with only external  aliases  remains  independent.
     Changed  file  identity,  attributes  or  link count during the read causes
     failure.  The input tree must remain stable throughout generation and pack-
     ing.  Archive pack and  inspection	 use  the  active  LC_CTYPE  locale  for
     libarchive	 pathname  conversion.	Use  an available UTF-8 locale for UTF-8
     filenames.

     Pack and manifest generation read symlink targets without	following  them.
     They reject lexical traversal above the target root; absolute targets refer
     to	 that  root.  Dangling links are preserved. Symlink xattr inspection re-
     quires /proc/self/fd on the build host. Metadata files must remain ordinary
     files.  These commands do not resolve chains of symlinks or  prove	 runtime
     targets  exist.   The  separate fetch --extract operation still refuses ab-
     solute symlinks.

     The db plan-set command resolves one explicit root against	 already  cached
     candidate	hashes	and cached artifacts from the installed catalog. It sup-
     ports exact-name package dependencies and	the  documented	 pacman	 version
     constraints  between Linux data, native static and restricted dynamic pack-
     ages, and nonempty hooks only after an explicit skip decision, existing  or
     declared  safe  directories and the same payload subset as db apply. It re-
     ports selected artifacts, reasons and requirement	edges  without	changing
     installed	state.	 Unused	 candidates are excluded from the operation. The
     plan digest binds target-root device/inode, generation, selected graph, ex-
     plicit provider choice and every selected manifest. Inter-package path  and
     slot conflicts are rejected.

     The  db  apply-set command accepts the reviewed plan digest followed by the
     same root and candidates. It holds one writer lock, checks the  plan  again
     and  writes transactions/set-journal before the first payload. All selected
     packages share one generation increment. Installed state  records	the  ex-
     plicit  root  and	dependency  reasons;  each instance retains the selected
     graph. The interface does not execute package hooks. A skipped hook  leaves
     the  package  installed-unconfigured.  Upgrades and grouped removal are not
     implemented by this interface.

     Repeated --skip-hooks SHA256 accepts every HOLY/hooks record in  the  exact
     selected  artifact	 without running its scripts. Without the flag, plan-set
     returns 3 and prints the hook records for review. The skip decision  enters
     the  plan	digest	and set journal; apply requires the same flag. Installed
     state retains the hooks, transform and  a	hash-bound  hooks-state	 record.
     check reports skipped-hook with status 4. An unrelated artifact cannot con-
     sume this decision.

     db	 configure-plan	 reviews native postinstall records with the syntax hook
     postinstall INTERPRETER RELATIVE_SCRIPT_PATH sha256 DIGEST	 in  HOLY/hooks.
     The  interpreter  is  an absolute target-root path. The script is a regular
     file owned by the installed package and its digest must match.  The command
     shows each script body, interpreter, root and UID, then prints a plan  hash
     without running code. The hash also binds the interpreter file bytes.  For-
     eign-script records and other phases remain unsupported by this command. db
     configure-apply  requires	that  hash and root privileges; it runs each re-
     viewed script through its interpreter inside a chroot of the selected  root
     with  PATH=/usr/bin:/bin, HOME=/ and LANG=C. Hooks may change files outside
     their package manifest.  The manager does not claim  isolation  from  arbi-
     trary root code.

     Before each hook, configure-apply synchronizes a running record in transac-
     tions/hook-journal. A successful hook advances the record. A failed hook or
     crash leaves status 5 and requires db configure-recover --retry before that
     hook  runs	 again.	 The user must inspect external effects before retrying.
     After all hooks succeed, hooks-state becomes  completed  and  the	database
     generation	 advances.  A  pending	hook journal blocks other package opera-
     tions.  The current command handles native postinstall hooks after	 instal-
     lation; preinstall, editing, service consent and automatic configure during
     add remain open.

     Repeated  --accept-privileged  SHA256 confirms installation of regular exe-
     cutable files with setuid in that	exact  selected	 artifact.  Without  it,
     plan-set returns 3 and names the artifact, path and mode. The choice enters
     the  plan	hash,  set  journal and installed state; apply requires the same
     flag. Setgid, sticky bits, setuid directories, symlinks and  hardlinks  re-
     main unsupported. The choice covers only native set transactions, not local
     preview,  single-package apply or cached update. The caller must review the
     full artifact payload and the target root before approving the mode.

     Repeated --accept-arch SHA256 confirms placement of selected new  artifacts
     whose  architecture  differs  from the native host mapping. Each exact hash
     needs its own decision. Without it, plan-set returns 3  and  reports  arti-
     fact,  host  and target. This includes x86 on an x86_64 host when execution
     support has not been established. The manager does not infer  IA32	 support
     from  uname alone.	 The flag does not execute payloads, change target meta-
     data, waive dependency ABI checks or confirm that the kernel  can	run  the
     result.  Native/noarch  artifacts, duplicate decisions and malformed hashes
     are invalid flag uses; unselected or already installed artifacts require  a
     separate decision.

     The  plan	displays  accepted-unverified with artifact scope and hashes the
     host/target decision. Apply must receive the same flags.  A  version-3  set
     journal  preserves them and the host for recovery, including when only part
     of the set was installed. Installed holy-instance-5 state retains the deci-
     sion; check reports accepted-arch-mismatch in text or an optional architec-
     ture object in JSON, with execution unverified. This  annotation  does  not
     turn  intact  files  into a failure. Reused providers retain their existing
     decision on that host.  It does not authorize a new artifact  hash:  cached
     replacement  of an instance carrying this decision currently returns 3. Up-
     date-specific  architecture  approval  and	 automatic  execution-capability
     probing remain unimplemented.

     Repeated --source ARTIFACT=SOURCE_ID explicitly associates selected new ar-
     tifacts with active registered sources. It is a user-confirmed origin asso-
     ciation  for  local delivery, not proof of retrieval or signature verifica-
     tion. Payload source-name/origin metadata cannot  grant  this  association.
     Unmapped new artifacts retain local delivery without a source ID. Duplicate
     artifact  mappings	 are  invalid;	a mapping for an unselected artifact re-
     quires a decision. Missing or inactive registered sources return 6.

     The plan displays each association and binds the registry digest and  saved
     alias  record.  Apply  requires the same mappings and registry; changing an
     alias after review invalidates the plan. The version-2  set  journal  saves
     associations  for recovery. Registry mutation is blocked while that journal
     remains incomplete.  Recovery verifies the source record of each  completed
     instance before continuing.  An already installed provider keeps its origi-
     nal  source  and  alias; specifying a new association for a reused instance
     returns 3. Source migration requires a separate operation, which is not im-
     plemented yet.

     An already installed dependency is reused only after its  metadata	 matches
     the  cached archive, its payload and ownership pass checks, and its own se-
     lected dependency edges remain unchanged. Its state, reason and  graph  re-
     main  intact;  the new consumer records its edge to that provider. The plan
     hashes the reused instance state as well as the selected  manifests.  Apply
     and  recovery verify it again and never reinstall it. The preview labels it
     installed. Re-requesting an already installed explicit root  returns  deci-
     sion-required;  this  interface  does not yet promote dependency reasons or
     perform reinstalls.

     Candidate discovery reads installed names and manifests for the package and
     literal ELF-path requirements of  the  supplied  candidates,  then	 follows
     their dependencies. For a HOLY/deps SONAME requirement it filters installed
     packages  by  recorded arch/libc, then scans their cached archives and com-
     pares actual DT_SONAME, ELF type and ABI scope; the name of a package or an
     unverified claim is insufficient. Other discovery uses installed names  and
     manifests. Installed candidates currently require their cached archives for
     ELF  scanning.   A	 missing archive returns unavailable instead of guessing
     ABI facts. Reuse requires the version-2 or version-3 installed  graph  for-
     mat.  Multiple  viable  providers	still  require	--choose;  automatic in-
     stalled/source preference ranking remains open.

     Dynamic sets require literal absolute PT_INTERP paths.  Absolute  DT_NEEDED
     paths  must  name exact provider payload paths. For a bare SONAME, the con-
     sumer must have a nonempty list of absolute RUNPATH or  RPATH  directories,
     or	 directories  based  on $ORIGIN. Holy resolves $ORIGIN from the consumer
     path inside target root and rejects traversal above that root. The selected
     provider must own a matching ELF file at the first existing  DIRECTORY/SON-
     AME,  or  own  its symlink chain. The planner checks architecture, runtime,
     symbols and version needs, and rejects unknown tokens  or	empty  path  en-
     tries.   It  rejects  a later provider when an earlier directory contains a
     file at the same SONAME. Installed	 check	repeats	 this  path-order  check
     against  the  target  root.  Cached  replacements	use the same validation.
     Loader defaults, other tokens paths and aliases crossing package  ownership
     remain  unresolved.   Parent  directories must exist or be declared in that
     package manifest; installation does not traverse  symlinked  parents.  This
     interface	does  not  automatically  rewrite  ELF	files  or resolve loader
     aliases.

     An interrupted set leaves generation unchanged unless final commit	 already
     published it. db status returns 5 for a recognized set journal.  db recover
     --finish-set  verifies  cached artifacts, the original plan hash, installed
     metadata/graphs and actual payloads before completing  generation	publica-
     tion  and	removing the journal. --continue-set additionally installs pack-
     ages that have no installed instance yet, after checking the whole	 remain-
     ing  set.	Already	 written payload must match exactly; missing entries are
     restored.	Neither mode overwrites a partial file or  repeats  a  partially
     written  instance.	 Those	cases require inspection. Recovery rejects mixed
     journals, changed artifacts, ownership conflicts  and  drift  in  completed
     package files.  The cache must retain the selected artifacts.

     db	 rm  lists installed consumers and requirements that still reference the
     provider. Without --accept-broken it returns decision-required status 3 and
     leaves the root unchanged. The explicit flag permits removal while	 retain-
     ing  those	 consumers  and their saved edges. db check then reports broken-
     provider.	Installing the original provider from cache through a new  plan-
     set  restores the graph when the same requirement can be satisfied. A saved
     graph belonging to a removed consumer does not keep its former dependencies
     alive. A completed removal retains a transaction  directory  keyed	 by  the
     SHA-256  of  its  plan, with the removed artifact, original generation, ac-
     cept-broken decision and a committed marker. The removed instance record is
     retained there as old-instance before the database generation changes.  Re-
     covery  uses that record if removal stopped after the instance left the in-
     stalled directory, and retains the decision when it completes.  Grouped re-
     moval remains pending.

     check  without  a	reference  inspects  all  installed   instances.   check
     SOURCE:PACKAGE  finds  the installed slot using its recorded source ID, in-
     cluding a source that is now inactive. files prints sorted	 absolute  paths
     from  that	 slot's installed manifest even when a live file has changed. It
     does not require the cached archive. When arch/libc variants make the  ref-
     erence  ambiguous,	 these	commands return decision-required status 3 until
     --arch or --libc selects one.  rm SOURCE:PACKAGE resolves the same slot and
     shows its artifact hash before confirmation. Without a terminal it	 returns
     decision-required	status	3; --yes confirms removal of that selected arti-
     fact. --accept-broken separately  permits	removal	 despite  dependent  in-
     stalled  packages. The database engine rechecks files, dependency edges and
     journal state under its writer lock.

     why SOURCE:PACKAGE reads the installed graph and prints one shortest  saved
     dependency	 path  from  an explicit root to that package. A package with no
     path from an explicit root is marked orphan. The command  reads  no  cached
     archives and makes no changes. It refuses incomplete or malformed installed
     graphs  and  missing provider instances. JSON output uses schema holy-why-1
     with path, orphan and summary events. The path reports package  identities;
     exact  requirement	 names remain in the saved graph and are not included in
     this view.

     add local:FILE stages a verified native artifact in  the  selected	 target-
     root  cache,  builds  a  read-only	 package-set plan and shows its selected
     packages, providers and plan hash. --candidate adds local archives	 to  the
     resolver  pool;  only  selected  packages are installed. --choose binds one
     stable requirement ID to an exact provider artifact hash. The default  root
     is	 /.  Local  archive metadata cannot assign a trusted source-id.	 --asso-
     ciate-source ALIAS is an explicit confirmation that the root local artifact
     belongs to an active registered source. The manager resolves the  alias  to
     its  immutable source-id under the database lock and binds that ID into the
     reviewed plan. This flag does not infer provenance from  archive  metadata,
     verify   a	 publisher  signature  or  associate  the  candidate  dependency
     archives. The association	requires  a  registered	 active	 source	 and  is
     checked  again  before apply.  --associate SHA256=ALIAS binds a staged root
     or candidate artifact to an active registered source.  The hash must  match
     an	 artifact supplied to this add operation. Repeat the option for packages
     from different sources; duplicate hashes are rejected.  This is an explicit
     provenance decision for each artifact, not signature verification. The  re-
     viewed  plan  records  each  binding and checks it on apply.  --accept-arch
     SHA256 confirms placement of one selected artifact whose architecture  dif-
     fers  from	 the  native  target.  It does not change the target metadata or
     prove execution.  --accept-privileged SHA256 confirms setuid placement  for
     one  selected  artifact. Both options may be repeated for distinct artifact
     hashes. The plan records each decision and apply checks it	 again;	 an  ap-
     proval for a previous version is not inherited.

     With  a  terminal,	 add asks for y before applying the displayed plan. An n
     answer leaves installed state unchanged. Without a terminal, add returns  3
     after  printing  the  plan	 and stages no installed files. --noninteractive
     forces this behavior unless --yes is also given. --yes  approves  only  the
     exact  plan  displayed by this invocation; the engine rebuilds it under the
     writer lock and refuses a changed generation, artifact or provider	 choice.
     --yes does not resolve missing dependencies.  Architecture and setuid deci-
     sions  require  their exact-hash flags. The cache may retain staged objects
     after a declined or unresolved operation. Automatic doas escalation, source
     lookup and script execution are not part of this local subset.

     add SOURCE:PACKAGE reads one sealed native mirror made by	sync.  --catalog
     selects a mirror for this invocation; without it the manager reads the mir-
     ror  bound	 to  the  active  source-id  by	 source catalog bind. The active
     source-id and URL must match the mirror record. For an index with	complete
     dependency, file and ELF SONAME records, the manager opens the root archive
     and indexed candidates reachable through declared requirements, interpreter
     paths,  shared-library  names and script interpreters. It verifies each se-
     lected candidate against the index before staging. Older indexes still  use
     the  full	candidate pool. If multiple packages share the root name, it re-
     turns decision-required (3). Every newly selected catalog package	receives
     the  registered source-id; reused installed providers retain their existing
     source. The reviewed plan binds the catalog index digest and selected arti-
     fact hashes. Before apply the manager  rechecks  the  source  and	catalog;
     changes  require  a  new  decision.  The transaction journal retains source
     bindings and index digest for recovery without network access.  An unsigned
     mirror record proves only local provenance. A source with a registered pub-
     lic key requires a signed mirror and rechecks its signature.  An  unrelated
     corrupt archive in a current indexed mirror does not block add; source cat-
     alog  bind	 and  sync still verify entire mirrors. The current add path can
     combine explicitly named candidate packages from other active sources  with
     --candidate SOURCE:PACKAGE.  Each candidate source must have a bound sealed
     mirror.  The  manager  stages  its	 indexed dependency closure, records the
     source-id of each selected artifact, and rejects an artifact  hash	 offered
     by	 two candidate sources. It checks each candidate mirror's source-id, in-
     dex digest and staged hashes again before apply. The root catalog index  is
     saved  in	the  transaction journal; the exact selected artifact hashes and
     source  bindings  are  saved  for	 every	 source.    --candidate-provider
     SOURCE:KIND:NAME  selects matching packages by exact indexed package, file,
     command or SONAME facts from the named source, then stages their  in-source
     dependency	 closure.   The selected package still undergoes payload and re-
     solver checks. The option requires a native index with complete dependency,
     file and SONAME records; an unavailable index returns status 6 and	 a  com-
     plete  index  without  a match returns status 4. Multiple matching packages
     remain candidates for  the	 reviewed  provider  choice.   --candidate-local
     SOURCE=FILE.holy  adds  a	verified local artifact to the same resolver and
     set plan as the native root package. SOURCE must be  an  active  registered
     alias;  the  option records the user's explicit source association and does
     not infer trust from the artifact metadata. This accepts outputs from  for-
     eign import, including APK.  The manager stages the artifact by hash, binds
     its  source-id  in	 the plan, and rechecks the source and local file before
     apply. Dependencies and ownership are checked by the usual set engine. Fur-
     ther foreign dependencies need additional candidate inputs until  a  source
     adapter  can  discover  them.  When a set has an unsatisfied exact package,
     package-or, file, command or SONAME edge, add probes  active  bound  native
     catalogs  for  that  edge	before	staging	 foreign artifacts. One matching
     source with complete coverage supplies its providers and in-source closure.
     For multiple offers, add prefers the missing consumer's registered	 source-
     id, then its saved parent source-id, then a matching source family. It next
     compares  configured source priorities within the same group; larger values
     win. It prints each rank and priority. An --answers entry	overrides  these
     preferences.  Remaining ties, or a family/priority match alongside unavail-
     able coverage, list aliases and ask for  one  on  a  TTY.	 Active	 foreign
     sources  are  skipped  during this native-catalog probe; their absence of a
     native mirror is not counted as a failed native lookup.  For a scanned  ELF
     SONAME  edge,  the	 source	 probe	checks	the consumer's machine, runtime,
     strong version needs and provider-attributed imported symbols against  each
     indexed  candidate.  A  same-name	library missing such a symbol is not of-
     fered.  An explicit SONAME metadata requirement without a consumer ELF path
     uses exact indexed-name lookup.  Without a TTY or	under  --noninteractive,
     add  returns  decision-required; --candidate-provider names the choice in a
     subsequent command. --yes approves the final plan but does	 not  choose  an
     ambiguous	source.	 The loop stops when the set is complete or no new arti-
     fact is found. It checks installed providers first; an inactive origin  can
     still satisfy a new consumer. An edge without a catalog match does not hide
     another  missing  edge in the same consumer; a required SONAME can still be
     found after an interpreter or libc path already satisfied by  an  installed
     package.  An  unavailable	catalog leaves coverage incomplete and returns 6
     when no provider can be found. Older indexes without file or  SONAME  facts
     report  unavailable  coverage for those requirements. Selected packages re-
     tain their source IDs, and candidate catalogs are checked again before  ap-
     ply. Fuzzy suggestions and runtime plugin discovery remain open. Executable
     hooks remain outside the supported installation subset. Recorded transforms
     are  accepted after payload verification; no transformation runs during in-
     stallation.

     For add SOURCE:PACKAGE, --answers FILE supplies source decisions by  stable
     consumer  artifact	 hash  and  requirement-id.  The file uses the holy.conf
     lexer: format holy-answers-1 on its first	non-comment  line,  followed  by
     records  source  CONSUMER_SHA256 REQUIREMENT_ID SOURCE_ALIAS. Quoted tokens
     are accepted.  The manager copies the file before staging	candidates,  re-
     jects duplicate consumer/id records, and checks that the named source actu-
     ally  offers  the	requirement.  Other decisions still use their documented
     flags. An answer tied to an old consumer  hash  cannot  silently  select  a
     provider after that artifact changes.

     up SOURCE:PACKAGE finds one installed slot by its immutable source-id, name
     and  optional  arch/libc.	It  checks the old artifact in the target cache,
     verifies the pinned catalog index, and compares its  records  in  the  same
     name/os/arch/libc	slot.  It  stages only the chosen artifact and checks it
     against its index record and actual payload. Other versions are not opened;
     a broken unselected archive does not block this slot update. Known	 pacman,
     deb,  apk,	 xbps and holy comparator families select the highest newer ver-
     sion; unknown or mixed comparator families	 require  --choose  SHA256.  The
     chosen  digest  can  explicitly select a rebuild or older version. No newer
     candidate leaves the system unchanged and writes no plan.	APK compares its
     full upstream pkgver, including -r revision. XBPS combines version and  re-
     lease  with  the  source  _revision  convention  before comparison.  An un-
     parsable version or an older index without comparator metadata still  needs
     an explicit choice.  An absent old artifact, missing source slot or changed
     catalog  is reported.  Without --prepare, up prints the full proposed plan,
     saves it, then asks for approval before applying the exact	 file  and  hash
     through the same apply command.  --yes approves only that plan; it does not
     choose an ambiguous version or approve architecture and privileged-file de-
     cisions.  Without a terminal or with --noninteractive, missing approval re-
     turns 3 and leaves the plan file for review.  --output  selects  its  path;
     otherwise	up creates a private temporary plan path.  Successful direct ap-
     plication removes that temporary file. --prepare only writes the  plan  and
     retains its temporary path; --yes is invalid with it.

     Preparation  writes  a  new mode-0600 plan file with the source-id, catalog
     path and index digest, old/new artifact hashes, exact version decisions and
     the complete update plan. It changes only	the  target  cache.  Review  the
     file, then run apply PLAN --sha256 PLAN_SHA256 with its whole-file SHA-256.
     Apply  snapshots and verifies the file, checks its embedded update-plan di-
     gest, active source and unchanged catalog generation. It  checks  that  the
     new artifact belongs to the installed slot in that exact index, even when a
     cached  artifact would satisfy the embedded database plan. It then rebuilds
     the plan under the writer lock. A changed database, source or payload needs
     a new plan. Successful apply uses the existing journaled cached-update  en-
     gine; its recovery command is db recover --update. This subset prepares one
     slot  at a time. Grouped updates, signed catalogs and root/VM trials remain
     open.

     The db plan command reads the prepared reservation at the current	database
     generation.  It  verifies a private snapshot of the cached artifact, checks
     root-path collisions and refuses unresolved requirements, interpreters  and
     ELF dependencies. The supported planning subset is linux/nolibc with noarch
     data  or  the  native  host  architecture	(x86_64 on x86_64, x86 on i686).
     Hooks must be empty. HOLY/transform may record completed  payload	changes.
     Payloads  may  contain  ordinary directories and regular files and relative
     symlinks owned by the current  UID/GID.  Hardlinks,  privileged  modes  and
     writes  inside  holypkg  state or cache trees are excluded. Output includes
     target-root device/inode, generation, artifact SHA-256, path  count  and  a
     SHA-256  over those identities and ordered manifest entries, including sym-
     link types and targets, and the  canonical	 resolver  record.  That  record
     identifies	 artifact candidates, not physical loader bindings. Apply stores
     the approved record as installed graph with a SHA-256  in	instance  state.
     Symlinks must have mode 0777. The narrow local planner rejects a second ac-
     tive  version  of the same slot, even when its payload paths differ. A slot
     consists of source-id, name, os, arch and libc; unassociated local delivery
     uses source-id "-". Source aliases and package versions do not  change  the
     slot.  Distinct  slots may coexist when their file ownership is compatible.
     The installed directory remains keyed by artifact hash, so registering  the
     same  artifact  as	 multiple installed instances is still unsupported. Slot
     replacement requires update transactions, which are  not  yet  implemented.
     This command does not persist a plan, reserve ownership, authorize apply or
     recheck the target root at mutation time. Concurrent changes can invalidate
     the  collision  check.  Apply revalidates inputs and paths under its writer
     lock.

     The db approve command recomputes the  plan  under	 an  exclusive	database
     lock.   If	 its  SHA-256 matches PLAN_SHA256, the command replaces the pre-
     pared reservation with an approved record bound to its artifact and genera-
     tion.  Status reports the approved digest; cancel	removes	 the  record.  A
     mismatched plan returns decision-required without changing the reservation.
     Approval  does  not  install  files or authorize a future implementation to
     skip path, artifact and generation checks under the same writer lock at ap-
     ply time.

     Database recheck compares an approved record with a  fresh	 verified  cache
     snapshot  and  target-root	 collision preview under a shared database lock.
     It returns 5 without an approved record, 3 if the plan digest differs and 4
     for a path conflict. The check changes neither database nor  rootfs.  Other
     processes	can  change  rootfs  paths  after recheck; it cannot replace the
     writer-locked validation required by apply.

     Plan construction checks each payload path against installed  manifests  as
     well  as  rootfs. An absent file remains owned until its installed claim is
     removed; another package cannot acquire that path by recreating it.  Shared
     directory	claims	remain	permitted. These checks read manifests directly;
     generated ownership indexes are not required for correctness.

     Database apply installs only an approved linux/nolibc  package  with  empty
     hooks and requirements. HOLY/transform is retained as a record of completed
     changes  and  is  never executed by apply. Its payload may contain ordinary
     regular files, including native static ELF executables, relative  symlinks,
     direct hardlinks and directory entries. Existing directories must match the
     manifest's	 mode  and numeric owner/group. Missing parents require explicit
     directory entries in that package; apply creates them in parent-first order
     before writing files.  A changed directory is  rejected  before  writing  a
     journal.	No  absolute  symlink,	privileged mode or file collision is ac-
     cepted. The caller must review the db plan digest	and  invoke  db	 approve
     first.  Apply  holds the database writer lock, recomputes the approved plan
     and rechecks every path against opened directory descriptors.   It	 creates
     each  regular  file  with	O_EXCL, then synchronizes it and its parent.  It
     creates symlinks with symlinkat without replacing existing entries and syn-
     chronizes their parent directory. Hardlinks use linkat after their verified
     regular targets are available, with no replacement of existing  names.  All
     parent  paths  must  be  real directories; payload writes do not follow in-
     stalled links. Relative  targets  may  be	dangling.   Lexical  containment
     checks  do	 not  prove the runtime meaning of symlink chains.  It records a
     journal before changing the rootfs and publishes installed metadata and the
     next database generation after copying payload files. The installed  record
     contains meta, files, deps, origin and state; local delivery has no trusted
     source-id.	 Apply	does  not  run package hooks or configure services.  De-
     clared directories require local numeric ownership,  owner	 search	 permis-
     sion,  and	 no group/other write or privileged mode bits. Apply prepares an
     empty publishes it with renameat2(RENAME_NOREPLACE)  and  synchronizes  the
     parent.   Missing renameat2 support prevents publication. Existing directo-
     ries are never chmodded or replaced. Archive entry order does not determine
     creation order.  A complete staged	 directory  can	 be  reused  by	 set/up-
     date/repair  recovery;  a	partly initialized or nonempty staging directory
     requires inspection.  Removal retains  directories	 and  unregistered  con-
     tents.

     An	 I/O  failure after journal publication leaves an incomplete transaction
     for inspection; db status returns 5 and db recover does not retry file  mu-
     tations.  db  recover --abort-empty can clear an incomplete journal only at
     its original generation, with the same approved artifact and  no  installed
     instance or payload files. Already created directories remain in place.  It
     retains  approval for a later apply or cancel.  Otherwise the operator must
     inspect the rootfs and journal manually.  A crash after publishing the next
     generation can leave the journal and approved reservation	behind.	 db  re-
     cover  --finish-apply  verifies the installed instance, its generation, all
     listed payload files and  any  remaining  approval	 before	 clearing  those
     records.  It refuses an incomplete payload and does not resume file extrac-
     tion.  A regular successful return requires both the installed  record  and
     generation	 publication.  General ownership replacement and automatic roll-
     back are not implemented. The command is not  an  installer  for  arbitrary
     .holy packages.

     db plan-update OLD_SHA256 NEW_SHA256 --root DIRECTORY previews one explicit
     cached  replacement.  It keeps the installed source-id, name, OS, architec-
     ture and libc slot; a different slot or an already active	target	artifact
     conflicts.	  For  a  non-native  target, plan-update requires --accept-arch
     NEW_SHA256 even when the old  installed  package  had  approval.  The  plan
     records  host  and	 target,  and  the new installed instance retains target
     metadata with an unverified execution status. Apply repeats the  flag;  re-
     covery reads it from the journal.	This authorizes placement, not execution
     by	 the  current kernel.  If the new artifact contains a setuid executable,
     plan-update requires --accept-privileged NEW_SHA256. The old installed  de-
     cision only authorizes checking and replacing the old file; it does not ap-
     prove  the	 new  hash. Apply must repeat the same flag. Update journal ver-
     sions 2, 3 and 4 bind privilege, architecture and both  decisions,	 respec-
     tively, to the new artifact.  Setgid, sticky and privileged hardlink groups
     remain  unsupported.  It requires the old archive, the proposed archive and
     archives for every other installed package in the cache. It does not select
     versions or download missing dependencies. The caller  explicitly	proposes
     local  delivery  in  the  installed  source's slot; metadata inside the new
     archive cannot assign a source-id or provide signature evidence.

     The command takes the database's shared lock, refuses pending  transactions
     and  checks  installed metadata, file ownership, payload and saved provider
     edges.  It verifies the entire proposed set with the old artifact	replaced
     by the new one. A broken dependent outside the updated package's own depen-
     dency  graph therefore prevents a valid plan. New dependencies must already
     be satisfiable by that proposed set; ambiguous  edges  return  decision-re-
     quired.  Installed reasons and all current state hashes remain bound to the
     plan.

     The first output line reports the SHA-256 of the  following  UTF-8	 record.
     The  holy-update-plan-1  record has update, installed, files and graph sec-
     tions.  It includes database generation, root/database  device  and  inode,
     old/new  hashes, source registry digest and current source alias, every in-
     stalled state hash, the canonical file delta and the  proposed  graph.  Re-
     peating  a	 preview  with	the  same  inputs produces the same bytes. Alias
     changes keep source identity but invalidate the plan; a deactivated  regis-
     tered  source  returns unavailable (6).  Unassociated local packages retain
     source-id "-".

     This preview writes no installed state or payload and executes  no	 package
     code.   Missing  or  modified ordinary installed files conflict. A modified
     regular file marked config in both artifacts stays at its public path;  the
     incoming  payload	is planned at PATH.holy-new. The plan binds the observed
     content hash and mode.  An existing PATH.holy-new must match the old  arti-
     fact  exactly;  the  update  then	replaces  it.  A  changed  or  colliding
     PATH.holy-new conflicts. Directory metadata changes,  hooks,  new	provider
     selection	and  multi-package  replacement are not implemented. The printed
     record is not accepted by db apply or db apply-set. JSON output is not  im-
     plemented.

     The  internal  file  planner  records retained, added, replaced and removed
     paths with stable IDs and archive hashes. Unsupported entries remain in the
     record and prevent application. Recovery checking accepts exact old or  new
     objects and rejects unrelated changes.

     db	 apply-update PLAN_SHA256 OLD_SHA256 NEW_SHA256 --root DIRECTORY applies
     that cached replacement after reconstructing  and	comparing  the	approved
     plan  under  the  writer lock. It preserves explicit/dependency reasons and
     source identity, rewrites each installed consumer's own provider edges, and
     increments the database generation once. A changed root, registry,	 genera-
     tion, artifact or installed state requires a new preview.

     Before  changing  target  files,  apply checks reserved sibling names, pub-
     lishes an immutable journal and plan  under  transactions/update,	prepares
     the  next	installed database, and stages all changed payload. The progress
     record tracks the latest file transition ID and  its  intent/result.  Files
     become  visible  individually; the operation does not atomically switch the
     whole rootfs.  Database  publication  requires  renameat2(RENAME_EXCHANGE),
     tested  on	 that  filesystem before payload mutation.  After validating the
     new payload, database and generation, apply retains the  old  database  and
     journal  under  transactions/PLAN_SHA256.	It  retains cached old archives.
     These records can supply a reviewed reverse update	 through  holypkg  roll-
     back.

     holypkg  rollback	accepts	 the  hash of a committed update transaction. It
     checks the committed marker, journal and exact plan hash, then  previews  a
     reverse  replacement  using  the cached old artifact and the current depen-
     dency graph.  The rollback-plan line gives the SHA-256 of the following up-
     date plan.	 --apply requires that exact hash; a stale plan or changed  root
     fails  before mutation. The reverse replacement gets its own update journal
     and recovery path.	 --accept-arch	and  --accept-privileged  are  artifact-
     scoped decisions for the restored artifact. Rollback is limited to one com-
     mitted update whose new artifact still occupies the installed slot. Missing
     cache  objects  return 6.	This operation restores package files and depen-
     dencies. It does not reverse external  hook  effects,  migrations	or  user
     data.

     When  an  update preserves a modified config, the installed instance stores
     the source HOLY/files as package-files and records the local files manifest
     plus its hashes in config-state. The local manifest owns both the preserved
     public config and PATH.holy-new. check and owner use that manifest; a later
     package update carries it forward. Changing the preserved	file  after  the
     plan was reviewed invalidates apply. Package removal leaves config files on
     disk  and	removes	 PATH.holy-new. Missing-only repair maps archived config
     bytes to PATH.holy-new and checks the installed manifest after  extraction.
     It	 cannot	 recreate a missing preserved public config from the archive and
     rejects that case before journaling. A repair plan binds the installed man-
     ifest hash.

     Hardlink updates stage one inode per new group and link each  changed  mem-
     ber's  temporary path to it. A group-stage record binds the reserved anchor
     sibling name to the plan. Retained anchors keep their inode. Group	 staging
     links  remain  until the new database and generation are published; cleanup
     validates the final groups before removing them. Equal bytes alone	 do  not
     satisfy  a	 group split or merge. External hardlinks to replaced files keep
     the old inode.

     db recover --update revalidates  the  immutable  plan,  cached  inputs  and
     old/new  file states before continuing the interrupted operation. It recog-
     nizes a completed database exchange or generation publication and does  not
     repeat them. Other state operations refuse the active update with status 5.
     Recovery  preserves  unexpected  or partly written reserved staging objects
     and returns 5 for inspection; it does not delete them automatically.  Miss-
     ing  cached inputs must be restored. Interruption before publishing the im-
     mutable journal requires manual  inspection.  Unchanged  files  must  still
     match  their  recorded  state. Recovery can finish a reviewed PATH.holy-new
     publication; it does not execute hooks or merge file contents.   An  inter-
     rupted  setuid update can leave a reviewed executable under a reserved mode
     are shown in the file plan; root operators must treat it as installed code.

     The internal resolver can also validate a complete proposed  artifact  set.
     It	 requires  every supplied artifact, including disconnected consumers and
     dependency cycles. Missing requirements fail the  set;  ambiguous	provider
     edges still require a decision. The caller must construct the installed set
     after  replacement	 and preserve instance reasons and source bindings. This
     interface does not discover update candidates or apply transactions.

     Static executable installation verifies ELF architecture and nolibc  facts;
     it	 does not execute package programs. The caller may run an installed pro-
     gram as a separate action. Executable payloads with an unknown  format  are
     refused;  an  executable  script  with  a direct absolute shebang creates a
     file-specific dependency edge to an executable ELF at that	 exact	path  in
     the selected set.	For relative symlinks in the supplied candidate set, the
     planner  follows  each  alias  and records a separate provider edge for its
     owning package and the final executable ELF. It rejects  ambiguous	 aliases
     and chains longer than 16 hops with a decision-required result. These edges
     are  saved	 in installed state and block provider removal unless the caller
     accepts broken dependents. The planner requires a decision	 for  env,  mal-
     formed  shebangs and paths it cannot resolve. For a newly added script, the
     planner reads existing relative aliases inside the target root and	 aliases
     in	 the supplied .holy candidates, then adds reachable installed owners and
     the final ELF owner to the candidate set.	 This  discovery  needs	 openat2
     with  root-confined path resolution; when the syscall is unavailable it re-
     turns a requirement error.	 Foreign architecture, including x86 on	 x86_64,
     returns  requirement  error 6 until architecture override decisions are im-
     plemented. No metadata is relabeled.

     Database check reads one installed manifest and compares its regular  files
     against  the  target  root by path, type, size, mode, numeric ownership and
     SHA-256. It compares symlink type, mode, numeric ownership and exact  read-
     link  target  without  following  the  link.  It  checks listed directories
     against their manifest mode and numeric owner/group and  rejects  symlinked
     parent  paths.  It	 returns  4 for changed or missing files, 6 when the in-
     stance is absent, and 5 while a file transaction is incomplete. The command
     neither downloads an archive nor repairs a file. This restricted check also
     checks recorded interpreter,  shebang  and	 needed-path  providers	 against
     their  installed  manifests. Missing or changed provider files produce bro-
     ken-provider findings with the absolute target path.  For	an  intact  exe-
     cutable  script it checks the shebang interpreter within the target root. A
     missing interpreter fails; a malformed shebang, env command, invalid inter-
     preter ELF or unresolved path reports unknown. This does  not  test  inter-
     preter  libraries	or runtime behavior. A missing openat2 syscall returns 6
     and reports unknown coverage.  For saved SONAME edges, check  opens  intact
     provider  ELF files through the target root and compares actual SONAME, ELF
     class, machine and strong version needs.  A direct literal loader directory
     can pass; unresolved loader context  reports  unknown-loader-context.  This
     does not model general loader search order. --all walks every supported in-
     stalled  manifest	under  the same shared lock and reports each artifact as
     intact, changed or unknown in digest order. It returns 4  if  any	artifact
     has changed or remains unknown. An empty installed set reports zero checked
     packages.	--json	emits  one holy-installed-check-1 JSON line per artifact
     followed by a summary of passes, failures and unknowns, or one  error  line
     on	 an  invalid  database, missing instance or incomplete transaction. Each
     artifact includes a findings array with code, severity  and  relative  path
     for  each	mismatch. Script interpreter findings also include target. miss-
     ing-file identifies an absent file, link or directory, including a path be-
     low a missing parent; changed-config identifies  a	 modified  regular  file
     marked config. changed-file covers other manifest mismatches, including in-
     accessible	 or  symlinked	parents. Paths encode non-ASCII bytes as \u00HH;
     consumers reconstruct the original bytes. Findings follow	manifest  order;
     intact  artifacts	have  an  empty array. The artifact-level code names the
     first finding. Coverage is data-manifest-and-direct-shebang, including  se-
     lected  literal-path  provider  files and the supported direct SONAME case.
     The coverage label is retained for the current JSON schema.

     Hardlink groups are checked by device and inode as	 well  as  contents  and
     metadata.	 Independent  copies  with  matching bytes fail the group check.
     Missing-only repair reuses an intact surviving group member when its  regu-
     lar anchor was removed; when the whole group is absent it restores contents
     from  the	cache  and  links all declared names. Removal unlinks only owned
     paths and preserves  external  hardlinks.	Cross-filesystem  link	failures
     leave  a  journal	and  report the linkat error. Cached updates also verify
     group topology during  partial  publication  and  recovery.  Full	manifest
     checks reject undeclared inode sharing between independent files or differ-
     ent groups within that manifest.

     db repair-plan SHA256 --root DIRECTORY prepares missing-only restoration of
     an	 installed  artifact  with  a  recorded dependency graph from the target
     cache. db repair SHA256 --plan PLAN_SHA256 --root DIRECTORY applies the re-
     viewed policy. The plan binds the artifact, stored graph, database	 genera-
     tion and root device/inode. Its scope is all absent files in that artifact,
     including	files  removed	after preparation.  Changed or partial files are
     preserved and require manual review. Declared missing directories	are  re-
     stored; existing directory metadata must remain intact. Repair does not run
     hooks  or	change providers.  holypkg repair SOURCE:PACKAGE resolves an in-
     stalled source slot and prints the	 same  read-only  plan.	 Passing  --plan
     PLAN_SHA256  applies  that exact plan. An inactive source alias remains re-
     solvable through its recorded source  ID.	When  multiple	arch/libc  slots
     match, --arch and --libc select the intended slot.

     Repair records stage repairing before writing files, verifies restored con-
     tents  and increments the generation once. An interrupted operation remains
     pending.  db recover --repair resumes that recorded policy after  verifying
     cache, installed metadata, ownership and graph. Partial files are not over-
     written.	Ordinary  check	 remains read-only. This is not general upgrade,
     rollback or configuration-file repair.

     make  bootstrap-musl  ARCH=i686|x86_64  INPUTS=DIRECTORY	OUTPUT=DIRECTORY
     builds pinned musl 1.2.5 as a native runtime package, preserving source and
     build hashes and licenses. The default target is x86_64. The i686 build re-
     quires  multilib  GCC and uses the x86 package architecture and i686-linux-
     musl private runtime path.	 Both packages can coexist; their  documentation
     and public loader paths differ.

     make  check-musl-abi STATIC_HOLYPKG=FILE MUSL32_PACKAGE=FILE MUSL32_CC=FILE
     MUSL_PACKAGE=FILE MUSL_CC=FILE compiles and runs ELF32  and  ELF64	 pthread
     probes  in	 one disposable root on an x86_64 kernel. The fixture explicitly
     approves the 32-bit artifacts, tests pipes in both directions and	restores
     either  or both removed runtimes through the static client and local cache.
     It requires doas, mount namespaces, patchelf and working 32-bit  execution.
     This  test	 does  not boot an i686 kernel or test glibc32 or hardware.  The
     build sets libc.musl-x86_64.so.1 as  SONAME  at  link  time;  it  does  not
     rewrite  the  self-bootstrapping loader with patchelf.  make check-libc-re-
     covery STATIC_HOLYPKG=FILE MUSL_CC=FILE MUSL_PACKAGE=FILE requires a static
     client, a musl compiler and that runtime package.	It  installs  glibc  and
     musl fixtures, runs both, removes each runtime and both together, then exe-
     cutes  cached  repair  inside the libc-free chroot. doas is required; guest
     commands run with the  caller's  UID/GID.	This  tests  local  recovery  on
     x86_64, not boot, i686, network recovery or general foreign package conver-
     sion.

     make  bootstrap-glibc  ARCH=i686|x86_64  INPUTS=DIRECTORY	OUTPUT=DIRECTORY
     builds the pinned glibc-2.42.tar.xz source as an ordinary user in	a  sepa-
     rate  build  directory.   The  default  is	 x86_64; i686 requires an x86_64
     builder with  multilib  GCC/G++.	The  i686  package  uses  arch	x86  and
     /usr/lib/holy/i686-linux-gnu, with a relative public ld-linux.so.2 link and
     separate  license/documentation  paths.   Host  GCC,  G++, binutils, kernel
     headers, make, gawk, bison, Python and patchelf are required.  --without-gd
     avoids linking the optional memusagestat tool against the host's libgd clo-
     sure. The output glibc.holy contains libc.so.6, its loader and upstream li-
     censes.  It records input hashes, build configuration and explicit private-
     path patches in bootstrap origin records. It is not yet  a	 complete  glibc
     SDK or locale/NSS package set. build.record distinguishes building from the
     separate  runtime	probes; the full upstream test suite is not implied by a
     successful build. make check-bootstrap-glibc OUTPUT=DIRECTORY runs that re-
     tained build's upstream test suite as an ordinary user and returns its  ac-
     tual status. GLIBC_PACKAGE can supply this artifact to check-libc-recovery;
     without it that fixture snapshots the host glibc pair.

     make   check-libc-abi   takes   the  same	inputs	as  check-musl-abi  plus
     GLIBC32_PACKAGE=FILE and GLIBC_PACKAGE=FILE. It installs four runtime pack-
     ages and four  architecture/libc  slots  of  one  probe  package.	It  runs
     pthread,  clock  and  pipe probes for every ordered pair, removes each run-
     time, each libc family and all  four  runtimes,  then  checks  and	 repairs
     through the static client inside the target root. JSON records runtime, ap-
     plication,	 client	 and probe source hashes. Glibc probes use host multilib
     headers and CRT objects; this does not validate a	packaged  SDK,	upstream
     glibc tests, NSS/locales or i686 boot.

     Database  owner reads installed manifests and lists the artifact digest and
     kind for an exact relative or root-absolute  path.	 Multiple  packages  may
     list the same directory. If multiple records claim one regular file or sym-
     link,  the	 command  returns conflict status 4 without listing an arbitrary
     owner. An absent path returns 6. It holds a shared database lock  and  does
     not  require the path to exist in the live rootfs; db check compares actual
     contents.	The top-level owner command calls this database lookup	for  the
     selected root.

     Database  rm  removes  one	 intact supported installed instance by artifact
     SHA-256. An object package several installed applications depend on has one
     owner and several dependents: removing one application  leaves  the  object
     and  the  other application untouched, while removing the object itself re-
     turns decision-required until the caller  passes  --accept-broken,	 and  db
     check  --all then reports the provider that is gone. It verifies all listed
     files before mutation, refuses changed files and pending reservations, then
     writes a removing journal. Before journaling, it also checks the other  in-
     stalled  manifests for conflicting ownership claims; shared directories are
     allowed. A conflict returns 4 without deleting files.  The removing journal
     records whether the operation accepted broken dependents; recovery	 accepts
     only the documented decision marker.  Recovery repeats this ownership check
     before  resuming  an  interrupted removal; conflicts retain the journal and
     return 5. It unlinks only listed regular files, symlinks and  the	instance
     record;  shared  directories  and	the cached artifact remain. The database
     generation advances after removal. If an I/O failure  interrupts  deletion,
     db	 status	 reports an incomplete journal.	 db recover --continue accepts a
     removing journal at  its  original	 generation  with  an  intact  installed
     record,  treats  absent  listed  files as removed, verifies every remaining
     file without mutation, then completes removal. Changed files or partial in-
     stalled records require manual inspection. --abort-empty applies only to an
     installing journal, never to removal. This command does not  remove  depen-
     dents.

     The local info command reads an LZ4-frame-compressed tar archive and prints
     the seven required fields from HOLY/meta. It reads archive data without ex-
     tracting  or  executing it. It checks for repeated metadata and unsupported
     format versions.  It prints the SHA-256 digest of the  input  archive.   It
     rejects  archive entries outside HOLY and DATA, including dot segments.  It
     requires all seven HOLY metadata members as regular files and  rejects  du-
     plicate members.  It does not validate the payload manifest, hashes, signa-
     tures or installability.

     search QUERY without --source visits every active source in alias order. It
     prints each source alias and immutable ID with its package or file results.
     Native  sources  use  their  sealed mirrors. APK sources search their bound
     repositories and label results with the repository name;  --repo  restricts
     an	 explicit APK source to one repository. XBPS sources query the bound re-
     podata for --arch; an explicit XBPS query without it  returns  decision-re-
     quired (3).  APT sources query the bound Packages index for --suite, --com-
     ponent  and  --index-arch; an explicit APT query without them returns deci-
     sion-required (3).	  APT  --file  uses  its  partial  Contents  index  when
     present.  XBPS  file coverage is unavailable. Missing or unsupported source
     catalogs report unavailable coverage. An empty  active  registry  exits  6.
     --catalog	requires  --source  and	 applies  to  native  mirrors or a bound
     APT/XBPS catalog.	search QUERY --source SOURCE checks the active source-id
     and the bound catalog before printing matches. info  SOURCE:PACKAGE  checks
     the  same	inputs;	 APK  info can require --repo when multiple repositories
     match. Neither command installs or runs package code.  APK	 package  search
     uses the checked package index; its file coverage is unavailable, so --file
     on APK returns 6. Native exact search and info leave unrelated archives un-
     opened;  source  binding  still  audits the complete native catalog. An un-
     signed mirror has no publisher authentication; a keyed source rechecks  its
     signature.	 With --file, QUERY must be an absolute path. A native version-3
     index records every verified nondirectory payload path  and  declares  com-
     plete  file  coverage.  The  result  prints matching packages, the coverage
     state, index digest and index timestamp. A miss in a complete index returns
     zero matches; a legacy index reports unavailable coverage and exits  6  be-
     cause  absence cannot be established. File queries verify the digest-pinned
     index and only matching archives; an unselected archive can change	 without
     invalidating  the query. No package code runs.  --fuzzy returns ranked sug-
     gestions for package names. With --file --fuzzy, QUERY may be a basename or
     absolute path; only file basenames from a complete index contribute sugges-
     tions. A suggestion prints its score, matched  name  or  path  and	 package
     record.  Up  to  20 suggestions are shown, in score and index order. Scores
     prefer ASCII case-insensitive equality, prefix, substring, then one or  two
     byte edits. These hints never satisfy a dependency or replace an exact SON-
     AME.  File hints from a legacy index report unknown coverage and exit 6.

     The  verify  command  checks  regular  DATA  files	 against  the  supported
     HOLY/files records, including size, mode, numeric	owner  and  SHA-256.  It
     checks  symlinks,	directories  and direct hardlinks, rejecting unsupported
     objects. It does not install or authenticate packages; the two read  passes
     do not provide a stable filesystem snapshot.

     The  manifest command stages a local archive, verifies the entire supported
     payload and HOLY/files, then lists validated objects in  path  order.  Each
     line  contains type, escaped relative path, mode, numeric UID/GID and size;
     files include SHA-256, links include targets and grouped hardlinks	 include
     their  group. Fields are borrowed from the verified snapshot during inspec-
     tion.  This read-only output does not prove that ownership	 can  be  mapped
     onto a target root or that a file can be installed without collision.

     The  requirements command stages and verifies a regular archive, then reads
     HOLY/deps using the holy.conf lexer. Its current typed subset accepts lines
     of eleven tokens:
     require ID CONSUMER KIND NAME ARCH LIBC RELATION VERSION ORIGINAL EVIDENCE
     KIND is package,  package-or,  file,  command,  soname,  symbol-version  or
     build.  For package-or, NAME contains Debian branches as NAME@RELATION@VER-
     SION joined by |; the outer ARCH, LIBC and RELATION fields are any and VER-
     SION is -.	 ARCH is any, x86, x86_64 or noarch; LIBC is any, glibc, musl or
     nolibc.  RELATION	is any, eq, ge, le, gt or lt. VERSION is - only for any.
     ORIGINAL and EVIDENCE retain the source expression and basis as  text.  Re-
     quirement	IDs  must be unique. The command rejects unsupported records and
     duplicate IDs rather than dropping them; it does not evaluate version  con-
     straints  or choose a provider.  With --json, stdout contains holy-require-
     ments-1 requirement events and a summary, or one error event on invalid in-
     put. Each requirement event has id, consumer, kind, name, arch, libc, rela-
     tion, version, original and evidence fields. The  JSON  encoder  maps  non-
     ASCII  bytes to \u00HH escapes; consumers reconstruct original bytes rather
     than treating them as normalized text.

     The solve	command	 verifies  and	scans  each  explicitly	 supplied  local
     archive, with the first archive as the requested root. Its supported subset
     accepts  Linux  packages with validated payload ABI facts, HOLY/hooks gated
     by an explicit skip decision at installation and an ordinary HOLY/transform
     record, and HOLY/deps package requirements with explicit  arch/libc  scopes
     or	 any,  plus  unversioned file requirements at literal absolute paths and
     unversioned bare command names.  Each consumer must equal its package name.
     The package's own metadata name and package claims in HOLY/provides  supply
     package capabilities. An alias retains its declared version; an unversioned
     alias  cannot  satisfy  a	version	 constraint.  Explicit claim scopes must
     agree with the artifact's arch/libc; any inherits that artifact scope.  Se-
     lection  preserves	 the  actual  package identity and records the requested
     alias on the dependency edge. Version constraints	eq/ge/gt/le/lt	use  the
     comparator	 declared  by  both  consumer and provider: pacman, deb or holy.
     For pacman and deb, the full foreign epoch:version-release	 string	 belongs
     in	 version;  release  remains  the native artifact revision and is not ap-
     pended a second time. A missing pkgrel  on	 one  side  does  not  constrain
     pkgrel. Numeric epochs, prerelease letters and separator widths follow pac-
     man's  rules.  The Debian comparator uses epoch, upstream version and final
     Debian revision, with tilde before the end of a  part.  Its  validator  re-
     quires  Debian version characters and a leading digit in the upstream part.
     Both foreign comparators limit input to 65536 bytes; unsupported  encodings
     have  no guessed order.  The Holy native comparator uses decimal components
     separated by dots and an optional lowercase prerelease suffix after  hyphen
     or tilde. It compares unbounded decimal runs by length and content, ignores
     missing trailing zero components, and places prereleases before finals. For
     updates,  it  compares  release  after an equal version. It limits input to
     65536 bytes. A package must declare x-version-family holy; untagged  native
     versions  keep manual update selection.  The adapter filters candidates be-
     fore the common libsolv solver receives exact requirement capabilities. The
     mixed solver pool does not compare foreign EVRs.  File  requirements  match
     nondirectory paths in the verified payload manifest, including symlinks and
     hardlinks.	 A  file  claim	 in HOLY/provides alone cannot satisfy them. The
     chosen file owner and path enter the reviewed  graph;  removal  checks  in-
     stalled file requirements. Versioned file requirements and nonliteral paths
     remain  unsupported.   Command requirements match executable payloads named
     in usr/bin, bin, usr/sbin or sbin. Symlink commands must resolve to an exe-
     cutable in the same artifact; direct hardlinks  retain  the  target's  exe-
     cutable  mode.  A command claim alone or a nonexecutable file does not sat-
     isfy the edge.  The chosen provider enters the installed graph, and removal
     checks that edge.	This test does not model a caller's custom PATH or shell
     builtins. Versioned command requirements remain unsupported.  Exact  unver-
     sioned  SONAME  requirements  from HOLY/deps match DT_SONAME of an observed
     ET_DYN library with the requested package arch/libc scope. A  typed  SONAME
     claim  without  that  ELF does not satisfy the requirement. This selects an
     artifact candidate; physical loader visibility needs a later check.  Unsup-
     ported metadata dependency forms return decision-required when  their  con-
     sumer   is	 selected.  Unsupported	 consumer  version  families  return  6.
     Providers from another or unknown family cannot satisfy a constrained edge;
     if no matching candidate remains, resolution  returns  dependency-conflict.
     A supplied --choose answer cannot bypass these checks. Unversioned require-
     ments  retain  exact  capability-name  matching  across families. Automatic
     newest-version selection in solve and cross-family overrides  remain  pend-
     ing.  There are no source IDs, installed packages or architecture overrides
     in this command.

     ELF payloads add file-scoped interpreter, DT_NEEDED  and  strong  undefined
     symbol  requirements,  even  when	HOLY/deps omits them. A SONAME candidate
     must match the exact name, ELF class, e_machine and  inferred  runtime.  It
     must  be  ET_DYN without DF_1_PIE, so an executable with a forged SONAME is
     not a shared-library candidate. It must define the required  version  nodes
     and  export  each	strong versioned reference assigned to that SONAME, with
     matching version and compatible symbol type. Weak undefined symbols do  not
     add mandatory symbol requirements. Weak definitions can provide strong ref-
     erences.  Hidden/internal	symbols	 cannot provide external references; ex-
     plicit versions may use compatibility exports, while unversioned references
     require default exports.

     The current  unversioned-symbol  scope  covers  the  consumer,  its  direct
     DT_NEEDED	objects	 and  interpreter. A choice for a SONAME must agree with
     the package used for its unversioned symbols.  Inherited  executable/global
     scopes and indirect lookup scopes are not modeled; an unresolved symbol re-
     ports  unknown-symbol-scope with code 3. An interpreter candidate currently
     needs a directly recorded ELF at its literal path with an	executable  per-
     mission  bit.  Unresolved interpreter paths report unknown-interpreter-con-
     text with code 3, since symlink and merged-/usr package views are not  mod-
     eled  by  this archive-only solver. DT_NEEDED containing a slash requires a
     launch context and returns 6. Nested requirements of selected library pack-
     ages participate in the same libsolv graph.

     ELF requirement IDs hash package name, arch/libc, consumer	 path,	require-
     ment  kind and target. They remain stable when candidate order changes. Ca-
     pabilities also include the consumer artifact digest so different	versions
     cannot  silently  share their provider constraints. ELF-edge events include
     id, consumer artifact, path, kind, target and  candidate/selected	provider
     artifact  digests.	 On a decision or conflict, root ELF-edge events precede
     the error to support explicit choices.

     The command prints selected artifact SHA-256 digests only	after  a  unique
     package  set is found. It returns 3 for multiple package sets, 4 for an un-
     satisfied requirement, and 6 for unsupported or invalid input. No plan, in-
     stall or mutation follows. Equal package names from two different artifacts
     remain separate candidates; the caller must choose when both could	 satisfy
     a requirement. Multiple selected providers for an edge also require a deci-
     sion.   Script  interpreter  and  plugin requirements are not inferred from
     payload in this subset, so selection is not an installability verdict.  Li-
     brary  placement, duplicate SONAME files inside one artifact, loader search
     order, RPATH/RUNPATH, ISA availability  and  symbol  interposition	 require
     later  context  checks;  an  artifact match does not prove that the runtime
     loader will select its matching  file.   For  a  direct  root  requirement,
     --choose pins a named requirement ID to the exact candidate artifact digest
     supplied  on  the command line. The candidate must satisfy the requirement,
     including a package capability, verified file path, executable  command  or
     observed  ELF  edge;  otherwise  the command returns decision-required. The
     choice applies to this solve only and  does  not  assign  a  source  ID  or
     rewrite  ABI  facts.  Unsupported syntax returns 2. Transitive requirements
     and multiple choices cannot yet be pinned by  this	 option.   With	 --json,
     stdout  contains  holy-local-solve-1  selected events carrying artifact di-
     gests and a count summary after a unique solution. Errors emit  one  struc-
     tured  error event without partial selected events; malformed arguments use
     invalid-query. Diagnostics remain on stderr.  For a missing provider  on  a
     path  of  uniquely	 determined candidates, the error event also carries the
     validated requirement-id and stderr names it. If a transitive edge has mul-
     tiple candidate providers, this diagnosis stops at that  edge  rather  than
     blaming an unselected candidate.

     Repository	 solve	accepts	 a package name in a sealed local repository. It
     validates the entire catalog and every artifact, freezes those artifacts in
     temporary snapshots, then invokes the same restricted read-only solver with
     the unique exact-name root first. Two versions of the requested name return
     decision-required. A missing name returns unavailable-artifact. An	 invalid
     generation returns invalid-catalog without partial results. --json uses the
     same  holy-local-solve-1  events  as  solve. This command reads all archive
     payloads per query and supports the same package aliases and  version  con-
     straints.	 It  does  not	import	remote sources or install packages.  The
     --choose form applies the same one-operation, direct-root	requirement  se-
     lection  after validating the sealed index and matching the selected digest
     to an artifact in that generation. It does not write a saved rule.	 On suc-
     cess, the text output ends with the sealed index  SHA-256	generation;  the
     --json  summary includes the same digest. A later index generation requires
     a new query before treating the result as current. The digest binds the lo-
     cal index bytes, not an authenticated publisher or a future installed plan.

     The provides command stages and  verifies	a  native  archive,  then  reads
     HOLY/provides as typed claims. Each supported line has seven tokens:
     provide KIND NAME ARCH LIBC VERSION EVIDENCE
     KIND  accepts package, file, command, soname, symbol-version or build. ARCH
     accepts any, x86, x86_64 or noarch; LIBC accepts any, glibc,  musl	 or  no-
     libc.   VERSION  is  text or - for an unversioned claim. File names must be
     absolute; SONAME must have no slash. Duplicate  KIND/NAME/ARCH/LIBC/VERSION
     claims  fail.   The parser does not prove a claimed file, command or SONAME
     exists, resolve a requirement or compare foreign version  schemes.	 Reposi-
     tory  and	cache writers reject unrecognized capability records rather than
     publishing them as parsed.	 With --json,  stdout  contains	 holy-provides-1
     capability events with kind, name, arch, libc, version and evidence, then a
     count summary. A malformed archive or capability emits one structured error
     event. Byte escapes in JSON map non-ASCII bytes to \u00HH; callers must re-
     construct the original bytes.

     The local fetch command copies any regular input file to an existing direc-
     tory  as  SHA256.holy.  It	 copies bytes without interpreting metadata, ex-
     tracting files or running hooks. It creates a mode 0600 temporary file rel-
     ative to the opened output directory and synchronizes it before a	no-over-
     write  hardlink creates the object. Repeating the command checks the exist-
     ing object's digest. A mismatched object is left untouched. Fetch does  not
     establish archive validity, provenance or a trusted root-owned cache.  Con-
     figured  source fetching remains separate from the pinned HTTPS mirror com-
     mand.

     With --extract, DIRECTORY must not exist. The command  copies  the	 regular
     input  into  a  private  temporary file, verifies that copy and checks that
     every entry is a  directory,  regular  file,  relative  symlink  or  direct
     hardlink.	Before	creating DIRECTORY, it rejects duplicate paths and paths
     nested under any non-directory archive entry.  It	then  creates  DIRECTORY
     and  writes  HOLY	and  DATA  there with directory-relative operations that
     refuse symlink  traversal	and  file  replacement.	 It  does  not	preserve
     UID/GID,  setuid  bits, capabilities or xattrs. It refuses absolute symlink
     targets and special nodes; hardlink targets must resolve to  regular  files
     within  the  output tree. Hooks never run. If an I/O error occurs after DI-
     RECTORY is created, partial output remains for inspection.	 This command is
     not a system installation or a root transaction.

     The local check command copies the regular input  to  a  private  temporary
     file,  verifies  that  copy and checks known ELF arch/libc mismatches, then
     compares its DATA members with a supplied filesystem root. It  follows  di-
     rectory  components  through  directory  descriptors without following sym-
     links. It compares types, mode, numeric UID/GID,  file  size  and	SHA-256,
     symlink  targets and hardlink inode identity. It reports each changed path.
     Check does not run package code, download files or modify the root. It does
     not consult an installed database, model ELF loader search,  check	 unknown
     runtime  dependencies or prove a stable snapshot if the root changes during
     checking.

     For matching regular ELF payloads, check reads PT_INTERP and tests	 whether
     an	 executable  ELF file with matching class and machine exists at that ab-
     solute path inside the target root. Missing targets  report  missing-inter-
     preter;  the  wrong  class or machine reports incompatible-interpreter. The
     lookup follows ordinary symlinks using openat2 with RESOLVE_IN_ROOT and RE-
     SOLVE_NO_MAGICLINKS.  Absolute symlink targets and	 parent	 traversal  stay
     within  the opened target root; merged-/usr and final loader links are sup-
     ported. A dangling link reports missing-interpreter. A  loop,  magic  link,
     invalid  ELF  or  inaccessible  path reports unknown-interpreter. A missing
     openat2  syscall  reports	unavailable-path-resolution  with  requires=ope-
     nat2:RESOLVE_IN_ROOT,  unknown  status and exit code 6.  Presence and class
     alone do not prove dynamic	 linking,  compatible  libc  or	 nested	 library
     availability.  For a matching executable script, check reads the first she-
     bang  line	 and looks up its absolute interpreter inside the target root. A
     missing target reports missing-interpreter. An existing executable ELF sat-
     isfies this path check. A malformed, relative or overlong	shebang	 reports
     unknown-interpreter.   For	 /usr/bin/env, check reports unknown-interpreter
     after finding env because	it  does  not  resolve	the  command  using  the
     script's  runtime	PATH.  Script interpreters, their nested loaders and li-
     braries are not recursively checked.  If all findings are unknown, the sum-
     mary status is unknown rather than fail; the check	 still	returns	 nonzero
     because it cannot report pass.

     With --json, check prints one JSON object per finding and a final pass/fail
     summary on stdout. The schema is holy-check-1; changed-payload and missing-
     payload  are  stable  finding  codes. Input or operational failures use in-
     valid-package or check-error and status unknown. Paths  use  byte	escapes.
     Only check, requirements, provides repo providers, solve, preview and data-
     base preflight support --json in this prototype.

     The  developer-facing  elf	 command reads a regular ELF through libelf/GElf
     without executing it or invoking ldd. It prints ELF  class,  numeric  e_ma-
     chine  and e_type, a recognized machine (x86, x86_64 or x32), the PT_INTERP
     path, and a libc runtime hint only for  recognized	 glibc	or  musl  inter-
     preters.  It reads PT_DYNAMIC to list DT_NEEDED, SONAME, RPATH, RUNPATH and
     DT_FLAGS_1 even  without  section	headers.  GNU  DT_VERNEED  records  list
     provider SONAME, version and weak flag. GNU DT_VERDEF records list version-
     definition	 names. DT_SYMTAB and DT_VERSYM records expose each dynamic sym-
     bol's binding, type, visibility, section index, version index,  hidden-ver-
     sion  flag,  version name and version-provider SONAME when recorded.  Unde-
     fined weak symbols retain binding=2 and  section=0.  IFUNC	 symbols  retain
     type=10;  the  reader does not execute their resolvers.  Symbol counts come
     from SysV or GNU hash tables. For an empty GNU hash with no SysV hash,  the
     reader  needs  the matching SHT_DYNSYM section; removing that section makes
     the symbol extent unsupported. Other supported  hash  tables  work	 without
     section  headers.	Malformed  symbol names, version indices, entry sizes or
     address ranges reject the input. GNU x86 ISA-needed properties  in	 PT_NOTE
     report  x86-64-baseline/v2/v3/v4 when present; absent or unrecognized prop-
     erties report unknown. ET_EXEC without PT_INTERP, PT_DYNAMIC  or  DT_NEEDED
     reports  nolibc.  An  architecture-matched musl libc SONAME supplies a musl
     hint for ET_DYN. Other files without a recognized	interpreter  report  un-
     known.  It does not model symbol lookup order or plugin loading; its output
     is not a dependency resolution or package ABI verdict.

     A PT_NOTE GNU build-id note is reported as build-id in lowercase  hex  when
     the file states one, and omitted otherwise. A second note of the same kind,
     an	 empty	note  and  a  note  longer than 32 bytes are not identities this
     reader states, so a file  carrying	 one  of  them	is  rejected.  elf  FILE
     --build-id	 reads	the note section instead of the loadable segments, which
     is how a separate debug file is checked after a split.

     The local scan command stages a regular .holy input in a private file, ver-
     ifies that copy, then copies ELF payload files to unnamed temporary  files.
     It	 reports each file's class, machine, runtime hint and ISA using the same
     reader. It does not execute payloads. It rejects a	 machine  mismatch  with
     the  package arch, including ELF in noarch, and a recognized glibc/musl in-
     terpreter that disagrees with the libc tag. For ET_DYN  without  an  inter-
     preter, an exact DT_NEEDED libc.so.6, including the basename of an absolute
     path,  is evidence for glibc and rejects a non-glibc package tag. Architec-
     ture-specific ld-musl and libc.musl names provide	musl  evidence;	 a  bare
     libc.so  remains unknown.	The matching x86/x86_64 ld-linux SONAME together
     with a GLIBC_PRIVATE version definition supplies glibc loader evidence; its
     bytes are not executed to classify it.  An unclassified ELF causes scan  to
     fail  instead of accepting an arbitrary package libc tag. ET_DYN without an
     interpreter is not classified as nolibc.  Static ET_EXEC is classified only
     without PT_DYNAMIC or DT_NEEDED. These checks do not prove plugin	require-
     ments  or	resolve	 dependencies.	 For  each  ELF	 it  also prints SONAME,
     DT_NEEDED, GNU version needs with weak or required status, version	 defini-
     tions  and	 dynamic  symbols with the fields described above, when present.
     These file-scoped facts do not prove that a provider exists or that a  ver-
     sioned symbol resolves.

     The  preview  command  stages and verifies a native archive, checks ELF ABI
     facts, preflights extraction and inspects each DATA path in a supplied root
     by directory descriptor. It reports new  paths,  existing	directories  and
     conflicts	without writing to the root. Parsed HOLY/deps requirements count
     as decisions still needed. It counts observed DT_NEEDED  edges  separately,
     including	ones  omitted  from HOLY/deps; it does not deduplicate or select
     providers. It also counts executable payload files beginning with #! as un-
     resolved script-interpreter edges. It does not  parse  env	 indirection  or
     verify  that  an interpreter exists. For each #! payload it reports the in-
     terpreter path from a bounded header read, or  unknown  for  an  incomplete
     header.  Simple  /usr/bin/env and /usr/bin/env -S forms also show a helper-
     command candidate. Quoted, escaped or option-heavy env arguments report un-
     known; no helper's existence is inferred. Any of these counts requires res-
     olution.  Preview returns decision-required for nonempty HOLY/hooks and re-
     fuses privileged payload modes. A zero-conflict preview is not  an	 instal-
     lable plan: it has no installed database generation, dependency resolution,
     ownership	decisions, transaction journal or apply command.  Changes to the
     root after preview invalidate the result.

     The  cache	  stage	  command   copies   a	 verified   local   archive   to
     ROOT/var/cache/holypkg/objects/sha256/SHA256.holy.	 It  validates known ELF
     ABI facts and the supported HOLY/deps and HOLY/provides subsets before pub-
     lication. It opens cache directories relative to the  target  root	 without
     following	symlinks and rejects a same-name object with a different digest.
     Existing target cache directories must allow writes by the caller and  must
     not  be group- or world-writable; each directory must belong to root or the
     caller. The command creates cache directories and the object, not installed
     state or payload files; it does not resolve providers  or	run  hooks.  The
     cache remains local and unsigned.

     Cache verify opens the object named by a lowercase SHA-256 through the same
     target-root  directory  chain, stages a private snapshot and checks the di-
     gest, payload, known ELF ABI facts and supported requirements.  It	 reports
     the  verified  name,  arch	 and libc. It does not mutate the cache or prove
     that other package dependencies can be satisfied.	cache list reads SHA-256
     objects in name order and reports size and current	 installed-slot	 status.
     It	 also  shows  hashes  marked unavailable after explicit deletion. It re-
     quires an intact database and does not verify payload bytes.   cache  clean
     SHA256  prints a read-only deletion preview. --yes removes the exact object
     after rechecking it under the database writer lock and cache lock. The pre-
     view reports whether an installed instance or retained  transaction  refers
     to the hash.  Such a deletion requires both --yes and --accept-unavailable.
     The  manager records the hash as unavailable; staging the same verified ob-
     ject clears that marker.  An incomplete transaction  blocks  deletion.  Un-
     known cache entries, unsafe file types and transaction records too large to
     inspect cause an error instead of deletion. The command does not remove in-
     stalled files or rewrite transaction history.

     Database  init creates an empty ROOT/var/lib/holypkg with installed, trans-
     actions and index directories, and a  generation  file  containing	 0.   It
     locks the database directory for this operation and uses a synced temporary
     file  plus	 link  for exclusive generation creation; repeating init retains
     the existing generation. Init checks existing records and generation before
     publishing a new generation file; unknown entries	cannot	turn  a	 partial
     database  into  an	 apparently  initialized one. Status holds a shared lock
     while validating the layout and reading the generation. It	 recognizes  in-
     stalled  instance directories and one pending reservation. Init rejects any
     nonempty installed, transactions or index directory. Both	commands  reject
     symlinked, group-writable or world-writable ancestor directories inside the
     target root.  Init does not register packages or install files.

     Database reserve checks a verified SHA-256 object in the target-root cache,
     locks the database at its current generation and publishes one fsynced pre-
     pared  reservation in transactions/pending. Status validates the record and
     returns 5 while it is present. Reserve refuses a second pending record with
     status 5. Database cancel validates and  removes  a  prepared  or	approved
     record;  it  leaves the cached archive and rootfs unchanged. The record has
     format holy-reservation-1, its stage, generation and  artifact  digest.  An
     approved  record  also  contains the plan digest.	This is a reservation of
     inputs, not a dependency-resolved install plan  or	 committed  transaction.
     Incomplete	 file  mutation	 requires manual inspection.  An unknown or mal-
     formed journal entry remains an error; cancel will not discard it silently.

     Status --json emits one holy-db-status-1 state event with	numeric	 genera-
     tion  and	pending	 null or a prepared/approved SHA-256 object. An approved
     object also includes its plan digest. A malformed database	 emits	one  in-
     valid-state  event	 and returns 1, without partial state on stdout. A valid
     file-mutation journal produces an incomplete event and exit code 5.  Status
     checks  the  installed  record  layout; it does not replace holypkg check's
     comparison of installed manifests against the actual rootfs.

     Database recover handles interruption of reservation  publication.	 It  ac-
     cepts  one	 .holy-tmp-  followed  by  32 lowercase hex digits, verifies its
     record against the current generation and removes that directory entry.  If
     pending  also  exists,  the temporary name must be a hardlink to that exact
     pending inode. A valid unpublished approved record for  the  same	artifact
     may  instead  be removed while leaving its prepared predecessor intact. Re-
     cover preserves pending and returns 5. With no pending it returns	0  after
     removing  the  orphan. Unknown entries, stale generations, unrelated inodes
     and malformed records fail without deletion.  For	an  incomplete	applying
     transaction, recover returns 5 unless --abort-empty proves that none of its
     payload  files  or installed instance has appeared. --finish-apply clears a
     completed applying transaction after validating the new generation and  in-
     stalled  payload.	For an incomplete removing transaction, --continue veri-
     fies and removes any remaining listed files. It does not  replay  hooks  or
     undo installed files.

     Database  preflight holds a shared database lock, validates the one pending
     reservation, reads a verified private snapshot of its cached  artifact  and
     runs  the	same target-root collision and dependency preview as preview lo-
     cal:FILE.	It returns 0 for a zero-decision preview, 3 for	 unresolved  re-
     quirements or runtime edges, 4 for path conflicts and 6 if the reservation,
     cached  input or supported payload profile is unavailable. The output names
     the database generation and artifact digest.  It does not turn the reserva-
     tion into an approved plan. File changes outside the database lock can  in-
     validate  the  preview  before apply; apply rechecks paths and the artifact
     under its writer lock.  With --json, both preview	and  database  preflight
     emit  holy-preview-1  path events and a summary only after the full archive
     walk. Path events include state new, existing-dir or conflict and	optional
     interpreter and helper fields. A completed database preflight adds a reser-
     vation  event  with  generation and artifact. A hook decision emits a deci-
     sion-required error event; database preflight also	 emits	its  reservation
     event.  Invalid  input and unavailable reservations emit a structured error
     event without partial path output.

     The repository index command validates regular .holy files in DIRECTORY and
     writes an unsigned, lexicographically ordered index through an  atomic  re-
     name.   It	 refuses  symlinked packages, duplicate package identities and a
     nonregular	 existing  index.  It  rejects	unsupported  HOLY/deps	records.
     Records  in format holy-index-prototype-8 contain the quoted name, version,
     release, os, arch, libc, relative filename, SHA-256, size and version  com-
     parator  family. The last field is - when the artifact declares no compara-
     tor. The reader checks this field against the  chosen  archive.   Following
     package  records  include	typed  claim lines bound to the package SHA-256,
     copied from validated HOLY/provides. Readers compare every indexed claim to
     the artifact before returning records. A separate	coverage  line	declares
     complete native payload file coverage. File records contain the package di-
     gest  and quoted nondirectory path from the verified manifest; readers com-
     pare them to the artifact. A separate coverage line declares  complete  na-
     tive  package  dependency coverage. Requirement records contain the package
     digest and all  ten  validated  HOLY/deps	fields.	 Readers  compare  these
     records  to  the  artifact. ELF-derived requirements still require artifact
     inspection. A separate coverage line declares complete DT_SONAME facts from
     scanned ET_DYN files, with exact name, architecture, libc class  and  path.
     repo providers DIRECTORY soname NAME uses these facts, ignoring unsupported
     or	 forged	 SONAME	 claims. A further coverage line and elf-version records
     bind defined version names to each library path. When an ELF  consumer  has
     strong  version needs for a DT_NEEDED name, indexed closure staging selects
     only same-ABI SONAME candidates carrying every required version. For  older
     indexes,  strong  symbol  imports	trigger a targeted scan of each matching
     candidate; a library with the right version name but without the  requested
     export  is	 excluded. Generation 7 indexes exported dynamic symbols per li-
     brary path, including version, type, binding, visibility and  hidden  flag.
     Provider search uses these facts to reject a missing export without opening
     the candidate archive. It compares indexed exports against the selected ar-
     tifact  before  staging.  The  resolver checks selected archives again. Old
     holy-index-prototype-1 through -7 generations  remain  readable,  with  the
     coverage  each  generation	 declares; optional signatures are sidecars to a
     sealed generation. Source adapters must not treat it as the native	 reposi-
     tory  format.   repo  requirements	 reads one unambiguous package's indexed
     HOLY/deps records from the pinned catalog generation  without  opening  its
     payload. It returns 6 when the index lacks complete dependency coverage and
     3 when name alone is ambiguous.  The digest-pinned index is metadata; pack-
     age  installation	still verifies the downloaded artifact and scans its ELF
     files.

     The seal command validates the entire local index, creates an  index.SHA256
     generation	 and  atomically  publishes a current pointer containing its di-
     gest.  The list and search commands require current and  check  its  digest
     before  reading  the generation. Indexing creates a draft index; publish it
     with seal after reviewing changes. Removing current makes the directory un-
     available to list and search rather than exposing an unsealed draft.  With-
     out --key, the pointer and artifacts remain unsigned. With --key, seal  re-
     quires  an	 Ed25519  PEM  private key, signs the exact index generation and
     publishes its 64-byte signature.SHA256 file before changing current. Exist-
     ing signatures for the same generation must verify under the supplied  key;
     seal does not replace them. Existing generation files remain in place.

     repo  verify requires an Ed25519 PEM public key. It checks the selected in-
     dex digest, the signature over the exact index  bytes  and	 the  referenced
     package artifacts. A missing or changed signature, wrong key or altered in-
     dex returns 4. The private key stays on the publishing machine. With --pub-
     lic-key,  repo  mirror  downloads	the signature over HTTPS and verifies it
     against  the  pinned  index  before  downloading	packages.   It	 records
     ed25519-pinned-key in mirror-origin together with SHA-256 of the raw public
     key;  a failed signature leaves the new mirror unpublished. Source sync en-
     forces a public key frozen by source plan when one is registered. Verifica-
     tion establishes authenticity only relative to the supplied  key;	it  does
     not  reject  an  older  signed  generation	 selected  by  a changed current
     pointer. Publishers must distribute the public key through a trusted  chan-
     nel and retain separate generation or hash pins where freshness matters.

     The  repository  list command reads that prototype index with the holy.conf
     lexer and checks each referenced regular archive's size, SHA-256, identity,
     payload and known ELF ABI facts before printing records. An index without a
     signature carries no provenance guarantee. Neither command	 installs  pack-
     ages or activates this directory as a package source.

     The  repository  search  command verifies the same complete local index and
     returns exact name matches. repo search-file takes an absolute path and re-
     turns matching package records plus coverage status, index hash  and  time-
     stamp.   With  a  version-3-or-newer index, it verifies only indexed candi-
     dates; a changed unselected archive does not invalidate this query.  Legacy
     generations return unavailable coverage and status 6. No match  in	 a  com-
     plete  native  index  prints  a zero-count summary. This prototype does not
     perform dependency resolution or provider selection.  --fuzzy emits  ranked
     hints,  capped  at	 20  displayed	rows.  A hint is not an exact capability
     match.

     Repository providers searches the sealed local catalog for	 an  exact  KIND
     and  NAME	match.	It finds indexed claims from HOLY/provides and the pack-
     age's own metadata name for KIND=package. With a version-5 index, KIND=son-
     ame uses scanned ELF facts instead of claims. For prototype-2 and later, it
     validates the complete index and  verifies	 only  candidate  artifacts  and
     their full claim sets before printing package records and a count. An unse-
     lected  object  can  change  without  invalidating this query; no match de-
     scribes the sealed index generation, not every file in the	 repository  di-
     rectory.  Prototype-1 queries still verify all artifacts. Listed claims are
     unverified: an exact name does not prove file presence, ABI  compatibility,
     version constraints, or successful execution. There is no source ranking or
     dependency	 solver yet; the prototype-2 query uses indexed claim lookup but
     still scans all index rows.

     The make check-solver target (also run by make check) exercises an internal
     libsolv interface with normalized, exact capability IDs  and  AND/OR,  con-
     flict  and	 cyclic	 fixtures.   The caller must pre-filter candidates using
     each source family's version semantics before it can  use	that  interface.
     The  fixture  is not a holypkg solve command or an installed-system test. A
     missing libsolv development package makes the target fail rather  than  re-
     porting a passed fixture.	The internal unique-solution check returns deci-
     sion-required when excluding a selected provider permits a second solution.
     It does not rank sources or ask the user for a choice. This detects differ-
     ing package sets, not multiple provider edges within one set. A plain solve
     returns one proposed set, not a reviewed installation plan.  With --json it
     emits  holy-repo-candidates-1 candidate events (package identity, filename,
     SHA-256 and byte size), then a count summary. Invalid catalogs emit one er-
     ror event without partial candidates; invalid KIND/NAME emits  an	invalid-
     query  event.  The	 JSON  candidate  identifies an artifact, not a selected
     provider edge or an ABI compatibility verdict.

     The repository fetch command requires a lowercase SHA-256 from  the  sealed
     index.  It	 verifies  the complete index and artifacts, then copies the se-
     lected snapshot to an existing output directory as SHA256.holy. It	 rejects
     a missing digest or a changed unrelated artifact. The copy does not install
     or	 grant	trust to the package; repository metadata and objects remain un-
     signed.

SOURCE REGISTRATION
     source plan reads the explicit configuration and writes a complete proposed
     registry to stdout. It reports alias changes, origin changes, additions and
     deactivations on stderr. A change to trust, key, parent, family or priority
     under the same source ID is reported as policy-change. Review and save  the
     plan,  then  supply  its  SHA-256	to source apply. An existing initialized
     database is required. No source command downloads packages or runs	 package
     code.

     The  plan binds the previous registry digest, installed database generation
     and database device/inode. Apply stages the plan, verifies its approved di-
     gest and checks those inputs under	 the  database	writer	lock.  It  never
     rereads  config  or  includes.  A changed input, another database or a dis-
     carded historical source returns decision-required (3). Malformed	proposed
     registry data returns 2; I/O or existing-state corruption returns 1; an in-
     complete transaction returns 5.

     The  registry  is /var/lib/holypkg/sources under the target root. Its holy-
     sources-3 records contain ID, alias, active/inactive state, canonical defi-
     nition, trust policy, public-key fingerprint, parent ID, family and  prior-
     ity.  source show ALIAS prints the effective registered definition and pol-
     icy  for  an active alias without downloading its catalog. Key rotation re-
     tains the source ID and changes the registry revision. Replacement	 uses  a
     private  temporary	 file, fsync, rename and directory fsync. Registry revi-
     sions are separate from installed database generations.  List prints  iden-
     tities and status without endpoint definitions.

     source catalog bind ALIAS MIRROR verifies the entire sealed mirror, its in-
     dex,  objects,  source-id	and exact registered URL. A source with a regis-
     tered key also verifies the signature against that key. It then records the
     catalog location and index	 digest	 in  /var/lib/holypkg/catalogs/SOURCE_ID
     under  the	 target	 root. The file is mode 0600 and replaced with fsync and
     rename under the database writer lock.  The  command  changes  neither  in-
     stalled  packages	nor  the  source registry. A renamed alias with the same
     source-id keeps its binding; an inactive or changed source cannot	use  it.
     Queries  without  --catalog  reread  the  binding	and  reject a missing or
     changed index; each queried or selected object is verified before use. When
     the mirror resides inside the target root, the binding  records  its  root-
     relative path and survives moving that root. An external mirror retains its
     host  path	 and  must be rebound after a move. Sync with --output exports a
     mirror without changing the binding.

     An ID identifies a configured origin; it is  not  signature  evidence.  The
     current registry retains inactive origins and supports explicit local-arti-
     fact associations in set installation and cached slot replacement. The sync
     command  reads one active registered SOURCE alias under the database shared
     lock. For a holy-http source with one URL, --sha256 INDEX_SHA256 mirrors an
     explicitly pinned index and all referenced artifacts through the same  val-
     idator  as	 repo mirror. A registered public key makes the signature manda-
     tory and records its hash with the source ID. Without --output,  sync  pub-
     lishes	a    verified	 generation    under	/var/cache/holypkg/cata-
     logs/SOURCE_ID/INDEX_SHA256 in the target root and binds it to  the  active
     source.  It reuses a valid cached generation and rejects a corrupt one. The
     source definition is checked again when binding, so an alias change  during
     download  cannot  bind  an	 unrelated  source. --output writes a standalone
     NEW_DIRECTORY without changing the binding. The URL must be an HTTPS direc-
     tory URL ending in slash. It writes the registered source-id in mirror-ori-
     gin before sealing current. The snapshot stays  in	 the  chosen  directory;
     repo  search,  solve and fetch can use it. Sync without --output writes the
     target cache and catalog binding, but does not  install  packages,	 execute
     scripts or migrate sources.

     For a registered holy-git source, sync requires both --commit and --sha256.
     The  commit  is a full lowercase 40- or 64-digit Git object ID. Sync clones
     the configured URL, checks out that commit in detached state, validates the
     sealed native index and every referenced artifact, and records  the  commit
     with  the	source	ID. A registered Ed25519 key also requires a valid index
     signature.	 The verified clone keeps its .git  directory  so  later  source
     queries can check that HEAD still names the pinned commit. --output exports
     the clone without binding it; without --output the normal target-root cata-
     log  cache and binding apply. The Git executable is a sync-time tool, not a
     package query dependency.	Git transport credentials must be supplied  out-
     side the source definition; the source URL and provenance record do not ac-
     cept embedded credentials.

     Without  --sha256,	 sync reads the remote current pointer over certificate-
     checked HTTPS. It accepts only one line of the form "sha256" followed by  a
     lowercase 64-digit digest and newline. An unsigned source reports decision-
     required  (3),  including that digest, without creating a catalog; --output
     can be omitted for this preview. --root defaults to /. A second  call  with
     --accept-unsigned	 INDEX_SHA256  rereads	current	 and  mirrors  index.IN-
     DEX_SHA256 only if the pointer still matches. A changed pointer requires  a
     new  decision.   The  selected  immutable index may remain usable if remote
     current advances during the later download. The snapshot records  selection
     current-accepted-unsigned	in  mirror-origin. Both pointer and index remain
     unsigned; the confirmation accepts this exact generation  without	claiming
     publisher signature verification. Malformed pointer data returns 4; missing
     network or CA inputs and oversized responses return 6. The current transfer
     has  a  4 KiB response cap, the same HTTPS-only redirect policy and a five-
     minute deadline. --sha256 and --accept-unsigned are mutually  exclusive.  A
     source  with  a registered public key verifies the signed index selected by
     current in one call; --accept-unsigned is invalid	for  it.  Cached  signed
     catalogs  and  bound  mirrors are checked against the registered key before
     reuse. Key rotation makes an older binding unavailable until it is replaced
     with a generation signed by the new key. Signature verification alone  does
     not  reject replay of an older signed current pointer; use a generation pin
     where freshness matters. There is no hidden TTY behavior.

     fetch SOURCE:PACKAGE reads a synced native mirror selected by --catalog  or
     the  binding  for	its active source-id. The active source alias must match
     the mirror's source-id and exact URL; the mirror's current	 index	and  se-
     lected  package object are verified before the named package is copied into
     an existing --output directory. --extract instead writes a new  output  di-
     rectory. More than one package with the same name requires a choice (status
     3);  an absent package or inactive source returns 6.  The mirror record re-
     tains the digest pin or verified  key  hash.  A  bound  signed  catalog  is
     rechecked against the registered key before source queries.

     For  an active type apk source, fetch SOURCE:PACKAGE uses a bound APK cata-
     log.  Specify --version and --arch to select one indexed artifact. A source
     with one repository selects it; otherwise specify --repo. Missing selection
     returns decision-required (3). The command verifies  the  catalog	binding,
     download and package signature according to the source key, then writes the
     original  APK  and	 selection receipt in a new --output directory. --import
     also writes converted converted output. --extract applies	only  to  native
     .holy  packages.  --catalog  can name a bound APK catalog; an arbitrary re-
     placement fails source binding.  Neither form installs files, hooks or  de-
     pendencies into the target root.

     The  source  registry  is	read  before  network transfer, so a later alias
     change does not change the snapshot's recorded ID. A  source  with	 another
     backend,  an  inactive alias or an untrusted TLS certificate is unavailable
     (6). The index digest is an explicit user pin, an accepted unsigned current
     value, or a current value whose index was verified by the	registered  key.
     The recorded source-id is provenance for this snapshot, not an installation
     authority	derived	 from package metadata.	 Multi-source dependency resolu-
     tion remains unimplemented.  Explicit cached replacement uses  db	plan-up-
     date  and db apply-update. These commands do not yet implement JSON output.
     See holy.conf(5) for identity rules and endpoint restrictions.

ORPHAN PACKAGES
     orphan reads a consistent installed-state	snapshot  under	 the  database's
     shared  lock.  The default root is /. It follows saved consumer-to-provider
     edges from every instance marked explicit and reports dependency  instances
     outside  that reachable graph. A dependency cycle with no explicit consumer
     is also orphaned.	Only each current instance's own edges participate; ref-
     erences copied from an older transaction's	 other	consumers  do  not  keep
     packages alive.

     The  command  does	 not  remove files, run package code, fetch artifacts or
     need the package cache. Each candidate includes its artifact hash,	 package
     name and the reason unreachable-from-explicit. Names in text output use the
     metadata  lexer's	byte  escapes.	JSON names preserve valid UTF-8. This is
     graph analysis, not a payload or application-health check; use db check for
     file integrity.

     With --json, holy-orphan-1 candidate events contain artifact, name,  reason
     and  generation.  A final summary contains generation, installed, explicit,
     reachable and orphans counts. Candidates are ordered by artifact hash. Out-
     put is delayed until the complete graph has been  read  and  linked,  so  a
     missing  provider	never produces a partial orphan list. Errors produce one
     error event with code and status: invalid-state (1), missing-provider  (4),
     incomplete-transaction  (5),  or  unknown-installed-graph	(6).  Legacy in-
     stalled entries without saved graphs require migration before this analysis
     can prove reachability.

INSTALLED CONFLICTS
     conflict reads a consistent installed-state snapshot under	 the  database's
     shared  lock  and reports the capabilities two installed artifacts both of-
     fer. The default root is /. It answers a question a  set  transaction  does
     not  ask:	a set resolves one requirement at a time, so it installs cleanly
     and still leaves a name two artifacts claim. The command  changes	nothing,
     runs no package code and needs no cache.

     Four  kinds  of  claim  are  read.	 A package name two artifacts provide is
     mixed-providers, a SONAME two artifacts provide  is  duplicate-provider,  a
     file  path	 two artifacts declare is duplicate-provider, and a program name
     two private trees place in a bin directory is shadowed-path, since the PATH
     a run derives from the private trees resolves that name by	 sort  order.  A
     private  program  is  the last component of a path under /usr/lib/holy/pri-
     vate/ARTIFACT-ID/ followed by usr/bin, bin, usr/sbin or sbin, which is  the
     shape a package's private layout has.

     Two  providers of one SONAME whose arch or libc records differ are abi-mis-
     match rather than a duplicate, since one name is a different capability for
     each runtime. The report names every provider with its artifact  hash,  its
     arch  and libc record and the capability, so the reader decides which one a
     set meant rather than being told one of them is correct. One artifact stat-
     ing a capability twice is not a conflict, since there is only one owner.

     Text output is one conflict line per finding, naming the kind, the capabil-
     ity, the provider count, the reason and every provider, followed by a  gen-
     eration, installed, capabilities and conflicts summary. Names use the meta-
     data  lexer's  byte  escapes.   With --json, holy-conflict-1 finding events
     contain kind, name, reason and a providers array of  artifact,  arch,  libc
     and package, ordered by artifact hash, and the final summary carries gener-
     ation,  installed, capabilities and findings. Status is 0 when nothing col-
     lides, 1 when a conflict was found, 2 for an invalid argument, 5 for an in-
     complete transaction and 6 when an instance or graph record is unavailable.
     A pending transaction means the installed set is mid-change, so no	 finding
     from it would be a fact.

INSTALLED FILE INDEX
     index  reads  a  consistent  installed-state  snapshot under the database's
     shared lock and answers two questions the planner answers internally: which
     installed artifact owns a path, and which artifacts provide a name. The de-
     fault root is /. With no selector it prints the whole index,  one	artifact
     record  followed by the paths it owns and the capabilities it declares, or-
     dered by artifact hash, by path and by capability.

     A path selector takes an absolute or a relative path, since  the  installed
     manifests	record the relative form, and names the artifacts that own it. A
     directory is shared and owns nothing, so it is not an index entry. A  capa-
     bility  selector  takes  a kind and a name and names the artifacts that de-
     clare it with the arch and libc each one records, since the  same	name  in
     two  ABIs	is  two capabilities. Naming a path and a capability at once, or
     one without the other, is a usage error.

     A name with more than one provider is a candidate list, and the  status  is
     1:	 choosing  one	of  them  would be a decision this report does not make,
     which is what a fuzzy candidate becomes when nothing names	 the  choice.  A
     path  or  a  capability no installed artifact owns or declares is status 6,
     since an absent answer is not  a  proof  that  nothing  provides  it.  With
     --json,  holy-file-index-1 records carry artifact, name, arch and libc, and
     the path and capability records carry the artifact they belong to.	 The fi-
     nal summary carries generation, artifacts, paths and  capabilities.  Status
     is	 0 for one candidate or the whole index, 1 for several, 2 for an invalid
     argument, 4 for an incomplete transaction, 5 for a pending transaction, and
     6 for an instance record that is unavailable.

RUN INSTALLED COMMAND
     run selects one installed slot by source alias and package name. Use --arch
     and --libc when several installed slots share that name.  The  local  alias
     selects a package installed without a registered source. A registered alias
     can still select its installed package after the source is removed from ac-
     tive  config.   The  command after -- must be a bare name in a standard bin
     directory, an absolute path in /usr/bin, /bin, /usr/sbin or  /sbin,  or  an
     absolute path the installed manifest owns under /usr/lib/holy/private/ARTI-
     FACT-ID/ with a bin directory and a plain file name after it. The last form
     is	 how  a	 package whose payload is private names its own entry point. run
     checks the installed manifest, including the  executable  bit  and	 current
     payload, before exec.

     When  the	installed manifest owns a matching path under /usr/lib/holy/pri-
     vate/ARTIFACT-ID/, run selects it before the public path.	run prepends the
     selected package's manifest-owned private bin directories to PATH even when
     the main executable uses a public path. It passes argv  unchanged	and  re-
     turns the program's exit status through exec. Without a path view this is a
     direct  launcher.	It  does not replace shell builtins or intercept another
     process that directly executes the public path. A private	path  still  re-
     quires  an	 installation  transform that places and records the file there;
     the current package installation flow does not create such a mapping from a
     conflicting public path.

     With --root, run executes the selected file at that root's	 host  path.  It
     does  not	chroot	or isolate the process. Dynamic interpreter and absolute
     paths use the host's namespace, so a trial root must use a compatible  host
     or	 a  static  program. An unavailable package or command returns 6; an al-
     tered payload returns 4. An incomplete transaction returns 5.

     --view PUBLIC=PRIVATE maps one selected package-owned regular file	 or  di-
     rectory  under  /usr/lib/holy/private/  onto an existing public path of the
     same type.	 PUBLIC	 may  be  under	 /usr/bin,  /usr/sbin,	/bin,  /sbin  or
     /usr/lib, or name an existing /app directory. run checks the selected pack-
     age manifest and current payload before creating user and mount namespaces.
     It	 makes	mount propagation private, bind mounts the selected file, enters
     the target root and execs the command with the  caller's  UID/GID	mapping.
     Descendants  inherit  the	view; the mount ends with its namespace. No host
     mount or setuid launcher is created. The user namespace maps  the	caller's
     primary  UID and GID; supplementary groups are not remapped. If namespaces,
     openat2 or mounts are unavailable, run returns 6.	An unowned private path,
     missing target, symlink target or file/directory type mismatch is rejected.
     Directory views require an existing target mountpoint; run does not  create
     one  in the target root.  --view changes only the listed paths. With --view
     and --root, the command executes inside the target root rather  than  at  a
     host-prefixed path.

     --auto-view derives regular-file bindings from the selected installed mani-
     fest: for a private path ending in usr/bin, bin, usr/sbin, sbin or usr/lib,
     it	 binds that package-owned file over an existing matching public file. It
     skips absent public paths and leaves directory views  to  explicit	 --view.
     Explicit  --view  entries	take  precedence. Two private files claiming the
     same public path require an explicit choice  and  return  decision-required
     (3).  The	same  namespace,  ownership and payload checks apply; the option
     does not alter other processes or persist a provider switch.

   AppImage staging
     appimage inspect accepts a type 2 ELF image, checks its x86 or  x86_64  ma-
     chine type, locates one plausible SquashFS superblock and prints its offset
     and  SHA-256.   The  command reads the image without executing its runtime.
     appimage extract copies the exact image to a new private  output  directory
     and  invokes  unsquashfs  with the recorded offset. It requires an unprivi-
     leged user and an available unsquashfs command. The output contains  origi-
     nal,  AppDir,  a  classification report and a conversion receipt with state
     extracted-unclassified.  The report lists ELF  arch/libc/ISA,  interpreter,
     DT_NEEDED,	 loader	 search	 paths, strong symbol versions, shebang scripts,
     links that need a path view and unknown executables without following  sym-
     links.  It reports the AppRun entrypoint and runtime probes that static in-
     spection cannot close. No .holy is produced and no	 package  is  installed.
     This operation does not claim that the extracted program can run.

     import  INPUT  --source  NAME --format appimage --output NEW_DIRECTORY uses
     the same extraction, records NAME as unverified provenance and  then  emits
     one  native package beside the review bundle. The package name is the image
     file name without its .AppImage suffix, and  a  name  the	manifest  cannot
     record  is refused with status 2 rather than rewritten. The version is read
     from the desktop entry the image ships, X-AppImage-Version	 or  Version;  a
     payload that states none records version 0 and the report says so. The arch
     and  libc	come  from the payload's own ELF files, and a payload that mixes
     architectures or runtimes is refused  with	 status	 3,  because  one  .holy
     records one of each.

     The  whole	 AppDir	 travels under /usr/lib/holy/private/NAME/appdir/, so no
     public path is claimed for the image's own files. The entry point is reach-
     able  as  /usr/lib/holy/private/NAME/usr/bin/NAME.appimage,   a   link   to
     ../../appdir/AppRun,  and /usr/bin/NAME is a launcher that starts that file
     in the package run context with holypkg run  SOURCE:NAME.	When  the  image
     ships  an	app  tree the launcher adds a path view from /app, and only when
     the target has /app. The launcher refuses to run as root because  the  con-
     verted   payload	is   no	  sandbox.  The	 desktop  entry	 is  carried  to
     /usr/share/applications/NAME.desktop with Exec and TryExec rewritten to the
     launcher, and the classification and conversion  reports  travel  with  the
     package  as  /usr/share/holy/NAME/. Icons are not installed by this package
     and no desktop database hook is declared; the distribution owns the cache.

     Dependencies are derived from the payload. A DT_NEEDED the	 payload  itself
     carries through its own SONAME is satisfied privately and names no require-
     ment;  every  other name becomes one soname requirement. A link with an ab-
     solute or escaping target cannot travel in a package payload, so  the  path
     it named becomes one file requirement and the report counts it. Every entry
     is	 attributed to the installing user, and each directory an entry sits un-
     der is declared by the same manifest.

     import returns status 3 after  writing  the  output,  because  the	 package
     changes  the  launch conditions and carries no image-level sandbox. The re-
     port in the output directory names	 the  changed  conditions,  the	 dropped
     sandbox,  the runtime probes static inspection cannot close, the path views
     a link needs, the scripts that carry an interpreter and the  version  deci-
     sion. NAME does not grant a registered source identity.

   Snap staging
     snap  inspect  accepts a file whose first eight bytes state a little-endian
     offset and a size, requires an offset of at least 8, checks that a SquashFS
     superblock sits there and prints type, offset, compression and  SHA-256.  A
     superblock states no machine class, so the architecture comes from the pay-
     load's  own  ELF  files.  The command reads the image without executing its
     runtime.

     snap extract copies the exact image to a new private output  directory  and
     invokes  unsquashfs  with	the recorded offset. It requires an unprivileged
     user and an available unsquashfs command. The output contains original, the
     snap tree, a classification report and a conversion receipt with state  ex-
     tracted-unclassified.   The  report  lists	 ELF arch/libc/ISA, interpreter,
     DT_NEEDED, loader search paths, strong symbol  versions,  shebang	scripts,
     links  that need a path view and unknown executables without following sym-
     links. It reports the command the manifest names and  runtime  probes  that
     static  inspection cannot close. No .holy is produced and no package is in-
     stalled. This operation does not claim that the extracted program can run.

     import INPUT --source NAME --format snap --output	NEW_DIRECTORY  uses  the
     same  extraction,	records NAME as unverified provenance and then emits one
     native package beside the review bundle. The package name and  version  are
     the  name and version the manifest declares; a name the package format can-
     not record is refused with status 2 rather than rewritten, and  a	manifest
     with no readable meta/snap.yaml or no command is refused with status 3. The
     arch  and	libc  come  from the payload's own ELF files, and a payload that
     mixes architectures or runtimes is refused with status 3, because one .holy
     records one of each.

     The whole snap tree travels under /usr/lib/holy/private/NAME/snap/,  so  no
     public  path is claimed for the image's own files. The command the manifest
     names has to sit inside that tree; a command that names a path  outside  it
     is	 refused  with	status	3.  The	 entry point is the snap image itself at
     /usr/lib/holy/private/NAME/usr/bin/NAME.snap,  and	  /usr/bin/NAME	  is   a
     launcher  that starts that file in the package run context with holypkg run
     SOURCE:NAME. The launcher refuses to run as root because the converted pay-
     load is no confinement.  The classification and conversion	 reports  travel
     with the package as /usr/share/holy/NAME/.

     Snap semantics that this format cannot keep are recorded, not emulated. The
     base  the	manifest names is a runtime snapd would mount from a snap store,
     so it becomes one package requirement on that name and the target	needs  a
     source that provides it; a superblock states no runtime, so the requirement
     names  no	libc.  The  plugs, the confinement, the system usernames and the
     layouts are dropped and counted, the hooks	 are  recorded	because	 nothing
     runs  them at install, and the environment names, the command-chain entries
     and the part stage-packages are kept as x- records with a report line each.
     A link with an absolute or escaping target cannot travel in a package  pay-
     load, so the path it named becomes one file requirement.

     import  returns  status  3	 after	writing	 the output, because the package
     changes the confinement and needs a base package no snapd provides. The re-
     port in the output directory names the base requirement, the  dropped  con-
     finement and interfaces, the recorded hooks, the command-chain and environ-
     ment records, the path views a link needs and the scripts that carry an in-
     terpreter. NAME does not grant a registered source identity.

   Scoop artifacts
     import  INPUT --source NAME --format scoop --output NEW_DIRECTORY reads one
     Scoop manifest as JSON text and writes a conversion directory  holding  the
     original  manifest,  one  native package and a package report. The manifest
     file name is the package name, as a bucket names an app,  and  a  name  the
     package  format  cannot record is refused with status 2 rather than rewrit-
     ten, as is a manifest with no  literal  version,  no  artifact  URL  or  no
     SHA-256 digest.

     The  artifact  has	 to sit beside the manifest, since nothing runs to fetch
     and unpack it, and its SHA-256 must be the digest the manifest pins; a dif-
     ferent digest or an absent file returns 6. An artifact libarchive reads has
     its members placed under /usr/lib/holy/private/NAME/, and the directory the
     manifest declares as extract_dir replaces the first component of every mem-
     ber path. Any other artifact travels as one file. A member with an absolute
     or escaping path, or of a kind a payload does  not	 carry,	 is  refused  or
     counted  and  reported.  The program the manifest names is looked up inside
     the payload and recorded as x-scoop-program when it is there.

     A Scoop dependency names an app of the same bucket, so each one  becomes  a
     package  requirement  the	target has to satisfy from a source that has it.
     The  installer,  pre_install,  post_install,   uninstaller,   env_add_path,
     env_set,  persist,	 shortcuts,  psmodule  and  suggest keys are dropped and
     counted, because a PowerShell step and a Windows integration  belong  to  a
     Windows  installation;  checkver  and  autoupdate	are counted too, since a
     bucket owns its own index. Nothing in the artifact is executed, and no Wine
     requirement is recorded, because a package cannot promise	a  runtime  this
     manager does not provide.

     import  returns status 3 after writing the output, because the payload is a
     program for another operating system. The report names the artifact and its
     digest, the directory and program the  manifest  states,  the  dropped  in-
     staller  and  integration keys, the requirements a bucket dependency became
     and any archive member the payload refused. NAME does not	grant  a  regis-
     tered source identity.

   WinGet artifacts
     import INPUT --source NAME --format winget --output NEW_DIRECTORY reads one
     winget-pkgs  manifest as YAML text and writes the same conversion directory
     a Scoop manifest produces: the original manifest, one native package and  a
     package  report.	PackageIdentifier is the package name and PackageVersion
     the version; a name the package format cannot record is refused with status
     2 rather than rewritten, as is a manifest with no literal version,	 no  In-
     stallerUrl	 or no InstallerSha256. A WinGet digest is written in upper case
     and is compared in lower case, so both forms verify.

     The artifact, the extract_dir and the counted keys are the shared	artifact
     rules  the	 Scoop	section states, so a WinGet package carries the verified
     artifact under /usr/lib/holy/private/NAME/ as well.  A  manifest  that  de-
     clares  no	 program  path	records none, and the report says so rather than
     guessing one from the archive.

     A PackageDependencies entry is the only nested block this converter  reads,
     because  it  names	 the  packages the manifest requires; every other nested
     block is skipped and its key counted. The installer keys, the Windows inte-
     gration keys and the catalog keys are dropped and counted the way the Scoop
     report counts them, and the catalog is named as  a	 WinGet	 catalog  rather
     than  a bucket. Nothing in the artifact is executed and no Wine requirement
     is recorded, so import returns status 3 after writing the output.

   Nix closures
     import CAPTURE --source NAME --format nix --output NEW_DIRECTORY reads  one
     captured closure as text and writes a conversion directory holding the cap-
     ture,  one native package per store path and a closure report. A store path
     is a 32-character Nix base32 hash, a hyphen and a name, with or without the
     /nix/store prefix, and a store path name the package format  cannot  record
     is refused with status 2 rather than rewritten. Two store paths of one name
     would  need one rewritten package name, so the capture is refused with sta-
     tus 2 as well.

     The capture is one record per line: path STORE_PATH declares a  store  path
     of	 the  closure,	root  STORE_PATH names the output root, entry STORE_PATH
     PATH names the program a  store  path  starts,  and  references  STORE_PATH
     STORE_PATH...  declares the store paths one path needs. A path or a root is
     named once; a reference to a store path the capture does not declare  loses
     a	closure	 member, so it is refused with status 2. A record name this con-
     verter does not model is counted and reported, since an unread reference is
     a requirement nobody counted.

     Every store path has to sit beside the capture as a directory named for it,
     because nothing runs to build or fetch a store, and an absent  one	 returns
     6.	   Each	   store    path    travels   whole   under   /usr/lib/holy/pri-
     vate/NAME/store/STORE_PATH/, and one pass over its own bytes  confirms  the
     references	 the  capture  declares: a reference the payload carries is con-
     firmed and a reference it does not is counted, because a store records  the
     references itself and a payload cannot prove that a store path has none.

     A	reference  to  a  store path the capture carries becomes one package re-
     quirement on that name, so two applications that name the same  store  path
     share  one	 package  with one owner and several dependents, and removing an
     application leaves it. A reference to a store path	 the  capture  does  not
     carry  becomes a requirement on that name whose original field is the store
     hash, and the target needs a  source  that	 provides  it;	the  requirement
     states  no	 architecture  and  no	runtime, since the store path that would
     state one is the one the capture does not carry. Nix states no version,  so
     every  package  records  version  0  and  the  store  hash is its identity,
     recorded as x-nix-store-hash.

     A store path that states an entry point gets a link  at  /usr/lib/holy/pri-
     vate/NAME/usr/bin/NAME  and  a  generated	launcher  at  /usr/bin/NAME that
     starts it in the package run context with holypkg run SOURCE:NAME. A  store
     path  that	 names	no entry point claims no public bin path, and the report
     says so rather than guessing one. An entry point that is not an  executable
     file of its own store path is refused with status 3.

     Nothing  is  executed.  No	 Nix store, daemon, profile or sandbox is repro-
     duced, and a program that opens an absolute /nix/store path needs	a  store
     view this manager does not build, which the report and the transform record
     name. import returns status 3 after writing the output. NAME does not grant
     a registered source identity.

   Solus eopkg
     import FILE.eopkg --source NAME --format eopkg --output NEW_DIRECTORY reads
     one  Solus binary package and writes a conversion directory holding the ar-
     tifact, one native package and an eopkg report. An eopkg is a ZIP	carrying
     metadata.xml,  files.xml  and  an install tar. The metadata is required and
     the install tar is required, and an artifact missing either is refused with
     status 2. A member this reader  does  not	model  is  counted  rather  than
     dropped, and a member that is not a regular file is refused, since an eopkg
     is a set of regular files.

     The  metadata  is	read as XML text. A value lands in its own context, so a
     Name under Source is a packager identity and the Name under Package is  the
     package name, and a dependency under BuildDependencies is not a runtime re-
     quirement.	 The fields carried are the name, the version, the architecture,
     the summary, the license, the source URL, the component PartOf  names,  the
     PiSi  format  and	each RuntimeDependencies entry with the distribution re-
     lease its releaseFrom attribute states. Solus states no release of its own,
     so the native release is 1. A metadata without a name, a version or an  ar-
     chitecture is refused with status 2, and a document that is not well formed
     or	 that  ends  inside  an element is refused the same way. An element this
     reader does not model is counted: a description, a packager, a history  en-
     try,  a  conflict, a replacement and a declared capability are all named in
     the report and none of them becomes a requirement.

     The architecture decides the placement. noarch, x86_64, i686,  aarch64  and
     armv7hl  name  an architecture this manager places, and anything else needs
     classification, so the import returns status 3 without writing a package.

     The install tar travels whole  under  /usr/lib/holy/private/NAME/eopkg/.  A
     Solus  package  owns  a system layout, and this manager records that layout
     rather than claiming it, so the payload installs under a private  path  and
     claims no public bin path. A leading ./ names the same path and is dropped;
     a member that names .. is refused rather than placed, and the conversion is
     refused  with  status  1.	A payload that is not an archive this reader can
     read is refused the same way. A member that is neither a  regular	file,  a
     directory	nor  a symbolic link is skipped and counted, and a symbolic link
     whose target leaves the private tree becomes a recorded file requirement on
     the path it named.

     Each runtime dependency becomes one exact package requirement on the  pack-
     age name, with any architecture and any runtime, since the dependency names
     a	repository  member  and	 not  a file the payload can place. The original
     field is the releaseFrom value when the metadata states one and -	when  it
     does  not,	 because  a distribution release is a property of the repository
     rather than of the dependency. A SONAME the payload needs and does not pro-
     vide becomes a SONAME requirement, and a package requirement on the package
     name is recorded as well.

     Nothing is executed. An install script, a COMAR object, a delta,  a  signa-
     ture  and a declared file list are named in the report and dropped: a COMAR
     object is a lifecycle ABI this manager does not provide, a delta is a  dif-
     ferent payload rather than a patch, and a signature is recorded without be-
     ing trusted, so the artifact is verified by its own digest only. import re-
     turns  status  3 after writing the output. NAME does not grant a registered
     source identity.

   Split proposal
     holypkg split TREE --output NEW_FILE [--split OUTPUT GLOB	...]  reads  one
     prepared  package	tree, the HOLY and DATA shape that manifest generate and
     pack consume, and writes a proposal naming the split  outputs  its	 payload
     needs.  It changes nothing, executes nothing and installs nothing; the pro-
     posal is what a holy-recipe(5) manifest states  in	 its  output  and  split
     records.

     Every  non-directory  path	 receives  exactly  one output, and the proposal
     names the three the tree may use: the package name as its	runtime	 output,
     NAME-devel	 and NAME-doc. A development or documentation output is declared
     only when a path is assigned to it or a decision suggests it, because a de-
     clared output that receives nothing is what a build rejects.  A  path  line
     records  the  path,  its output and the reason, so an operator can overrule
     the heuristic.

     An explicit --split rule outranks a heuristic: the first rule that	 matches
     a	path  assigns  it,  and	 two rules naming different outputs for one path
     leave that path a repeated decision rather than a guess. A	 rule  may  only
     name  one of the three outputs the proposal declares, and a rule naming any
     other output is refused with status 2.

     The heuristics are deliberately weak, because a file  extension  is  not  a
     sufficient	 criterion.  A header, an include directory and pkg-config meta-
     data are proposed for the development output. A shared  object  carrying  a
     version stays in the runtime output, and a man page, an info page or a ref-
     erence  document  is proposed for the documentation output; a license and a
     runtime data file are not documentation, however a	 general  pattern  would
     match them, and they stay in the runtime output.

     Four  cases  are  decisions rather than assignments, each reported with the
     output a heuristic would have chosen and the reason. An unversioned  shared
     object  is	 a  decision: the payload may open it through dlopen at runtime,
     and a tree states no metadata or probe that settles that. A static	 archive
     is	 a decision: it is development material to a builder and a link input to
     nothing at run time, and only the project knows which. A link whose  target
     leaves  the tree or is absolute is a decision, since a payload carries nei-
     ther, and two rules contradicting each other are a decision by definition.

     The command prints the path counts per output and one decision line per un-
     settled path, and returns status 3 when any path  is  a  decision.	 A  tree
     without HOLY/meta or without a name the output names may be derived from is
     refused  with  status  2, and a tree that is not there returns 6. A device,
     socket or fifo is refused, because a payload carries none of them.

     --debug adds a NAME-debug output whose files are cut from the runtime files
     with objcopy. Each debug record names the runtime	path  and  the	build-id
     note both files keep, so a stripped artifact and its debug file are matched
     by	 an  identity  rather than by a name, and a debug record states the tool
     that cuts the pair: objcopy --only-keep-debug on the runtime file, then ob-
     jcopy --strip-debug --add-gnu-debuglink on the artifact that  installs.  An
     ELF  that states no build-id is a decision rather than an untraceable debug
     entry, because nothing then ties a debug file to the artifact  it	was  cut
     from.  A  file this reader cannot parse as an ELF is refused, since --debug
     reads only the ELF payloads of a tree.

     holypkg elf FILE --build-id prints the GNU build-id note  of  one	file  in
     lowercase	hex, reading the note section rather than the loadable segments.
     A separate debug file keeps the note and loses the segments a loadable  ar-
     tifact  needs,  so the strict elf reader refuses it and this form still an-
     swers. A file that states no note, or is not an ELF, returns 2.

   Recipe conversion
     holypkg convert PKGBUILD --source NAME  --output  NEW_DIRECTORY  reads  one
     PKGBUILD  as text and writes a conversion directory containing the original
     file, a copy of each local source it names, a holy-recipe(5) manifest and a
     conversion report. A file named template reaches the Void converter, a file
     named APKBUILD reaches the Aports converter, and a name ending  in	 .Slack-
     Build  reaches the SlackBuild converter, a name ending in .spec reaches the
     RPM spec converter, a directory named debian reaches the  Debian  converter
     and a name ending in .ebuild reaches the Gentoo converter and a name ending
     in	 converter,  a name ending in .scm reaches the Guix converter and a name
     ending in while any other name reaches the pacman converter, and import IN-
     PUT  --source  NAME  --format   pkgbuild|void|aports|slackbuild|rpmspec|de-
     bian|gentoo|pacstall|flatpak|homebrew|guix --output NEW_DIRECTORY names the
     family  explicitly.  None of these commands installs a package, builds one,
     or grants NAME a registered source	 identity;  the	 report	 records  it  as
     provenance.

     The  PKGBUILD  converter carries pkgbase, pkgver, pkgrel, pkgdesc, url, li-
     cense, arch, epoch,  depends,  makedepends,  checkdepends,	 optdepends  and
     backup,  expands  $pkgbase, $pkgname, $pkgver and $pkgrel inside source en-
     tries, and turns a sha256sums entry into source-sha256. A list is read  the
     way  a  shell reads it: whitespace separates elements and a comma inside an
     element belongs to its name. The build, check and package bodies keep their
     original Bash with a prologue that maps the makepkg working variables  onto
     the exported Holy paths, so $srcdir is $HOLY_SRC and $pkgdir is $HOLY_DEST,
     or	 $HOLY_SPLIT_DEST  inside a package_NAME split output. An install= frag-
     ment is copied into the payload and recorded as one postinstall hook.  pro-
     vides,  conflicts,	 replaces, noextract, validpgpkeys, options, non-SHA-256
     checksums and  architecture-specific  source  lists  are  preserved  as  x-
     records  or reported as unknown. The build environment of makepkg itself is
     not reproduced, so a converted recipe reports makepkg.conf	 and  the  phase
     environments as unresolved helpers.

     The  Void	converter  carries pkgname, version, revision, short_desc, home-
     page, license, maintainer and changelog, reads distfiles  and  checksum  as
     lists,  and expands $pkgname, $pkgbase, $version, $revision, $sourcepkg and
     $pkgver inside them. The xbps-src phase functions keep their original  Bash
     behind  a	prologue  that	maps  $wrksrc  onto  $HOLY_SRC,	 $masterdir onto
     $HOLY_WORK and $DESTDIR onto $HOLY_DEST, so HOLY_SRC takes the place of the
     $wrksrc directory that xbps-src builds. The v* helpers  a	body  calls  are
     carried  into  that prologue, and vman, vsv, vsed, vcompletion and vsrccopy
     are reported as unresolved. A NAME_package function becomes an output whose
     split step carries its pkg_install body, with DESTDIR still the  main  tree
     and  PKGDESTDIR  the staging tree. A patches or files directory is archived
     beside the recipe and named by PATCHESDIR or FILESDIR, and	 an  INSTALL  or
     REMOVE file becomes one hook.  build_options are fixed to build_options_de-
     fault,  so	 a  $(vopt_with)  call	becomes its recorded value rather than a
     shell helper. A phase the template leaves out is reported	as  supplied  by
     common/build-style/NAME.sh, which the converter does not run.

     The Aports converter carries pkgname, pkgver, pkgrel, pkgdesc, url, license
     and maintainer, maps arch onto the Holy machine names, and reads depends as
     depend  and  makedepends,	makedepends_build, makedepends_host and checkde-
     pends as build-depend, so a !NAME conflict becomes x-conflicts and a so: or
     cmd: requirement is reported. The abuild phase bodies keep	 their	original
     shell  behind  a  prologue that maps $srcdir onto $HOLY_SRC, $startdir onto
     $HOLY_WORK, $pkgdir onto the main tree  and  $subpkgdir  onto  the	 staging
     tree,  and	 the  step  changes  into  $builddir because abuild runs a phase
     there. Each subpackages entry becomes an output whose  split  step	 carries
     its split function, with the function taken from the entry or from the last
     dash-separated suffix of the name, and an entry with no written function is
     reported  as  needing the abuild default_dev, default_doc or default_static
     helper. A post-install or pre-deinstall  script  becomes  one  hook.  Since
     aports  pins  sha512sums,	which  a Holy source cannot use, a remote source
     with no sha256sums entry is reported rather than  fetched,	 while	a  local
     source  beside  the APKBUILD is copied and hashed as SHA-256. The default_*
     helpers, the abuild phases the template leaves out, the  cross  and  chroot
     variables and any top level statement abuild would source as a shell script
     are reported rather than run.

     The  SlackBuild  converter carries PRGNAM, VERSION, BUILD, TAG and PKGTYPE,
     reads the summary, homepage, requires and conflicts out of slack-desc,  and
     reads  the	 upstream URL and the MD5 sum out of the info file. A SlackBuild
     script is one linear shell program, so it becomes a single build step whose
     prologue maps $ARCH onto $HOLY_ARCH, $CWD and  $TMP  onto	$HOLY_SRC,  $PKG
     onto   $HOLY_DEST	 and  $OUTPUT  onto  $HOLY_OUT.	 The  cd  $PKG	and  the
     /sbin/makepkg call are left out because the engine packs the  payload,  and
     so	 is  a tar line that reads $CWD, because the engine has already unpacked
     the recorded archive. Every other file the script reads through $CWD  trav-
     els  beside  the recipe as a source, a doinst.sh becomes one hook, and this
     format pins an MD5 sum rather than a SHA-256 digest, so a remote archive is
     reported unless a local copy is beside the script. The strip pass, the own-
     ership rewrite, the user and group creation  and  the  loader  and	 desktop
     cache helpers are reported as unresolved.

     The RPM spec converter carries Name, Version, Release, Summary, License and
     URL,  collects  the  %global and %define records, and expands the macros it
     can resolve, so a body keeps its own words with _sourcedir,  _builddir  and
     buildroot	rewritten  onto the exported paths. BuildRequires becomes build-
     depend and Requires becomes depend, read one record per line so the compar-
     ison travels with the name, while Provides, Conflicts, Obsoletes and Recom-
     mends become x- records because none of them is a	requirement.  The  prep,
     build,  install and check sections become the matching phases, %setup, %au-
     tosetup and %autopatch become a cd into the unpacked tree and a patch pass,
     and every other rpm section command is reported and left in the body so the
     build fails visibly. A %package block becomes an output  whose  split  step
     copies  the  paths	 its own %files list named out of the main tree. A local
     Source or Patch file beside the spec is copied and hashed as  SHA-256;  one
     that is absent is reported, since a spec normally pins no digest.

     The  Debian  converter  reads debian/control and takes the version from the
     first record of debian/changelog, so the distribution version is  what  the
     recipe  records.  The Debian revision becomes the Holy release, an epoch is
     preserved and dropped, and a native package with no revision  gets	 release
     one.  A  relationship field is a comma separated list of groups and a group
     may offer alternatives with a pipe, so the first alternative of each  group
     is	 carried  and  the rest are reported, while Provides, Breaks, Conflicts,
     Replaces, Recommends, Suggests and Enhances become x- records. A dpkg  sub-
     stitution	variable  such	as  $  {misc:Depends}  is  reported  rather than
     guessed. Each binary stanza becomes an output, and a binary  that	names  a
     .install,	.docs,	.manpages or .links file list becomes a subpackage whose
     split step copies the paths that list named out of the main tree, while the
     binary that names no list owns the whole tree.   debian/rules  becomes  the
     build step behind a prologue that sets DEB_HOST_MULTIARCH and DEB_BUILD_OP-
     TIONS,  and  every debhelper call, every debhelper override and dpkg-build-
     package are reported and left in the body so the build fails  visibly.  The
     maintainer scripts, debian/copyright, debian/watch and debian/source/format
     are copied next to the recipe.

     The Gentoo converter takes the identity from the file name, which is PN-PV-
     rPR.ebuild, so a trailing -rN becomes the Holy release and a file name with
     no revision gets release one, and an epoch is preserved and dropped.  EAPI,
     LICENSE  and SLOT are carried, and KEYWORDS names the machines an ebuild is
     tested on rather than the machine that builds it, so arch is any. A  depen-
     dency atom is a category, a package and an optional comparison, so the cat-
     egory  is	dropped,  a blocker becomes x-conflicts, and a version keeps its
     upstream part with the same comparator names the PKGBUILD converter uses. A
     USE conditional, an any-of group, a slot, a use dependency	 and  a	 virtual
     are  reported,  since  a Holy recipe has no USE flags and cannot choose be-
     tween the members of a group, and the atoms inside one are carried	 anyway.
     A mirror:// entry and a remote archive are reported, because a Gentoo Mani-
     fest  pins	 a  BLAKE2B rather than the SHA-256 a Holy source needs, while a
     PATCHES entry and any other file named beside the ebuild is copied next  to
     the  recipe  and hashed.  Each standard phase function becomes the matching
     phase behind a prologue that rebuilds EPREFIX,  ED,  D,  DESTDIR,	WORKDIR,
     DISTDIR,  T,  PN,	PV,  PR, PF, P and PVR from the exported Holy paths, and
     every eclass and every ebuild.sh helper a body  calls  is	reported  rather
     than run, so the build fails visibly rather than losing a step.

     The  Pacstall  converter carries pkgname, pkgver, pkgrel, pkgdesc, url, li-
     cense, maintainer, repology, arch and gives, and expands  $pkgname,  ${pkg-
     name},  $pkgver,  $pkgrel,	 $gives,  $pkgbase and $epoch inside a value, as
     well as a variable the same pacscript states in an assignment of its own. A
     value that needs the shell to choose a substring is a computed identity and
     returns 2. An epoch is preserved  and  dropped,  amd64  and  x86_64  become
     x86_64,  i386  and	 i686 become i686, any and all become any, and a machine
     Holy does not carry is written as it stands and reported. A source entry is
     NAME::URL, ?NAME::URL or a plain URL, a sha256sums entry in the same  order
     becomes source-sha256, and a file named beside the pacscript is copied next
     to the recipe and hashed; a git address, a remote source with no digest and
     a	plain  http address are reported.  depends, makedepends and checkdepends
     become depend and build-depend, a group of alternatives written with a pipe
     is reported with the first of them carried, pacdeps become depend with  the
     fact  that they name packages of the same pacstall repository reported, and
     provides, conflicts, breaks, replaces, enhances,  recommends  and	suggests
     become  x-	 records while an optdepends entry becomes x-optdepend. A backup
     entry becomes config, and an r: prefix becomes config mutable.  Every  list
     written  per machine or per distribution under a suffixed name is reported,
     as is every setting that steers a Pacstall run and every digest list  other
     than  sha256sums.	prepare,  build,  check	 and package become the matching
     phase behind a prologue that rebuilds  pkgdir,  pacdir,  srcdir,  startdir,
     builddir, TARCH, NCPU, pkgname, pkgbase, pkgver, pkgrel, pacname, gives and
     epoch  from  the  exported	 Holy paths; a list of names with a pkgbase is a
     split pkgbase whose package_NAME functions become the split steps that fill
     each output. Every helper a body calls and every variable of  the	Pacstall
     environment  a  body  reads  is  reported,	 and  pre_install,  pre_upgrade,
     post_install and post_upgrade become one install hook while pre_remove  and
     post_remove  become one remove hook, each written beside the recipe and in-
     stalled into the payload.

     The Flatpak converter reads a JSON manifest. The name is  the  last  dotted
     component	of  its	 application  id,  and	an id that names a machine and a
     branch after a slash keeps that reflex in x-app-id while  the  branch  sup-
     plies  the	 machine. The version, summary, url, command, branch and machine
     are carried; a manifest that states no version records zero and the  report
     says  so. The sdk becomes a build requirement and the runtime a runtime re-
     quirement, because the SDK that builds the modules and the runtime the pro-
     gram runs on are two different ids. A module becomes one step in module or-
     der: its build-options export env, the flag variables and append-path,  its
     commands  keep their shell, and the make, autotools, autogen, cmake and me-
     son templates are replaced by the shell that runs the same tools, which the
     report names. A patch applies with -p1 before its module builds, an  inline
     source  becomes a file beside the recipe, a local archive is copied next to
     the recipe and a remote one keeps its declared sha256. A /app path inside a
     command becomes $DESTDIR and the prefix of a module becomes /usr, so a con-
     verted build writes into the  payload.   finish-args  permissions,	 cleanup
     steps,  build  extensions and a buildsystem with no Holy phase are reported
     as dropped or unresolved, and a manifest with several modules is  reported,
     because  a	 Flatpak  build	 shares one prefix across its modules while each
     step here installs into the payload.

     The Homebrew converter reads a formula as Ruby text and never evaluates it.
     The class name becomes the package name, the description, homepage and  li-
     cense are carried, the url and its sha256 become one pinned source, the re-
     vision  becomes  the  release, and a formula that states no version records
     the version its source url carries or zero, with the report naming which. A
     depends_on becomes a runtime requirement and a :build  dependency	a  build
     requirement;  a  :recommended  or :optional dependency is reported, since a
     build cannot promise a feature it did not ask for. A resource  or	a  patch
     block  that  pins	a url and a digest becomes a fetched source, and a patch
     applies with -p1 in the prepare phase.

     A system call inside def install or on_linux becomes a build step that runs
     the same command in the source root, and the Homebrew prefix  is  rewritten
     onto  the	build  root:  #{prefix}	 and  HOMEBREW_PREFIX become $HOLY_DEST,
     #{libexec}	  becomes   $HOLY_DEST/libexec,	  #{etc}   and	 #{var}	  become
     $HOLY_DEST/etc and $HOLY_DEST/var, and #{buildpath} becomes $HOLY_BUILD. An
     interpolation  this  reader  does not model keeps its text and is reported.
     Every other statement of that body is Ruby, so the formula is copied beside
     the recipe as homebrew-install.rb, the build declares a ruby build require-
     ment, and the report names the file and line of  each  statement:	a  shell
     step that pretended to run Ruby would be a lie. An engine lift puts the ex-
     tracted  source root where a Homebrew build runs, since the engine extracts
     an archive under its own name. A head, a mirror, a	 uses_from_macos  frame-
     work,  an	on_macos,  on_arm  or  on_intel block, a bottle block, a service
     block and a test block are reported, because a bottle is a prebuilt foreign
     binary, a launchd job has no Linux counterpart and a Homebrew test	 harness
     does not exist here.

     The  Guix	converter  reads  a  package definition as Scheme text and never
     evaluates it.  The name, version, synopsis,  homepage,  license  and  build
     system  are  carried, and a definition that states no version records zero,
     which the report names. An origin becomes one pinned source: a url-fetch is
     fetched by its uri, a uri written as a string-append becomes the concatena-
     tion of its literals, and the base32 digest a definition writes is	 decoded
     into  the	hex  a Holy source records. An origin that is not a url-fetch is
     reported, since a git or a local origin is a source this converter does not
     fetch. Each name in inputs becomes a runtime requirement and each	name  in
     native-inputs  a  build requirement; a versioned entry contributes only its
     name, since a version constraint is not a name a record can hold.

     The build system becomes the tools it runs.  gnu-build-system  becomes  au-
     toreconf when the source carries configure.ac or configure.in, then config-
     ure  with the payload prefix, make and make install; cmake-build-system and
     meson-build-system become their three commands; a build system this  reader
     does not replace, and the trivial one whose procedure is a Scheme body, are
     reported.	An engine lift puts the extracted source root where a guix build
     runs, since the engine extracts an archive under its own name. A  #:config-
     ure-flags,	 #:make-flags or #:install-flags argument whose entries are lit-
     eral strings becomes the flags of the phase that takes them, and  an  argu-
     ment  that	 computes  a  value is reported. A #:phases argument, a #:tests?
     that turns the suite off, a patch-shebang and any	expression  this  reader
     does not evaluate, such as a modulo, are reported.

     All  of  these  reports  name every carried, preserved, helper, unknown and
     changed item with its source file and line range, and their status	 is  na-
     tive  or  review-required.	 A review-required conversion returns 3 with the
     recipe written; a computed identity, a missing identity or	 malformed  text
     returns 2, and an unreadable input returns 6.

   Prepared source set
     add  SOURCE:PACKAGE  --prepare prints the selected set, source bindings and
     plan hash, then returns success  without  installing  files  or  writing  a
     transaction. It can stage verified artifacts in the target cache. It cannot
     be	 combined  with --yes. The caller must preserve the catalog and artifact
     hashes when carrying this selection into another target root.

EXIT STATUS
     0 indicates success under the implemented checks; 1 indicates a failed  lo-
     cal  fetch,  extraction or check; 2 indicates invalid arguments, configura-
     tion or package inspection. Diagnostics go to standard error except  --json
     check events, which go to standard output.

     Preview  returns  3  when valid requirements need provider decisions, 4 for
     path conflicts and 6 when hooks or privileged modes  need	unsupported  re-
     view. It returns 1 on target-root I/O failure.

SEE ALSO
     holy.conf(5), holy-package(5)

Holy				 September 2026			      HOLYPKG(8)
holy-recipe.5 source=holy version=development sha256=fc71736aaf42d4756d92187a3c5ca1825374ce0127c222a8af22a73ea20c372f
HOLY-RECIPE(5)		       Holy package format		  HOLY-RECIPE(5)

NAME
     holy-recipe - Holy build recipe, phases and build environments

SYNOPSIS
     format holy-recipe-1
     name NAME
     version VERSION
     release RELEASE
     arch ARCH
     libc LIBC
     summary TEXT
     source NAME INPUT
     source-sha256 NAME DIGEST
     build-depend EXPRESSION [RELATION VERSION]
     depend EXPRESSION [RELATION VERSION]
     output NAME KIND
     split OUTPUT GLOB
     config PATH [mutable]
     hook-install INTERPRETER PATH
     hook-remove INTERPRETER PATH
     x-KEY VALUE
     step PHASE INTERPRETER [ARG...] <<TAG
     TAG
     step-file PHASE INTERPRETER [ARG...] PATH
     split-step OUTPUT split INTERPRETER [ARG...] <<TAG
     TAG

DESCRIPTION
     A	Holy recipe is a UTF-8 text manifest plus executable steps. The metadata
     lines use the holy.conf(5) lexer. No shell expansion, variable substitution
     or command substitution is performed  on  manifest	 values.  An  executable
     block  starts with step PHASE INTERPRETER and a <<TAG marker; every byte up
     to a line containing only TAG is the step body. The metadata  parser  never
     executes  a block. step-file names a script relative to the recipe file in-
     stead of an inline block. An interpreter with arguments is an argv	 record:
     the  step runs those words plus the script path, never a concatenated shell
     string. split-step names the output it fills instead of a phase, so it  may
     only appear in the split phase.

     Required  keys  are format, name, version, release, arch, libc and at least
     one output. format must be holy-recipe-1. A repeated scalar key is an error
     with its line number. Unknown keys are errors; keys with the x- prefix  are
     preserved in the produced HOLY/meta as one key with its words rejoined into
     a	single	quoted	value, since HOLY/meta records one key and one value per
     line. A source may be an https URL, an absolute path or a path relative  to
     the  recipe file. A network source needs source-sha256; a local source with
     source-sha256 is verified before use and a mismatch is an error. An archive
     source is extracted as a compressed tar when libarchive recognizes it,  and
     a plain file is placed unchanged.

OUTPUTS
     output  NAME KIND declares one produced artifact. KIND accepts runtime, de-
     vel, docs, debug and metapackage. split OUTPUT GLOB assigns  payload  paths
     to	 that  output  using fnmatch semantics; the first matching rule wins and
     unmatched paths belong to the first declared  output.  Every  non-directory
     payload  path belongs to exactly one output, and the build fails when a de-
     clared output receives nothing.

     holypkg split(8) writes a proposal of those records from  a  prepared  tree
     without  building	anything. The proposal names the runtime, NAME-devel and
     NAME-doc outputs, records the reason each path received one, and reports  a
     path  it cannot settle as a decision rather than assigning it from the file
     extension. An explicit rule in the proposal outranks the  heuristic,  so  a
     settled tree yields a manifest an operator can paste and build.

     With  --debug  the proposal also declares a NAME-debug output and one debug
     record per runtime ELF, naming the build-id both the stripped artifact  and
     its  debug	 file  keep.   The arch, libc, dependencies, provides, files and
     hashes of every output are computed from that output's own files, so a doc-
     umentation output and an ABI library never inherit one another's metadata.

     split-step OUTPUT fills a private staging tree for that output. It runs af-
     ter the package phase with HOLY_SPLIT_DEST set to that tree, and every path
     it creates belongs to OUTPUT. No split pattern may	 redirect  those  paths,
     and a split step whose staging tree stays empty fails the build. A require-
     ment  found in a file, and a hook whose script sits in a tree, are recorded
     only in the output that carries that file.

     Each output is grouped by the ABI facts of the  files  it	receives.  Files
     without  a	 recognized  ELF  class	 land in the noarch-nolibc group; an ELF
     whose machine or runtime cannot be classified fails the  build.  A	 payload
     mixing    several	 ABIs	produces   one	 artifact   per	  group,   named
     NAME--ARCH--LIBC.holy. A symlink or a data file in a  multi-ABI  output  is
     assigned  to  the	first  group of that output and reported as ambiguous. A
     metapackage output carries no payload and depends on the produced ABI vari-
     ants of the same build.

CONFIG FLAGS AND HOOKS
     config PATH marks a payload file as config; config PATH mutable marks it as
     config,mutable. The packer writes flag none, so build applies the	declared
     flags  to	the  generated manifest. A path outside the payload is an error.
     hook-install and hook-remove record runtime hooks with an	absolute  inter-
     preter and a script path relative to the target root. The script must exist
     in	 the  built  payload: its SHA-256 is recorded in HOLY/hooks, and the in-
     staller reads the body from the installed manifest. No hook runs during the
     build.

PHASES
     Normalized phases run in this order:  fetch,  unpack,  prepare,  configure,
     build,  check,  package,  split.  A phase without a step is skipped, except
     that the manager always fetches and  extracts.  Each  step	 is  a	separate
     process  with  its	 own  working directory: build, check, package and split
     start in HOLY_BUILD, the other phases in HOLY_WORK. A split step names  its
     output instead of a phase and always runs after the package phase, whatever
     the order of its line.

     The  manager  sets	 HOLY_WORK,  HOLY_SRC,	HOLY_BUILD, HOLY_DEST, HOLY_OUT,
     HOLY_ARCH, HOLY_LIBC, HOLY_JOBS,  HOLY_BUILD_TARGET,  HOLY_HOST_TARGET  and
     HOLY_TARGET to absolute paths in the selected build root. A split step also
     receives  HOLY_SPLIT_DEST.	 Fetched  sources  live in HOLY_WORK/sources. An
     archive source is extracted into HOLY_SRC/NAME;  a	 plain	file  is  placed
     there unchanged.  An unpack step runs after the manager has extracted every
     source, so it may move or reshape that content.

BUILD
     holypkg  build  RECIPE --output NEW_DIRECTORY [--environment host|clean|vm]
     [--work NEW_DIRECTORY] [--jobs N] [--yes] [--noninteractive] [--keep]

     --work selects an existing empty build root; without it a private directory
     under /tmp is created and removed after a successful build. --keep	 retains
     a	root  the  manager created and prints its path; with --work the root al-
     ready belongs to the caller and is never removed, so the printed line names
     the caller instead. --jobs sets HOLY_JOBS. A recipe  phase	 step  is  shown
     with  its interpreter, argv, working directory, uid and full body before it
     runs; on a terminal the operator answers per step, where  a  accepts  every
     remaining	step.  Without a terminal and without --yes the build stops with
     decision-required (3).  --noninteractive always requires --yes.  A	 failing
     step  aborts the build and reports its phase; an interpreter that cannot be
     executed returns 6.

     --environment host runs the steps in the current environment. --environment
     clean creates a separate build root with a fixed PATH and no HOME,	 and  is
     not  isolation  from  the host kernel. --environment vm needs a booted Holy
     image and qemu-system; when neither is available it returns 6 and names the
     missing capability. Git sources, converter evaluation and cross build roots
     are not implemented and are rejected.

CONVERSION
     holypkg convert PKGBUILD --source NAME --output NEW_DIRECTORY holypkg  con-
     vert  TEMPLATE --source NAME --output NEW_DIRECTORY holypkg import PKGBUILD
     --source NAME --format pkgbuild --output NEW_DIRECTORY holypkg import  TEM-
     PLATE --source NAME --format void --output NEW_DIRECTORY

     A	file  named  template  reaches	the  Void converter and every other name
     reaches the pacman converter. Each reads its input as  text  and  writes  a
     conversion	 directory  holding  the  original  file,  a copy of every local
     source and directory it names, a holy-recipe-1 manifest  and  a  conversion
     report.  NAME  is	a source alias without a colon and is recorded as prove-
     nance; it grants no installed source id. The original file	 is  never  exe-
     cuted.

   PKGBUILD
     pkgbase,  pkgver,	pkgrel,	 pkgdesc,  url,	 license,  arch, epoch, depends,
     makedepends, checkdepends, optdepends and backup are  carried.  A	list  is
     read  the	way a shell reads one: whitespace separates elements, so a comma
     belongs to the element that holds it. A  comparison  operator  becomes  the
     matching relation: >= ge, <= le, > gt, < lt, = eq. arch maps x86_64, x86 to
     i686,  and	 noarch	 or any unchanged; any other list needs review. A source
     entry  has	 $pkgbase,  $pkgname,  $pkgver	and  $pkgrel  expanded,	 and   a
     sha256sums	 entry	becomes	 source-sha256. A local source is copied next to
     the recipe and its original PKGBUILD line is recorded. A function body ends
     at the first closing brace that is not quoted and not part of a command  or
     parameter substitution.

     prepare,  build, check and package keep their bodies in Bash, preceded by a
     prologue that rebuilds the makepkg variables from the exported Holy  paths:
     $pkgdir  becomes  $HOLY_DEST,  $srcdir  becomes  $HOLY_SRC,  $startdir  and
     $builddir become $HOLY_BUILD, and a $pkgdir inside	 a  split  step	 becomes
     $HOLY_SPLIT_DEST.	 $srcdest, $pkgdest, CFLAGS, CXXFLAGS, CPPFLAGS, LDFLAGS
     and MAKEFLAGS are redefined only when the environment leaves them empty.  A
     single  source  is lifted out of its own name directory so that HOLY_SRC is
     the makepkg $srcdir. A package_NAME function  becomes  split-step	for  the
     output  NAME,  and	 install=  fragments  are  copied into the payload under
     /usr/share/holy and recorded as a	postinstall  hook,  so	pre_install  and
     post_install arrive as one hook.

     provides,	conflicts  and replaces, epoch, groups, noextract, validpgpkeys,
     options, non-SHA-256 checksums and architecture-specific source  lists  are
     preserved as x- records or reported as unknown.

   Void template
     pkgname,  version,	 revision, short_desc, homepage, license, maintainer and
     changelog are carried. distfiles is read as a list and $pkgname,  $pkgbase,
     $version,	$revision, $sourcepkg and $pkgver are expanded; a checksum entry
     becomes source-sha256, a leading @ contents digest is reported as	unknown,
     and a local distfile is copied next to the recipe. hostmakedepends, makede-
     pends and checkdepends become build-depend, and depends becomes depend with
     the same comparator names as the PKGBUILD converter; a virtual? requirement
     and  a  build  dependency	that  carries a version are reported as unknown.
     conf_files becomes config and mutable_files becomes config mutable,  and  a
     path with a wildcard needs review.

     pre_fetch,	 do_fetch,  post_fetch,	 the  extract,	patch, configure, build,
     check and install families keep their Bash and  become  the  matching  Holy
     phase, each behind a prologue that rebuilds the xbps-src variables from the
     exported  paths: $wrksrc and $build_wrksrc become $HOLY_SRC, $masterdir be-
     comes $HOLY_WORK, $XBPS_BUILDDIR becomes  $HOLY_BUILD,  $XBPS_MAKEJOBS  be-
     comes  $HOLY_JOBS,	 and  $DESTDIR	becomes	 $HOLY_DEST with $PKGDESTDIR the
     same, or $HOLY_SPLIT_DEST in a split step. The step  changes  into	 $wrksrc
     first  because  xbps-src  runs  a phase there. A distfile is extracted into
     HOLY_SRC, which therefore takes the place of the  xbps-src	 $wrksrc  direc-
     tory. The v* helpers a body calls are carried into the prologue; vman, vsv,
     vsed, vcompletion and vsrccopy are reported as unresolved, as is any use of
     a cross, verbose or chroot variable.

     A	NAME_package function becomes output NAME plus a split step carrying its
     pkg_install body, so DESTDIR stays the main tree and PKGDESTDIR becomes the
     staging tree. depends, replaces, conflicts and short_desc set  inside  that
     function are reported with their lines rather than moved into the main out-
     put,  because  a  Holy  recipe  has one depend list. A patches directory is
     archived next to the recipe and applied in the prepare step  with	a  .args
     file  per	patch, and a files directory is archived next to it and named by
     FILESDIR. An INSTALL or REMOVE file becomes one hook and is  reported,  be-
     cause  a Holy hook runs with ACTION unset and its pre and post branches are
     not reproduced.

     build_options are fixed to	 build_options_default	before	they  reach  the
     recipe, so vopt_if, vopt_with, vopt_enable, vopt_bool and vopt_feature pro-
     duce their value and a top level vopt_conflict is checked against that same
     set.  The	remaining build variables, such as bootstrap, repository, archs,
     shlib_provides, nostrip and skip_extraction, are preserved as x- records. A
     phase the template leaves out is  reported	 as  supplied  by  common/build-
     style/NAME.sh,  which  the converter does not run, so its result is review-
     required. A conditional block, a case block or a vopt_conflict is	reported
     with its line, since the converter evaluates none of them.

   Aports APKBUILD
     pkgname,  pkgver, pkgrel, pkgdesc, url, license and maintainer are carried.
     arch maps all and noarch to noarch, x86_64 to x86_64 and x86 to  i686;  any
     other machine name and a negated architecture are reported. depends becomes
     depend  and  makedepends,	makedepends_build, makedepends_host and checkde-
     pends become build-depend with the same comparator names  as  the	PKGBUILD
     converter;	 a  !NAME  conflict becomes x-conflicts, a so: or cmd: prefix is
     reported, and the per subpackage  depends_NAME  lists  are	 preserved  with
     their lines because a Holy recipe has one depend list.

     source  is	 read  as a list and $pkgname, $pkgver and $pkgrel are expanded,
     with $pkgver giving the bare upstream version there and version-rrelease in
     a dependency; a filename::url target name is preserved. A local  source  is
     copied  next  to the recipe and hashed as SHA-256, and a mismatch against a
     declared sha256sums entry is reported. A remote source is carried with  its
     declared  sha256,	or  reported  when  there  is  none, because aports pins
     sha512sums, which a Holy source cannot use, and the report names every such
     source.

     prepare, build, check and package keep their shell and become the	matching
     Holy  phase, each behind a prologue that rebuilds the abuild variables from
     the  exported  paths:  $srcdir   becomes	$HOLY_SRC,   $startdir	 becomes
     $HOLY_WORK,  DESTDIR  becomes  $HOLY_DEST	with  PKGDESTDIR  the  same,  or
     $HOLY_SPLIT_DEST in a split step, $pkgdir stays the main  tree  and  $subp-
     kgdir   becomes   the   staging   tree.	$JOBS,	$MAKEFLAGS,  $SAMUFLAGS,
     $CMAKE_BUILD_PARALLEL_LEVEL and the other abuild.conf parallel settings are
     rebuilt from $HOLY_JOBS. The step	changes	 into  $builddir  first	 because
     abuild  runs  a  phase  there; a declared builddir is rebased on the source
     tree and an absent one is the abuild default  of  $srcdir/$pkgname-$pkgver,
     which  is	reported.  The	extracted  tree therefore takes the place of the
     abuild $srcdir directory, and that lift replaces default_unpack.

     Each subpackages entry is NAME, NAME:function  or	NAME:function:arch,  and
     the  split	 function  is the named one or the last dash-separated suffix of
     NAME, with -bash-completion, -zsh-completion and  -fish-completion	 mapping
     to	 bashcomp,  zshcomp  and  fishcomp. A split function with a body becomes
     output NAME plus a split step carrying it; one without a body  is	reported
     as	  needing  the	abuild	default_dev,  default_doc,  default_static,  de-
     fault_openrc or default_libs helper, which moves files by	pattern,  so  no
     output  is	 declared for it and a declared architecture is reported. An in-
     stall entry is post-install, pre-install, pre-upgrade,  post-upgrade,  pre-
     deinstall or post-deinstall; the first and the fourth map onto hook-install
     and  hook-remove, are copied into the payload under usr/share/holy/NAME and
     are reported as a semantic change, since a Holy hook runs with  ACTION  un-
     set, and the rest are reported as having no Holy hook stage.

     options,  provider_priority,  replaces_priority, triggers, install_if, pkg-
     groups, pkgusers, giturl, pcprefix, sonameprefix, langdir, soname, provides
     and replaces are preserved as x- records. A conditional block  is	reported
     with  its	line,  and  so	is  any	 other top level statement, since abuild
     sources the file as a shell script and the converter executes none	 of  it.
     The default_* helpers, the abuild phases the template leaves out, the cross
     and  chroot variables, $CBUILD, $CHOST, $CTARGET and $CARCH are reported as
     unresolved or unreproduced.

   SlackBuild script
     PRGNAM, VERSION, BUILD, TAG and PKGTYPE are carried, whether they are writ-
     ten as NAME=value or as NAME=${NAME:-value}; a computed value  is	reported
     instead  of guessed. A SlackBuild script is one linear shell program rather
     than a set of phase functions, so it becomes a single build step,	and  the
     prologue rebuilds the variables the script reads: $ARCH becomes $HOLY_ARCH,
     $CWD  and	$TMP become $HOLY_SRC, $PKG becomes $HOLY_DEST with $DESTDIR the
     same, $OUTPUT becomes $HOLY_OUT, and $SLKCFLAGS, $CFLAGS,	$CXXFLAGS,  $LD-
     FLAGS and $MAKEFLAGS are rebuilt from $HOLY_JOBS.

     The  body	runs  from the set -e line to the /sbin/makepkg call, and the cd
     $PKG before that call is left out, because the engine  packs  the	payload.
     The  engine  also	fetches	 and unpacks the recorded archive, so a tar line
     that reads $CWD is reported and left out, as is the rm -rf $PRGNAM-$VERSION
     that precedes it. The machine  the	 script	 picks	with  uname  -m	 becomes
     $HOLY_ARCH	 and  the  LIBDIRSUFFIX	 it derives per machine becomes empty on
     x86_64, both reported. The archive	 name  comes  from  the	 tar  line  with
     $PRGNAM,  $VERSION	 and  $BUILD expanded; an archive that is not beside the
     script is reported, since this format pins an MD5 sum rather than a SHA-256
     digest, and a local one is copied next to the recipe and hashed as SHA-256.
     Every other file the script reads through $CWD travels  beside  the  recipe
     and is declared as a source, so the engine stages it where $CWD points dur-
     ing a step.

     slack-desc beside the script carries the summary, the homepage, and the re-
     quires  and conflicts lists, which become depend and x-conflicts; the other
     field keys are preserved with their lines. The info file beside the  script
     carries  the  upstream  DOWNLOAD and its MD5SUM, which is reported as unus-
     able. A doinst.sh the script copies into $PKG/install becomes one hook  and
     is copied into the payload, and the $PKG/install tree itself is reported as
     packaging	metadata  that stays in the payload as ordinary files. The strip
     pass, the ownership rewrite, the user and group creation, the loader  cache
     update  and  the desktop, mime, icon and font cache helpers are reported as
     unresolved.

   RPM spec
     Name, Version, Release, Summary, License and URL are carried. A Version  or
     Release  written  with  a	macro in it keeps only its literal part, and the
     macro is reported, so the value stays what the spec says; a field	with  no
     literal  text at all is refused. The distribution suffix on Release is left
     out, which is reported. BuildArch noarch becomes noarch and any other value
     becomes any, because the payload decides the machine, and ExclusiveArch  is
     preserved.

     The  %global  and %define records are collected, and a macro this converter
     can resolve is expanded everywhere it appears:  the  identity  fields,  the
     path  macros  such as _sourcedir, _builddir, _topdir and buildroot, and the
     directory macros such as _bindir and _libdir.  A  macro  that  resolves  to
     nothing  and  is  optional is left out, an unresolved one stays in the text
     and is reported, and a value that is a pattern rather than a word stays in-
     side the body.

     BuildRequires becomes build-depend and Requires becomes  depend,  with  the
     same  comparator  names as the PKGBUILD converter, and the list is read one
     record per line because an rpm requirement carries its comparison. Provides
     becomes x-provides, Conflicts and Obsoletes become x-conflicts, and  Recom-
     mends, Suggests and Enhances become x-suggests, since none of them is a re-
     quirement.	 A requirement that names a file, a rich dependency or an rpmlib
     capability is reported rather than turned into a record.

     Source and Patch records name the files the build needs. A local  file  be-
     side  the	spec is copied next to the recipe and hashed as SHA-256, and one
     that is absent is reported, since a spec normally pins no	digest	at  all.
     The  engine fetches and unpacks the recorded sources, so the extracted tree
     takes the place of _sourcedir.

     The prep, build, install and check	 sections  become  the	prepare,  build,
     package  and  check phases, each behind a prologue that rebuilds the macros
     the body reads from the exported paths and	 changes  into	_sourcedir/NAME-
     VERSION  when the tree was unpacked under that name. %setup, %autosetup and
     %autopatch become a cd into that directory followed by a  patch  pass  over
     the  declared  patches,  and %make_install, %make_build and the __ prefixed
     helpers become the shell line they stand for.  Every other rpm section com-
     mand is reported and left in the body, so the build  fails	 visibly  rather
     than  losing  a  step.  An	 rpm  conditional, which this converter does not
     choose between, is reported with its section.

     A %package block becomes an output, and because an rpm subpackage is a file
     list rather than a body, its split step copies the	 paths	its  own  %files
     section  named out of the main tree. A path that keeps a macro is reported,
     a %files option such as -f is reported, and a  subpackage	with  no  %files
     list  gets	 no payload.  The main %files list is not carried, since it only
     checks what the install already placed, and that is reported. The %descrip-
     tion blocks are not carried.


   Debian source package
     A debian directory is recognized by its  basename,	 or  named  with  import
     --format	debian.	  The  version	comes  from  the  first	 record	 of  de-
     bian/changelog, which is the distribution version rather than the	upstream
     one.  It is split at the last dash: an all-numeric tail is the Debian revi-
     sion and becomes the Holy release, and a version with no such tail	 is  na-
     tive,  so	its release is one.  Either outcome is reported, as is an epoch,
     which names a packaging revision order and is dropped. A changelog with  no
     version  on  its first line is malformed. The source stanza gives the name,
     the section gives the summary of the main binary package, and Homepage  be-
     comes the homepage.


A relationship field is a comma separated list of groups, and a group may
     offer  alternatives  with a pipe. One Holy depend record names one package,
     so the first alternative of each group is carried	and  the  rest	are  re-
     ported.  Build-Depends and Build-Depends-Indep become build-depend, Depends
     and  Pre-Depends  become depend, with the same comparator names as the PKG-
     BUILD converter; a strict comparison becomes lt or gt, and a Debian version
     has the same epoch and revision, so the version keeps  its	 upstream  part.
     Provides  becomes	x-provides, Breaks, Conflicts and Replaces become x-con-
     flicts, and Recommends, Suggests and Enhances  become  x-suggests.	 A  dpkg
     substitution  variable such as $ {misc:Depends} is filled in by dpkg and is
     reported, and an entry with an architecture qualifier  is	reported  rather
     than turned into a record. Only the source stanza and the main binary pack-
     age reach the recipe; a requirement of a subpackage is reported, since that
     package is built on its own.


Each binary stanza becomes an output. A binary that names a file list beside
     the control file is a subpackage, and because a debian subpackage is a file
     list  rather  than	 a body, its split step copies the paths that list names
     out of the main tree, which is reported. A .install line is a source and  a
     destination,  and	a line with no destination names the source itself, so a
     directory destination is copied whole. A .docs, .manpages and  .links  list
     names  a  path  the same way, and a list that names no path is reported in-
     stead of written as a split step that would fill no tree. The  binary  that
     names  no	file  list  is the main output and owns the whole tree. A source
     with no binary stanza still builds one output, and	 more  than  one  binary
     that  names no file list is reported, since the converter cannot tell which
     one is the main tree.


debian/rules becomes the build step, behind a prologue that sets
     DEB_HOST_MULTIARCH and DEB_BUILD_OPTIONS and changes into the source  tree.
     dh	 is  a	macro  framework  rather than a script, so every debhelper call,
     every debhelper override and dpkg-buildpackage are reported and left in the
     body, which means the build fails visibly rather than losing  a  step.  The
     maintainer scripts, debian/copyright, debian/watch and debian/source/format
     are copied next to the recipe and reported; a lintian-overrides file is re-
     ported as well, since it suppresses a report rather than building anything.
     Standards-Version is preserved.


   Gentoo ebuild
     An	 ebuild is recognized by its .ebuild suffix, or named with import --for-
     mat gentoo.  It states its identity in  its  file	name,  which  is  PN-PV-
     rPR.ebuild,  so  the  name is the text before the last dash a digit follows
     and the version is what follows it; a trailing -rN is the revision and  be-
     comes  the Holy release, and a file name with no revision gets release one.
     An epoch names a packaging revision order rather than a version, so  it  is
     preserved	and  dropped.  A file name that carries no version is malformed.
     EAPI, LICENSE and SLOT are carried, DESCRIPTION is the summary,  and  HOME-
     PAGE  is  the  homepage. KEYWORDS names the machines an ebuild is tested on
     rather than the machine that builds it, so arch is any.


The engine fetches and unpacks the recorded sources, so the extracted tree
     takes the place of WORKDIR, which is reported. A mirror:// entry  names  no
     single  address  and is reported, and a remote archive is reported too, be-
     cause a Gentoo Manifest pins a  BLAKE2B  and  a  SHA-512  rather  than  the
     SHA-256  a Holy source needs. A PATCHES entry, and any other file named be-
     side the ebuild, is copied next to the recipe and hashed as SHA-256. An en-
     try behind a USE flag is a file the converter  cannot  reach,  and	 is  re-
     ported.


A dependency atom is a category, a package and an optional comparison. The
     category  is dropped and the name is what a record holds, a blocker becomes
     x-conflicts, and a version keeps its upstream part with the same comparator
     names as the PKGBUILD converter. A ~ atom is a range and a wildcard is  not
     a	version,  so  both are reported; a slot, a use dependency and a virtual,
     which names an interface rather than a package, are reported as well.  RDE-
     PEND  and PDEPEND become depend and DEPEND and BDEPEND become build-depend.
     A USE conditional and an any-of group are reported, since a Holy recipe has
     no USE flags and cannot choose between the members	 of  a	group,	and  the
     atoms  inside  one	 are carried anyway so the build still holds them. IUSE,
     REQUIRED_USE, RESTRICT and PROPERTIES are reported as package manager  set-
     tings.


Each standard phase function becomes the matching phase, and a phase the
     ebuild  leaves  out  is the one the inherited eclasses supply. A body keeps
     its own shell behind a prologue that  rebuilds  EPREFIX,  ED,  D,	DESTDIR,
     WORKDIR,  DISTDIR,	 T,  PN,  PV,  PR, PF, P, PVR, EAPI and changes into the
     source tree. An eclass is a helper environment, so every inherited	 one  is
     reported,	and  so	 is every ebuild.sh helper a body calls, which means the
     build fails visibly rather than losing a step. A pkg_preinst, pkg_postinst,
     pkg_prerm or pkg_postrm function runs at install time through Portage,  and
     a Holy hook carries a script rather than a function, so each is reported.


   Pacstall pacscript
     A	pacscript  is  recognized by its .pacscript suffix, or named with import
     --format pacstall.	 It is bash with a metadata header  written  as	 assign-
     ments,  so	 pkgname,  pkgver,  pkgrel,  epoch, pkgdesc, url, license, main-
     tainer, repology, arch and gives are carried, with pkgdesc as  the	 summary
     and  url  as  the	homepage.  A  value  written  with $pkgname, ${pkgname},
     $pkgver, $pkgrel, $gives, $pkgbase or $epoch, or with a variable  the  same
     file states in an assignment of its own, is written out, and one that needs
     the  shell	 to  choose a substring is a computed identity and returns 2. An
     epoch names a packaging revision order rather than a version, so it is pre-
     served and dropped. amd64 and x86_64 become x86_64, i386  and  i686  become
     i686,  any and all become any, and a machine Holy does not carry is written
     as it stands and reported. A list of machines is reported, because the pay-
     load decides the machine the recipe is built for.


A source entry is NAME::URL, ?NAME::URL or a plain URL, and a sha256sums entry
     in the same order becomes source-sha256. The engine fetches and unpacks the
     recorded sources, so the extracted tree takes the place of srcdir, which is
     reported. A file named beside the pacscript is copied next	 to  the  recipe
     and  hashed  as  SHA-256.	A  git	address is reported, since a Holy source
     fetches archives, and so is a remote source with no sha256sums entry and  a
     plain http address, since a Holy source is fetched over https.


depends, makedepends and checkdepends become depend and build-depend with the
     comparator	 names	the PKGBUILD converter uses, and a group of alternatives
     written with a pipe is reported with the first of	them  carried,	since  a
     Holy  record cannot choose one. pacdeps become depend as well, and the fact
     that they name packages of the same pacstall repository  is  reported,  be-
     cause a Holy resolver has to find them in a source that has them. provides,
     conflicts,	 breaks, replaces, enhances, recommends and suggests name no re-
     quirement, so they are preserved as x- records, and an optdepends entry be-
     comes x-optdepend with its description. A backup entry becomes  config,  an
     r:	 prefix	 becomes  config  mutable and is reported, since a config record
     only marks a file. A list written per machine or per distribution	under  a
     suffixed  name  is reported, and so is every setting that steers a Pacstall
     run: priority, external_connection, incompatible, compatible,  mask,  noex-
     tract,  custom_fields  and	 ppa. A digest list other than sha256sums is re-
     ported, because a Holy source needs SHA-256.


prepare, build, check and package become the matching phase, and a body keeps
     its own shell behind a  prologue  that  rebuilds  pkgdir,	pacdir,	 srcdir,
     startdir, builddir, TARCH, NCPU, pkgname, pkgbase, pkgver, pkgrel, pacname,
     gives  and	 epoch	from the exported Holy paths and changes into the source
     tree. Every helper the Pacstall environment supplies  that	 a  body  calls,
     such  as  fancy_message, makepkg, parse_options or ask, is reported, and so
     is a variable of that environment a body reads:  KVER,  STAGEDIR,	homedir,
     DISTRO, DIR, full_version and pacstall_root. A list of names with a pkgbase
     is a split pkgbase: every name becomes an output and its package_NAME func-
     tion  becomes  the	 split step that fills it, and a package function beside
     those is reported. pre_install, pre_upgrade, post_install and  post_upgrade
     become  one  install  hook, and pre_remove and post_remove one remove hook;
     each hook is written beside the recipe, declared as a source and  installed
     into  the	payload,  and a Holy hook runs with ACTION unset, so the pre and
     post bodies arrive in the order Pacstall calls them.  A  conditional  block
     and  an  assignment  inside one are reported, since the converter evaluates
     neither.


   Flatpak manifest
     A manifest is recognized by its .json, .yml or .yaml suffix, or named  with
     import  --format  flatpak.	 Only the JSON form is read; another form of the
     same manifest returns 2 rather than a guess. The package name is  the  last
     dotted  component of the application id, and an id that names a machine and
     a branch after a slash keeps that reflex in x-app-id while the branch  sup-
     plies the machine. A version the manifest states is carried and one it does
     not  state	 records  zero,	 which is reported.  summary, url, runtime, sdk,
     command, branch and the machine are carried; arch is the machine the  mani-
     fest or its branch names, and any means the machine the build runs on.


     The  sdk  is a build requirement and the runtime a runtime requirement, be-
     cause the SDK that builds the modules and the runtime the program	runs  on
     are  two different Flatpak ids, and the fact is reported. Each id loses its
     leading components, since a record names one package. The command is a path
     under /app, so it is kept as x-flatpak-command, and the prefix of a  module
     becomes  /usr.  A	/app  path inside a build command becomes $DESTDIR, so a
     converted build writes into the payload and nowhere else.


     The engine fetches and unpacks the recorded sources, so one  top  directory
     inside  an	 extracted  archive is lifted into place, which is what a module
     builds in, and the step changes into that tree. An archive	 with  an  https
     address  becomes  a source with the sha256 the manifest pins, and one named
     beside the manifest is copied next to the recipe and hashed there. A  file,
     a	patch  and  an inline source travel beside the recipe as well, an inline
     body becoming a file of its own. A patch applies with -p1 in a prepare step
     before its module builds, a shell source runs inside the step of  its  mod-
     ule,  and a sed source, a directory, a git, svn or bzr checkout, strip-com-
     ponents, dest-filename and dest are reported.


     Each module becomes one step in module order. Its build-options export env,
     cflags, cxxflags, ldflags and cppflags and	 prepend  append-path,	and  its
     pre-commands,  build-commands,  post-install  and	post-commands keep their
     shell. A simple module is exactly its commands. The make, autotools,  auto-
     gen, cmake and meson templates are replaced by the shell that runs the same
     tools,  which  is reported, since the template that normally runs them does
     not travel with the recipe. The cargo template builds  without  an	 install
     step  and is reported, and a buildsystem with no Holy phase is a helper the
     report names rather than a guess.


     A finish-args permission, a cleanup step, a build extension  and  a  module
     cleanup  are  dropped  and counted, since a Flatpak sandbox decision has no
     Holy equivalent.  A manifest with more than one module is reported, because
     a Flatpak build shares one prefix across its modules while each  step  here
     installs  into  the  payload,  so a later module cannot read an earlier in-
     stall.


   Homebrew formula
     A formula is recognized by its .rb suffix, or named  with	import	--format
     homebrew.	 It  is	 Ruby,	and  it is read as text and never evaluated. The
     class name becomes the package name, and a class that inherits from a  cask
     is reported, since a cask installs an application bundle rather than build-
     ing  a  source tree. The description, homepage and license are carried, the
     url and its sha256 become one pinned source, the revision becomes	the  re-
     lease,  and a formula that states no version records the version its source
     url carries before its archive suffix, or zero, which is reported.


     A depends_on becomes depend and a :build dependency  becomes  build-depend,
     while  a  :recommended  or	 :optional dependency is reported, since a build
     cannot promise a feature it did not ask for. A resource or	 a  patch  block
     that  pins a url and a digest becomes a fetched source, and a patch applies
     with -p1 in a prepare step. A block that prepares its content with	 a  Ruby
     expression is a helper the report names.


     A system call inside def install or on_linux becomes a build step that runs
     the  same	command	 in the source root, because a Homebrew build runs there
     and a Holy build step starts in the build directory. The Homebrew prefix is
     rewritten	onto  the  build  root:	 #{prefix}  and	 HOMEBREW_PREFIX  become
     $HOLY_DEST, #{libexec} becomes $HOLY_DEST/libexec, #{etc} and #{var} become
     $HOLY_DEST/etc and $HOLY_DEST/var, and #{buildpath} becomes $HOLY_BUILD. An
     interpolation this reader does not model keeps its text and is reported. An
     engine  lift  puts	 the  extracted source root where a Homebrew build runs,
     since the engine extracts an archive under its own name and a  distribution
     tarball keeps one top directory inside it.


     Every  other statement of an install body is Ruby, so it is not translated.
     The formula is copied beside the recipe as homebrew-install.rb,  the  build
     declares  a  ruby build requirement, and the report names the file and line
     of each such statement, since a shell step that pretended to run Ruby would
     be a lie. A head, a  mirror,  a  uses_from_macos  framework,  an  on_macos,
     on_arm or on_intel block, a bottle block, a service block, a test block and
     a	def  other than install are reported: a bottle is a prebuilt foreign bi-
     nary, a launchd job has no Linux counterpart, a Homebrew test harness  does
     not exist here and a development checkout is not the pinned source.

   Guix package definition
     A	definition is recognized by its .scm suffix, or named with import --for-
     mat guix.	It is Scheme, and it is read as text and  never	 evaluated.  The
     name,  version, synopsis, homepage, license and build system are carried, a
     definition that states no version records zero, which is  reported,  and  a
     definition	 whose package form states no name takes the name of its define-
     public variable, which is reported as a change.


     An origin becomes one pinned source. A url-fetch is fetched by its	 uri,  a
     uri  written  as  a string-append becomes the concatenation of its literals
     and the expression is reported, and the base32 digest a  definition  writes
     is decoded into the hex a Holy source records. An origin that is not a url-
     fetch is reported, since a git or a local origin is a source this converter
     does  not	fetch.	A  definition  that states no origin is refused, since a
     build has no source to fetch.


     Each name in inputs becomes depend and each name in  native-inputs	 becomes
     build-depend.  A versioned entry contributes only its name, since a version
     constraint is not a name a record can hold, and the entry	is  reported.  A
     requirement  a definition writes as a name with a range the reader does not
     walk is reported.


     The build system becomes the tools it runs.  gnu-build-system  becomes  au-
     toreconf when the source carries configure.ac or configure.in, then config-
     ure with the payload prefix, make and make install, since a guix build con-
     figures  the  package  prefix  and	 stages the install with DESTDIR. cmake-
     build-system and meson-build-system become	 their	three  commands,  and  a
     build system this reader does not replace, and the trivial one whose proce-
     dure  is  a  Scheme  body,	 are reported. An engine lift puts the extracted
     source root where a guix build runs, since the engine extracts  an	 archive
     under  its	 own name and a distribution tarball keeps one top directory in-
     side it.


     A #:configure-flags, #:make-flags or #:install-flags argument whose entries
     are literal strings becomes the flags of the phase that takes them; an  ar-
     gument whose entry is a Scheme expression keeps its text and is reported. A
     #:phases  argument	 replaces the build system phases, a #:tests? that turns
     the suite off is reported as a change, and a patch-shebang and any	 expres-
     sion the reader does not evaluate, such as a modulo, are reported.


CONVERSION  REPORTThe report lists every carried, preserved, helper, unknown and
     changed item with
     its source file and line range, and its  status  is  native  or  review-re-
     quired.  A	 review-required  conversion  returns 3 with the recipe written,
     since review is a statement about execution, not  about  whether  the  text
     could be carried. A missing identity, a computed identity or malformed text
     returns 2; an unreadable input returns 6.

RESULTS
     Each  output  artifact  is written to the output directory. Its manifest is
     regenerated from the copied payload. HOLY/meta records format,  name,  ver-
     sion,  release,  os,  arch, libc, x-version-family holy, x-build-target and
     installed-size, plus any  x-  record.  HOLY/deps  carries	declared  depend
     records plus one soname requirement per DT_NEEDED entry, each attributed to
     the  file	that needs it and written only into the output that carries that
     file.  HOLY/provides records the package  name  and  the  SONAME  of  every
     shared  object  in	 the payload. HOLY/hooks records a declared hook only in
     the output whose payload holds its script, and the build fails if an output
     declares a hook it does not carry. HOLY/origin records  the  recipe  inputs
     with  their  pinned  digests and verification built-locally. HOLY/transform
     records the build environment and the declared build dependencies. The fin-
     ished .holy is installed by a normal transaction; the  build  itself  never
     writes to the target root.

EXAMPLES
     format holy-recipe-1
     name example
     version 1.0
     release 1
     arch x86_64
     libc glibc
     summary Example package
     build-depend "toolchain:x86_64-linux-gnu"
     build-depend cmd:make
     source src "https://example.org/example-1.0.tar.xz"
     source-sha256 src "0000000000000000000000000000000000000000000000000000000000000000"
     output example runtime
     output example-doc docs
     split example-doc usr/share/doc/*
     step build /bin/sh <<BUILD
     cd "$HOLY_SRC"
     make -j"$HOLY_JOBS"
     BUILD
     step package /bin/sh <<PACKAGE
     cd "$HOLY_SRC"
     make DESTDIR="$HOLY_DEST" PREFIX=/usr install
     PACKAGE

     A second output built from its own staging tree:

     output example runtime
     output example-doc docs
     split-step example-doc split /bin/sh <<DOCS
     mkdir -p "$HOLY_SPLIT_DEST/usr/share/doc/example"
     cp README "$HOLY_SPLIT_DEST/usr/share/doc/example/README"
     DOCS

EXIT STATUS
     0	the build produced every declared output. 1 an operational failure. 2 an
     invalid recipe, argument or conversion. 3 a decision is required. 6  a  re-
     quired artifact or system capability is unavailable.

SOURCES
     PKGBUILD:	    https://pacman.archlinux.page/PKGBUILD.5.html      APKBUILD:
     https://wiki.alpinelinux.org/wiki/APKBUILD_Reference     abuild	 phases:
     https://gitlab.alpinelinux.org/alpine/abuild/-/raw/master/functions.sh.in
     abuild			 default.conf:			    https://git-
     lab.alpinelinux.org/alpine/abuild/-/raw/master/default.conf    RPM	   spec:
     https://rpm.org/docs/latest/manual/spec.html  rpm macros: https://rpm-soft-
     ware-management.github.io/rpm/manual/macros.html	  SlackBuild	 script:
     https://slackbuilds.org/howto/	slack-desc     format:	  https://slack-
     builds.org/guidelines/ Void Manual: https://raw.githubusercontent.com/void-
     linux/void-packages/master/Manual.md v* helpers: https://raw.githubusercon-
     tent.com/void-linux/void-packages/master/common/environment/setup/in-
     stall.sh  build  style:  https://raw.githubusercontent.com/void-linux/void-
     packages/master/common/build-style/gnu-makefile.sh		RPM	   spec:
     https://rpm.org/docs/latest/manual/spec.html      SlackBuild      template:
     https://slackbuilds.org/templates/autotools-template.SlackBuild Debian con-
     trol fields: https://www.debian.org/doc/debian-policy/ch-controlfields.html
     Debian  package relationships: https://www.debian.org/doc/debian-policy/ch-
     relationships.html	   Debian    packaging	   concepts:	 https://www.de-
     bian.org/doc/debian-policy/concepts.html	debhelper:  https://manpages.de-
     bian.org/trixie/debhelper/debhelper.1.en.html	  Gentoo	 ebuild:
     https://wiki.gentoo.org/wiki/Ebuild	  Package	  specification:
     https://wiki.gentoo.org/wiki/Repository_format  eclass:   https://wiki.gen-
     too.org/wiki/Eclass     USE     flag     dependencies:    https://wiki.gen-
     too.org/wiki/USE_atoms Pacstall: https://github.com/pacstall/pacstall  Pac-
     stall	   manual:	  https://github.com/pacstall/pacstall/blob/mas-
     ter/misc/man/pacstall.8 Pacstall programs: https://github.com/pacstall/pac-
     stall-programs Flatpak manifests:	https://docs.flatpak.org/en/latest/mani-
     fests.html	   flatpak-builder   modules:	https://docs.flatpak.org/en/lat-
     est/flatpak-builder.html

holy				      2026			  HOLY-RECIPE(5)