feat(shares): R-7b Part 3 — offsite shares leg (Model B') + B' isolation proof

ONE additional restic call tagged [felhom-offbox, _shares] carrying the payload
staging dir + every mandatory share folder. Hooked into runOffboxInternal AFTER the
per-app loop and BEFORE retention, so forget --group-by host,tags covers the _shares
group with no flag change. Reuses resticStep, the caller's repo-ensure and
single-flight, and the SAME enlargement-gate arithmetic.

- quota gate degrades the push to MANIFEST-ONLY, never to nothing
- EnlargedBlocked keeps the RAW _shares key (templates index by it); the display
  mapping applies only at the notification + Hungarian-prose boundaries
- OffboxTarget gains SharesLastRun/Status/Count for per-tier page truth
- zero-toggle notice suppressed when the shares leg provided coverage
- reserved-name defense: an app keyed _shares is excluded from the run loudly

RED-PROOFS RUN AND REVERTED (all fired):
  1. shares leg appends into the app's argv -> isolation test FAILS
  2. mandatory->offsite mapping inverted    -> Scenario A + B FAIL
  3. manifest-only degradation dropped      -> Scenario C FAILS
This commit is contained in:
2026-07-18 12:51:46 +02:00
parent c81df55dcb
commit 85b76e0fc3
5 changed files with 522 additions and 4 deletions
+8
View File
@@ -165,6 +165,14 @@ type OffboxTarget struct {
// OK run (sorted; empty clears). Drives the per-app "config+DB only" note on /backups/remote and
// the edge-triggered enlarge-blocked notification. Not a secret (app-name list).
EnlargedBlocked []string `json:"enlarged_blocked,omitempty"`
// Shares offsite leg status (R-7b). The offsite run gained a SIBLING shares source that pushes the
// „Felhőmentés"-marked SMB shares plus the share-definition manifest under the reserved `_shares`
// tag. These three fields let the „Megosztás" page state per-tier truth instead of inferring it
// from the app-wide LastStatus. SharesLastCount is the number of share folders in the push (0 = a
// definitions-only push, e.g. quota-degraded or no share is marked for the cloud). Not secrets.
SharesLastRun string `json:"shares_last_run,omitempty"` // RFC3339
SharesLastStatus string `json:"shares_last_status,omitempty"` // "ok" | "error" | "blocked" | "skipped"
SharesLastCount int `json:"shares_last_count,omitempty"`
// EscrowState (fork-4) gates offsite RUNS on the repo password being escrowed under R: ""|"pending"
// |"escrowed". Enabling offsite stages the password to the agent and sets "pending"; no offsite run
// proceeds until an operator confirms the escrow ceremony ("escrowed") — so no un-recoverable