<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>SOW: Package Repository Manager by Pigsty on SOW</title><link>https://sow.pgsty.com/</link><description>Recent content in SOW: Package Repository Manager by Pigsty on SOW</description><generator>Hugo</generator><language>en</language><atom:link href="https://sow.pgsty.com/index.xml" rel="self" type="application/rss+xml"/><item><title>SOW 0.2: Documentation Preview</title><link>https://sow.pgsty.com/blog/release/sow-docs-launch/</link><pubDate>Tue, 04 Aug 2026 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/blog/release/sow-docs-launch/</guid><description>&lt;p&gt;&lt;strong&gt;Published:&lt;/strong&gt; 2026-08-04 · &lt;strong&gt;Version:&lt;/strong&gt; &lt;code&gt;sow 0.2.0-dev&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;SOW is a self-contained package repository manager from &lt;a href="https://pigsty.io"&gt;Pigsty&lt;/a&gt;. It
is one static Go binary that creates and maintains APT (DEB) and YUM (RPM) repositories
on Linux and macOS, and it does the whole job itself: &lt;code&gt;createrepo_c&lt;/code&gt;,
&lt;code&gt;dpkg-scanpackages&lt;/code&gt;, &lt;code&gt;reprepro&lt;/code&gt;, and &lt;code&gt;modifyrepo_c&lt;/code&gt; are never invoked. There is no daemon,
no database server, and nothing to install alongside it. The name is the verb — you sow
packages into a repository, and the repository grows.&lt;/p&gt;</description></item><item><title>Download &amp; Install</title><link>https://sow.pgsty.com/download/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/download/</guid><description>&lt;p&gt;SOW is one static executable. There is no installer, no package to add, no service to
enable, and no state directory until you run a command that needs one. Installing it
means putting a single file on your &lt;code&gt;PATH&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="prebuilt-binaries"&gt;Prebuilt binaries&lt;/h2&gt;
&lt;p&gt;Release archives for every supported platform are published on the
&lt;a href="https://github.com/pgsty/sow/releases"&gt;GitHub releases page&lt;/a&gt;. Download the archive that
matches your OS and CPU, extract it, and move the binary into place:&lt;/p&gt;</description></item><item><title>Build a YUM Repository</title><link>https://sow.pgsty.com/docs/tutorial/yum-repo/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/tutorial/yum-repo/</guid><description>&lt;p&gt;This tutorial builds a production-shaped RPM repository from scratch. By the end you will have a
workspace holding a &lt;code&gt;pigsty&lt;/code&gt; repository with an &lt;code&gt;el9&lt;/code&gt; Dist, two architecture views rendered from
one package pool, debuginfo noise filtered out, only the newest version of each package kept,
and a &lt;code&gt;.repo&lt;/code&gt; file that &lt;code&gt;dnf&lt;/code&gt; accepts.&lt;/p&gt;
&lt;p&gt;Plan for about fifteen minutes. Every command runs locally; nothing talks to the network.&lt;/p&gt;
&lt;h2 id="before-you-start"&gt;Before you start&lt;/h2&gt;
&lt;p&gt;You need three things.&lt;/p&gt;</description></item><item><title>Capability Overview</title><link>https://sow.pgsty.com/docs/feature/overview/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/feature/overview/</guid><description>&lt;p&gt;SOW is a self-contained software repository manager: a single static Go binary (&lt;code&gt;CGO_ENABLED=0&lt;/code&gt;) that creates and maintains APT (DEB) and YUM (RPM) repositories on Linux and macOS. It does not call &lt;code&gt;createrepo_c&lt;/code&gt;, &lt;code&gt;dpkg-scanpackages&lt;/code&gt;, &lt;code&gt;reprepro&lt;/code&gt;, or &lt;code&gt;modifyrepo_c&lt;/code&gt;, and it does not run a daemon. This page is the map of what it covers; the rest of this section explains how each piece works.&lt;/p&gt;
&lt;p&gt;The current release is &lt;code&gt;sow 0.2.0-dev&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="two-execution-paths"&gt;Two execution paths&lt;/h2&gt;
&lt;p&gt;SOW gives you two ways to build a repository, and they are deliberately isolated from each other. Nothing is shared between them except the low-level package parsers, renderers, version comparators, locks, and safe file primitives.&lt;/p&gt;</description></item><item><title>Install SOW</title><link>https://sow.pgsty.com/docs/start/install/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/start/install/</guid><description>&lt;p&gt;SOW ships as a single static executable. Installing it means putting one file somewhere
on your &lt;code&gt;PATH&lt;/code&gt;. There is no package to install, no service to enable, and no state
directory created until you run a command that needs one.&lt;/p&gt;
&lt;h2 id="supported-platforms"&gt;Supported platforms&lt;/h2&gt;
&lt;p&gt;The binary is built with &lt;code&gt;CGO_ENABLED=0&lt;/code&gt;, so it has no libc dependency and runs on any
reasonably modern kernel of the matching OS and CPU family.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;OS&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;amd64&lt;/code&gt;&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;arm64&lt;/code&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Linux&lt;/td&gt;
					&lt;td&gt;supported&lt;/td&gt;
					&lt;td&gt;supported&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;macOS (Darwin)&lt;/td&gt;
					&lt;td&gt;supported&lt;/td&gt;
					&lt;td&gt;supported&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Windows is not supported. SOW relies on POSIX advisory locks, hardlinks, and atomic
&lt;code&gt;rename&lt;/code&gt;, and it is only tested on local POSIX filesystems — network filesystems such as
NFS do not provide the locking and durability semantics it depends on.&lt;/p&gt;</description></item><item><title>Design Principles</title><link>https://sow.pgsty.com/docs/design/principles/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/design/principles/</guid><description>&lt;p&gt;SOW is not primarily a metadata generator. It is an ownership and state-transition system
whose output happens to be APT and RPM repositories. The following principles keep that
system small enough to reason about.&lt;/p&gt;
&lt;h2 id="one-owner-for-every-durable-fact"&gt;One owner for every durable fact&lt;/h2&gt;
&lt;p&gt;Every durable fact has one scope and one authority:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Fact&lt;/th&gt;
					&lt;th&gt;Owner&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Package bytes and package identity&lt;/td&gt;
					&lt;td&gt;Repository&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Desired memberships and Built state&lt;/td&gt;
					&lt;td&gt;Repository&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Generation and Changeset&lt;/td&gt;
					&lt;td&gt;Repository&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Publication attempt and applied checkpoint&lt;/td&gt;
					&lt;td&gt;Repository + target prefix&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Remote inventory, grace, and delete evidence&lt;/td&gt;
					&lt;td&gt;Repository + target prefix&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;State is not silently shared across Repositories or publish prefixes. The same package may
therefore exist once in each Repository or target. That is intentional: local deduplication
must not create distributed ownership.&lt;/p&gt;</description></item><item><title>sow create</title><link>https://sow.pgsty.com/docs/reference/cli/create/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/reference/cli/create/</guid><description>&lt;p&gt;&lt;code&gt;sow create&lt;/code&gt; turns a directory that already contains &lt;code&gt;.rpm&lt;/code&gt; and &lt;code&gt;.deb&lt;/code&gt; files into a flat repository
by writing indexes next to the packages. It is the whole of Plain mode: no &lt;code&gt;sow.yml&lt;/code&gt;, no SQLite, no
Workspace discovery. This page covers the scan rules, the atomic &lt;code&gt;--pigsty&lt;/code&gt; compatibility operation,
and RPM signing with &lt;code&gt;--sign-with&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="synopsis"&gt;Synopsis&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow create [DIR] [-j N] [--pigsty] [-S KEY [--overwrite]] [-T DUR | -N] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;DIR&lt;/code&gt; defaults to the current directory.&lt;/p&gt;</description></item><item><title>Build an APT Repository</title><link>https://sow.pgsty.com/docs/tutorial/apt-repo/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/tutorial/apt-repo/</guid><description>&lt;p&gt;This tutorial builds a managed APT repository: a Debian-style package pool grouped by source
package, one index per architecture, &lt;code&gt;by-hash&lt;/code&gt; index copies so clients never race a rebuild, and
client configuration in both the modern deb822 format and the legacy one-liner.&lt;/p&gt;
&lt;p&gt;Plan for about fifteen minutes.&lt;/p&gt;
&lt;h2 id="before-you-start"&gt;Before you start&lt;/h2&gt;
&lt;p&gt;You need SOW installed (&lt;a href="https://sow.pgsty.com/docs/start/install/"&gt;Installation&lt;/a&gt;), some &lt;code&gt;.deb&lt;/code&gt; files, and a
directory you can write to.&lt;/p&gt;
&lt;p&gt;This tutorial continues from &lt;a href="https://sow.pgsty.com/docs/tutorial/yum-repo/"&gt;Build a YUM Repository&lt;/a&gt; by adding a
second Dist to the same &lt;code&gt;pigsty&lt;/code&gt; repository — one pool, two package ecosystems. If you are
starting fresh, run these three commands first and then continue from Step 1:&lt;/p&gt;</description></item><item><title>sow.yml Reference</title><link>https://sow.pgsty.com/docs/reference/config/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/reference/config/</guid><description>&lt;p&gt;&lt;code&gt;sow.yml&lt;/code&gt; is the single configuration file of a managed workspace. It sits at the
workspace root, declares which repositories and distributions exist, and holds the
membership policy and signing settings that every build applies. Plain mode
(&lt;code&gt;sow create&lt;/code&gt;) never reads it.&lt;/p&gt;
&lt;p&gt;This page lists every field the parser accepts. Anything not listed here is rejected —
there are no undocumented keys and no keys reserved for future use.&lt;/p&gt;
&lt;h2 id="how-the-file-is-read"&gt;How the file is read&lt;/h2&gt;
&lt;p&gt;SOW parses &lt;code&gt;sow.yml&lt;/code&gt; with a strict decoder. Practically, that means:&lt;/p&gt;</description></item><item><title>Plain Flat Repositories</title><link>https://sow.pgsty.com/docs/feature/plain/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/feature/plain/</guid><description>&lt;p&gt;&lt;code&gt;sow create&lt;/code&gt; takes a directory that already contains &lt;code&gt;.rpm&lt;/code&gt; and &lt;code&gt;.deb&lt;/code&gt; files and writes an index over them, in place. That is the whole job. This page explains what it reads, what it writes, what it promises never to touch, and how it survives being killed halfway through.&lt;/p&gt;
&lt;h2 id="the-invariants"&gt;The invariants&lt;/h2&gt;
&lt;p&gt;Three rules hold for every &lt;code&gt;sow create&lt;/code&gt; run, and everything else follows from them:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;SOW only replaces index paths it owns.&lt;/strong&gt; Your packages, your &lt;code&gt;README&lt;/code&gt;, your leftover files from another tool — untouched. The one exception is &lt;code&gt;--pigsty&lt;/code&gt;, which is an explicit request to delete specific packages.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Same input, same bytes.&lt;/strong&gt; Timestamps and compression parameters are fixed and sort order is stable, so re-running over an unchanged directory produces a byte-identical index and reports &lt;code&gt;noop=true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The commit is all-or-nothing per format pointer.&lt;/strong&gt; Metadata is fully generated and validated in a staging area on the same filesystem, and only then swapped in with atomic renames. If anything fails before the swap, the previous index keeps serving.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Plain mode has no workspace, no configuration file, and no database. It does not read &lt;code&gt;sow.yml&lt;/code&gt; even if one exists in a parent directory, and it never performs workspace discovery.&lt;/p&gt;</description></item><item><title>Quick Start</title><link>https://sow.pgsty.com/docs/start/quickstart/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/start/quickstart/</guid><description>&lt;p&gt;This page takes about five minutes. You will put some packages in a directory, run one
command, serve the directory over HTTP, and install from it with &lt;code&gt;dnf&lt;/code&gt; or &lt;code&gt;apt&lt;/code&gt;. No
configuration file, no workspace, no database — plain mode writes indexes next to your
packages and nothing else.&lt;/p&gt;
&lt;h2 id="1-collect-the-packages"&gt;1. Collect the packages&lt;/h2&gt;
&lt;p&gt;Any directory containing &lt;code&gt;.rpm&lt;/code&gt; or &lt;code&gt;.deb&lt;/code&gt; files works. The files stay where they are;
SOW never moves or renames them.&lt;/p&gt;</description></item><item><title>sow init</title><link>https://sow.pgsty.com/docs/reference/cli/init/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/reference/cli/init/</guid><description>&lt;p&gt;&lt;code&gt;sow init&lt;/code&gt; creates the root &lt;code&gt;sow.yml&lt;/code&gt; and the private &lt;code&gt;.sow/&lt;/code&gt; state directory that make a directory a
Workspace. It is also the convergence command for a config you wrote by hand: if &lt;code&gt;sow.yml&lt;/code&gt; already
declares Repositories and Dists, &lt;code&gt;init&lt;/code&gt; materializes the ones that don&amp;rsquo;t exist yet and leaves the
finished ones alone.&lt;/p&gt;
&lt;h2 id="synopsis"&gt;Synopsis&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow init [DIR] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;DIR&lt;/code&gt; defaults to the current directory. &lt;code&gt;init&lt;/code&gt; takes no &lt;code&gt;-C/--workdir&lt;/code&gt; — the positional argument
already names the target unambiguously.&lt;/p&gt;</description></item><item><title>System Model</title><link>https://sow.pgsty.com/docs/design/model/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/design/model/</guid><description>&lt;p&gt;The model is deliberately layered. Configuration expresses intent, the database records
owned state, and the public tree is a deterministic projection. None of those layers may
quietly become a substitute for another.&lt;/p&gt;
&lt;h2 id="object-hierarchy"&gt;Object hierarchy&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Workspace
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── Repository
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── Package Object
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── Dist
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ └── Membership -&amp;gt; Package Object
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── Desired state
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── Built Generation
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── Retained Generation references
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── Publication Target
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └── Repository + provider + prefix
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="workspace"&gt;Workspace&lt;/h3&gt;
&lt;p&gt;A Workspace supplies discovery, configuration, and coordination. It owns &lt;code&gt;sow.yml&lt;/code&gt;, the
private &lt;code&gt;.sow/&lt;/code&gt; directory, and stable lock paths. It is not a package deduplication domain.&lt;/p&gt;</description></item><item><title>Your First Workspace</title><link>https://sow.pgsty.com/docs/start/workspace/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/start/workspace/</guid><description>&lt;p&gt;This page takes about ten minutes and builds a managed repository from nothing: a
workspace, one repository, an RPM distribution and a DEB distribution inside it, packages
added to both, and a look at what landed on disk. Unlike &lt;a href="https://sow.pgsty.com/docs/start/quickstart/"&gt;plain mode&lt;/a&gt;,
a workspace remembers what you asked for — so you add and remove packages by name instead of
by shuffling files around, and SOW rebuilds only what changed.&lt;/p&gt;
&lt;h2 id="1-create-the-workspace"&gt;1. Create the workspace&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p /srv/sow
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /srv/sow
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow init .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;initialized /srv/sow: config_created=true repositories_initialized=0 dists_initialized=0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;init&lt;/code&gt; created two things: &lt;code&gt;sow.yml&lt;/code&gt;, which is the single source of truth for what this
workspace contains, and a hidden &lt;code&gt;.sow/&lt;/code&gt; directory holding locks, per-repository SQLite
state, and the operation journal used for crash recovery. You never edit anything under
&lt;code&gt;.sow/&lt;/code&gt; and you never serve it.&lt;/p&gt;</description></item><item><title>Managed Workspaces</title><link>https://sow.pgsty.com/docs/feature/managed/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/feature/managed/</guid><description>&lt;p&gt;Managed mode is what you use when the same repository will be updated for months: packages arrive in batches, policy decides what stays, and you need to prove afterwards what changed and when. This page explains the three-tier model, the layout it produces, and how commands figure out which repository and which Dist you meant.&lt;/p&gt;
&lt;h2 id="the-three-tiers"&gt;The three tiers&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Workspace discovery and configuration boundary
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── Repository ownership boundary: pool, dists, SQLite, lock, generations
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └── Dist a named membership set in exactly one format
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └── Architecture View a rendered projection — not a membership
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Each tier has one job, and the boundaries are strict:&lt;/p&gt;</description></item><item><title>Package References</title><link>https://sow.pgsty.com/docs/reference/package-ref/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/reference/package-ref/</guid><description>&lt;p&gt;&lt;code&gt;sow rm&lt;/code&gt;, &lt;code&gt;sow show&lt;/code&gt;, and &lt;code&gt;sow where&lt;/code&gt; all take a &lt;code&gt;PACKAGE&lt;/code&gt; argument. This page defines
what you may write there. The same grammar applies to all three commands; only the
handling of an ambiguous name differs.&lt;/p&gt;
&lt;p&gt;Nothing here applies to &lt;code&gt;sow add&lt;/code&gt;, which takes filesystem paths, not references.&lt;/p&gt;
&lt;h2 id="the-five-forms"&gt;The five forms&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Form&lt;/th&gt;
					&lt;th&gt;Example&lt;/th&gt;
					&lt;th&gt;Matches&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Content digest&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;sha256:d06d7f23b9cf...b98b1229&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Exactly one package object&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;RPM coordinate&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;rpm:pev2-0:1.23.0-1.noarch&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Exactly one RPM&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;DEB coordinate&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;deb:libpq5=18.3-1.pgdg12+1:amd64&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Exactly one DEB&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Filename&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;pev2-1.23.0-1.noarch.rpm&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;The package stored under that filename&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Bare name&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;pev2&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Every version and architecture of that name&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The first three are exact: they name one object and either hit it or fail. The last two
are conveniences that may match more than one object.&lt;/p&gt;</description></item><item><title>Sign Your Repository</title><link>https://sow.pgsty.com/docs/tutorial/signing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/tutorial/signing/</guid><description>&lt;p&gt;An unsigned repository is a repository anyone on the path can rewrite. This tutorial closes that
hole: you generate a signing key, configure SOW to sign what it publishes, verify the signatures
by hand, and turn on client-side enforcement so &lt;code&gt;dnf&lt;/code&gt; and &lt;code&gt;apt&lt;/code&gt; refuse anything that does not
check out.&lt;/p&gt;
&lt;p&gt;Plan for about twenty minutes.&lt;/p&gt;
&lt;h2 id="two-independent-trust-chains"&gt;Two independent trust chains&lt;/h2&gt;
&lt;p&gt;Package repositories have two things worth signing, and they are not the same thing.&lt;/p&gt;</description></item><item><title>Single-Payload Repository</title><link>https://sow.pgsty.com/docs/design/single-payload/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/design/single-payload/</guid><description>&lt;p&gt;The 0.3 development design changes the physical RPM layout while preserving the ownership
model introduced in v0.2. Its objective is precise: within one Repository and within each
publish prefix, every live Package Object has exactly one payload path.&lt;/p&gt;
&lt;div class="alert alert-warning" role="alert"&gt;&lt;div class="h4 alert-heading" role="heading"&gt;Development design&lt;/div&gt;
&lt;p&gt;This page describes the implemented 0.3 source layout. The released v0.2 operational
reference still describes C2 view-local hardlinks. Read &lt;a href="https://sow.pgsty.com/docs/design/evolution/"&gt;Design Evolution&lt;/a&gt;
before migrating an existing v0.2 repository.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="canonical-tree"&gt;Canonical tree&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;lt;repo&amp;gt;/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── pool/ # canonical package payloads
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── &amp;lt;prefix&amp;gt;/&amp;lt;source&amp;gt;/&amp;lt;filename&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── dists/ # metadata-only projections
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├── &amp;lt;rpm-dist&amp;gt;/&amp;lt;arch&amp;gt;/repodata/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └── &amp;lt;deb-dist&amp;gt;/&amp;lt;component&amp;gt;/binary-&amp;lt;arch&amp;gt;/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There is no canonical &lt;code&gt;release/&lt;/code&gt;, &lt;code&gt;reposync/&lt;/code&gt;, per-view &lt;code&gt;pool/&lt;/code&gt;, per-generation package
tree, or snapshot package tree. &lt;code&gt;pool/ + dists/&lt;/code&gt; is the complete relocation and publication
unit.&lt;/p&gt;</description></item><item><title>sow config</title><link>https://sow.pgsty.com/docs/reference/cli/config/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/reference/cli/config/</guid><description>&lt;p&gt;&lt;code&gt;sow config&lt;/code&gt; has two read-only subcommands. &lt;code&gt;config check&lt;/code&gt; is the full preflight over &lt;code&gt;sow.yml&lt;/code&gt; —
run it after every hand edit and in CI. &lt;code&gt;config show&lt;/code&gt; prints the configuration SOW actually computed,
which is where you confirm that defaults, inherited architectures and normalized aliases resolved the
way you expected.&lt;/p&gt;
&lt;p&gt;Neither subcommand creates directories, touches a database, or corrects your file.&lt;/p&gt;
&lt;h2 id="synopsis"&gt;Synopsis&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow config check [-C DIR] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow config show [--all] [-C DIR] [-r NAME] [-d NAME]... [--json]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;sow help config&lt;/code&gt; lists both.&lt;/p&gt;</description></item><item><title>Core Concepts</title><link>https://sow.pgsty.com/docs/start/concepts/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/start/concepts/</guid><description>&lt;p&gt;Once you have run &lt;a href="https://sow.pgsty.com/docs/start/quickstart/"&gt;the quick start&lt;/a&gt; and
&lt;a href="https://sow.pgsty.com/docs/start/workspace/"&gt;built a workspace&lt;/a&gt;, a handful of ideas explain everything else
SOW does. This page covers them: the two modes and how to choose, the four layers of the
managed model, and the distinction between what you asked for and what is currently
published.&lt;/p&gt;
&lt;h2 id="two-ways-to-build-a-repository"&gt;Two ways to build a repository&lt;/h2&gt;
&lt;p&gt;SOW has two engines that never touch each other. Plain mode does not read &lt;code&gt;sow.yml&lt;/code&gt;, does
not perform workspace discovery, and does not create a database. Managed mode never treats
a plain directory as a repository. Picking one is the first decision you make.&lt;/p&gt;</description></item><item><title>Repository Layout</title><link>https://sow.pgsty.com/docs/reference/layout/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/reference/layout/</guid><description>&lt;p&gt;SOW&amp;rsquo;s on-disk layout is fixed. There is no &lt;code&gt;path:&lt;/code&gt; setting, no template, and no way to
relocate a repository — every path is derived from the workspace root, a validated name,
and a constant relative segment. This page is the complete map, so you know what to serve,
what to copy, and what to keep private.&lt;/p&gt;
&lt;h2 id="plain-mode"&gt;Plain mode&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;sow create&lt;/code&gt; writes indexes next to the packages and touches nothing else. The directory
you point it at stays a flat repository: packages and metadata share one level.&lt;/p&gt;</description></item><item><title>Pool &amp; Architecture Views</title><link>https://sow.pgsty.com/docs/feature/views/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/feature/views/</guid><description>&lt;p&gt;If you list a Managed repository you will find the same package file at three different paths, and &lt;code&gt;du&lt;/code&gt; will insist it only occupies space once. That is not an illusion and it is not a symlink. This page explains the projection model — why it exists, what it guarantees, and the one constraint it puts on your filesystem.&lt;/p&gt;
&lt;h2 id="the-invariant"&gt;The invariant&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;The root pool owns the bytes. Everything under &lt;code&gt;dists/&lt;/code&gt; is a projection that can be deleted and rebuilt without touching an owned object.&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Publication &amp; Recovery</title><link>https://sow.pgsty.com/docs/design/publication/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/design/publication/</guid><description>&lt;p&gt;Building and publishing are separate state transitions. A build produces a target-neutral
Generation. Publication applies that Generation to one provider prefix and records enough
evidence to recover without guessing.&lt;/p&gt;
&lt;h2 id="ownership-split"&gt;Ownership split&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Repository-scoped&lt;/th&gt;
					&lt;th&gt;Target-prefix-scoped&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Package Object&lt;/td&gt;
					&lt;td&gt;Publication Attempt&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Desired and Built state&lt;/td&gt;
					&lt;td&gt;Applied Checkpoint&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Generation and Changeset&lt;/td&gt;
					&lt;td&gt;Remote inventory&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Retained payload/metadata references&lt;/td&gt;
					&lt;td&gt;Grace and deletion evidence&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The split prevents a successful filesystem publication from being treated as proof about
R2, and prevents one target&amp;rsquo;s partial attempt from contaminating another target.&lt;/p&gt;</description></item><item><title>Serve Repositories</title><link>https://sow.pgsty.com/docs/tutorial/serving/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/tutorial/serving/</guid><description>&lt;p&gt;SOW builds a static directory. Anything that can serve static files can serve it — there is no
daemon, no application server, and no runtime component. This tutorial covers what to point a
web server at, a tested Nginx configuration, a one-command local preview, and how to move the
tree to a host that cannot reach your build machine.&lt;/p&gt;
&lt;p&gt;Plan for about fifteen minutes.&lt;/p&gt;
&lt;h2 id="what-you-actually-serve"&gt;What you actually serve&lt;/h2&gt;
&lt;p&gt;For a managed workspace, the document root is the &lt;strong&gt;repository&lt;/strong&gt; directory:&lt;/p&gt;</description></item><item><title>sow repo</title><link>https://sow.pgsty.com/docs/reference/cli/repo/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/reference/cli/repo/</guid><description>&lt;p&gt;A Repository owns one &lt;code&gt;pool/&lt;/code&gt;, one &lt;code&gt;dists/&lt;/code&gt;, one SQLite database and one private state directory. It
is the boundary of locking, transaction recovery, Generation numbering and Changesets — nothing is
deduplicated across Repositories and no cross-Repository commit is atomic. &lt;code&gt;sow repo&lt;/code&gt; manages that
boundary.&lt;/p&gt;
&lt;h2 id="synopsis"&gt;Synopsis&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow repo ls [-C DIR] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow repo new NAME [-C DIR] [-T DUR | -N] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow repo show [NAME] [-C DIR] [-r NAME] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow repo rm NAME [-f|--force] [-C DIR] [-T DUR | -N] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="naming"&gt;Naming&lt;/h2&gt;
&lt;p&gt;A Repository name must match &lt;code&gt;[a-z0-9][a-z0-9._-]*&lt;/code&gt; and may not be &lt;code&gt;.&lt;/code&gt;, &lt;code&gt;..&lt;/code&gt;, &lt;code&gt;.sow&lt;/code&gt;, &lt;code&gt;pool&lt;/code&gt;,
&lt;code&gt;dists&lt;/code&gt;, or collide with a Workspace reserved file.&lt;/p&gt;</description></item><item><title>Compatibility Boundaries</title><link>https://sow.pgsty.com/docs/design/compatibility/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/design/compatibility/</guid><description>&lt;p&gt;&amp;ldquo;Compatible&amp;rdquo; is too broad to be a useful engineering claim. A package may install while a
mirror tool refuses the same metadata; a tree may work on POSIX disk while multiplying
objects after upload. SOW therefore treats compatibility as a set of independent gates.&lt;/p&gt;
&lt;h2 id="the-layers"&gt;The layers&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Layer&lt;/th&gt;
					&lt;th&gt;Question&lt;/th&gt;
					&lt;th&gt;Required evidence&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Format&lt;/td&gt;
					&lt;td&gt;Is the metadata valid rpm-md / Debian archive syntax?&lt;/td&gt;
					&lt;td&gt;parser and structural validation&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Ordinary client&lt;/td&gt;
					&lt;td&gt;Can &lt;code&gt;apt&lt;/code&gt;, &lt;code&gt;dnf&lt;/code&gt;, or &lt;code&gt;yum&lt;/code&gt; refresh, resolve, download, verify, and install?&lt;/td&gt;
					&lt;td&gt;real client run&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Mirror tool&lt;/td&gt;
					&lt;td&gt;Can the named mirror tool materialize the repository safely?&lt;/td&gt;
					&lt;td&gt;that exact tool and version&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Relocation&lt;/td&gt;
					&lt;td&gt;Does a whole-root copy remain byte-closed and consumable?&lt;/td&gt;
					&lt;td&gt;copy + manifest + client run&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;HTTP/proxy&lt;/td&gt;
					&lt;td&gt;Are relative URLs normalized inside the same prefix without traversal or double encoding?&lt;/td&gt;
					&lt;td&gt;target HTTP matrix&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Storage&lt;/td&gt;
					&lt;td&gt;Do object identity, conditional operations, listing, caching, and deletion match the state machine?&lt;/td&gt;
					&lt;td&gt;real provider protocol test&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;No row inherits PASS from another row or from an earlier Repository layout.&lt;/p&gt;</description></item><item><title>Exit Codes</title><link>https://sow.pgsty.com/docs/reference/exit-codes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/reference/exit-codes/</guid><description>&lt;p&gt;Every &lt;code&gt;sow&lt;/code&gt; command exits with one of seven codes. They are stable, they are the same for
every command, and they are meant to be branched on in scripts — the distinction between
&amp;ldquo;this failed&amp;rdquo; and &amp;ldquo;this was correctly refused&amp;rdquo; is the whole point of having more than one
nonzero code.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Code&lt;/th&gt;
					&lt;th&gt;Meaning&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Complete success, or an idempotent no-op&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Runtime I/O, parser, renderer, or unknown internal error&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Usage, workspace discovery, or configuration error&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Partial success: at least one item committed, at least one failed&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;4&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Write lock unavailable — held and &lt;code&gt;--no-wait&lt;/code&gt;, or the timeout expired&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;5&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Integrity or recovery error, or &lt;code&gt;check&lt;/code&gt; judged the result not deliverable&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;6&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Expected rejection: conflict, protected, no match, incompatible architecture&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Human-readable results go to stdout; warnings and diagnostics go to stderr. Each code has
a stable message prefix on stderr, and a matching &lt;code&gt;class&lt;/code&gt; in
&lt;a href="https://sow.pgsty.com/docs/reference/json/"&gt;JSON output&lt;/a&gt;:&lt;/p&gt;</description></item><item><title>Membership Policy</title><link>https://sow.pgsty.com/docs/feature/policy/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/feature/policy/</guid><description>&lt;p&gt;Policy is the answer to &amp;ldquo;I dumped a build directory into this Dist and I do not want the debuginfo packages, and I only want the latest version of each package.&amp;rdquo; Two rules do that work, they run in a fixed order, and they run over the whole candidate set — not just the packages you happened to add this time.&lt;/p&gt;
&lt;h2 id="the-two-rules-and-their-order"&gt;The two rules and their order&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;candidate set → exclude → limit → Desired Membership
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;exclude&lt;/code&gt; drops packages that match a rule. &lt;code&gt;limit&lt;/code&gt; then caps how many versions survive per package name and architecture. The order is fixed and never configurable, because the reverse order would let an excluded package consume a version slot on its way out.&lt;/p&gt;</description></item><item><title>Migrate from createrepo_c / reprepro</title><link>https://sow.pgsty.com/docs/tutorial/migration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/tutorial/migration/</guid><description>&lt;p&gt;You already have a repository. This tutorial replaces the tool that builds it without breaking
the clients that consume it — including the leftover files nobody warns you about and the layout
differences you should know before, not after.&lt;/p&gt;
&lt;p&gt;Two paths, depending on what you have. Read the one that matches, then the comparison at the end.&lt;/p&gt;
&lt;h2 id="choose-your-target"&gt;Choose your target&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;You have&lt;/th&gt;
					&lt;th&gt;Migrate to&lt;/th&gt;
					&lt;th&gt;Read&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;createrepo_c&lt;/code&gt; on a directory of RPMs&lt;/td&gt;
					&lt;td&gt;Plain mode, in place&lt;/td&gt;
					&lt;td&gt;&lt;a href="https://sow.pgsty.com/docs/tutorial/migration/#path-a-createrepo_c-in-place"&gt;Path A&lt;/a&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;dpkg-scanpackages&lt;/code&gt; on a flat DEB directory&lt;/td&gt;
					&lt;td&gt;Plain mode, in place&lt;/td&gt;
					&lt;td&gt;&lt;a href="https://sow.pgsty.com/docs/tutorial/migration/#path-a-createrepo_c-in-place"&gt;Path A&lt;/a&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;A reprepro archive with &lt;code&gt;pool/&lt;/code&gt; and &lt;code&gt;dists/&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Managed workspace&lt;/td&gt;
					&lt;td&gt;&lt;a href="https://sow.pgsty.com/docs/tutorial/migration/#path-b-reprepro-to-a-workspace"&gt;Path B&lt;/a&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;createrepo_c&lt;/code&gt; plus scripts for multiple architectures&lt;/td&gt;
					&lt;td&gt;Managed workspace&lt;/td&gt;
					&lt;td&gt;&lt;a href="https://sow.pgsty.com/docs/tutorial/migration/#path-b-reprepro-to-a-workspace"&gt;Path B&lt;/a&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Plain mode is the drop-in replacement: same directory, same URLs, one command instead of a
toolchain. Managed mode is a change of shape — a workspace, a pool, per-architecture views — and
gives you membership policy, transactional builds, and an audit trail. Migrate to Plain first if
you just want the dependency gone; move to Managed when the repository&amp;rsquo;s lifecycle is what hurts.&lt;/p&gt;</description></item><item><title>sow dist</title><link>https://sow.pgsty.com/docs/reference/cli/dist/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/reference/cli/dist/</guid><description>&lt;p&gt;A Dist is a named set of packages in exactly one format (&lt;code&gt;rpm&lt;/code&gt; or &lt;code&gt;deb&lt;/code&gt;) inside one Repository. It is
what a client points at. A Repository can hold RPM and DEB Dists side by side; they share one &lt;code&gt;pool/&lt;/code&gt;
but render into completely separate &lt;code&gt;dists/&lt;/code&gt; subtrees.&lt;/p&gt;
&lt;h2 id="synopsis"&gt;Synopsis&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow dist ls [-C DIR] [-r NAME] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow dist new NAME --format rpm|deb [-C DIR] [-r NAME] [-T DUR | -N] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow dist show NAME [-C DIR] [-r NAME] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow dist rm NAME [-f|--force] [-C DIR] [-r NAME] [-T DUR | -N] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="naming"&gt;Naming&lt;/h2&gt;
&lt;p&gt;Dist names follow the same rule as Repository names: &lt;code&gt;[a-z0-9][a-z0-9._-]*&lt;/code&gt;, excluding &lt;code&gt;.&lt;/code&gt;, &lt;code&gt;..&lt;/code&gt;,
&lt;code&gt;.sow&lt;/code&gt;, &lt;code&gt;pool&lt;/code&gt; and &lt;code&gt;dists&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Design Evolution</title><link>https://sow.pgsty.com/docs/design/evolution/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/design/evolution/</guid><description>&lt;p&gt;SOW&amp;rsquo;s old documents came from three materially different systems. Preserving them without
a version boundary made contradictory statements look simultaneous. This page keeps the
useful decisions while making their scope explicit.&lt;/p&gt;
&lt;h2 id="timeline"&gt;Timeline&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Line&lt;/th&gt;
					&lt;th&gt;Primary problem&lt;/th&gt;
					&lt;th&gt;Physical model&lt;/th&gt;
					&lt;th&gt;Disposition&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;V1 experiment (July 2026)&lt;/td&gt;
					&lt;td&gt;absorb Pigsty&amp;rsquo;s existing APT/YUM trees and remote publishing workflow&lt;/td&gt;
					&lt;td&gt;Git/CAS, route-aware projections, edge/provider contracts&lt;/td&gt;
					&lt;td&gt;archived research and implementation evidence&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;v0.2.0&lt;/td&gt;
					&lt;td&gt;ship a compact local Plain + Managed repository manager&lt;/td&gt;
					&lt;td&gt;root Pool plus C2 view-local RPM hardlinks&lt;/td&gt;
					&lt;td&gt;released; operational docs remain live&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;0.3 development&lt;/td&gt;
					&lt;td&gt;publish one canonical payload per Repository/target prefix&lt;/td&gt;
					&lt;td&gt;root Pool plus metadata-only views and target-scoped publication&lt;/td&gt;
					&lt;td&gt;implemented in source; release evidence pending&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="what-survived-v1"&gt;What survived V1&lt;/h2&gt;
&lt;p&gt;The broad V1 program explored repository adoption, remote publication, provider fencing,
edge authorization, migration, recovery, and large-repository evidence. Much of its exact
Git/CAS/route model was replaced, but several principles survived:&lt;/p&gt;</description></item><item><title>JSON Output</title><link>https://sow.pgsty.com/docs/reference/json/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/reference/json/</guid><description>&lt;p&gt;Every command that produces data accepts &lt;code&gt;--json&lt;/code&gt;. The output is a single line on stdout
carrying a versioned envelope, so you can pipe it straight into &lt;code&gt;jq&lt;/code&gt; without worrying
about which command produced it.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow status --json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;schema&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sow.cli/v1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;ok&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;repository&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pigsty&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;operation&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;result&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;repository&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pigsty&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;clean&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;ready_to_copy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;desired_revision&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;built_generation&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;dirty_dists&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:[],&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;dirty_reasons&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:[],&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;pending&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;count&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;bytes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;recent_operation&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;8632724976452398569&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;kind&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;add&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;state&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;done&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;created_at&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2026-08-04T04:07:17.665377Z&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;updated_at&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2026-08-04T04:07:18.293848Z&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;repository_locked&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;errors&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:[]}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(Line-wrapped here for readability; the real output is one line.)&lt;/p&gt;
&lt;h2 id="the-envelope"&gt;The envelope&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Field&lt;/th&gt;
					&lt;th&gt;Type&lt;/th&gt;
					&lt;th&gt;Meaning&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;schema&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;string&lt;/td&gt;
					&lt;td&gt;Always &lt;code&gt;sow.cli/v1&lt;/code&gt;. Check it before parsing anything else.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;command&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;string&lt;/td&gt;
					&lt;td&gt;The command as invoked, including the subcommand: &lt;code&gt;add&lt;/code&gt;, &lt;code&gt;repo ls&lt;/code&gt;, &lt;code&gt;config show&lt;/code&gt;.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;ok&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;bool&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;true&lt;/code&gt; when &lt;code&gt;errors&lt;/code&gt; is empty. Equivalent to exit code &lt;code&gt;0&lt;/code&gt;.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;repository&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;string or null&lt;/td&gt;
					&lt;td&gt;The selected repository, or &lt;code&gt;null&lt;/code&gt; for workspace-wide and plain-mode commands.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;operation&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;string or null&lt;/td&gt;
					&lt;td&gt;The operation ID for write commands, &lt;code&gt;null&lt;/code&gt; for read-only ones.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;result&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;object or null&lt;/td&gt;
					&lt;td&gt;Command-specific payload, described below.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;errors&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;array&lt;/td&gt;
					&lt;td&gt;Zero or more &lt;code&gt;{code, class, message}&lt;/code&gt; objects.&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;All seven fields are always present. &lt;code&gt;result&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt; only when the command failed
before it could produce anything — an unknown flag, for example.&lt;/p&gt;</description></item><item><title>Signing Model</title><link>https://sow.pgsty.com/docs/feature/signing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/feature/signing/</guid><description>&lt;p&gt;There are two different questions a client can ask about a repository, and SOW answers them with two separate mechanisms. Confusing them is the most common source of &amp;ldquo;I signed it but &lt;code&gt;dnf&lt;/code&gt; still complains&amp;rdquo;, so this page starts by pulling them apart.&lt;/p&gt;
&lt;h2 id="two-independent-trust-chains"&gt;Two independent trust chains&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;/th&gt;
					&lt;th&gt;Metadata signing&lt;/th&gt;
					&lt;th&gt;RPM package signing&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Question answered&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;Is this index really from you, and unmodified?&amp;rdquo;&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;Is this &lt;code&gt;.rpm&lt;/code&gt; file really from you?&amp;rdquo;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Configured by&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;signing.rpm.metadata&lt;/code&gt;, &lt;code&gt;signing.deb.metadata&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;signing.rpm.packages&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Produces&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;repodata/repomd.xml.asc&lt;/code&gt;, &lt;code&gt;InRelease&lt;/code&gt;, &lt;code&gt;Release.gpg&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;an OpenPGP signature embedded in the package&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Changes package bytes&lt;/td&gt;
					&lt;td&gt;no&lt;/td&gt;
					&lt;td&gt;yes&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Client setting&lt;/td&gt;
					&lt;td&gt;dnf &lt;code&gt;repo_gpgcheck=1&lt;/code&gt;, apt &lt;code&gt;Signed-By&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;dnf &lt;code&gt;gpgcheck=1&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Available in Plain mode&lt;/td&gt;
					&lt;td&gt;no&lt;/td&gt;
					&lt;td&gt;yes, via &lt;code&gt;create -S KEY&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;They are configured separately and can be used separately. Metadata signing alone is usually the right starting point: it authenticates the whole index in one place and requires no change to the packages you received from upstream.&lt;/p&gt;</description></item><item><title>sow add</title><link>https://sow.pgsty.com/docs/reference/cli/add/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/reference/cli/add/</guid><description>&lt;p&gt;&lt;code&gt;sow add&lt;/code&gt; is the main write path. It parses the packages you point at, derives their format and
architecture from the package headers, applies the Dist&amp;rsquo;s membership policy, and — unless you pass
&lt;code&gt;--skip&lt;/code&gt; — rebuilds every affected index before it returns. When the command exits &lt;code&gt;0&lt;/code&gt;, clients can
already see the new packages.&lt;/p&gt;
&lt;h2 id="synopsis"&gt;Synopsis&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow add PATH... [-R|--recursive] [--skip] [-j|--jobs N] [-C|--workdir DIR] [-r|--repo NAME] [-d|--dist NAME]... [-T|--timeout DUR | -N|--no-wait] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="options"&gt;Options&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Flag&lt;/th&gt;
					&lt;th&gt;Description&lt;/th&gt;
					&lt;th&gt;Default&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-R, --recursive&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Descend into subdirectories of a &lt;code&gt;PATH&lt;/code&gt; directory&lt;/td&gt;
					&lt;td&gt;off (top level only)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;--skip&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Update Desired state only; do not build&lt;/td&gt;
					&lt;td&gt;off&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-j, --jobs N&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Parallel workers for parsing, hashing and rendering&lt;/td&gt;
					&lt;td&gt;logical CPU count&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-C, --workdir DIR&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Workspace discovery start directory&lt;/td&gt;
					&lt;td&gt;current directory&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-r, --repo NAME&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Select a repository&lt;/td&gt;
					&lt;td&gt;selection rules&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-d, --dist NAME&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Select a distribution; repeatable&lt;/td&gt;
					&lt;td&gt;selection rules&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-T, --timeout DUR&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Maximum lock wait; &lt;code&gt;0&lt;/code&gt; waits indefinitely&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-N, --no-wait&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Fail immediately when the lock is held&lt;/td&gt;
					&lt;td&gt;false&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;--json&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Emit the versioned JSON envelope&lt;/td&gt;
					&lt;td&gt;false&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="inputs-and-targets"&gt;Inputs and targets&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;PATH&lt;/code&gt; can be a file or a directory. A directory is scanned top level only unless you pass &lt;code&gt;-R&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Compatibility</title><link>https://sow.pgsty.com/docs/reference/compatibility/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/reference/compatibility/</guid><description>&lt;p&gt;SOW writes standard rpm-md and Debian archive metadata, so the question is not whether a
client &lt;em&gt;can&lt;/em&gt; read it but which clients have actually been verified against it. This page
lists the tested matrix, the platforms the binary runs on, and the handful of constraints
that will bite you if you ignore them.&lt;/p&gt;
&lt;h2 id="package-manager-clients"&gt;Package manager clients&lt;/h2&gt;
&lt;p&gt;Every row below was exercised end to end against a repository built by SOW: refresh the
index, list packages, and install one.&lt;/p&gt;</description></item><item><title>sow rm</title><link>https://sow.pgsty.com/docs/reference/cli/rm/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/reference/cli/rm/</guid><description>&lt;p&gt;&lt;code&gt;sow rm&lt;/code&gt; takes packages out of the Desired Membership of the Dists you select and, by default,
rebuilds the affected indexes immediately. It never deletes bytes from &lt;code&gt;pool/&lt;/code&gt; — membership and
content are separate concepts, and there is no garbage collection.&lt;/p&gt;
&lt;h2 id="synopsis"&gt;Synopsis&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow rm PACKAGE... [-c|--check] [--skip] [-j|--jobs N] [-C|--workdir DIR] [-r|--repo NAME] [-d|--dist NAME]... [-T|--timeout DUR | -N|--no-wait] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="options"&gt;Options&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Flag&lt;/th&gt;
					&lt;th&gt;Description&lt;/th&gt;
					&lt;th&gt;Default&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-c, --check&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Preview only; compute and print the plan without writing anything&lt;/td&gt;
					&lt;td&gt;off&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;--skip&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Update Desired state only; do not build&lt;/td&gt;
					&lt;td&gt;off&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-j, --jobs N&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Parallel workers&lt;/td&gt;
					&lt;td&gt;logical CPU count&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-C, --workdir DIR&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Workspace discovery start directory&lt;/td&gt;
					&lt;td&gt;current directory&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-r, --repo NAME&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Select a repository&lt;/td&gt;
					&lt;td&gt;selection rules&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-d, --dist NAME&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Select a distribution; repeatable&lt;/td&gt;
					&lt;td&gt;selection rules&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-T, --timeout DUR&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Maximum lock wait; &lt;code&gt;0&lt;/code&gt; waits indefinitely&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-N, --no-wait&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Fail immediately when the lock is held&lt;/td&gt;
					&lt;td&gt;false&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;--json&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Emit the versioned JSON envelope&lt;/td&gt;
					&lt;td&gt;false&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;--check&lt;/code&gt; and &lt;code&gt;--skip&lt;/code&gt; are mutually exclusive:&lt;/p&gt;</description></item><item><title>Transactions &amp; Recovery</title><link>https://sow.pgsty.com/docs/feature/transactions/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/feature/transactions/</guid><description>&lt;p&gt;Repository tools fail in one of two embarrassing ways: they leave an index that points at packages that no longer exist, or they corrupt their own database and require a rebuild from scratch. SOW is built to make both impossible, and this page explains the machinery that does it.&lt;/p&gt;
&lt;h2 id="the-invariant"&gt;The invariant&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;A client following a protocol pointer always reads a complete old view or a complete new view. There is no third option, including after a power loss.&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>sow ls / show / where</title><link>https://sow.pgsty.com/docs/reference/cli/query/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/reference/cli/query/</guid><description>&lt;p&gt;Three commands answer three different questions. &lt;code&gt;ls&lt;/code&gt; lists what a Dist should contain, &lt;code&gt;show&lt;/code&gt;
inspects one package object in detail, and &lt;code&gt;where&lt;/code&gt; finds which Dists — in any Repository — carry a
package. All three are read-only, take no write lock, and share the same &lt;code&gt;--json&lt;/code&gt; envelope.&lt;/p&gt;
&lt;h2 id="synopsis"&gt;Synopsis&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow ls [-C|--workdir DIR] [-r|--repo NAME] [-d|--dist NAME]... [--json]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow show PACKAGE [-C|--workdir DIR] [-r|--repo NAME] [-d|--dist NAME]... [--json]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow where PACKAGE [-C|--workdir DIR] [-r|--repo NAME] [-d|--dist NAME]... [--json]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="common-options"&gt;Common options&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Flag&lt;/th&gt;
					&lt;th&gt;Description&lt;/th&gt;
					&lt;th&gt;Default&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-C, --workdir DIR&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Workspace discovery start directory&lt;/td&gt;
					&lt;td&gt;current directory&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-r, --repo NAME&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Select a repository&lt;/td&gt;
					&lt;td&gt;selection rules&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-d, --dist NAME&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Select a distribution; repeatable&lt;/td&gt;
					&lt;td&gt;selection rules&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;--json&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Emit the versioned JSON envelope&lt;/td&gt;
					&lt;td&gt;false&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;There is no &lt;code&gt;--pool&lt;/code&gt;, no &lt;code&gt;--match&lt;/code&gt;, and no per-command format flag.&lt;/p&gt;</description></item><item><title>Observability &amp; Audit</title><link>https://sow.pgsty.com/docs/feature/audit/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/feature/audit/</guid><description>&lt;p&gt;Four read-only commands answer four different questions, and each one refuses to do the others&amp;rsquo; job. That separation is deliberate: a cheap status check that occasionally hashes the whole repository is useless in a loop, and a full verification that silently repairs things is useless as evidence.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Command&lt;/th&gt;
					&lt;th&gt;Question&lt;/th&gt;
					&lt;th&gt;Cost&lt;/th&gt;
					&lt;th&gt;Writes&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;status&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;What state is this repository in right now?&lt;/td&gt;
					&lt;td&gt;cheap, no hashing&lt;/td&gt;
					&lt;td&gt;never&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;check&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Can I prove this tree is correct and shippable?&lt;/td&gt;
					&lt;td&gt;full verification&lt;/td&gt;
					&lt;td&gt;never&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;changes&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Which files do I need to copy to bring a mirror up to date?&lt;/td&gt;
					&lt;td&gt;reads the generation manifest&lt;/td&gt;
					&lt;td&gt;never&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;log&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;What happened, when, and to which packages?&lt;/td&gt;
					&lt;td&gt;reads the ledger&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;prune&lt;/code&gt; only&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="status--cheap-state"&gt;&lt;code&gt;status&lt;/code&gt; — cheap state&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; sow status
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;repository=pigsty status=clean ready_to_copy=true revision=4 generation=4 dirty_dists= pending=0/0 locked=false
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;status&lt;/code&gt; never hashes the repository, never recovers an operation, and never builds. It reports the repository state, the Desired revision, the Built generation, which Dists are dirty, how many pending payload objects exist and how many bytes they occupy, whether a lock is held, and the most recent operation.&lt;/p&gt;</description></item><item><title>sow build / status / check / changes</title><link>https://sow.pgsty.com/docs/reference/cli/build/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/reference/cli/build/</guid><description>&lt;p&gt;One concept, one command. &lt;code&gt;status&lt;/code&gt; is the cheap read, &lt;code&gt;check&lt;/code&gt; is the full verification, &lt;code&gt;build&lt;/code&gt; is
the only thing that changes the public tree, and &lt;code&gt;changes&lt;/code&gt; is the physical file diff between
Generations. This page covers all four, because you almost always use them together.&lt;/p&gt;
&lt;h2 id="synopsis"&gt;Synopsis&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow status [-C|--workdir DIR] [-r|--repo NAME] [-d|--dist NAME]... [--json]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow build [-j|--jobs N] [-C|--workdir DIR] [-r|--repo NAME] [-d|--dist NAME]... [-T|--timeout DUR | -N|--no-wait] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow check [-j|--jobs N] [-C|--workdir DIR] [-r|--repo NAME] [-d|--dist NAME]... [--json]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow changes [BASE_GENERATION] [-C|--workdir DIR] [-r|--repo NAME] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="the-state-model"&gt;The state model&lt;/h2&gt;
&lt;p&gt;Every Repository tracks two things: the &lt;strong&gt;Desired Revision&lt;/strong&gt; in SQLite, and the &lt;strong&gt;Built Generation&lt;/strong&gt;
that the &lt;code&gt;dists/&lt;/code&gt; tree on disk corresponds to.&lt;/p&gt;</description></item><item><title>sow log</title><link>https://sow.pgsty.com/docs/reference/cli/log/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/docs/reference/cli/log/</guid><description>&lt;p&gt;Every write command inside a Repository commits an application-level Operation to that Repository&amp;rsquo;s
SQLite database &lt;em&gt;before&lt;/em&gt; it produces any external file side effect. That record is what makes crash
recovery possible — and once the Operation reaches a terminal state, the same record is your audit
trail. &lt;code&gt;sow log&lt;/code&gt; reads it.&lt;/p&gt;
&lt;h2 id="synopsis"&gt;Synopsis&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow log [OPERATION] [-C|--workdir DIR] [-r|--repo NAME] [-d|--dist NAME] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow log export [FILE] [-C|--workdir DIR] [-r|--repo NAME] [-d|--dist NAME]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow log prune BEFORE [-C|--workdir DIR] [-r|--repo NAME] [-T|--timeout DUR | -N|--no-wait] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="operation-lifecycle"&gt;Operation lifecycle&lt;/h2&gt;
&lt;p&gt;Understanding the &lt;code&gt;state&lt;/code&gt; field is most of understanding the log:&lt;/p&gt;</description></item><item><title>Page Not Found</title><link>https://sow.pgsty.com/404/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/404/</guid><description>&lt;p&gt;The page you are looking for has moved, been deleted, or does not exist.&lt;/p&gt;
&lt;p&gt;Try the &lt;a href="https://sow.pgsty.com/docs/"&gt;documentation home&lt;/a&gt;, or search with &lt;kbd&gt;⌘K&lt;/kbd&gt; / &lt;kbd&gt;Ctrl K&lt;/kbd&gt;.&lt;/p&gt;</description></item></channel></rss>