Skip to content

Metadata Reference

Every rootfs FlatRoot builds contains a .flatroot/ directory at its root. This page documents the on-disk format, field specifications, checksum algorithms, and reinstallation behaviour. For the design rationale (why metadata is recorded at install time, why it is excluded from exports, why the format is plain text), see The metadata layer.

Location

<root>/.flatroot/
  manifest                    # top-level rootfs identity
  packages                    # per-package records
  files/
    <name>:<arch>             # one file per installed package
  scripts/
    <name>:<arch>/            # staged post-install scripts (persisted, never pruned)
  bin/                        # stub programs placed on PATH during post-install (persisted)

All text files use UTF-8 encoding, \n line endings, and carry no trailing newline at end-of-file. Record ordering is byte-ascending (equivalent to LC_ALL=C sort).

Manifest

Path

<root>/.flatroot/manifest

Format

A single dpkg-style record (Key: Value) with fixed key order, written with no trailing newline — consistent with the end-of-file rule above.

Fields

Key Description
FlatrootVersion Version of the FlatRoot binary that wrote this file, from CARGO_PKG_VERSION.
Sources Deduplicated union of distro source strings across all installed packages. Comma-space separated, byte-ascending.
Architectures Deduplicated union of architecture strings across all installed packages. Comma-space separated, byte-ascending.
PackageCount Number of records in the packages file.

Example

FlatrootVersion: 0.1.0
Sources: debian:bookworm@2026-04-21
Architectures: i686, x86_64
PackageCount: 247

Packages

Path

<root>/.flatroot/packages

Format

Dpkg-style records (Key: Value), one per installed (name, architecture) pair. Records are separated by exactly one blank line. Sorted by (name, architecture) byte-ascending. Every record has the same set of keys in fixed order.

Fields

Key Description
Package Package name as published by the upstream index.
Version Upstream version string, verbatim. Interpretation requires knowing the Source: (for its version-comparison algorithm).
Architecture Target architecture in Linux kernel naming (x86_64, i686, aarch64, etc.).
Source Full source string from --from, including any @date suffix.
Url Fully qualified URL of the archive on the upstream mirror.
Checksum Typed hash in <algo>:<hex> form. See Checksum algorithms.
Size Archive size in bytes. 0 means the index did not publish a size.
Depends Flattened hard dependency list in dpkg syntax. May be empty, but the key is always present.

Example

Package: libc6
Version: 2.36-9+deb12u7
Architecture: x86_64
Source: debian:bookworm@2026-04-21
Url: https://snapshot.debian.org/archive/debian/20260421T000000Z/pool/main/g/glibc/libc6_2.36-9+deb12u7_amd64.deb
Checksum: sha256:a4f8e6c1f0b4c7d3e9a1b8c4f7e0d3a6b9c2e5f8a1d4b7e0c3f6a9d2b5e8c1f4
Size: 2700000
Depends: libgcc-s1, libcrypt1 (>= 1:4.1.0)

Dependency Syntax

The Depends field flattens FlatRoot's in-memory dependency representation to dpkg syntax, regardless of the source distribution:

  • Groups (hard dependencies) are separated by , and a space.
  • Alternatives within a group are separated by |.
  • Version constraints are written as (<constraint>) after the name.

For distros whose native indices carry information that does not map cleanly to package names — RPM file-path deps like /bin/sh, apk sonames like so:libc.musl-x86_64.so.1 — the raw token is preserved verbatim.

Checksum Algorithms

Distros Algorithm Prefix Scope
Debian, Ubuntu, Arch, CachyOS, CentOS, Fedora, AlmaLinux, Rocky SHA-256 sha256: Full archive
openSUSE SHA-512 sha256: Full archive
Alpine Q1+base64 SHA-1 q1-sha1: Control section only

The Alpine checksum is not interchangeable with a plain sha1: hash — it is a base64-encoded SHA-1 of the package's control section, prefixed with Q1.

The openSUSE prefix is sha256: even though the recorded digest is a SHA-512 hash: the prefix is taken from the package format's declared scheme (shared by every RPM-family distro), while download verification infers the true algorithm from the digest's length.


Filelists

Path

<root>/.flatroot/files/<name>:<arch>

Format

Plain text, one absolute path per line, sorted byte-ascending. Includes regular files, directories, and symlinks written during extraction. Excludes entries under .flatroot/ — those are FlatRoot metadata, not package payload.

Example

files/bash:x86_64:

/bin/bash
/etc/bash.bashrc
/etc/skel/.bash_logout
/etc/skel/.bashrc
/etc/skel/.profile
/usr/share/doc/bash/copyright
/usr/share/man/man1/bash.1.gz

Cross-Distro Protection

On every flatroot install against an existing rootfs, FlatRoot reads the existing manifest file and compares every entry in Sources against the incoming --from string byte-for-byte. Any mismatch aborts the install before any network access. The check is strict: a rootfs is scoped to one exact source string for its lifetime.

Error Shape

Error: cannot install from 'ubuntu:noble' into rootfs at /tmp/rootfs
  existing source: debian:bookworm@2026-04-21
  a rootfs is scoped to one exact source — different distros, releases, snapshot dates, and pinned vs unpinned variants are all refused
  to start fresh, remove /tmp/rootfs/.flatroot/ or use a different directory

Allowed Operations

Operation Allowed? Reason
Reinstallation (same --from) Yes Source strings match exactly
Multi-arch within one --arch invocation Yes One --from produces one source string across every per-arch record
Additional architecture via a second invocation with same --from Yes Source strings match exactly; only --arch differs
Different release, same distro (debian:bookwormdebian:trixie) No Source strings differ; would mix package universes across release generations
Different @date, same release (debian:bookworm@2025-01-01@2025-06-01) No Source strings differ; would mix snapshot dates
Pinned vs unpinned of same release (debian:bookwormdebian:bookworm@2024-06-15) No Source strings differ; pinning is part of the rootfs identity
Different distro prefix (debian:*ubuntu:*) No Incompatible version comparison, checksum, and ABI

Reinstallation

Running flatroot install against an existing rootfs compares each newly resolved package against the existing packages record by (name, architecture) key:

Condition Behaviour
Version and checksum match Package skipped — no download or extraction, and its own setup script is not re-staged. The prior record is carried forward verbatim, including its Source, Url, and files list (only Depends, version, checksum, and size are re-read). If any other package was extracted this run, post-install still replays every script under scripts/, the skipped package's included.
Version or checksum differs Package re-downloaded and re-extracted. Old record replaced. One line printed to stderr: replacing <name>:<arch>: <old> (<chk>) -> <new> (<chk>), source <old> -> <new> (ASCII ->).
Every package matches Entire post-install phase skipped. Prints Nothing to do. All N packages already current in <path>.
Package only in new install Downloaded and extracted normally.
Package only in existing rootfs Record retained unchanged.

The reinstallation key is (name, architecture) — there is never more than one record per pair.


Export Exclusion

The top-level <root>/.flatroot/ directory is excluded from every export format (OCI images, tar archives, SquashFS, DwarFS). The metadata is specific to the build and has no meaning inside a container image or compressed filesystem. There is no --include-metadata flag.


Atomic Writes

All metadata files are written to a <path>.tmp sibling and atomically renamed into place. A crash partway through leaves either the old file (rename not executed) or the new file (rename completed). A partially-written .tmp is never visible to readers.

  • Appendix / Packages / SBOM, CycloneDX, and SPDX — A Software Bill of Materials (SBOM) is a machine-readable inventory of every software component that went into a build artifact: name, version, origin, license, cryptographic...
    reproducibility metadata appendix
  • Explanation / The metadata layer — Every rootfs FlatRoot builds contains a .flatroot/ directory at its root. The directory is not part of the distribution — no upstream package ships it, no post-install script...
    metadata reproducibility explanation
  • Reference / Cache Reference — FlatRoot caches both package indices and downloaded package archives locally to avoid redundant network requests across runs.
    reference cache