# REPORT — v0.116.0/v0.116.1: observability pass (always-on debug ring + agent tab + self-log pull + sweep) **Date:** 2026-07-11 · **Version:** controller v0.116.1 (from v0.115.0; 0.116.1 = the debug-surface ungate found by live validation) · **MinAgent:** 0.81.0 unchanged · **Deployed:** guest 9201 (`0.116.1` healthy) · **NOT published/vouched** — Peti stays 0.113.0; this reaches him with the next publish train. Pairs with agent v0.83.0 + hub v0.46.0. Task-wide record: this file + each repo's CHANGELOG + `felhom.eu/documentation/runbooks/logging-conventions.md` (the codified conventions). ## Motivating incident → root causes closed A NAS-verify refusal on an `info` box showed NOTHING remotely. Three stacked causes, all fixed: 1. the `LogBuffer` ring only EXISTED at `logging.level=debug` (setupLogger) → now always built; stdout respects the level via `LevelFilterWriter` (docker logs unchanged); 2. the new flows emitted few lines → the leveled `internal/logx` sweep (phases, verdicts, durations); 3. **the `/debug` page + `/api/debug/*` 404'd at info** (found live — v0.116.1): the viewer is now available at any level, still session-authed (RequireAuth + CSRF); the nav link always renders. ## What shipped - **Capture layer**: always-on 1000-entry ring; `MultiWriter(LevelFilterWriter(stdout, level), ring)`; `logx.Debugf/Infof/Warnf/Errorf` (caller-attributed); legacy `isDebug()` emission sites untouched. - **Report self-log pull** (`report/selftail.go`): ACK `controller_log_requested` → next report ships `controller_log_tail` (128 KB, consume-once, the v0.111.0 logtail.go shape; the customer-visible `operator log pull served` INFO rides IN the tail). App-tail wire byte-compatible (schema-tested). - **Debug page tabs**: `Vezérlő | Ügynök`; the agent tab proxies agent `GET /debug/logs` via the new `Client.DebugLogs` (typed-404 → "Az ügynök naplónézete az ügynök következő frissítése után érhető el."; non-404 stays an honest error). Template gates green. - **Sweep**: netstorage_job (start + per-phase transitions + verdicts + rollback outcomes + durations), netprobe exec/result, handler validation refusals (which check), orphan-share WARN, capability gate line now carries the SOURCE (`SupportsWithSource`: version/probe-cache/probe), agentapi per-call DEBUG (`SetLogger` on the memoized client) + version-change line, migrate per-phase + duration, tier2/offbox run-start + previously swallowed status-persist errors → WARN. ## Red-proofs (demonstrated, restored) | Scenario | Reverted shape | Failure seen | |---|---|---| | S1 | LevelFilterWriter pass-through | `stdout carries the DEBUG line at level info` | | S2 | self-tail drain removed | `second build shipped again — consume-once broken` | | S7 | probe-verdict line dropped | `phase line "probe verdict: ok=true" missing` | (S3 schema + S6 both-polarity notice tests pass; their traps are asserted structurally.) ## Live validation (9201, `logging.level: info`, 2026-07-11 ~17:10 CEST — via the exact endpoints the UI invokes; rendering-only residual) - Real NAS add (`POST /api/storage/netstorage/add`, unreachable endpoint 192.168.0.199) → job `failed` with `category=unreachable` + the exact §3.2 Hungarian message in ~2 s. - **Vezérlő tab** (`/api/debug/logs?level=DEBUG`) at info shows the whole flow: capability gate `netstorage_verify=yes (source=version)` ← the 0.82/0.83 version channel live, add started INFO, `[agentapi] POST /netstorage/add -> 502 (2001ms)`, failed WARN with category+duration. - **Ügynök tab** (`/api/debug/agent-logs`) proxies the agent ring (201 entries) incl. `POST /netstorage/add status=502 duration_ms=2001`. ## NOT live-validated (expected + why) - **Hub bundle round-trip (button → pending → bundle → download):** the hub UI is operator-password- gated and no logged-in browser session was available — **operator follow-up: click "Request controller logs" + "Request agent logs" on hub.felhom.eu/hosts/ and download both.** The full round-trip incl. consume-once + S6 stays-pending is proven by hub API tests. - **Blocked-secret branch live:** deliberately test-level only (no real secret is ever planted live). ## Observations - Legacy `isDebug()` call sites left in place per spec — their DEBUG detail still doesn't exist at info (only NEW logx lines do). Future sweeps can migrate them incrementally. - Swallowed-error branches found + fixed with a WARN (not more): tier2 `SetCrossDriveConfig` ×3, offbox `UpdateOffboxStatus` ×2. The offbox stats persist (best-effort, stale-safe) left as-is. - The guest's local-API token was incidentally printed to the operator terminal during config inspection (never into a file/commit); rotating it is cheap if desired.