From e569ec6c5f712f5791e25f608f7326c3ca482930 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Thu, 15 Oct 2026 21:54:58 +0200 Subject: [PATCH] REPORT + CONTEXT: v0.157.0 live proof on the three test boxes; not vouched Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb --- CONTEXT.md | 6 +++++ REPORT.md | 65 +++++++++++++++++++++++++++++------------------------- 2 files changed, 41 insertions(+), 30 deletions(-) diff --git a/CONTEXT.md b/CONTEXT.md index 7eac1f1..6cf431f 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -1,5 +1,11 @@ # CONTEXT — felhom-agent working state +> **2026-10-15 (night) — v0.157.0 RELEASED, NOT VOUCHED (storage identity build A, felhom.eu `16` §13).** Every storage +> place carries `kind`, `physical_disks`, `identity` (+ reason) in `GET /disks` and the hub report; `POST /disks/same-disk` +> answers the controller (v0.317.0, MinAgent 0.157.0). Computed on every read, never cached. Delivered by signed jobs to +> Tester 1, demo-hp, N100 only. Next: the operator vouches 0.157.0 → the global floor 0.317.0 / MinAgent 0.157.0. Build B +> (partition candidates, the internal place) waits for a task file (R-1079). + > **2026-10-08 (day) — UNRELEASED on main, ships with tomorrow's release (decision 178).** R-899: `POST /backup?trigger=manual` > runs no OS leg (`localapi/server.go`); after-boot kernel reports carry the saved block's ring (`kernelReportRing`). R-304: > `escrow.ErrRetainedUnchecked` → HTTP 424 `older_unchecked` when not every earlier package was tried (withheld, caps, diff --git a/REPORT.md b/REPORT.md index 7e2b01e..3a00bb3 100644 --- a/REPORT.md +++ b/REPORT.md @@ -1,38 +1,43 @@ -# REPORT — v0.156.1: after a power cut the box clears up (R-1006, R-1008) (2026-10-14) +# REPORT — v0.157.0: every storage place knows its physical disk(s); POST /disks/same-disk (2026-10-15) -Evidence: felhom.eu `documentation/audits/power-cut-fixes-2026-10-14/` — the spike (C1 the night's leftover, C2 a killed -worker, C3 a real power cut, C4 a full disk), the 17 red-proofs. - -## What the spike showed - -- A power cut mid-backup leaves `vzdump-lxc--.tar.dat` + `.tmp/` (root, in `/var/lib/vz/dump`); Proxmox never - lists it as a backup; nothing removes it; every later backup is skipped „not enough space". -- The dead vzdump task stays in Proxmox's active list ~30–60 s after the boot — long enough for the agent's start-up pass - to call it „genuinely in flight" (R-1008). Short, so R-1008's harm is small. -- A killed worker leaves `tar`/`zstd` writing into the `.tar.dat` for minutes, none named „vzdump" — the reason the root - helper checks open files, not only process names. -- On „No space left" vzdump removes its own partial (both paths): the preflight's sizing stays. But a full host root breaks - LVM's own metadata writes (a half-removed snapshot; the janitor cannot clear it — new row). - -## 0.156.0 is superseded — do not vouch it - -A background security review of the pushed 0.156.0 flagged „fail-open state drift": its in-flight rule compared a task's -wall-clock start with the kernel's `btime`, which moves when the clock is corrected after the boot (an NTP step after a -power cut) — a live backup could then look „from before the boot" and its lock be cleared. 0.156.1 uses Proxmox's own -liveness rule instead (the UPID's pid + pstart against `/proc//stat` start tick and state; no clock), and fails safe -when this agent cannot see root's processes (PID 1 not visible). +Written in ASD-STE100 Simplified Technical English. Design read first: felhom.eu `architecture/16-storage-physical-identity.md` +(§3, §4, §8, §10; ACCEPTED 2026-10-15, §13 = what was built), `03-host-agent.md`. Task: storage identity build A (operator +rulings D1–D6). Controller counterpart: felhom-controller v0.317.0 (MinAgent 0.157.0); hub v0.154.0 shows the fields. ## What changed -See `CHANGELOG.md` v0.156.0: `vzdumpInFlight` behind the one `BackupRunning`; `internal/vzpartial` at start-up and before -each backup; the root helper `felhom-vzdump-partial-clean` + one sudoers line + the bundle entry. +- `internal/storage/identity.go`: the physical disk(s) under a place, from `/sys`, `/run/udev/data`, `/proc/mounts` only + (no block I/O). `proven`, or `unknown` with `vm` / `network` / `usb_bridge` / `weak_wwn` / `no_serial`. +- `GET /disks` rows and the hub report's `storage_targets` gain `kind`, `physical_disks`, `identity`, `identity_reason`. +- `POST /disks/same-disk` `{a, b}` → `{different, proven, reason, a, b}`; scoped like every `/disks` call; a path the agent + did not mount itself is `unmapped`. +- `configs/` unchanged. -## Gates +## Tests and red-proofs -`go build ./... && go vet` clean; `go test ./... -count=1` rc 0; `agent_gates.py` all OK; `visudo -cf` parsed OK; the -config bundle tests (55) and the helper's tests (21) pass. 17 mutations, 17 red. +Fixture `/sys` + udev trees for every spike case and five same-disk handler tests. Seen failing first: the LVM thin +„diamond" (tmeta/tdata under one pool) read as a failure — fixed by counting a seen node once. Broken on purpose and seen +failing: the VM rule, the vendor-less WWN rule, the own-mount rule (an absent drive), the `sys_drive` mapping. +`python3 scripts/agent_gates.py`: all OK. -## Next +## Release and delivery -Released: tag `v0.156.0`, binary sha256 `8db22788…`, bundle `a2160521…`, step bundle `0.156.0-step1` `8be2bb8f…`. Then the operator's vouch + floor, then the live proof on demo-hp (a cut mid-backup) and -delivery to Tester 1 and the N100. +- `scripts/release-agent.sh 0.157.0`: tag `v0.157.0`, sha256 `addd4041…0aef`, bundle `0604bc60…397a`. +- Delivered by signed `agent_update` jobs to Tester 1, demo-hp and the N100 (the three test boxes). **NOT VOUCHED** — the + operator's act. Until the vouch, the global floor cannot declare MinAgent 0.157.0. + +## Live proof (method: the agent's local API on each PVE host, with the guest's own token) + +| Box | `GET /disks` | same-disk: drive vs system data | +|---|---|---| +| demo-hp | `local`/`local-lvm` proven (SATA SSD), NVMe drive proven (`eui:`), PBS `network` | different, proven | +| N100 | system proven (SATA SSD serial), USB drive proven (the bridge passes the real serial) | different, proven | +| Tester 1 (VM) | every place `unknown/vm` | not proven (`vm`) | + +On all three: system data vs `/var/lib/docker` → same disk, proven; a drive name that is not mounted → `unmapped`. The hub +stored the same fields (read from its database with the WAL). Evidence: felhom.eu `audits/storage-identity-buildA-2026-10-15/`. + +## Observations + +1. FILED: R-1083 — scratch box 9202 has no `local_api` in its `bootstrap.json`, so it cannot use any agent call. +2. NOT-A-FINDING: `usb_bridge` is built from the design's rule and was not seen on a real enclosure; that is R-1077, already open.