R-518: a press with the local storage absent backs up nothing (never the off-site tier as a stand-in); an agent that flags no primary keeps the first tier

09 §3 decision 156 says the button makes the local copy only.
Test: TestManualRunTiers_NoPrimaryAvailable_BacksUpNothing (red-proved on the previous version).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-06 15:09:37 +02:00
parent d720495cd5
commit 9d2d62831a
2 changed files with 48 additions and 10 deletions
+32 -6
View File
@@ -453,24 +453,50 @@ func (l *Loop) quiesceAndPoll(ctx context.Context) error {
// `09` §3 decision 156 (R-518 option A): the press makes the local copy with one short stop; the
// off-site tier follows at the next scheduled night run. Pinned by TestManualPress_RunsOnlyLocalTier.
//
// The primary is the tier the agent FLAGS Primary — not the first in the list. If no kept tier carries
// the flag (the primary's storage reported absent, or an agent that flags none), the first kept tier is
// backed up rather than nothing: a press that silently backs up nothing would be the applied-and-empty
// fault in a different costume.
// The primary is the tier the agent FLAGS Primary — not the first in the list. If the agent flags a primary
// but its storage is reported absent, the press backs up NOTHING and says so at ERROR: the ruling is „the
// local copy only", so the off-site tier is not a stand-in (it still runs at night), and no app is stopped
// (an empty window returns before the stop). Pinned by TestManualRunTiers_NoPrimaryAvailable_BacksUpNothing.
// An agent that flags NO tier primary at all (none advertised it) keeps the old order: the first tier.
func (l *Loop) manualRunTiers(ctx context.Context) []dueTier {
all := l.allTiersForManualRun(ctx)
if len(all) <= 1 {
if len(all) == 0 {
return all
}
if len(all) == 1 && all[0].target == "" {
return all // a pre-R-82 agent: the single untargeted tier
}
for _, t := range all {
if t.primary {
return []dueTier{t}
}
}
l.logger.Printf("[WARN] [quiesce] manual run: no available tier is flagged primary — backing up tier %s (the first available)", tierLabel(all[0].target))
if l.primaryAdvertised(ctx) {
l.logger.Printf("[ERROR] [quiesce] manual run: the local copy's storage is not available — nothing backed up now; the off-site copy follows at the night run (`09` §3 decision 156)")
return nil
}
l.logger.Printf("[WARN] [quiesce] manual run: the agent flags no tier as the local one — backing up tier %s (the first available)", tierLabel(all[0].target))
return all[:1]
}
// primaryAdvertised reports whether the agent flags ANY tier primary, its storage absent or not.
func (l *Loop) primaryAdvertised(ctx context.Context) bool {
tb, ok := l.backend.(TieredBackend)
if !ok {
return false
}
tiers, err := tb.Tiers(ctx)
if err != nil {
return false
}
for _, t := range tiers {
if t.Primary {
return true
}
}
return false
}
// allTiersForManualRun lists every tier the agent can back up now: all advertised tiers whose storage
// is not absent on an R-82 agent, or the single untargeted tier otherwise. manualRunTiers picks the
// primary from it.