Switch the default provider from Anthropic to OpenAI and the default
model to gpt-5.3-codex, so Pi runs on a ChatGPT Plus/Pro (Codex)
subscription. The OAuth login stays unmanaged in ~/.pi/agent/auth.json,
as before.
Install the grill skill globally from the skills flake, alongside wiki and
consume. It interviews the operator relentlessly about a plan or design,
resolving every branch to an explicit decision before any implementation.
Add `modules.zfs`, the host-level pool import: a host declares its ZFS host id
and the pools to import with their dataset mountpoints, and the module imports
those pools as durable state rather than recreating them, so a service's data
survives any rebuild or reimage.
Add a shared `storage` group with a fixed gid to the base config both the host
base and the guest-base build on, so a host and every guest carry the same
number and an identity-mapped container write lands on the pool as that group
without per-service permission juggling.
No host enables the module: the only host is a laptop with no pools and a
kernel with no ZFS build, so the enabled build was verified by ad-hoc
enablement against a ZFS-supported kernel while the committed tree stays inert.
A guest sets `vlan` to attach to its host's `br-vlan<id>` bridge, `mac`
to reuse an existing address (else a stable one is derived from its
namespace path and read back via `nix eval`), and `address` for a static
IP (else DHCP). The MAC and address are pinned inside the guest by its
own networkd, the only stable MAC pin for a nested container. A guest
naming a VLAN its host has not declared fails the build with an
actionable message.
The `br-vlan<id>` naming moves into a shared `bridgeName` in the lib, so
the bridge a guest attaches to and the bridge the host emits have one
source.