From 6e9dd1bfa19d548ce4702adcd54d279f97c37220 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Sat, 11 Jul 2026 17:19:14 +0200 Subject: [PATCH] docs: REPORT + CONTEXT for v0.116.0/v0.116.1 (deployed 9201, live-validated at info level) Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6 --- CONTEXT.md | 21 ++++++++++- REPORT.md | 100 +++++++++++++++++++++++++++++------------------------ 2 files changed, 74 insertions(+), 47 deletions(-) diff --git a/CONTEXT.md b/CONTEXT.md index 8f8456d..308d24d 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -7,7 +7,26 @@ > > Ask Claude Code: "Please update CONTEXT.md with what we did today" -Last updated: 2026-07-11 (v0.115.0 — version-aware Supports + DSM-validated guidance; pairs with agent v0.82.0 + hub v0.45.0) +Last updated: 2026-07-11 (v0.116.1 — observability pass; pairs with agent v0.83.0 + hub v0.46.0) + +> **2026-07-11 — v0.116.0/0.116.1: OBSERVABILITY PASS (LIVE on 9201; agent v0.83.0 + hub v0.46.0). +> MinAgent: 0.81.0 unchanged.** The debug ring (`LogBuffer`) now ALWAYS exists — logger = +> `MultiWriter(LevelFilterWriter(stdout, logging.level), ring)`, so DEBUG detail is remotely +> readable on an `info` box while docker logs keep the configured level. New `internal/logx` +> leveled helpers = the sweep standard (netstorage_job phases/verdicts/durations, netprobe, +> validation refusals, orphan WARN, `SupportsWithSource` gate line, agentapi per-call DEBUG, +> migrate phases, tier2/offbox unswallowed persists). Report ACK gains `controller_log_requested` → +> next report ships `controller_log_tail` (selftail.go, consume-once, 128 KB; the customer-visible +> `operator log pull served` INFO rides in the tail; app-tail wire byte-compatible). Debug page: +> `Vezérlő | Ügynök` tabs — the agent tab proxies agent `GET /debug/logs` (`Client.DebugLogs`; +> typed-404 → the "after the agent's next update" notice). **v0.116.1 (found by live validation): +> `/debug` + `/api/debug/*` + the nav item were STILL gated on logging.level=debug — ungated (auth +> unchanged), the incident's actual blind spot.** Live-proven at info: a real refused NAS add is +> fully reconstructable on both tabs (capability gate w/ source=version, phase lines, 502+duration, +> category). Conventions: `felhom.eu/documentation/runbooks/logging-conventions.md`. OPEN: operator +> clicks the hub's two "Request logs" buttons (hub UI password-gated) to close the live bundle +> round-trip; legacy `isDebug()` emission sites left for incremental migration. NOT published — +> Peti stays 0.113/0.81. > **2026-07-11 — v0.115.0: version-aware Supports + DSM-validated NAS guidance (LIVE on 9201, pairs > with agent v0.82.0 + hub v0.45.0). MinAgent: 0.81.0.** Capability detection now compares the agent diff --git a/REPORT.md b/REPORT.md index 6a37eed..d382e4c 100644 --- a/REPORT.md +++ b/REPORT.md @@ -1,61 +1,69 @@ -# REPORT — v0.115.0: version-aware Supports (agent version channel) + DSM-validated NAS guidance +# 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.115.0 (from v0.114.0) · **MinAgent:** 0.81.0 (the -version channel FALLS BACK to the probe — agent 0.82 is NOT required). Pairs with agent v0.82.0 + -hub v0.45.0. Part B of the NAS/coupling backlog-clear task (composite A–F; this repo = B). +**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). -## Baselines → shipped +## Motivating incident → root causes closed -| Repo | main @ start | → shipped | Version | -|---|---|---|---| -| felhom-controller | `ac6adaaa` (v0.114.0) | `b6842a4` | **v0.115.0** — live on 9201 | -| felhom-agent | `1e60e88` (v0.81.0) | `fa9c7fe` | v0.82.0 — demo-deploy (version channel) | -| felhom.eu | `4eaabb2` | (A findings + hub train) | DSM spike + hub v0.45.0 | +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 (files) +## What shipped -`internal/agentapi/client.go` (`noteAgentVersion` on all four Do sites — passive capture even on -404/errors; strict bare-semver validation; `AgentVersion()`), `internal/agentapi/features.go` -(`featureMinAgent` table + `AgentVersionReporter` + version-first `Supports`, probe fallback -unchanged), NEW `internal/util/version.go` (THE one comparator, moved verbatim from selfupdate which -now aliases it), `internal/selfupdate/version.go` (aliases), `internal/web/templates/storage_network.html` -(DSM-validated NFS guidance from Part A). Tests: `internal/agentapi/features_version_test.go`, -`storage_network_template_test.go` (unchanged content check). +- **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. -## Tests + red-proofs (mutation → predicted failure → reverted → green) +## Red-proofs (demonstrated, restored) -| Test | Red-proof mutant | Observed failure | +| Scenario | Reverted shape | Failure seen | |---|---|---| -| `TestSupports_VersionKnown_ComparesWithoutProbe` (0.82/0.81/1.0/0.100→Yes; 0.79/0.80.9→No, no probe) | version short-circuit dropped | `version-known path must NOT probe (ver=0.82.0, probes=1)` | -| `TestSupports_GarbageOrNoVersion_ProbeFallback` (`""`/dev/`0.82`/rc1/`evil;`… → exactly one probe, cached) | trust unparseable header as "too old" | `unusable version "dev" must fall back to EXACTLY one probe, got 0` | -| `TestSupports_NonReporterProber_Unchanged` | — | (non-reporter probers keep v0.114.0 behavior) | -| `TestVersionComparator_Table` (numeric-not-lexicographic, v-prefix, pre-release rejected) | — | — | -| `TestClient_VersionHeaderWins_WireLevel` / `TestClient_GarbageHeaderIgnored_WireLevel` (real pinned client) | — | header wins over a routeless agent; garbage ignored at capture | +| 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` | -Green gate `go build && go vet && go test ./...` PASS; `template_id_gate.py` + `emoji_gate.py` green. +(S3 schema + S6 both-polarity notice tests pass; their traps are asserted structurally.) -## Deployed + verified +## Live validation (9201, `logging.level: info`, 2026-07-11 ~17:10 CEST — via the exact endpoints the UI invokes; rendering-only residual) -9201 (golden/bootstrap): `felhom-controller:0.115.0 Up (healthy)`. Live check (real add endpoint, -agent 0.82 = the SUPPORTED branch): a bogus-export add returned the categorized `nfs_export` -failure + full rollback, and the debug log shows `capability gate: netstorage_verify=yes` — the -verdict now sourced from the **version compare** (agent 0.82 header), zero probe calls. The probe -fallback is regression-tested (T3/non-reporter) and is Peti's live path (his agent stays 0.81, no -header → probe). +- 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`. -## Part A (DSM spike) — the guidance edits landed here +## NOT live-validated (expected + why) -Real DSM 7.2 (virtual-dsm) validated the consumer recipes end-to-end through the v0.114 pipeline: -NFS "Map all users to admin" = Route A PASS (hardlink incl.); squash-off = `not_writable` refusal; -plain-user SMB PASS **with working hardlinks** (the Q5 caveat CLOSED for Synology); wrong-password/ -wrong-share classify identically (`smb_auth`/`smb_share`). The NFS guidance gained the verified -Synology menu path (File Services → NFS → **NFSv4.1**; NFS Permissions rule; `/volume1/`); -the "útmutató készül" caveat narrowed to **QNAP only** (no emulator — nothing fabricated). Record: -`felhom.eu/documentation/audits/SPIKE-nas-dsm-2026-07-11.md`. +- **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). -## NOT live-validated +## Observations -- The `agent_outdated`/held branches on a real