# Архив исходника docs/OPERATIONS.md Источник: Virfield, commit a1460d3372bdfbb5cb19d633d41dd5d3fb3164e6. Снимок перед релизной очисткой. Исторические утверждения ниже относятся к моменту исходной записи; актуальное состояние — в [[personal/projects/virfield]]. ````markdown # Operations This runbook describes current Tart + SSH nodes. Virfield does not use Lume; the separate old LaunchDaemon was disabled and booted out on 2026-10-14, its rollback files preserved. [Historical Lume operations](history/OPERATIONS-before-2026-10-14.md) are archived. Current defects and acceptance limits are in [Verification](VERIFICATION.md). Orchard is not deployment-ready. ## Standard VM account policy The operator requires standard **`admin/admin`**, with no automatic random account password rotation. Standard-account candidates (`0f8bc20` and later) use the configured account name as its password. Samsung Monterey has two complete live cycles; other profiles still require their own acceptance. For old images, a new journaled disposable clone authenticates the standard password first, and only if needed authenticates the recorded inherited password before converting that clone to the standard account. It verifies the result and preserves/migrates keychain items. Existing golden disks and credential journals remain intact. Securing a legacy image in place is refused with `image_account_policy_migration_required`; build a new image instead. Unknown keychain credentials fail readiness and require diagnosis, never a reset. Do not reset a login keychain or overwrite a golden to force the standard password. Per-image/lease management and caller keys, fresh VM host keys, pinning and key-only SSH remain required. Physical shared accounts are unaffected. Older rotation descriptions are dated mechanics of `f60efe3` and earlier. New VM accounts retain the standard password; compatible login-keychain migration still preserves items. Native GUI/new SSH I/O and actual reboot need per-profile acceptance. A successful fresh image does not repair an older unknown keychain. ## Paths A deployment directory owns installed binaries, `config.json`, the operator token and generated service/client configuration. `state_dir` may be a separate private directory. Runtime disks stay in configured Tart containers or node storage. The checkout is never runtime state. The existing personal installation uses `~/.virfield-v2` for deployment and `~/.virfield-tart` for state; the old directory name is not a runtime/version claim. Do not initialize another installation or change its port to upgrade it. Generic examples use: ```sh VIRFIELD_HOME="$HOME/Library/Application Support/Virfield" VIRFIELD_URL="http://127.0.0.1:7780" ``` ## Configuration and prerequisites Local VM hosts require Apple Silicon macOS, Tart and private storage. Image construction additionally requires Packer; developer recipes also require a verified Xcode XIP cache unless the approved base already provides that Xcode. `runtime.provider` selects Tart; `runtime.nodes` adds pinned SSH nodes. Containers have stable IDs, absolute paths, local/external kind and, for removable storage, a pinned volume UUID. CPU/RAM/disk reserve and VM slots are explicit. Tart checks directory availability and fresh allocatable capacity with `statfs` on every refresh. It reuses the verified volume UUID only for the same kernel filesystem ID, device and mount point; a changed mount needs a new lookup. A failed or interrupted lookup never substitutes an older identity. Only complete Tart VM specs with a positive virtual disk size are cached. A temporary ASIF size zero remains unknown and is reread even if config.json is unchanged; never override admission or rebuild a qualified golden to clear it. Node Podman also depends on its user runroot filesystem: available VM HDD bytes do not establish runroot capacity. The HTPC speech-log/runroot incident and its verified correction are recorded in Verification. Speech Dispatcher 0.12.1 logs every voice-list entry at level 1; lowering level 3 to 1 does not prevent the flood. The node account now has a private user configuration copied from its distribution configuration, changing only `LogLevel` to 0 and `LogDir` to `~/.local/state/speech-dispatcher/log`, outside Podman tmpfs. The system file, speech modules and autospawn remain unchanged. Three real autospawn/idle-exit cycles left the new files at zero bytes; the old runtime log and its HDD backup were explicitly authorized for deletion and removed. When updating the speech package, reconcile its distribution configuration with that user override. Physical-node and node-VM resource safety limitations are recorded in Verification. Config/token/state must belong to the daemon account. Tokens and credential files are owner-only; state is mode 0700. Never copy token values into client config. ### Physical nodes `runtime.nodes` adds physical hosts beside the Tart runtime. Virfield controls them over pinned SSH as one unprivileged account (no sudo), and a node lease uses that node's own slot, never a Mac VM slot or Mac CPU, memory or disk. ```json "nodes": [ {"id": "mbp-2014", "address": "192.168.1.79", "user": "admin", "host_key": "ssh-ed25519 AAAA…", "host_keys": ["ssh-ed25519 AAAA… (Big Sur)"], "os": "macOS", "arch": "amd64"}, {"id": "htpc", "address": "192.168.1.86", "user": "bazzite", "host_key": "ssh-ed25519 AAAA…", "os": "linux", "arch": "amd64", "keep_awake_file": "/tmp/rsync-active", "wake_on_lan": {"mac": "B0:6E:BF:60:6D:64", "broadcast": "192.168.1.255:9"}} ] ``` Take `host_key` from a trusted `known_hosts` entry and compare its fingerprint with the node. On first start `virfieldd` creates its node management key in `state_dir/nodes/management`; append `state_dir/nodes/management.pub` once to the node account's `~/.ssh/authorized_keys` (each macOS boot volume has its own home and is enrolled when booted). Each boot volume of a multi-boot Mac also has its own SSH host key, so the same address presents a different identity per booted system. List the extra identities in `host_keys`: Virfield accepts any configured key and reports the one presented in the lease's `ssh.host_key`. For an interactive client, keep one `known_hosts` line per identity for the address (OpenSSH accepts any matching line); `ssh-keyscan -t ed25519
` while the new volume is booted gives the key, which you compare out of band before trusting it. Node IDs must differ from the primary Tart host ID and all storage-container IDs. Ambiguous runtime host ownership blocks admission instead of changing routing. A node reports its booted environment as a pseudo-golden named after the boot volume (`Monterey`, `Big-Sur`, `bazzite`). A template with `"provider": "baremetal"`, `"location": ""`, `"name": ""` and `guest_user` is available only while that volume is booted. An unreachable node is `offline` (or `asleep` with Wake-on-LAN, then still admissible and woken at start); it is re-probed at most every 30 seconds, and an online node at most once a minute so inventory never keeps it awake. Each node's last probe is kept in `state_dir/nodes/.probe.json`, so a daemon restart while a node sleeps keeps it admissible and keeps its leases in inventory; the first observation after a restart still dials every node. A MacBook node is kept awake on its charger by the node itself, once per boot volume (each volume has its own power settings): ```bash ssh -t admin@192.168.1.79 'sudo pmset -c sleep 0 disksleep 0 standby 0 autopoweroff 0 powernap 0 displaysleep 10 womp 1 tcpkeepalive 1' ``` Applied on Ventura (2026-10-08); Monterey, Big Sur and Catalina still need it. Closing the lid still sleeps the Mac unless `pmset -a disablesleep 1`. On Catalina, if the Sharing pane hangs on "Remote Login starting…", start SSH with `sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist`. UI tests (XCUITest) on a macOS node need Developer Mode on that boot volume and Automation Mode that does not require authentication (`automationmodetool enable-automationmode-without-authentication`, present from macOS 12.6); otherwise testmanagerd asks for an admin password on the node's display and the run fails with "Timed out while enabling automation mode". This lets any process of that account drive the UI without a password, which is intended for a dedicated test node. Virfield has no sudo on nodes, so set both once per boot volume: ```bash scp deploy/node-ui-testing.sh admin@192.168.1.79: ssh -t admin@192.168.1.79 'bash ~/node-ui-testing.sh' ``` Copy the script first: piped over stdin, sudo has no terminal to prompt on. Each boot volume presents its own host key (see above); a lease's generated `ssh-config` already pins the booted volume's key, so `ssh -t -F virfield` works without editing `known_hosts`. The node account must also own the console session (log it in on the display, or enable automatic login). The probe reports the result on the node's pseudo-golden as `ui_testing`: `ready`, `devtools_disabled`, `automation_mode_requires_auth` or `no_console_session`. A lease authorizes the client key in `authorized_keys` (tagged `virfield-lease-`), creates `~/virfield/leases//workspace`, and keeps the node awake (`caffeinate` on macOS, the `keep_awake_file` on Linux, removed only after the last reference if Virfield created it; pre-existing holds are preserved). Release revokes the key and removes the workspace. Physical hosts are not disposable: processes the lease started under the shared account are not killed. ### macOS VMs on a Linux node (R2) A Linux node with `vms` runs disposable macOS VMs as rootless Podman containers of a digest-pinned `dockurr/macos` image (QEMU + OpenCore). No sudo or libvirt group is needed; the node account must be able to use `/dev/kvm` and `/dev/net/tun`. ```json "vms": {"image": "docker.io/dockurr/macos@sha256:08d1bcaac74ad44d548b7ce683b3dded083512d2a0d26416f9a620b763f8ea3d", "goldens_dir": "/run/media/system/Data/virfield/goldens", "port_base": 22100, "max": 2, "cpu": 4, "memory_gb": 8, "disk_size": "100G", "storage_dir": "/run/media/system/Data/virfield/runtime"} ``` - **Bootstrap goldens** are installed once by hand (see the [R2 spec](superpowers/specs/2026-10-08-hackintosh-nodes-r2-design.md)): `admin`/`admin`, Remote Login, passwordless sudo, SIP disabled through `.opencore.plist` (`csr-active-config` `0x7F`). They are never leased: a clone without a verified image is refused. - **Secured goldens** are built by Virfield from a template whose image is `{"node": {"golden": ""}, "macos": …, "build": …, "disable_sip": true}` (`POST /api/v1/images/