This is the multi-page printable view of this section. .
About Farrow
- 1: Design
- 2: Status
- 3: Engineering
- Design explains why Farrow has one Inventory, one deployment, and one fixed-IP network.
- Status separates implemented behavior, native validation, and remaining release gates.
- Engineering defines source, generated-output, package, image-pipeline, and evidence boundaries.
1 - Design
One useful abstraction
Farrow boots one Pigsty Inventory as one local QEMU deployment. It deliberately has no project marker, project registry, lease model, provider layer, or second configuration format.
State lives under ~/.farrow for one Unix user. The product assumes one active
Pigsty deployment per computer; this is not a root-enforced cross-user
singleton.
Node-level convergence
Farrow extracts only the documented VM and Pigsty-native fields, computes
per-node hashes, and keeps applied state plus process identity. Additions are
incremental. Changes require an
explicit per-node recreate. up also starts selected existing stopped nodes;
already-running peers remain untouched. Absence never authorizes deletion.
Runtime selection
Guest architecture is deployment-wide desired state. Omitted/native follows
the host; explicit amd64 or arm64 selects that Catalog artifact exactly.
Native HVF/KVM remains the default. A foreign architecture or one catalogued
image/host incompatibility selects a fixed TCG profile; there is no user
accelerator argument and no arbitrary failure fallback.
The effective architecture and accelerator are persisted in each QEMU
invocation and exposed by status. Before destructive recreate, Farrow proves
the selected QEMU binary and version, network backend, image bytes, boot mode,
and firmware. A later binary changing runtime policy cannot mix new nodes with
old invocations: runtime drift requires whole-deployment recreation.
Two NICs, one fixed subnet
The management NIC supplies DHCP, DNS, egress, and loopback SSH. The fixed-IP NIC supplies host/peer/Ansible traffic. macOS uses socket_vmnet. Linux follows active NetworkManager; otherwise it uses systemd-networkd and connects through the distribution bridge helper. Inactive networkd is started only after an activation-safety scan proves existing units cannot claim a real host link.
On Debian, the helper is temporarily and reversibly scoped to a group the caller actually belongs to. A real unprivileged QEMU bridge smoke must pass before setup accepts the network; failure triggers manifest-bounded rollback.
Safety boundary
QEMU and all guest artifacts run as the caller. Root is limited to host network setup and the optional hosts publisher. Destruction requires matching ownership, containment, node identity, QMP/process identity, and an allowlist of artifacts. Ambiguity stops the operation.
Review conclusion
The pivot away from projects and leases is correct for a one-lab product and greatly reduces cognitive and state complexity. Native review was still essential: the first implementation had cross-layer gaps in control-node keys, sudo policy, Debian helper access, NetworkManager verification, runtime preflight, result messages, and failed-install cleanup. Those paths were fixed and replayed on macOS and Linux before this documentation was simplified. A later adversarial review also caught destructive preflight ordering and signed Catalog-baseline upgrade bugs before EL7/EL8 compatibility was committed.
2 - Status
Farrow is pre-1.0. Source tests, dated native replays, packages, release, CI, and the public site are separate gates.
Last recorded native replay — 2026-08-27
This matrix belongs to the exact checkpoint exercised that day. Later source or documentation edits do not inherit native proof without another replay.
| Host | Path | Result |
|---|---|---|
| macOS 26.6.2 arm64 | HVF, QEMU 11.1, socket_vmnet | one node and additive four nodes passed |
Ubuntu 26.04 amd64 (mx) |
KVM, QEMU 10.2.1, NetworkManager | setup, one node, additive four nodes, and uninstall passed |
Both hosts passed fixed IP, SSH readiness, default CPU/memory/root/data disk, cloud-init, stop/start, cross-directory commands, unchanged control-node boot ID during scale-out, control-to-peer SSH, ignored unconsumed Pigsty changes, absence-never-destroys, and explicit destroy.
Linux additionally proved valid NOPASSWD automation, caller-accessible Debian helper policy, unprivileged bridge smoke, refusal to uninstall with four tap members, and exact restoration after destroy.
Interactive host-network and hosts commands now invoke sudo themselves; an
external sudo -v is optional. Darwin cleanup can reconstruct an uninstall-
only ownership plan from byte-identical interface evidence, the exact launchd
plist, and installed binary digests when network.json is missing.
On 2026-08-28 the post-calibration tree passed unit, race, vet, staticcheck, govulncheck, all four cross-builds, the simulated image-pipeline boundary, license verification, and GoReleaser configuration validation. An isolated local GoReleaser snapshot also built and verified all four archives, both DEB/RPM architectures, SPDX documents, checksums, dependencies, modes, and archive/package parity. Nothing was published, and those results do not extend this native matrix.
EL7/EL8 compatibility — 2026-08-28
Commit 7c666c7 restored EL7/EL8 after two independent Claude Code Opus 5 max
adversarial reviews. The first review blocked on destructive runtime preflight
ordering and signed-Catalog baseline migration; both were fixed, regression
tested, and the second review returned PASS with no required fixes.
Catalog 2026082801 is signed and active on the development repository: 9
families, 17 image artifacts, and 19 SHA-verified repository payloads including
the two socket_vmnet archives. A clean client accepted the public signature and
exact embedded digest.
An isolated macOS arm64 lifecycle replay booted Rocky Linux 8.10 arm64 with the
built-in TCG compatibility rule, passed stop/start and readiness in 44.2 seconds,
and verified NetworkManager, fixed IP/no-route/no-DNS, dba UID/GID 88, and the
generation/spec marker. EL7 bytes, qcow2 structure, BIOS layout, and 4K XFS root
are verified; the current native Linux/amd64 Farrow lifecycle replay remains
open.
Still open
- EL9 + NetworkManager + firewalld native replay;
- current systemd-networkd replay;
- host reboot persistence;
- macOS amd64 and Linux arm64 native runs;
- EL7 through the current native Linux/amd64 lifecycle;
- current 9p share replay;
- a complete current Pigsty
configure → farrow up → install.ymlrun; - published Homebrew/DEB/RPM consumption and release CI.
Current images remain testing, except EOL EL7 which is deprecated. Active
and standby Catalog public keys are embedded, but the repository must move off
the development host and private-key custody/rotation plus release custody must
be formalized before 1.0.
3 - Engineering
Repository boundary
The Farrow source repository contains code, tests, build/package definitions, legal notices, and a short landing README. This site is the authoritative home for user, design, operator, and release documentation. Raw review transcripts, historical scratch inventories, demo directories, generated binaries, and release output trees are not source inputs and must not be committed.
Generated output is disposable:
bin/— development builds;dist/and.goreleaser-*— release/snapshot staging;- root
farrow,farrow-hosts-helper, andcatalogsignbinaries; - Hugo
public/andresources/.
Build and source gates
make check combines these gates. A source gate is not native VM evidence;
macOS HVF, Linux KVM/networking, package consumption, release publication, and
the public render remain separate gates.
Release and package contract
Release tooling under packaging/, .goreleaser.yaml, and .github/workflows
is source, even though its generated directories are not. Archives and Linux
packages contain the matching binaries plus LICENSE, the minimal source
README, build metadata, and exact upstream license bytes reconstructed from the
module versions pinned by go.mod. Those generated license texts live under
licenses/ in archives and are not tracked as source. Detailed documentation
stays on this versioned site rather than being copied into every binary payload.
Never infer publication from a successful build. Commit, tag, archive/package, signature/attestation, upload, CI, and public consumption are distinct gates.
Image normalization
packaging/image-pipeline/ accepts an explicit local qcow2 source; it never
downloads or uploads. It copies and hashes the source, forces qcow2 parsing,
rejects backing/external/encrypted/unknown features, runs qemu-img check, and
can perform a no-network offline Guest mutation in an explicit QEMU sandbox.
UID/GID 88 collisions are rejected rather than rewritten ambiguously.
Catalog bytes are exported with:
The exporter is atomic and no-clobber. Catalog signing and application release signing use separate keys and trust domains.
Evidence policy
Historical M0–M4 notes were useful during implementation but are not product documentation. Their durable conclusions are condensed into Design and Status. A later source edit inherits no native proof; every status claim names its date, host, path, and remaining gates.