Skip to content

This is the multi-page printable view of this section. .

Return to the regular view of this page.

About Farrow

The simplified product model, implementation boundaries, native evidence, current limits, and release gates.
  • 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

Farrow’s simplified one-deployment architecture, networking, state, safety boundaries, and review conclusion.

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

What the current simplified tree has passed natively, what remains unverified, and what blocks 1.0.

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.yml run;
  • 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

Source layout, build and test gates, image normalization, release outputs, and evidence policy.

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, and catalogsign binaries;
  • Hugo public/ and resources/.

Build and source gates

make build
make test
make race
make vet
make staticcheck
make vuln
make cross-check
make image-pipeline-test
make license-check

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:

go run ./tools/catalogexport /absolute/new/catalog.json

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.