docs: REPORT + CONTEXT for v0.116.0/v0.116.1 (deployed 9201, live-validated at info level)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
2026-07-11 17:19:14 +02:00
parent 458d7e1ebc
commit 6e9dd1bfa1
2 changed files with 74 additions and 47 deletions
+54 -46
View File
@@ -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 AF; 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/<share>`);
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/<demo host> 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 <MinAgent agent (no such box exists — test-proven).
- Q1c restart survival: tested in Part E and **FAILED** (empty-dir; not a controller bug) — the fix
is felhom-agent's, spec'd at `felhom.eu/documentation/backlog/FOLLOWUP-nas-automount-guest-reboot-reassert.md`.
A controller follow-on (health cross-check the GUEST-visible mount) is noted there.
- 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.