v0.246.0: an interrupted restore is told; the recovery-code reminder waits until the box can take it
gates / gates (push) Successful in 15s

MinAgent: 0.131.0 (unchanged). Requires hub v0.117.0 for restore_interrupted.

R-550 (operator ruling: fix). A design reversed and recorded: the restore
op-status was in memory by choice. Now restore-status.json in DataDir, written
atomically at both ends of an op. At startup a record still marked running
becomes a failed, interrupted result kept per app until that app's next
restore, shown on /backups/restore and the off-site wizard, and raised once as
restore_interrupted. Cooldowns stay in memory.

R-546. The R-543 reminder bar consults the agent's own preflight ok (every
blocking item, not a copy of pbs_storage_id), cached 60 s, probed only while
paused. /backup/escrow shows a waiting card that polls and reloads instead of
red crosses and English diagnostics. POST /api/escrow/start refuses 409 before
staging or starting - the direct path chaos night used. Unknown readiness keeps
the bar.

Red-proofs (each seen failing): restore record across restart; main() calls
both startup functions; startup helper with loading skipped; restore page card;
bar held back; waiting card; start refusal. go build/vet/test ./... green, 28
packages; controller_gates --fast all OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-09-17 10:45:29 +02:00
parent 714d5bce09
commit 0fe315b759
21 changed files with 788 additions and 10 deletions
@@ -13,7 +13,27 @@
<span class="domain-badge">{{.Domain}}</span>
</div>
{{if not .AgentSupported}}
{{if .EscrowNotReady}}
<!-- R-546: the box cannot run the ceremony yet (the agent's own preflight is not ok — typically the
first minutes after a bind, before the PBS storage is applied). No checklist of red crosses, no
start form that would refuse, none of the agent's raw diagnostics: one sentence, and the page
polls and reloads itself when the agent says ready. -->
<div class="settings-card" id="escrow-not-ready">
<div class="alert alert-info">{{.EscrowNotReadyMessage}}</div>
<p class="form-hint">Ehhez nem kell semmit tenned. Ha fél óra múlva is ezt látod, szólj az üzemeltetőnek.</p>
</div>
<script>
(function(){
function check(){
fetch('/api/escrow/preflight',{headers:{'Accept':'application/json'}})
.then(function(r){ return r.json(); })
.then(function(j){ if(j && j.data && j.data.ok){ window.location.reload(); } })
.catch(function(){});
}
setInterval(check, 20000);
})();
</script>
{{else if not .AgentSupported}}
<div class="alert alert-info">A funkcióhoz az ügynök frissítése szükséges — a frissítés automatikusan megérkezik. Próbálja újra később.</div>
{{else}}