docs: R-204 item 4 (box half) — CONTEXT + REPORT (controller v0.199.0)
gates / gates (push) Successful in 10s
gates / gates (push) Successful in 10s
This commit is contained in:
+34
-1
@@ -7,7 +7,40 @@
|
|||||||
>
|
>
|
||||||
> Ask Claude Code: "Please update CONTEXT.md with what we did today"
|
> Ask Claude Code: "Please update CONTEXT.md with what we did today"
|
||||||
|
|
||||||
Last updated: 2026-08-05 (v0.198.0 — R-204 items 1 & 3: the reset code and the restore scope)
|
Last updated: 2026-08-05 (v0.199.0 — R-204 item 4: a rebuilt box declares it needs a credential)
|
||||||
|
|
||||||
|
> **2026-08-05 — v0.199.0 (R-204 item 4 / R-193).** The last of the four manual interventions the
|
||||||
|
> 2026-08-04 drill needed. **Operator ruling: automate it, and the trigger is a state the BOX
|
||||||
|
> DECLARES.** From the hub an absent off-site object has FOUR meanings — never configured,
|
||||||
|
> mid-restart, a transient config read failure, rebuilt-and-stranded — and the hub cannot tell them
|
||||||
|
> apart. The box can.
|
||||||
|
>
|
||||||
|
> **The declaration needs BOTH halves** (`backup.needsOffsiteCredential`): a fresh data area (no
|
||||||
|
> repository password) AND a hub-held recovery package (the ACK's `identity_blob_present`). Freshness
|
||||||
|
> alone is a box that never had off-site backups; dropping that condition makes the whole fleet ask
|
||||||
|
> for credentials, which is what `TestOffsiteDeclare_NeverHadOffsiteSaysNothing` catches. A merely
|
||||||
|
> DISABLED target is the customer's own choice and never declares.
|
||||||
|
>
|
||||||
|
> **The ACK field stopped being discarded.** `EscrowAutoConfirmer.Reconcile` returns early when the box
|
||||||
|
> is neither pending nor escrowed — exactly a rebuilt box — so the fact was thrown away every cycle. It
|
||||||
|
> is recorded FIRST, before every gate, via `RecordPresence`, wired in main.go and asserted by
|
||||||
|
> `TestMainWiresRecordPresence` (AST, comments dropped). Last-write-wins, not set-only, so a customer
|
||||||
|
> RESET turns the declaration back off; a nil ACK escrow records nothing.
|
||||||
|
>
|
||||||
|
> **Inert to every existing reader:** `enabled:false` + zero sizes, so the hub's `isStale` and
|
||||||
|
> `fillBand` both short-circuit; an unknown `state` string is ignored by encoding/json. **A configured
|
||||||
|
> box's report JSON is byte-identical to v0.198.0's.** The one reader that would have misread it is the
|
||||||
|
> hub's `reportHasOffsite`, tightened in hub v0.96.0 to require `enabled:true`.
|
||||||
|
>
|
||||||
|
> *Live:* both demo boxes now record `hub_escrow_identity_present=true` in settings.json (the recorder
|
||||||
|
> working on a HEALTHY box). demo-felhom 9201, arranged reversibly into the stranded shape, produced
|
||||||
|
> report id=16743 carrying `{enabled:false, state:needs_credential, quota_gb:0, repo_size_bytes:0}`;
|
||||||
|
> the single declaration was absorbed by the hub's debounce (no self-heal event) and the box was
|
||||||
|
> restored the same minute. **The hub half is felhom.eu v0.96.0.**
|
||||||
|
>
|
||||||
|
> *Rider:* `.githooks/pre-push` in all four repos now refuses a push from a clone outside
|
||||||
|
> `/mnt/5_hdd/felhom.eu`. Proven both ways against a scratch clone.
|
||||||
|
|
||||||
|
|
||||||
> **2026-08-05 — v0.198.0 (R-204 items 1 & 3).** The 2026-08-04 drill (R-201) passed only because a
|
> **2026-08-05 — v0.198.0 (R-204 items 1 & 3).** The 2026-08-04 drill (R-201) passed only because a
|
||||||
> person was there; four manual interventions stood between a recovered key and a restored file. Two
|
> person was there; four manual interventions stood between a recovered key and a restored file. Two
|
||||||
|
|||||||
@@ -1,158 +1,95 @@
|
|||||||
# REPORT — R-204 items 1 & 3 (controller v0.198.0), 2026-08-05
|
# REPORT — R-204 item 4 (controller v0.199.0), 2026-08-05
|
||||||
|
|
||||||
**Two of the four steps a customer would have hit alone.** The 2026-08-04 R-201 drill passed and only
|
**A rebuilt box declares that it needs a credential.** The box half of the last manual intervention
|
||||||
passed because a person was there. Items 1 and 3 are this repo's; item 2 is the hub's
|
the 2026-08-04 drill needed. Hub half: `felhom.eu` v0.96.0, reported in that repo's
|
||||||
(felhom.eu v0.95.0); item 4 remains open (R-193).
|
`REPORT-r204-item4.md`.
|
||||||
|
|
||||||
## 1. Baselines, re-read on arrival
|
## 1. Baselines
|
||||||
|
|
||||||
| Repo | Expected | Found |
|
`felhom-controller` at `68f195676b91` / v0.198.0 — **exact match**, tree clean, `HEAD == origin/main`.
|
||||||
|---|---|---|
|
§4's landmarks held: `backup.OffboxReportStatus` returned `nil` when no target existed (the ambiguity),
|
||||||
| `felhom-controller` | `f4796e0d00e9` / v0.197.0 | **exact match**, tree clean, `HEAD == origin/main` |
|
and the ACK's `escrow` object was discarded on an unconfigured box because
|
||||||
|
`EscrowAutoConfirmer.Reconcile` returns early when the box is neither pending nor escrowed.
|
||||||
|
|
||||||
§3.1's landmarks held: `claim.go:46` `effectiveClaimCode`, and the `--print-reset-code` block in
|
**Register drift worth flagging:** the task states R-204 is the highest ID in use. It is **R-211**;
|
||||||
`cmd/controller/main.go` loading its OWN `settings.Load` from `cfg.Paths.DataDir+"/settings.json"` —
|
grepped before minting, and the hub session mints R-212.
|
||||||
the separate-process seam the whole item turns on. §3.3's held: `mode` defaulted to `"unit"`, and the
|
|
||||||
`full` path was two-step and size-gated.
|
|
||||||
|
|
||||||
**One drift, in the sibling repo:** §3.2 described `offsite.go:222-231` carrying a known-consequence
|
## 2. What changed
|
||||||
comment. That comment had already been rewritten (the R-196 comment-correction commit) and now gave a
|
|
||||||
*non-false* ground for the mark — the guest-rebuild shape. That made Scenario D the crux rather than a
|
|
||||||
formality; see the hub's REPORT.
|
|
||||||
|
|
||||||
## 2. Per-item outcome
|
**The ACK field stopped being discarded.** `RecordPresence` is called FIRST in `Reconcile`, before
|
||||||
|
every gate. It lives in the auto-confirmer because that is already the one place the ACK escrow object
|
||||||
|
arrives and is already wired — a second consumer would be a second wiring point, and this project's
|
||||||
|
built-but-never-wired count is six. Last-write-wins, not set-only, so a customer RESET turns the
|
||||||
|
declaration back off; a nil ACK escrow records nothing (absence of a statement is not a statement of
|
||||||
|
absence); a record failure is logged and does not block the auto-confirm.
|
||||||
|
|
||||||
| Item | Outcome |
|
**The declaration needs BOTH halves** (`needsOffsiteCredential`): a fresh data area (no repository
|
||||||
|---|---|
|
password) AND a hub-held recovery package. Freshness alone is a box that never had off-site backups —
|
||||||
| **1 — the reset code needs a restart** | **CLOSED.** `effectiveClaimCode` reads through to the persisted claim state (`settings.ReloadClaimCode`) before applying the precedence rule, which is **unchanged**. Read-through only, on the claim path only; fails closed. |
|
declaring on it would make every un-configured box in the fleet ask for a credential. A merely
|
||||||
| **3 — the restore's default returns the wrong thing silently** | **CLOSED.** `restoreScratchOutcomeMsg` names what was restored, what was not, and the next step; the wizard card states its scope before the choice. Size gate untouched. |
|
DISABLED target is the customer's own choice and never declares.
|
||||||
| **2 — a re-issue marks a healthy escrow stale** | The hub's half — shipped in felhom.eu v0.95.0. |
|
|
||||||
| **4 — a rebuilt box cannot obtain an off-site credential unaided** | **REMAINS OPEN.** Dependency: the one-shot credential design decision. It needs an operator ruling and belongs to **R-193**. Not begun. |
|
|
||||||
|
|
||||||
## 3. The exact Hungarian strings added (for review as copy)
|
**Inert to every existing reader**, established from the hub's code: `enabled:false` + zero sizes, so
|
||||||
|
`isStale` short-circuits on `!Enabled` and `fillBand` returns OK on a zero quota/size; an unknown
|
||||||
|
`state` string is ignored by `encoding/json`. **A configured box's JSON is byte-identical to
|
||||||
|
v0.198.0's.** The one reader that would have misread it is the hub's `reportHasOffsite`, tightened in
|
||||||
|
hub v0.96.0.
|
||||||
|
|
||||||
**Unit-restore outcome** — with the scratch path resolved (the fallback drops `: <path>`):
|
## 3. Files modified
|
||||||
|
|
||||||
> A(z) **<app>** beállításai és adatbázisa visszaállítva ellenőrző mappába: **<path>**. A saját
|
|
||||||
> fájljaid (dokumentumok, képek, feltöltések) NEM kerültek vissza — ez az ellenőrző visszaállítás csak
|
|
||||||
> az alkalmazás beállításait és adatbázisát hozza vissza. Ha a fájljaidra van szükséged, indítsd el a
|
|
||||||
> „Teljes visszaállítás előkészítése” lépést ezen az oldalon. A meglévő adatok változatlanok.
|
|
||||||
|
|
||||||
**Full-restore outcome:**
|
|
||||||
|
|
||||||
> A(z) **<app>** teljes mentése visszaállítva ellenőrző mappába: **<path>** — a saját fájljaiddal
|
|
||||||
> együtt. A meglévő adatok változatlanok.
|
|
||||||
|
|
||||||
**Wizard intent card 1** (heading + body, stated BEFORE the choice):
|
|
||||||
|
|
||||||
> **1. Ellenőrzés külön mappába (beállítások és adatbázis)**
|
|
||||||
> Az alkalmazás beállításait és adatbázisát hozza vissza egy külön ellenőrző mappába. A saját
|
|
||||||
> fájljaidat (dokumentumok, képek, feltöltések) **nem** hozza vissza — azokhoz a 3. pont teljes
|
|
||||||
> visszaállítása kell. Az élő adataid nem változnak.
|
|
||||||
|
|
||||||
**Claim fail-closed message** (new — shown on the page and on a refused submission):
|
|
||||||
|
|
||||||
> A beállító állapot most nem olvasható — próbáld újra néhány perc múlva.
|
|
||||||
|
|
||||||
## 4. Was the restore default changed? NO — and why
|
|
||||||
|
|
||||||
**The default stays `mode=unit`.** All three wizard forms set `mode` explicitly, so the `mode == ""`
|
|
||||||
fallback in `offboxRestoreHandler` is reachable **only by a hand-crafted POST**. Changing it would
|
|
||||||
alter nothing a customer sees while silently changing that POST's behaviour — and it would push a
|
|
||||||
mode-less request into the size-gated two-step path. The defect was **silence**, not the choice of
|
|
||||||
default, and silence is what was fixed: a mode-less POST now gets the same scoped wording, pinned by
|
|
||||||
`TestOffboxRestore_DefaultModeGetsTheScopedOutcome`. **The size gate stays in every case.**
|
|
||||||
|
|
||||||
## 5. Files created / modified
|
|
||||||
|
|
||||||
| File | Change |
|
| File | Change |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `controller/internal/settings/settings.go` | **new** `ReloadClaimCode()` — read-through of the persisted claim fields only |
|
| `controller/internal/settings/settings.go` | **new** `HubEscrowIdentityPresent` field + accessors (saves only on a change) |
|
||||||
| `controller/internal/web/claim.go` | `effectiveClaimCode` reads through + returns an error; `claimGateActive`, `claimLegacyOpen`, `handleClaimPage`, `handleClaimSubmit` fail closed |
|
| `controller/internal/report/escrow_confirm.go` | **new** `RecordPresence` seam, called before every gate |
|
||||||
| `controller/internal/web/claim_readthrough_test.go` | **new** — Scenarios A, B and the fail-closed case |
|
| `controller/internal/backup/offbox.go` | **new** `OffsiteStateNeedsCredential`, `needsOffsiteCredential`; `State` on the report object |
|
||||||
| `controller/internal/web/offbox_handlers.go` | **new** `restoreScratchOutcomeMsg`; the handler calls it with `full` |
|
| `controller/cmd/controller/main.go` | wires `RecordPresence` |
|
||||||
| `controller/internal/web/offbox_restore_scope_test.go` | **new** — Scenarios E and F through the real handler |
|
| `controller/internal/backup/offbox_declare_test.go` | **new** — Scenarios A and B + the two exclusions + the byte-compat assertion |
|
||||||
| `controller/internal/web/restore_wizard_test.go` | intent-card copy assertion updated to the new scope wording |
|
| `controller/internal/report/escrow_presence{,_wiring}_test.go` | **new** — the recorder and its AST wiring test |
|
||||||
| `controller/internal/web/templates/backups_restore_wizard.html` | intent card 1 states its scope |
|
| `.githooks/pre-push` | the workspace-root assertion (rider) |
|
||||||
| `CHANGELOG.md`, `CONTEXT.md`, `controller/README.md` | v0.198.0 entry; session block; claim-hatch + restore-scope architecture notes |
|
|
||||||
|
|
||||||
**Commits on `main`:** `73b6dbc` (item 1) · `2e936f4` (item 3) · `33fcc50` (CHANGELOG).
|
**Commits on `main`:** `1214bae` (the declaration) · `a91f055` (rider) · `992803c` (CHANGELOG).
|
||||||
**Deployed:** `gitea.dooplex.hu/admin/felhom-controller:0.198.0` on demo-felhom 9201 and demo-hp 9201.
|
**Deployed:** `felhom-controller:0.199.0` on demo-felhom 9201 and demo-hp 9201, both healthy.
|
||||||
|
|
||||||
## 6. Tests and red-proofs
|
## 4. Tests and red-proofs
|
||||||
|
|
||||||
Green gate after each phase: `go build ./... && go vet ./... && go test ./...` — **full suite rc=0**;
|
Green gate: `go build ./... && go vet ./... && go test ./...` — **rc=0**.
|
||||||
`python3 controller/scripts/controller_gates.py --fast` — **all eight gates OK**.
|
`python3 controller/scripts/controller_gates.py --fast` — **all eight gates OK**.
|
||||||
|
|
||||||
| Test | Result | Red-proof — what was mutated | Outcome |
|
| Scenario | Test | Result | Red-proof — what was mutated | Outcome |
|
||||||
|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| `TestClaimCode_FreshlyMintedByHatch_AcceptedWithoutRestart` (A) | PASS | deleted the `ReloadClaimCode()` call in `effectiveClaimCode` | **FAILED** — *"freshly minted code refused… the running server did not see the persisted code"* |
|
| A | `TestOffsiteDeclare_RebuiltBoxDeclaresNeedsCredential` | PASS | dropped the escrow condition from `needsOffsiteCredential` | **Scenario B FAILED** — *"a box that never had off-site backups DECLARED a need… every un-configured box in the fleet would now ask for a credential"*. This is the plausible wrong fix, and B is the guard that catches it. |
|
||||||
| `TestClaimCode_SupersededByASecondMint_RefusedImmediately` (B) | PASS | substituted a **per-instance 30 s TTL cache** for the read-through | **FAILED** — *"the SUPERSEDED code was accepted — a stale/TTL read left an old code alive"* |
|
| B | `TestOffsiteDeclare_NeverHadOffsiteSaysNothing` | PASS | (as above) | **FAILED** |
|
||||||
| `TestClaimCode_UnreadablePersistedState_FailsClosed` | PASS | both mutations above | **FAILED** both times (*"the gate OPENED on an unreadable claim state"*) |
|
| — | `TestOffsiteDeclare_BoxThatStillHoldsItsRepoPasswordDoesNotDeclare` | PASS | — | — |
|
||||||
| `TestOffboxRestore_UnitOutcomeNamesWhatItDidNotRestore` (E) | PASS | reverted `restoreScratchOutcomeMsg` to the single pre-R-204 sentence | **FAILED** on all four assertions |
|
| — | `TestOffsiteDeclare_DisabledTargetIsNotStranded` | PASS | — | — |
|
||||||
| `TestOffboxRestore_DefaultModeGetsTheScopedOutcome` | PASS | same | **FAILED** |
|
| — | `TestOffsiteDeclare_ConfiguredBoxJSONIsUnchanged` | PASS | — | — |
|
||||||
| `TestOffboxRestore_FullPathUnchanged` (F) | PASS | same | **FAILED** on the full-outcome assertion; the size-gate half stayed green, correctly |
|
| — | `TestEscrowConfirm_RecordsPresenceEvenWhenOffboxUnconfigured` (+ nil-ACK, record-failure) | PASS | — | — |
|
||||||
| `TestOffboxRestore_UnitRestrictsToTheUnitPath` | PASS | — (the mechanism half of E) | — |
|
| seam | `TestMainWiresRecordPresence` | PASS | commented out `RecordPresence:` in main.go | **FAILED** — *"EscrowAutoConfirmer is constructed WITHOUT RecordPresence — R-204 item 4 ships inert"* |
|
||||||
|
|
||||||
Each mutation removed every guard its test covers, except deliberately in the last row: reverting the
|
## 5. Live validation
|
||||||
message does **not** touch the size gate, and Scenario F's gate assertions correctly stayed green
|
|
||||||
while its wording assertion failed. That split is the evidence the two halves are independent.
|
|
||||||
|
|
||||||
**A red-proof that first failed for the WRONG reason, corrected and recorded** (task §10's exact
|
1. **The recorder works on a HEALTHY box** — the case that used to return early. Both demo boxes now
|
||||||
trap). Scenario B's first TTL mutation used a *package-level* variable, so test A's earlier read had
|
carry `hub_escrow_identity_present = true` in `settings.json`.
|
||||||
already opened the window and B failed with *"the gate is not active after the first mint"* — no code
|
2. **The declaration, produced live without wiping a box.** demo-felhom 9201 was arranged
|
||||||
at all, rather than a superseded code surviving. Two fixes: the mutation was made **per-`Settings`**
|
**reversibly** into the stranded shape (settings + `offbox/` backed up first). The hub received
|
||||||
(what a real TTL fix would be), and the test was restructured so the server has **already seen the
|
report **id=16743**: `{"enabled":false,"escrow_state":"","state":"needs_credential",
|
||||||
first code** — through `claimGateActive()`, the production path a page load takes — before the second
|
"snapshot_count":0,"repo_size_bytes":0,"quota_gb":0}`. Restored the same minute — report id=16744 is
|
||||||
is minted. Only then does the TTL demonstrably keep the old code alive.
|
healthy. **The single declaration was absorbed by the hub's debounce; no self-heal event fired.**
|
||||||
|
3. **A push from outside the workspace is refused**, naming the expected root, before the gates run;
|
||||||
|
with the assertion removed the same push succeeds. Both directions demonstrated.
|
||||||
|
4. **Part 4 (the deletion) HALTED at its STOP** — the measured paths do not match the register. See
|
||||||
|
`felhom.eu/REPORT-r204-item4.md` §8 and R-212.
|
||||||
|
|
||||||
**Seams named.** The claim tests stub **nothing**: a real `settings.Load` on a real file, the real
|
**Teardown:** demo-felhom restored and verified (`enabled=True`, `escrow_state=escrowed`,
|
||||||
`PrintLocalResetCode` against a second `*Settings` loaded from the same path (the `docker exec`
|
`repo_password present=True`); the pre-change backup remains at `/root/r204-backup` on that guest.
|
||||||
shape), and submission through `fullMux()` (RequireAuth + CsrfProtect + ServeHTTP). The restore tests
|
Scratch clones removed. Nothing provisioned.
|
||||||
stub **only the restic exec** (`SetOffboxRunner`) and drive `offboxRestoreHandler` itself, asserting
|
|
||||||
the flash on `RestoreStatus().Last.Message` — the field the wizard renders — and waiting on a real
|
|
||||||
completion marker (`!Running && Last.FinishedAt != 0`), never a fixed sleep.
|
|
||||||
|
|
||||||
## 7. Live validation (endpoint-level; `claude-in-chrome` is not available on DooPlex)
|
## 6. CI and hooks
|
||||||
|
|
||||||
| # | What | Observable |
|
**`--no-verify` was NOT used.** Every push ran the pre-push gate, including the new workspace-root
|
||||||
|---|---|---|
|
assertion. CI runs were confirmed green by head_sha for each push.
|
||||||
| 1 | **A freshly minted code is accepted with nothing restarted** | demo-felhom 9201. Two codes minted through the real hatch (`docker exec … --print-reset-code`, generations 3 then 4). Container `StartedAt 05:21:28Z`, **`RestartCount=0`**, both mints after it. The **current** code reached *"A jelszónak legalább 12 karakter hosszúnak kell lennie"* — a **positive** observable reachable only **after** the hash, generation and expiry checks all pass. The same code was then submitted with the real password: **302 → `/`**, accepted end to end. |
|
|
||||||
| 2 | **The previously valid code is refused** | The generation-3 code, superseded seconds earlier, returned **„Hibás vagy lejárt kód"**. No window. |
|
|
||||||
| 3 | **A unit restore names what it did not restore** | demo-hp 9201, app `privatebin`, via `POST /backup/offbox/restore` (mode=unit), read back from `/api/backup/restore-status`: **„A(z) privatebin beállításai és adatbázisa visszaállítva ellenőrző mappába: /mnt/sys_drive/felhom-data/backups/offsite-restore/privatebin. A saját fájljaid (dokumentumok, képek, feltöltések) NEM kerültek vissza — ez az ellenőrző visszaállítás csak az alkalmazás beállításait és adatbázisát hozza vissza. Ha a fájljaidra van szükséged, indítsd el a „Teljes visszaállítás előkészítése” lépést ezen az oldalon. A meglévő adatok változatlanok."** |
|
|
||||||
| 4 | **The full-restore size gate still computes and reveals** | Same box/app, `mode=full` **without** `confirm`: `302 → /backups/restore/app?name=privatebin&full_prep=privatebin&full_size=6.8+KB`, and **no restore ran**. |
|
|
||||||
|
|
||||||
**Method:** authenticated `curl` against the container IP with the mandatory `Host` header, run inside
|
## 7. Observations — noticed, NOT acted on
|
||||||
the guest; Hungarian strings transported base64 so the `ssh → pct exec → bash` chain could not mangle
|
|
||||||
an accented assertion.
|
|
||||||
|
|
||||||
**demo-hp fences respected:** no wipe, no ceremony, no re-issue. `privatebin` was chosen precisely so
|
- The workspace-root assertion is per-clone like the rest of the hook, so it binds only an armed
|
||||||
the drill's `calibre-web` scratch stayed untouched — confirmed after teardown, it is the only
|
clone; CI remains the half that is neither per-clone nor skippable (R-168).
|
||||||
directory left under `backups/offsite-restore/`.
|
- `felhom-agent`'s `reuse-refs` gate incidentally also fails outside the workspace (the shared checker
|
||||||
|
lives in the `felhom.eu` sibling). Repo-specific and not a substitute for the assertion.
|
||||||
**Why 9201 on demo-felhom could not serve items 3–4:** its off-site repository is **orphaned with 0
|
|
||||||
snapshots** (`status: error`, the known R-193 guest-rebuild shape), so no restore can run there.
|
|
||||||
|
|
||||||
## 8. Teardown
|
|
||||||
|
|
||||||
Nothing was provisioned. The outstanding generation-4 reset code on 9201 was **consumed** through the
|
|
||||||
real claim flow using the box's existing password, so the box is left **claimed, healthy and with an
|
|
||||||
unchanged password** and no live reset code; re-submitting it now returns „Hibás vagy lejárt kód".
|
|
||||||
The `privatebin` restore scratch created on demo-hp was removed. All credential-bearing helper scripts
|
|
||||||
were deleted from `/tmp` on both Proxmox hosts and both guests. No secret appears in any committed
|
|
||||||
file — the minted codes are one-time, now consumed or superseded, and are referenced here only by
|
|
||||||
generation number.
|
|
||||||
|
|
||||||
**CI:** run **153** for `33fcc50` — success. `--no-verify` was **not** used; the pre-push gate ran and
|
|
||||||
passed on every push.
|
|
||||||
|
|
||||||
## 9. Observations — noticed, NOT acted on
|
|
||||||
|
|
||||||
- **`--print-reset-code` rewrites the WHOLE settings file** from its own `settings.Load`. If the
|
|
||||||
running server persists a setting between that load and the hatch's save, the hatch's write wins and
|
|
||||||
the server's change is lost. Not triggered here (the hatch is short-lived and operator-driven) and
|
|
||||||
out of scope — but it is a genuine lost-update window on a shared file.
|
|
||||||
- The hub's `allowedEventTypes` still lists **`escrow_stale`**, which now has **no producer** in
|
|
||||||
either repo. Harmless, but inert; removing an allowlist entry is a behaviour change and was left
|
|
||||||
alone.
|
|
||||||
- `/` on DooPlex is at **86%** used. Under the 90% abort line, but worth watching before large builds.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user