v0.173.0 — R-77: endpoint-drift detection, samba protected-set gate, channel log honesty
Source: felhom.eu/documentation/audits/DIAG-agent-channel-2026-07-26.md bootstrap.DetectEndpointDrift names a controller.yaml vs bootstrap.json local_api.endpoint divergence -- one ERROR carrying BOTH values and BOTH paths, its own event type local_api_endpoint_drift, and its own Hungarian banner shown ABOVE the channel banner because drift is the cause and "agent unreachable" the symptom. It writes NOTHING: reconciling from bootstrap.json would clobber a correct controller.yaml on any half-provisioned or hand-repaired guest, so the authority ruling is deferred to R-78. Fail-safe silent on absent/unparseable/ incomplete bootstrap and on an empty endpoint (ensureLocalAPI's fill-if-missing path is untouched). Fingerprint compared as a BOOLEAN only; token never compared, logged or exposed. EffectiveProtected now gates samba on Enabled && UserSet, mirroring BOTH of reconcileSambaAt's early returns, and the doc comment is corrected in the same change -- it claimed "detection and deployment agree in both directions" while citing only !smb.Enabled, an assertion that went false when !smb.UserSet was added. Not over-suppressed: sharing on WITH a password and a dead container still alarms. Channel log: the debounce placeholder is stateUnconfirmed (rendered "unseeded") instead of "up", so a born-down channel no longer logs "up->down" and orUnseeded stops being dead code. Logging only -- the placeholder is still matched in the re-arm condition, so F2 born-down alerting is byte-for-byte unchanged and all nine pre-existing channelhealth tests pass. Tests 951 -> 959, all green. Red-proofs A (both directions), E and F. MinAgent unchanged; felhom-agent untouched.
This commit is contained in:
@@ -251,14 +251,28 @@ func checkDocker() error {
|
||||
//
|
||||
// - cloudflared is dropped when no tunnel token is configured (a LAN-only node legitimately runs
|
||||
// without it, so it must not be reported as a missing protected container forever);
|
||||
// - the samba container is ADDED when network sharing is switched on (R-7b). Sharing is a
|
||||
// customer-toggled feature, so it can never appear in the golden controller.yaml — but once it
|
||||
// IS on, a dead sharing service is exactly as customer-visible as a dead traefik and must raise
|
||||
// the same protected-container issue → alert → Hungarian degradation e-mail. When sharing is
|
||||
// off the container is absent from the set, so a box that never enabled it stays quiet.
|
||||
// - the samba container is ADDED only when network sharing is switched on AND the household
|
||||
// password has been set (R-7b, tightened by R-77). Sharing is a customer-toggled feature, so it
|
||||
// can never appear in the golden controller.yaml — but once it is actually RUNNING, a dead
|
||||
// sharing service is exactly as customer-visible as a dead traefik and must raise the same
|
||||
// protected-container issue → alert → Hungarian degradation e-mail.
|
||||
//
|
||||
// The bring-up applies the same conditions (stacks.EnsureBaseStack for cloudflared, ensureSamba's
|
||||
// `if !smb.Enabled { return }` for samba), so detection and deployment agree in both directions.
|
||||
// THE COUPLING, and why it is spelled out: this set must mirror EVERY early return in
|
||||
// stacks.reconcileSambaAt, because that function decides whether the container exists at all. It has
|
||||
// TWO:
|
||||
//
|
||||
// if !smb.Enabled { return } // feature off
|
||||
// if !smb.UserSet { return } // on, but no household password yet → deliberately NOT deployed
|
||||
//
|
||||
// R-77 exists because this comment previously claimed "detection and deployment agree in both
|
||||
// directions" while citing only the first. The second was added later and never mirrored here, so
|
||||
// enabling sharing without setting a password made the box report health=fail forever for a state
|
||||
// the controller had deliberately chosen (observed live on demo-hp, 2026-07-26). A THIRD early
|
||||
// return in reconcileSambaAt would need the same mirror — and this comment must be updated with it,
|
||||
// because a comment asserting a guarantee the code no longer provides is how the bug came back.
|
||||
//
|
||||
// Deliberately NOT over-suppressed: sharing on WITH a password and a dead container still raises the
|
||||
// issue. That is the case the protected set exists for.
|
||||
//
|
||||
// NOTE: the entries are CONTAINER names (checkProtectedContainers docker-inspects them). For the
|
||||
// base stacks the container name happens to equal the stack name; for samba it does NOT — the stack
|
||||
@@ -272,7 +286,8 @@ func EffectiveProtected(cfg *config.Config, smb settings.SMBSettings) []string {
|
||||
}
|
||||
out = append(out, name)
|
||||
}
|
||||
if smb.Enabled {
|
||||
// Mirrors reconcileSambaAt's two early returns — see the coupling note above.
|
||||
if smb.Enabled && smb.UserSet {
|
||||
out = append(out, infra.SambaContainerName)
|
||||
}
|
||||
return out
|
||||
|
||||
Reference in New Issue
Block a user