On this page
Internal Layout
The contents of a package's tar archive are divided into metadata entries (under a reserved prefix) and payload entries (the files that will be installed on the target system).
§3.2.1 Reserved metadata prefix
All metadata entries MUST appear under the path prefix
.peipkg/ at the archive root. This prefix is RESERVED:
payload entries MUST NOT use any path beginning with
.peipkg/.
.peipkg/ prefix is conventional for package metadata
and is unlikely to collide with real upstream content. The
leading dot keeps it sorted before payload entries on most
file managers.§3.2.2 Required metadata entries
Every package MUST contain the following entries:
| Entry path | Purpose | Section |
|---|---|---|
.peipkg/manifest.json |
Authoritative package metadata | §3.3 |
.peipkg/files.json |
Per-file integrity manifest | §3.5 |
.peipkg/signature |
Inline package signature | §5.1 |
§3.2.3 Entry ordering
Tar entries MUST appear in the archive in the following order:
.peipkg/manifest.json.peipkg/files.json- All payload entries, sorted lexicographically by path (per §3.1.4)
.peipkg/signature
The manifest appears first so that streaming consumers can read the package's identity and reject mismatched packages (wrong name, wrong version, wrong architecture) before reading the payload.
The signature appears last and signs the archive content preceding it (§5.1 specifies what is signed and how).
§3.2.4 Optional metadata entries
A package MAY include additional entries under .peipkg/
for forward-compatible extensions. The set of entries
recognised by this specification is fixed (the three above);
unrecognised entries under .peipkg/ MUST be ignored on
parse but MUST NOT prevent installation.
When present, optional metadata entries MUST appear between
.peipkg/files.json and the first payload entry, sorted
lexicographically by path.
§3.2.5 Payload entries
Payload entries are tar entries with paths that do not begin
with .peipkg/. These are the files, directories, and
symlinks that the package installs on the target system.
§3.2.6 Permitted entry types
Tar payload entries MUST be of one of the following types:
- Regular file (typeflag
0or\0) - Directory (typeflag
5) - Symbolic link (typeflag
2)
Tar entries of any other type MUST cause the package to be rejected. This explicitly excludes:
- Hardlinks (typeflag
1) - Character devices (typeflag
3) - Block devices (typeflag
4) - FIFOs (typeflag
6) - Contiguous files (typeflag
7) - Vendor-specific types
§3.2.7 Payload path constraints
Payload paths MUST be relative (MUST NOT begin with /).
Payload paths MUST NOT contain any segment equal to . or
.. or any encoding thereof.
Payload paths MUST be valid UTF-8 (RFC 3629).
Payload paths MUST NOT contain NUL bytes (0x00) or any
ASCII control character (0x01-0x1F, 0x7F).
Payload paths MUST NOT contain backslash (\) characters.
Payload paths MUST be in Unicode Normalization Form C (NFC) per Unicode 16.0.
Each path component MUST be at most 255 bytes long when encoded as UTF-8.
A complete payload path MUST be at most 4096 bytes long when encoded as UTF-8.
A payload path MUST NOT begin with the prefix .peipkg/,
or with .peipkg followed by end-of-path (i.e., no payload
entry may be literally named .peipkg).
A consumer MUST validate every payload path against these constraints before any further processing of the entry. A package containing a non-conforming payload path MUST be rejected.
The on-disk install location is the payload path resolved
against the filesystem root. Path resolution MUST NOT
canonicalise away .. or . segments by interpretation;
such segments are forbidden in the input (above) and any
appearance is a format error, not a path-canonicalisation
question.
usr/bin/nginx installs to
/usr/bin/nginx on the target system. A tar entry at path
usr/lib/x86_64-linux-peios/libssl.so.3 installs to
/usr/lib/x86_64-linux-peios/libssl.so.3.§3.2.8 Empty package payloads
A package MAY have zero payload entries. A package with no payload contains only metadata; its install operation is limited to recording the package in the system database and running any side-effect declarations (§4.3).
§3.2.9 Resource limits
To bound consumer-side resource usage during package parsing, the format establishes minimum-conformance limits. A consumer MUST process packages whose characteristics fall within these limits and MUST reject packages that exceed them.
| Limit | Maximum value |
|---|---|
| Number of payload entries | 100,000 |
Manifest JSON size (.peipkg/manifest.json) |
16 MiB |
Files manifest JSON size (.peipkg/files.json) |
64 MiB |
Signature envelope JSON size (.peipkg/signature) |
64 KiB |
| Single payload path component (UTF-8 bytes) | 255 |
| Complete payload path (UTF-8 bytes) | 4096 |
| Path nesting depth (number of components) | 256 |
dependencies array length |
10,000 |
optional_dependencies array length |
10,000 |
conflicts array length |
10,000 |
provides array length |
10,000 |
replaces array length |
1,000 |
sd_overrides array length |
100,000 |
Single SD override sd field decoded length |
64 KiB |
A consumer MAY raise these limits via operator configuration but MUST NOT raise them silently; operator-tuned values SHOULD be logged and surfaced in diagnostic output.
A producer SHOULD stay well below these limits in practice. The limits exist to bound consumer resource usage when processing maliciously-crafted packages, not to define the typical scale of a well-formed package.
size_installed plus the 1% allowance.