docs: v0.114.0 CHANGELOG (MinAgent header convention) + README NAS gate + CONTEXT + REUSE + coupled-feature rule in CLAUDE.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -1,5 +1,39 @@
|
||||
## Changelog
|
||||
|
||||
### v0.114.0 — agent-capability gate for coupled features (2026-07-11) — MinAgent: —
|
||||
|
||||
Box-level backstop for the publish-train ordering discipline (incident: the 0.81/0.113 train's
|
||||
9-minute controller-before-agent skew on Peti's box — RUNBOOK-publish-0.81-0.113-2026-07-11): the
|
||||
controller now detects whether its agent supports a coupled feature and refuses that feature up
|
||||
front, instead of failing mid-pipeline with a misleading rollback. No agent or hub changes; works
|
||||
against agents 0.79–0.81 as they exist. (Retroactive note: v0.113.0's effective MinAgent was
|
||||
0.81.0 for the NAS add — this release is the machinery that makes such coupling self-protecting.
|
||||
Header convention from here on: coupled releases declare `MinAgent: X.Y.Z` on this line.)
|
||||
|
||||
- **agentapi typed status (1.1):** non-2xx GETs surface as typed `*StatusError{Path,Code}` (same
|
||||
message text as the old formatted error) — the probe keys on `Code==404` via `errors.As`, never
|
||||
string matching.
|
||||
- **`internal/agentapi/features.go`:** `Feature`/`SupportState` + `featureProbes` table (one row:
|
||||
`netstorage_verify` → `GET /netstorage/verify-status`, the route that shipped WITH the coupled
|
||||
add semantics in agent v0.81.0) + `SupportCache` (TTL 5 min, Yes/No cached, Unknown NEVER cached
|
||||
or refused) + `Client.Supports`. 2xx ⇒ Yes; 404 ⇒ No; transport/timeout/401/5xx ⇒ Unknown — an
|
||||
agent problem is never claimed as "too old".
|
||||
- **Add gate:** `handleNetStorageAdd` refuses on `SupportNo` BEFORE the single-flight claim —
|
||||
HTTP 412, machine code `agent_outdated`, message "Az ügynök frissítése szükséges ehhez a
|
||||
funkcióhoz — a frissítés megérkezése után próbáld újra." `SupportUnknown` passes through to the
|
||||
existing agent-error paths. `remove`/`list`/health are NOT gated — old shares stay manageable.
|
||||
- **Settings page:** `NetAddSupport` (yes/no/unknown, short 2 s probe budget + cache) — `no` swaps
|
||||
the add form for the honest banner; the share list + remove render in every state.
|
||||
- **Tests:** T1 gate refusal (job never starts, slot never claimed, zero agent calls), T2 unchanged
|
||||
happy path + warm-cache NEGATIVE assertion (probe count stays 1 across two adds), T3
|
||||
indeterminate-never-refuses, T4 classification incl. the string-match trap case, T5 banner
|
||||
render, T6 TTL re-fire, wire-level 404-typing through the pinned client. Red-proofs RP1–RP5 run +
|
||||
reverted (recorded in REPORT.md).
|
||||
- Also: fixed a scheduling flake in `TestBackupTier2Restore_DoubleClickRefused` (pre-existing).
|
||||
- **Docs:** publish-train rules codified at `felhom.eu/documentation/runbooks/publish-train-rules.md`
|
||||
(manifest-before-floor; floor field LAST — the DB row overrides env and acts immediately;
|
||||
MinAgent fleet gate; this gate as backstop).
|
||||
|
||||
### v0.113.0 — NAS verify-before-commit + page redesign + protocol-honest guidance (2026-07-11)
|
||||
|
||||
Kills the "bogus share sits at Készenlét forever" bug: `POST /api/storage/netstorage/add` now
|
||||
|
||||
@@ -88,6 +88,10 @@ Per-package helpers/seams/traps: **`REUSE.md`** (maintained same-commit as helpe
|
||||
skill; templates must pass `controller/scripts/template_id_gate.py` + `emoji_gate.py`.
|
||||
- Testing doctrine (non-hollow tests, red-proofs, seams): use the `felhom-testing` skill.
|
||||
- Update `REUSE.md` if you added/changed/deprecated a shared helper or pattern (same commit).
|
||||
- **Coupled features** (controller behavior that depends on a specific agent version): add a
|
||||
`featureProbes` table row in `internal/agentapi/features.go` + a `Supports` gate call at the
|
||||
feature's entry point; declare `MinAgent: X.Y.Z` in the CHANGELOG entry header. Rules:
|
||||
`felhom.eu/documentation/runbooks/publish-train-rules.md`.
|
||||
|
||||
> **In every repository where you make a change, update both files in that repo:**
|
||||
> - **`CHANGELOG.md`** — cumulative log, newest on top.
|
||||
|
||||
+17
-1
@@ -7,7 +7,23 @@
|
||||
>
|
||||
> Ask Claude Code: "Please update CONTEXT.md with what we did today"
|
||||
|
||||
Last updated: 2026-07-11 (v0.113.0 — NAS verify-before-commit + page redesign; pairs with agent v0.81.0)
|
||||
Last updated: 2026-07-11 (v0.114.0 — agent-capability gate for coupled features)
|
||||
|
||||
> **2026-07-11 — v0.114.0: agent-capability gate (option-1) + publish-train rules (option-2).**
|
||||
> Answer to the 0.81/0.113 train's 9-minute controller-before-agent skew (Peti's box): the box now
|
||||
> protects itself. `internal/agentapi/features.go` — `Supports(Feature)` route-probes the agent
|
||||
> (`GET /netstorage/verify-status` = the v0.81.0 coupling signal; typed `StatusError` 404 ⇒ No, 2xx
|
||||
> ⇒ Yes, transport/5xx ⇒ Unknown NEVER refused; `SupportCache` TTL 5m both polarities, Unknown
|
||||
> uncached). `handleNetStorageAdd` refuses on No BEFORE the single-flight claim (412 +
|
||||
> `agent_outdated` + honest Hungarian message); settings page swaps the add form for a banner
|
||||
> (list/remove untouched in every state). remove/list NOT gated. NO agent/hub changes; NOT
|
||||
> published, floor untouched, Peti stays 0.113.0 — the gate is inert protection until the next
|
||||
> train. Rules codified: `felhom.eu/documentation/runbooks/publish-train-rules.md` (manifest before
|
||||
> floor; floor field LAST — hub_settings DB row overrides env + acts immediately; MinAgent fleet
|
||||
> gate — CHANGELOG header convention starts with this release; the gate as box-level backstop).
|
||||
> Tests T1–T6 + wire-level 404-typing; red-proofs RP1–RP5 in REPORT.md. Roadmap: agent
|
||||
> version-in-envelope upgrade of `Supports`; hub floor-UI separation = its own task. The
|
||||
> `agent_outdated` branch is test-proven only (demo agent is current — downgrade not justified).
|
||||
|
||||
> **2026-07-11 — v0.113.0: NAS verify-before-commit + page redesign (LIVE on 9201, pairs with agent
|
||||
> v0.81.0 + host-install v1.13.0).** `POST /api/storage/netstorage/add` no longer registers blind
|
||||
|
||||
@@ -110,6 +110,8 @@
|
||||
| `Client.FormatDisk` | controller/internal/agentapi/client.go | `(ctx, device, fstype, confirmed, durableID)` | ONLY format/wipe entry | Sentinels: `ErrNeedsConfirmation` (user-data, resubmit confirmed+durableID) / `ErrFormatRefused` (system/backup — operator opsign only). Agent re-checks role server-side |
|
||||
| `Client.EjectDisk` / `Decommission` / `AssignDisk` / `GuestAttach` / `ListCandidates` | controller/internal/agentapi/client.go | disk lifecycle | Delegate ALL disk ops to agent | Controller holds no Proxmox creds — never shell out to disk tools in-guest |
|
||||
| `Client.AddNetStorage/ListNetStorage/RemoveNetStorage` | controller/internal/agentapi/client.go | NAS mounts (A1) | Network storage | Password passes through to agent's 0600 cred file; controller NEVER persists it |
|
||||
| `agentapi.StatusError` | controller/internal/agentapi/client.go | `{Path, Code}` typed non-2xx GET error | Distinguishing HTTP statuses from transport errors (`errors.As`) | NEVER string-match agent error text — the capability probe keys on `Code==404` |
|
||||
| `SupportCache.Supports` / `Client.Supports` | controller/internal/agentapi/features.go | `(ctx, prober, Feature) SupportState` | Agent-capability gate for COUPLED features (route probe, TTL 5m) | 404 ⇒ No; transport/5xx ⇒ Unknown (NEVER refuse on Unknown). New coupled feature = new `featureProbes` row + gate call at the entry point + `MinAgent:` in the CHANGELOG header (publish-train-rules.md). Web layer: `Server.netFeatures` through the `netAgent` seam |
|
||||
|
||||
### Notifications / hub sync
|
||||
|
||||
|
||||
@@ -813,6 +813,17 @@ not just those with HDD data. Non-HDD apps can configure destination, method, an
|
||||
> (`storage_network.html`) is on the canonical form pattern with staged poll progress and the
|
||||
> protocol-honest NAS guidance (SMB-first; NFS map-all-users vs full-fidelity `anonuid=<uid+100000>`).
|
||||
> Authoritative doc: `felhom.eu/documentation/controller/network-storage-nas.md`.
|
||||
> - **Agent-capability gate (v0.114.0):** the verify-before-commit add is COUPLED to agent ≥ v0.81.0,
|
||||
> so the add entry point now probes the agent first (`internal/agentapi/features.go`,
|
||||
> `Supports(FeatureNetstorageVerify)` — a route probe on `GET /netstorage/verify-status`: 2xx ⇒
|
||||
> supported, typed 404 ⇒ older agent, transport/5xx ⇒ indeterminate, cached 5 min both polarities).
|
||||
> On an older agent the add is refused SYNCHRONOUSLY (HTTP 412, machine code `agent_outdated`,
|
||||
> honest Hungarian message) BEFORE the single-flight claim — never a misleading mid-pipeline
|
||||
> rollback; indeterminate NEVER refuses (a down agent speaks through the existing error paths). The
|
||||
> settings page swaps the add form for a banner on `SupportNo` (share list + remove stay usable in
|
||||
> every state). Convention: every future coupled feature adds a `featureProbes` row + a gate call at
|
||||
> its entry point and declares `MinAgent` in its CHANGELOG header — see
|
||||
> `felhom.eu/documentation/runbooks/publish-train-rules.md`.
|
||||
> - **Limits (v1):** a share's `+100000` uid mapping is fixed at add-time (one app / same-uid apps); for
|
||||
> write apps on a soft NFS mount, an in-flight file can truncate if the NAS vanishes mid-write (prefer
|
||||
> atomic-write apps / SSD-staging).
|
||||
|
||||
Reference in New Issue
Block a user