0df72ea643
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
54 lines
3.3 KiB
Markdown
54 lines
3.3 KiB
Markdown
# REPORT — agent v0.83.0: observability pass (capture ring + /debug/logs + heartbeat log-pull + sweep)
|
|
|
|
**Date:** 2026-07-11 · **Commit:** `cb692f8` · **Deployed:** felhom-pve (backup `.bak-0.82.0`) ·
|
|
**NOT published** (Peti stays 0.81.0; reaches him with the next publish train)
|
|
|
|
## What shipped
|
|
|
|
- **Capture layer** (`internal/log`): `applog.New` → `(logger, *Ring)`. slog fan-out: stderr/journald
|
|
at the configured level (unchanged), a 1000-entry ring FIXED at LevelDebug. `Ring.Lines(maxBytes)`
|
|
renders newest-kept plain text (the heartbeat tail source).
|
|
- **`GET /debug/logs`** on the local API (token-authed, self-scoped like every sibling; `?raw=1`
|
|
plain text; 503 unwired) + request-level DEBUG middleware (method/path/status/duration, never bodies).
|
|
- **Heartbeat log-pull**: `ControlEnvelope.log_tail_requested` (additive) → the NEXT heartbeat
|
|
carries `log_tail {collected_at, lines[]}` (128 KB cap, newest kept). Consume-once mirrored from
|
|
report logtail.go: local pending drains onto the carrying push; a failed push is re-armed by the
|
|
next envelope (retry proven in tests). Serving a pull logs `operator log pull served` (INFO).
|
|
- **Gap-fill sweep**: netverify (job start / trigger outcome / **/proc/mounts verdict** / journal
|
|
byte-count / classification code / rollback outcome / durations), netstorage add (pre-probe PASS
|
|
verdict, creds staged/removed — path only), netmount (unit install/enable/remove-step results),
|
|
signedjobs (jobs fetched ids+duration; op received class/host/expiry — never signatures),
|
|
selfupdate (invariants passed, download sha-match+duration), disks (assign/eject/decommission
|
|
outcome INFO), ReassertGuestBinds pass summary, controller-swap (pre-pull verify, negative health
|
|
verdict), desired syncer + hub loop per-exchange DEBUG.
|
|
|
|
## Red-proofs (all demonstrated, then restored)
|
|
|
|
| Scenario | Reverted shape | Failure seen |
|
|
|---|---|---|
|
|
| S1 capture-at-info | ring handler gated at the emit level | `ring holds 1 entries, want 2` |
|
|
| S2 consume-once | `logTailPending = false` drain removed | `report 3 carries a tail again — consume-once broken` |
|
|
| S7 log sequence | /proc/mounts verdict Debug dropped | `phase line "netverify: /proc/mounts verdict" missing` |
|
|
|
|
## Live validation (felhom-pve, 2026-07-11 ~17:00 CEST)
|
|
|
|
- `felhom-agent 0.83.0` live; journal clean (ReassertGuestBinds bound felhom-usb, local-api
|
|
listening, no capability degradation).
|
|
- A real NAS add from controller 0.116.1 at `logging.level=info`: the agent ring (via the
|
|
controller's Ügynök tab) shows the request middleware lines including
|
|
`POST /netstorage/add status=502 duration_ms=2001` — the refusal flow is reconstructable remotely.
|
|
- Heartbeat log-pull live round-trip: **pending the operator's hub button click** (hub UI is
|
|
password-gated; CC cannot log in). The channel is fully proven by hub API tests incl. the S6
|
|
stays-pending case.
|
|
|
|
## Green gate
|
|
|
|
`go build ./... && go vet ./... && go test ./...` — all green (no flakes this run).
|
|
|
|
## Observations
|
|
|
|
- Pre-existing (not from this change): `lanresolver: cannot list provisioned guests — permission
|
|
denied on /var/lib/felhom-agent/guests` WARN at startup — worth a follow-up look.
|
|
- The 20 s reconcile tick adds one DEBUG ring line per pass (`guest-bind re-assert pass`) — accepted
|
|
ring churn (~180/h; the ring holds ~1000).
|