R-1295 live on hub rc.1 (a fresh Tester4 install set up its whole-guest off-site tier; the box consumed the credential and made its first copy); R-1294 read: an honest plan the cap can never catch up with (D54); R-1291 design (08 §10, D53); design lines for R-1295, R-1285, R-1292, R-1294; R-1296 filed; STATUS.
gates / gates (push) Successful in 13m41s
gates / gates (push) Successful in 13m41s
This commit is contained in:
1 parent
ee38dee2c9
commit
232f42d21e
17 files changed
+138
-10
No files matched your search
@@ -391,6 +391,17 @@ the explicit Re-issue action") and the re-issue itself then refused with 400 —
|
||||
tier. **Not built:** releasing ONLY the token on host delete. The endpoint's only removal op
|
||||
(`deprovision`) destroys the backups too, so a token-only release needs a new endpoint operation.
|
||||
|
||||
**[DESIGN — R-1295, hub v0.172.0 (rc.1 deployed for the proof) + tenantsync v1.4.0 (committed, not on ep0)] A new
|
||||
token's self-check waits out PBS's permission cache, and a failure is never silent.** PBS's proxy caches permissions for
|
||||
up to 5 s and an ACL-only change does not clear that cache; a request from another client between the token create and
|
||||
its grant leaves the token refused (403) for up to ~5 s, and the script's one quick retry fell inside the window
|
||||
(Tester4, 2026-10-26: rolled back, the box got no whole-guest off-site tier, only a log line). Measured on a throwaway PBS
|
||||
4.2.5 under load: v1.3.0 failed 11 of 30, v1.4.0 0 of 30 (`audits/r1295-pbsdr-selfcheck-2026-10-26/`). The endpoint now
|
||||
re-checks the same token (and its own admin token) for up to 15 s; the hub repeats a `self_check_failed` rollback (3
|
||||
attempts, 7 s apart, a log line each) in the provision and the F-14 re-issue paths; a final failure of the WG hook raises
|
||||
the operator-only `pbsdr_provision_failed` („… save the customer config to retry"). Live 2026-10-26 on hub rc.1: a fresh
|
||||
Tester4 install provisioned the tier on the first try.
|
||||
|
||||
## 15. Customer e-mails — what the hub writes to a household [hub v0.118.0, R-558]
|
||||
|
||||
**The section this document did not have.** The hub composes every sentence a household reads before
|
||||
|
||||
@@ -255,6 +255,13 @@ the identity bundle's shape is `{tunnel_token, pbs_token, wg_private_key, restic
|
||||
|
||||
**[DESIGN] Off-site deletion custody (decisions 68–69, 2026-10-03) — BUILT hub v0.127.0 / controller v0.289.1, live on both demo boxes.** The restic repository password stays on the box only. The box's off-site key is append-only (pinned in `authorized_keys`, written by the hub — the key registrar); the box never receives the sub-account password, which the hub stores encrypted at rest. Old snapshots are pruned by the box itself, only in a weekly window the hub opens, behind a fake-snapshot guard (R-822); the window has run live on both demo boxes since 2026-10-05 (R-95, closed). The guard's residual — past-dated fakes steering the keeps, and a window check that trusts the box's own counts — is R-822 and R-895. **Hub v0.158.0 (built 2026-10-18; deployed the same day on the operator's yes — corrected 2026-10-24) adds the hub's own check:** the 07:10 key audit compares the repository's `snapshots/` listing, over the hub's own login, with yesterday's — files gone that no clean-up window explains raise `offsite_snapshots_vanished` (error), files no reported box run explains raise `offsite_snapshots_unexplained` (warning); both operator-only (R-895 slice 2). A Felhom-side pruner holding repository passwords is rejected.
|
||||
|
||||
**[FINDING — R-1294, 2026-10-26, read only; a rule change waits for the operator (STATUS D54)] A store that once goes
|
||||
over the window's cap never comes back by itself.** The cap is half the store (hub `offsitekeys.MaxRemove`); each refused
|
||||
window adds a week of snapshots and removes none, so the plan grows faster than the cap. demo-hp: one test day
|
||||
(2026-10-16, 152 snapshots) aged past 7 days and the 10-26 window refused 209 > 179 — an HONEST plan (every removal 7–30
|
||||
days old, every app keeps ≥ 9 or its last copies; `audits/r1294-offsite-cap-2026-10-26/`). The existing way out is the
|
||||
operator's one-shot raised cap (R-833, `GrantOffsiteWindowOnceMax`).
|
||||
|
||||
**[DESIGN, built hub 2026-10-07 — R-32 option A, `09` §3 decision 167] What RESET does to the household's off-site
|
||||
copy.** On the shared pool box a sub-account is a LOGIN, not the data: deleting it leaves its folder (measured
|
||||
2026-07-21: 1.4 GB in two `.orphaned-*` folders after a RESET), and a re-enabled customer lands on the same folder
|
||||
|
||||
@@ -596,7 +596,9 @@ normal use; work it does not explain is the sign of a hacked app. Numbers and me
|
||||
(`upwatch.line_test_holds`), then the apps; a record whose app was removed while held is dropped (it used to stop the
|
||||
50 % rule for good); qBittorrent's hold names its slot (`up_limit` / `alt_up_limit` through `app/preferences` —
|
||||
`transfer/uploadLimit` follows the CURRENT speed mode, measured on 5.2.4), so the household's switch to the
|
||||
alternative speed during the test never leaves 1 KiB/s behind. **[FACT]** the night's rig (BYO VM, agent 0.165.0,
|
||||
alternative speed during the test never leaves 1 KiB/s behind. **[DESIGN — R-1292, controller `2619191`, unreleased]:**
|
||||
the 50 % rule owns the NORMAL slot only (`up_limit` through `app/preferences`); the household's alternative limit is
|
||||
never read or written by it, and a mode switch never reads as „the household changed it". **[FACT]** the night's rig (BYO VM, agent 0.165.0,
|
||||
rc.1, two seeders to 9202's qBittorrent): with a mode switch mid-test both limits came back, the test refused
|
||||
(the switch let qBittorrent upload); without, both held (qBittorrent in its alternative slot), 94.8 Mbit/s measured,
|
||||
both limits back exactly (`audits/night-2026-10-25/rig/hold-watch*.txt`).
|
||||
@@ -607,3 +609,43 @@ normal use; work it does not explain is the sign of a hacked app. Numbers and me
|
||||
whatever the API says; not built. The box cannot tell LAN from internet bytes per app; a host-network container
|
||||
(Samba) has no counter; the push floor is a lower bound, the weekly test is close to the line.
|
||||
7. **Release:** released 2026-10-24 on the operator's yes (controller v0.342.0, hub v0.169.0; R-1244) — corrected 2026-10-24.
|
||||
|
||||
## 10. A held app the operator can see [DESIGN — proposed, R-1291, 2026-10-26; no code]
|
||||
|
||||
**Why.** A held app is stopped on purpose and stays stopped until a person acts — and today nobody is told after the
|
||||
first minute. demo-hp's Kimai sat held for 11 days (2026-10-14 → 10-26) and was found by accident (R-1286). The
|
||||
controller sends one event when the crash-loop guard stops an app (`app_stopped_unhealthy`); no other hold sends
|
||||
anything, and the hub has no held-app state at all. On a household box the same silence would hide a failed restore.
|
||||
|
||||
**The holds that exist** (controller `settings.RestoreHold.Reason`, the sentences of `holdWhy`, R-1286):
|
||||
|
||||
| Reason | What put it there | Who may clear it |
|
||||
|---|---|---|
|
||||
| `restore_failed` | a restore whose rollback also failed | **a person only** (R-379: support, `--clear-restore-hold`) |
|
||||
| `restore_mixed` | an off-site restore whose database replay failed | a person (the same) |
|
||||
| `update_failed` | a failed update | the household, by restoring the app from its backup |
|
||||
| `unhealthy_stop` | the crash-loop guard | the household's Start (one more try, `09` §3 decision 28) |
|
||||
| `put_back_pending` | a restore waiting for its pre-restore copy | nobody — it clears itself when the drive comes back |
|
||||
|
||||
**What the controller reports.** The legacy report is frozen (hub rule), so the event channel carries it:
|
||||
`app_held` when a hold is written (stack, reason, since — the hold's own `At`) and `app_hold_cleared` when it goes.
|
||||
Because an event can be lost, the controller re-sends `app_held` for every hold still in place **once a day**; the hub
|
||||
treats it as idempotent. Both types enter `allowedEventTypes` AND `customerMessages` (hu + en) in the same hub commit
|
||||
(the coupling rule); `app_held` is operator-only in v1.
|
||||
|
||||
**Where the hub shows it.** The host page (and the customer page) get a „Held apps" list: app, reason in one line
|
||||
(the `holdWhy` sentence), since, and who may clear it. Built from the open `app_held` events per customer and stack.
|
||||
|
||||
**When it mails.** One operator mail per hold after a grace that follows the reason: `put_back_pending` 6 hours (it
|
||||
should have cleared itself — if not, something is stuck); `restore_failed` / `restore_mixed` 1 day (only a person can
|
||||
act); `update_failed` and `unhealthy_stop` 3 days (the household can act first). Then one reminder a week while it
|
||||
lasts, through the dispatcher's existing per-type cooldown (§6.2). A cleared hold sends nothing.
|
||||
|
||||
**Who clears it.** Unchanged: R-379 holds only a person; the household's Start or restore for its own two. **The hub
|
||||
never clears a hold** — it only shows and reminds.
|
||||
|
||||
**Cost.** One controller release (the two events + the daily re-send, ~½ day with tests) and one hub release (allow-list,
|
||||
the i18n keys, the list on two pages, a reminder checker; ~1 day). No agent change.
|
||||
|
||||
**Open pick (STATUS D53):** v1 operator-only (CC's pick), or also mail the household for the two holds it can clear
|
||||
itself („press Start" / „restore from the backup")?
|
||||
@@ -84,6 +84,10 @@ boxes installed. Nobody keeps a hand-written list.
|
||||
one (R-1285). **[DESIGN — R-1285, agent `abcc1e6`, unreleased]:** right after every bundle install the agent asks the
|
||||
wrapper now on disk for a policy pass (`mode: "bundle-policy"`), which removes our appliance-only files from a BYO
|
||||
record (no signature: it only removes a file we wrote; a failing `sshd -t` puts it back).
|
||||
**[DESIGN — R-1285 follow-up, agent `b1bc63d`, unreleased]:** in the normal delivery the bundle job runs in the OLD
|
||||
process (measured on demo-hp 2026-10-26: the bundle 09:03:07–09:03:09, the restart into 0.166.0 at 09:03:10), so the
|
||||
new agent also runs the pass once right after its self-update commits (`selfupdate.Manager.SetOnCommitted`). Only a
|
||||
box coming from 0.164.0 can show it: 0.165.0's wrapper already applies D43 at plan time.
|
||||
- **The Proxmox MAJOR upgrade** (PVE 9 → 10). It is a later step of its own, drilled first (R-808 item 5).
|
||||
- **`cloudflared` and the other infrastructure images** (traefik, filebrowser). **[FACT] (C8)** They are containers in
|
||||
the guest, pinned in the controller (`internal/infra/infra.go:26`: `cloudflare/cloudflared:2026.6.0`, since
|
||||
|
||||
Reference in new issue
Block a user