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:
@@ -566,17 +566,40 @@ mismatch table above (`mp0` 50 G vs `mp1` 20 G) describes what a merged box no l
|
||||
before provision grew them). **Read it as a function of `mp1`, and only for a box still on the split
|
||||
layout.** Measured: `audits/SPIKE-r165-mp1-merge-2026-08-02.md` M1.
|
||||
|
||||
**What replaced the partition's second job.** `mp1` was also a BULKHEAD: an overflow was refused per
|
||||
app with the last good unit byte-identical, and it **could not reach `/var/lib/docker`**, because that
|
||||
was a different filesystem. On a merged box it can. Decision **B2**, shipped in controller
|
||||
**v0.192.0**, is that bulkhead made deliberate — a two-term capture floor (97% used or 1 GiB free) in
|
||||
**What replaced the partition's second job — the reserve.** `mp1` was also a BULKHEAD: an overflow was
|
||||
refused per app with the last good unit byte-identical, and it **could not reach `/var/lib/docker`**,
|
||||
because that was a different filesystem. On a merged box it can. Decision **B2**, shipped in controller
|
||||
**v0.192.0**, is that bulkhead made deliberate — a two-term reserve (97% used or 1 GiB free) in
|
||||
`internal/fillwatch`'s shape, sitting beyond its critical band so the customer is always warned first.
|
||||
It **refuses per app and never deletes**: nothing on this filesystem is generational, so pruning could
|
||||
only destroy a different app's only local copy.
|
||||
|
||||
**Status caveat, deliberately explicit:** as of 2026-08-03 **no box has been reinstalled from the
|
||||
merged golden** (R-178), so every box in the field is still on the split layout and everything above
|
||||
still describes them exactly. This subsection describes what a box built from golden ≥ 0.192.0 gets.
|
||||
**THE CONTRACT, stated as what the code provides (controller v0.193.0, R-181).** The reserve is a
|
||||
**per-app, per-run ADMISSION decision, not a capture check.** It is taken once for an app, immediately
|
||||
before that app's FIRST write of the run, and it covers **all three write legs — the database dump, the
|
||||
volume dump and the recovery-unit capture**. Those three write under one per-app root
|
||||
(`backups/primary/<app>`), which is what makes one verdict able to cover them honestly.
|
||||
|
||||
- **What it guarantees.** A refused app has **nothing written for it in that run**, its previous unit
|
||||
is **byte-identical**, it is **not stopped**, nothing anywhere is deleted, and the operator gets
|
||||
**exactly one** alert naming the app, the term that bound and the disk figures.
|
||||
- **Two terms, two questions.** *Headroom*: is the filesystem already below the reserve? *Size*: would
|
||||
THIS app's write take it below? The size estimate is the app's previous `.sql` + `.tar` on disk;
|
||||
with no history the decision degrades to headroom alone, deliberately — otherwise the first backup
|
||||
is the one that can never happen.
|
||||
- **Why it is decided lazily and not once per run.** Space changes during a run: app A's dump can put
|
||||
app B under the reserve, so a verdict taken at run start reads a disk that no longer exists.
|
||||
- **Why it is never re-decided between an app's own legs.** That is precisely the shape v0.192.0 had —
|
||||
the two dump legs unguarded and only the capture refused — under which the reserve was consumed by
|
||||
the very write it exists to bound, and the refusal's *"the previous unit is untouched"* was measured
|
||||
false. Proven live on demo-hp 2026-08-03 (R-181), fixed the same day, and re-proven by filling the
|
||||
box for each of the two terms.
|
||||
- **It sits ahead of `DumpAppVolumesSafe`**, which stops the stack as its first act — a refusal
|
||||
decided inside it would already have bounced the app it is refusing to back up.
|
||||
|
||||
**Status caveat, deliberately explicit:** every box in the field that has not been reinstalled is still
|
||||
on the split layout and everything above still describes them exactly. This subsection describes what a
|
||||
box built from golden ≥ 0.192.0 gets. Both demo boxes were reinstalled from it on 2026-08-03 (R-178).
|
||||
|
||||
Two things are deliberately **not** recorded here. **The sizing ratio is the operator's ruling**
|
||||
(**R-163**) — this section states the constraint, not a number. And **the same-device placement is
|
||||
|
||||
Reference in New Issue
Block a user