docs: R-181 closed, R-156 closed, R-110 + R-115 rulings recorded, R-182 filed
gates / gates (push) Successful in 7s
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:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user