v0.258.0: the last four Hungarian things an English household met
gates / gates (push) Successful in 24s

R-589 the update badge, R-590 the data-folder backup sentence, R-573 the two channel
banners, R-572 two dead helpers. All four were built in Go, which is why neither the
template parity fixtures nor TestI18nEnglishPages could see them; slice 5's LIVE proof
is what found them.

R-590 is the one that matters most: it is a promise about the customer's files. It
said, in Hungarian and under an already-English folder label, that a drop-zone is
temporary and unbacked. The test now asserts the CONSEQUENCE in both languages — and
that the two languages do not produce the same string, which would mean the English
fell back.

R-572 is not what its row said. The row claimed a template renders "vasárnap" on an
English page; measured, NO template and no Go file called pruneLabel or
nextPruneLabel. They were dead func-map entries returning Hungarian, so they are
deleted rather than translated — translating dead code would add machinery with no
reader and a test pinning a fiction. Deletion is fail-loud and that was proven: a
template naming the removed function panics loadTemplates at startup.

Five red-proofs. One of them says something about the gate rather than the code: the
Go-parity gate does not measure localeFuncs keys against the base capture, so the
citation to TestLocaleFuncsHungarianBundleMatchesFuncMap is what carries them — the
test was extended to make that citation true.

MinAgent: 0.131.0 (unchanged). Hungarian byte-identical.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-09-20 18:10:53 +02:00
parent ecefdf2dc5
commit 7c4a33b6d1
12 changed files with 425 additions and 74 deletions
+14 -7
View File
@@ -1325,7 +1325,7 @@ func main() {
}
sched.Every("hub-report", pushInterval, func(ctx context.Context) error {
r := report.BuildReport(cfg, *configPath, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths(), sett.GetGeoRestriction(), sett.GetSMBSettings(), logger)
r.Claimed = sett.GetClaimed() // v0.122.0 (F-4): set-only claim flag for the hub
r.Claimed = sett.GetClaimed() // v0.122.0 (F-4): set-only claim flag for the hub
r.Language = sett.GetLanguage() // v0.247.0 (i18n): the hub e-mails follow it (slice 3)
if err := hubPusher.Push(r); err != nil {
return err
@@ -1432,7 +1432,7 @@ func main() {
if hubPusher != nil {
if cfg.Hub.Enabled {
r := report.BuildReport(cfg, *configPath, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths(), sett.GetGeoRestriction(), sett.GetSMBSettings(), logger)
r.Claimed = sett.GetClaimed() // v0.122.0 (F-4): set-only claim flag for the hub
r.Claimed = sett.GetClaimed() // v0.122.0 (F-4): set-only claim flag for the hub
r.Language = sett.GetLanguage() // v0.247.0 (i18n): the hub e-mails follow it (slice 3)
var pushErr error
for attempt := 1; attempt <= 3; attempt++ {
@@ -1515,7 +1515,7 @@ func main() {
if hubPusher != nil && cfg.Hub.Enabled {
fireReport := func() error {
rep := report.BuildReport(cfg, *configPath, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths(), sett.GetGeoRestriction(), sett.GetSMBSettings(), logger)
rep.Claimed = sett.GetClaimed() // v0.122.0 (F-4): set-only claim flag for the hub
rep.Claimed = sett.GetClaimed() // v0.122.0 (F-4): set-only claim flag for the hub
rep.Language = sett.GetLanguage() // v0.247.0 (i18n): the hub e-mails follow it (slice 3)
return hubPusher.Push(rep)
}
@@ -1708,7 +1708,7 @@ func main() {
// Startup-only is sufficient and correct: both files are read at boot and neither changes under a
// running controller, so a periodic re-check would add noise without adding signal.
if d := bootstrap.DetectEndpointDrift(*configPath, cfg, logger); d != nil {
alertMgr.SetEndpointDriftAlert(true, d.HungarianMessage())
alertMgr.SetEndpointDriftAlert(true, "alert.endpoint_drift", d.HungarianMessage())
if notifier != nil {
notifier.NotifyEndpointDrift(d.EnglishMessage(), d.FingerprintAgrees)
}
@@ -1720,7 +1720,7 @@ func main() {
if hubPusher != nil {
dc.TriggerHubReportPush = func() error {
r := report.BuildReport(cfg, *configPath, stackMgr, backupMgr, cpuCollector, metricsStore, Version, sett.GetStoragePaths(), sett.GetGeoRestriction(), sett.GetSMBSettings(), logger)
r.Claimed = sett.GetClaimed() // v0.122.0 (F-4): set-only claim flag for the hub
r.Claimed = sett.GetClaimed() // v0.122.0 (F-4): set-only claim flag for the hub
r.Language = sett.GetLanguage() // v0.247.0 (i18n): the hub e-mails follow it (slice 3)
return hubPusher.Push(r)
}
@@ -3135,8 +3135,15 @@ type channelSink struct {
alertMgr *web.AlertManager
}
func (s channelSink) SetDashboard(down bool, _ channelhealth.Reason, msg string) {
s.alertMgr.SetAgentChannelAlert(down, msg)
// R-573: the checker already CLASSIFIES the fault, so the banner is keyed by that classification
// rather than by the sentence it happened to compose. An unmapped reason passes an empty key and the
// AlertManager falls back to the composed sentence — never a blank banner.
func (s channelSink) SetDashboard(down bool, reason channelhealth.Reason, msg string) {
key := ""
if down && reason != "" {
key = "alert.agent_channel." + string(reason)
}
s.alertMgr.SetAgentChannelAlert(down, key, msg)
}
func (s channelSink) NotifyDown(reason channelhealth.Reason, eventType, severity, msg string) {
s.notifier.NotifyAgentChannelDown(string(reason), eventType, severity, msg)