docs: R-181 closed, R-156 closed, R-110 + R-115 rulings recorded, R-182 filed
gates / gates (push) Successful in 7s

R-181 CLOSED (controller v0.193.0 + v0.193.1) and proven live on demo-hp for
BOTH reserve terms. The reserve is now a per-app, per-run ADMISSION decision
taken before the app's first write and covering all three write legs, and it
gained a size term. The refusal's wording was not weakened; the behaviour moved
so it became true, verified by sha256 tree fingerprint.

R-156 CLOSED — papra's template mounts the app's own data root. Precondition
re-measured rather than inherited (both boxes were wiped today).

Part 4, documentation only, nothing built:
- R-110 WAITING-ON-OPERATOR -> READY. Ruling: option (b), the installer's
  publish channel moves to a TAG. Recorded with the condition that decides
  whether it works at all — it must cover BOTH the /scripts/ git-sync and the
  nine files the installer fetches from raw/branch/main.
- R-115 WAITING-ON-OPERATOR -> READY. Ruling: mechanism (b), a build-side gate
  refusing to deploy or vouch an unpublished version. The third instance (agent
  v0.120.0) would have silently downgraded both demo boxes while succeeding.

R-182 NEW: the periodic status refresh has no admission scope, so a refused app
re-alerts on every poll (measured: a second alert pair 13s after the run's).
Pre-existing in v0.192.0; deliberately not fixed in the R-181 task.

capability map: the local-backup row moves to PROVEN-LIVE in BOTH halves.
ROADMAP: R-165 collapses to CLOSED; R-181 collapsed into it.
07-backup-architecture.md: the reserve's contract stated as what the code
provides (S-1 — an architectural contract changed in the same session).
STATUS.md trimmed 150 -> 111 lines, "What's broken" no longer holds shipped
work, and the stale "After:" line (pointing at work that shipped on 2 August)
is fixed.
This commit is contained in:
2026-08-03 11:36:16 +02:00
parent 06cbf8df29
commit fb652024ea
7 changed files with 324 additions and 449 deletions
+53 -92
View File
@@ -27,107 +27,74 @@ time, and an app switched off deliberately stayed off every time.
also delete it. A daily snapshot is armed as a stopgap, and we have never restored from that copy.
*(R-95, R-87)*
**Three apps out of fifty-three kept their data where backups never looked.** They reported healthy;
the data would vanish on the next update. Two are fixed, the third is now clear to fix because it is
installed nowhere. *(R-156)*
**A full disk emails you repeatedly instead of once.** When the reserve refuses an app's backup you
are told once by the backup run — correctly — but the page showing backup status re-checks on a timer
and sends the same message again each time. Not new: as old as the reserve itself, and seen only
because we watched the alerts closely while proving the fix below. Harmless if the hub already
collapses repeats — which a comment claims and nobody has checked. *(R-182)*
**The reserve does not guard the step that actually fills the disk.** The rule that refuses a backup
when space runs low is checked at the wrong moment: the big write happens first, unchecked, and only
the small write after it is refused. So the thing meant to stop a runaway backup is the thing it
runs past. Worse, when it does refuse it says *"your last good copy is untouched"* — and we measured
that copy being overwritten by the earlier step anyway. Found by deliberately filling a rebuilt demo
machine. Nothing was deleted and you were emailed, both correctly. *(R-181)*
## What shipped recently
**When that happens, only one page says so** — no email, no alert. The page that answers "is this app
backed up?" is the one that stays silent. *(R-158)*
**The backup partition is gone, and both demo machines run on the new shape.** Wiped and rebuilt on
3 August and taken through the whole customer journey — set up, install an app, back it up, restore
it. One storage area instead of two; the space a backup can use went from 19 GB to 65 GB on the small
machine and 45 GB to 233 GB on the big one. Three reboots each, correct every time. The two were
rebuilt deliberately differently — one from a local copy of the image, one by the ordinary customer
route with the published fingerprint checked — so the disk shape and the delivery route are both
proven, rather than one proven twice. Their previous demo apps and data are gone; that was the point
of a wipe, and you approved it. *(R-165, R-178)*
**The checks now have two nets, and the second one emails you.** Every repository has one command
that runs all of its checks; it runs by itself before every push and refuses a push that fails. That
one lives on the workstation and can be skipped. So the build server now runs the same checks again,
on a machine that does not care who pushed or what they typed — and **when they fail it sends you an
email**, because a red mark on a page nobody watches is not a warning. Proven with a real broken
change, not assumed. The one thing it still cannot do is *stop* the change: every change here goes
straight to the main copy with no review step, so there is no point in the road for it to stand at.
It notices, quickly, and tells you. *(R-29, R-161, R-168, R-169)*
**What replaced the wall — and it now watches the right moment.** The wall was quietly doing a second
job: keeping a runaway backup from eating the space the machine needs to keep running. That job is now
explicit, and as first built it was checked too late — the big write happened first, unchecked, and
only the small write after it was refused, while the message still promised your last good copy was
untouched. **Fixed and proven on 3 August.** The machine now decides once, per app, **before it writes
anything at all**, and that one answer covers all three steps: a refused app writes nothing, is not
restarted, and the promise is now literally true — checked by fingerprinting every file before and
after. It also stopped being blind to size, so an app is no longer waved through at 96% full and then
allowed to write two gigabytes. Proven by deliberately filling a demo machine, once for each way it
can refuse. Nothing is ever deleted to make room: every app has only one local copy, so "delete the
oldest" would always mean destroying some other app's only copy. *(R-181)*
**A filling disk now warns the customer before anything breaks, and a failed backup now reaches you.**
Until today the first sign that a disk was filling up was a backup that did not happen — nothing said
anything beforehand. Two things changed. The customer is now warned while there is still room to act,
naming the drive and how much space is left, in plain Hungarian that says what to do about it. And
when one app's backup fails for any reason, **you** are told which app and why, with the disk figures
attached — the page that answers "is this app backed up?" was, until now, the one page that never
said. The customer is deliberately *not* told about that second one: they can free up space, but they
can do nothing about a backup that failed, so telling them would only alarm them.
**The last of the three apps that never saved their data is fixed.** Installed nowhere, so nothing was
stranded — checked on both demo machines and in the fleet list rather than assumed. Proven by the check
that caught it, run in both directions: it clears the fixed version and still convicts the old one.
*(R-156)*
Both were proven on the demo machine by actually filling a disk. One detail is worth knowing because
it is why there are two rules and not one: the serious warning fired when free space dropped below a
fixed amount while the disk was only 91% full — a percentage on its own would have missed it.
**A filling disk warns the customer before anything breaks, and a failed backup reaches you** — the
customer while there is still room to act, naming the drive and the space left; you when one app's
backup fails, with the disk figures. The customer is deliberately not told about the second: they can
free space, but they can do nothing about a failed backup. Both proven by filling a real disk. There
are two rules and not one because the serious warning fired on free space while the disk was only 91%
full — a percentage alone would have missed it. *(R-167, R-158)*
**These went in *before* the partition change deliberately.** The partition being removed is also a
barrier against a runaway backup filling the space the machine needs to run; putting the warnings in
first means that when it comes down, the thing watching is already working and already tested.
*(R-167, R-158)*
**The backup partition is gone — and both demo machines now run on the new shape.** Each was wiped
and rebuilt from the new base image on 3 August and taken through the whole journey a customer takes:
set the machine up, install an app, back it up, restore it. One storage area instead of two, and the
space a backup can use went from 19 GB to 65 GB on the small machine and from 45 GB to 233 GB on the
big one. The wall does not move; it stops existing. Each machine was rebooted three times over and
came back correctly every time. **The two machines were rebuilt deliberately differently** — the
first from a copy of the image held locally, the second by the ordinary route a real customer takes,
fetching the image and checking it against the fingerprint we publish, so both the disk shape and the
delivery route are now proven rather than one twice.
**Their previous demo apps and data are gone.** That was the point of a wipe and you approved it; the
machines now carry a couple of small test apps instead.
**What replaced the wall.** It was quietly doing a second job — keeping a runaway backup from eating
the space the machine needs to keep running. That job is now explicit: if a backup would push the disk
below a safe reserve, **that one app's backup is refused, its last good copy is left exactly as it
was, and you are told.** Nothing is ever deleted to make room; every app has only one local copy, so
"delete the oldest" would always mean destroying some other app's only copy.
**How the shape was chosen — worth one line, because it was not the obvious one.** Three ways of doing
it were built and rebooted rather than argued about. All three worked. They differed in what they
quietly broke: one put your backups inside Docker's own storage, where the normal way of fixing a sick
Docker would wipe them; another exposed all of Docker's internals to the part of the system that
manages your drives. The third does neither, and costs one extra line of configuration.
**The new base image is now switched on**, so any machine installed from here on gets the new shape.
The tester's box is untouched and keeps working exactly as before; it gets the new shape whenever it
is reinstalled. *(R-165, R-178)*
**The checks have two nets and the second emails you.** Every repository has one command that runs all
its checks, before every push. That one can be skipped, so the build server runs them again and emails
you on failure. It cannot *stop* a change — everything goes straight to the main copy with no review
step — but it notices quickly and tells you. *(R-29, R-161, R-168, R-169)*
## What we're working on
- **Now:** the last app whose data was never saved; today's decisions written down.
- **Next:** fixing the reserve so it guards the step that fills the disk, and stopping it from
claiming your last good copy is untouched when it is not *(R-181)*. The partition merge itself is
done and proven on both machines.
- **After:** rebuilding how the machine records whether an app is meant to be running.
- **Now:** both of today's items are done — the reserve and the last unsaved app. Your two decisions
are written down and are ours to build.
- **Next:** building those two — moving the installer onto a labelled version so publishing is one
step you can undo, and a check that refuses to install a version nobody can download *(R-110, R-115)*.
- **After:** the off-site copy that the machine making it can still erase *(R-95, R-87)*.
## Waiting on you
- **How a new version reaches a machine — and it has now been forgotten a third time.** Pushing the
installer publishes it: half a minute later every new machine downloads it, with no staging and no
way back but another push. And publishing is a step we remember rather than one the release
performs. On 3 August the new agent — the half of the partition merge that runs on the machine —
turned out to have been built and installed on both demo machines but **never published**, so a
rebuild would have quietly put the *old* one back and proved a version nobody ships. Caught before
the wipe and fixed in ten minutes, but only because someone happened to look. Nothing is installing
today, so this is the cheapest moment to settle it. *(R-110, R-115)*
- **A job, not a decision: the hub password needs changing.** A diagnostic command printed it into a
session log; nothing suggests anyone else saw it. *(R-132)*
- **Nothing on the partition merge itself** — the shape is chosen, built, and now proven on both demo
machines. The tester's box needs no conversion: it will simply be reinstalled. What is left is the
reserve defect above, which is ours to fix, not yours to decide. *(R-165, R-181)*
- **Nothing else.** You settled both open questions on 3 August — the installer moves onto a labelled
version, and a check will refuse to install a version nobody can download. Both are written down and
are ours to build. *(R-110, R-115)*
## Changed since last update
- **2026-08-03** — Both demo machines wiped and rebuilt from the new base image, and taken through
set-up → install an app → back it up → restore it. The backup space ceiling is gone and measured.
The hard stop that replaced the old partition was fired for the first time on real hardware — it
refused, it deleted nothing, it emailed you, **and it turned out to be watching the wrong step**;
that is now the top thing to fix.
- **2026-08-03** — The reserve now guards the step that fills the disk, and its promise is true; the
last app whose data was never saved is fixed. Both proven on a demo machine, not just in tests.
Earlier the same day: both demo machines wiped and rebuilt from the new base image and taken through
set-up → install an app → back it up → restore it, with the backup space ceiling gone and measured.
- **2026-08-02** — The false "host offline" warning is fixed. The hub's database was supposed to be in
a mode where reading a page cannot block a machine's status update; a one-word difference meant that
@@ -140,11 +107,5 @@ is reinstalled. *(R-165, R-178)*
and fixed the same day.
- **2026-08-02** — Thirteen mechanical checks had built up and nothing ran most of them; two were
failing quietly. Fixed, and the arrangement that replaced them is described above.
- **2026-08-02** — Decided: the 20 GB backup partition goes away and shares space with app data. That
changes the disk layout, so it happens before any machine is installed outside the house. **Measured
since:** no machine outside the house is registered yet, so this is as cheap now as it will ever be;
and the two demo machines can simply be reinstalled rather than converted.
- **2026-08-02** — Decided: only this machine and the tester's box are protected; every other box,
demo boxes included, may be broken or reinstalled freely. Two of the three apps that never saved
their data are fixed; this page created.
failing quietly. Fixed. Decided the same day: the 20 GB backup partition goes away; and only this
machine and the tester's box are protected, every other box may be broken or reinstalled freely.