Commit Graph

154 Commits

Author SHA1 Message Date
admin fd40b29119 docs: v0.152.0 REPORT/CONTEXT + fix an async race in TestFabUpload_GCAndIdleTimeout
The fab-upload GC test stat-ed the .part immediately after observing the slot
free, but expireIdleUpload unlinks AFTER releasing the mutex. Passed alone,
failed in the full package once this release's render tests made web heavier.
Not a production defect - a new upload mints a fresh random .part. The test now
waits for the outcome it asserts on the same deadline; red-proofed by removing
the unlink from production.
2026-07-20 13:55:03 +02:00
admin 5c105fb49b docs: v0.151.0 REPORT + CONTEXT — deployed, live-verified, 3 red-proofs recorded 2026-07-20 10:54:50 +02:00
admin 8db9232dea docs: REPORT for v0.150.0 (green gate restored, F7 export-link fix, dhclient cleanup) 2026-07-20 09:45:30 +02:00
admin 4646be1515 docs: REPORT for the 2026-07-20 remote-site remediation + F3 fix (v0.149.0) 2026-07-20 09:09:14 +02:00
admin 062357f778 v0.148.0 — coherent snapshot pairs + an offsite restore that actually restores (R-43 + R-44)
Closes the two findings from DIAG-immich-restore-2026-07-19. Viktor deleted 11
immich photos to test offsite restore; both runs flashed success and the photos
stayed gone. Two independent defects.

R-43 — no offsite path could restore a database. All three buttons were
file-only: the two "visszaállítás" actions staged to a scratch folder and never
touched postgres, and place-to-live merged only MISSING files. For a DB-indexed
app the bytes returned and the app still could not see them. The dump was
carried INTO every snapshot and could never be replayed OUT of one.

New ReconstituteFromOffsite (/backup/offbox/reconstitute): safety dump → stop →
files overwritten to the snapshot version → start → the snapshot's own dump
replayed → health wait. Two invariants:
  - nothing is ever deleted (-a, no --ignore-existing, no --delete): a file
    created after the snapshot survives as an extra;
  - the undo exists before the act — the pre-restore- dump is verified ON DISK
    before anything is stopped, overwritten or replayed; if it cannot be taken
    the operation refuses with zero changes.
The replay reads the SCRATCH unit: the live unit is never overwritten, so
replaying from it would replay the current DB over itself and restore nothing.

R-44 — a manual push shipped an unrefreshed dump (up to ~24h old). That day's
predated the customer's account by four hours and probed to asset:0/user:0/
album:0 inside 52MB whose bulk was immich's shipped geodata. Every run, manual
AND nightly, now refreshes dumps + units BEFORE capturing. Order is the
mechanism: the gap can only ADD files the DB does not reference yet, never
remove one it does. Manifests carry offsite_run_id + dumps_at, so coherence is
verifiable at restore time rather than assumed; the periodic refresh carries a
prior stamp forward and never invents one.

Honesty surfaces, all warn-level and none a gate: unstamped (pre-v0.148) pairs
report their skew, ValidateDump gained an EXACT-match accounts-table sniff for
customer-empty dumps, the completion flash states an outcome instead of a
mechanism, and the missing-only button now says what it does NOT do.

11 tests; 5 red-proofs run and reverted. Two of those found real test weaknesses
rather than confirming strength — the first undo mutation was caught by a second
guard, and the first table-matching test did not discriminate between the two
matchers at all. Both tests were rewritten to the cases that separate them.

NOT in scope: R-41's catalog invariant check, nightly cadence, retention, quota
math, tier-2, and v0.147.x progress semantics beyond one added phase line.

Live acceptance (§9) has NOT run: no capability-map flip, customer-restore row
stays MISSING, R-3 stays DRAFT.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P9Nn14TWGzKoqAJAiVwC2s
2026-07-19 12:21:16 +02:00
admin 10ca8ac884 docs(report): v0.147.0-.3 feedback slice 1
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nn3VgQk9iwEGgyx6QJ2NvE
2026-07-19 10:03:17 +02:00
admin 7f0b41c3e7 docs(report): v0.146.0 nav polish
Overwrites REPORT.md per convention. Records the two changes, the four design
decisions behind the accordion (real <button>, landing-pages-survive check,
server-side open state, grid-rows instead of max-height), and — importantly —
what could NOT be verified and why: the demo controller's password is
customer-owned since the claim flow, so the build-server credentials are stale
and a curl-login returns the Bejelentkezés page. The four red-proofed render
tests stand in for the server-side half; the visual leg needs Viktor's browser.

Also notes the fleet gap: v0.146.0 is live on the demo box but the golden still
bakes 0.143.0, deferred to the next session.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nn3VgQk9iwEGgyx6QJ2NvE
2026-07-18 21:04:06 +02:00
admin 57be785bad docs(R-7b): finding (f) now points at ROADMAP R-29, with the dating and diagnosis
The gate landed v0.125.0 (2026-07-13), realVolumeSize landed v0.129.0 (2026-07-14)
-> red for 16 releases unnoticed. Records that the flagged mount is a NAMED VOLUME
(the safe shape) so the fix is an allowlist entry, not a rewrite of correct code.
2026-07-18 15:17:12 +02:00
admin cc50918244 docs(R-7b): CORRECTION — offsite leg + restore round-trip ARE live-proven
The prior revision claimed the demo box had no offsite target and that both legs
were unexercised. All three clauses were false on a box that had run a successful
offsite backup minutes earlier.

Evidence: offsite snapshots e0b9d723 (Viktor 12:18:16Z) and 4e2b15ec, tagged
felhom-offbox,_shares, each carrying the payload dir (manifest + passdb.tar, 0600)
plus both share folders. Restore round-trip through the real routes returned a
deleted probe byte-identical and a deleted DEFINITION with its original flags,
without overwriting the two pre-existing files. R-7b is fully PROVEN-LIVE.

Root cause in new REPORT section 7b: the check read a GUESSED settings key
('offbox_target') where the real tag is 'offbox' (settings.go:96), got None for
every field, and read that as 'not configured' instead of 'wrong key'.
2026-07-18 14:32:28 +02:00
admin a5d870ea0e docs(shares): REPORT.md — R-7b v0.145.0 ship report
Findings, all six red-proof outcomes, deployment, live-validation evidence, and an
explicit list of what was NOT live-exercised (offsite leg + restore round-trip: the
demo box has no offsite target).
2026-07-18 13:34:59 +02:00
admin 3dfc49e578 docs(samba): Explorer human leg PASSED — R-7 slice 1 fully PROVEN-LIVE
Viktor confirmed on the demo box: Network -> FELHOM -> both shares open; an
INTERACTIVE Explorer save into dokumentumok succeeded and landed owned 1000:1000
(force user holds for a real Explorer write, not just a scripted one); a write
into the read-only filmek was refused by Windows with the folder left empty on
disk. Capability-map row flipped to PROVEN-LIVE in felhom.eu.
2026-07-18 12:12:51 +02:00
admin a4c82a2651 docs(samba): CHANGELOG v0.144.0 + REPORT + CONTEXT + README §16 + REUSE
Records the R-7 slice 1 ship, the four red-proof outcomes, live-validation
evidence, the two bugs live validation caught, and the Part-4 Step-1 enumeration
finding + the reported design fork (share data classified but not yet in a live
backup run — needs a Viktor ruling, suggested R-7b).
2026-07-18 12:03:24 +02:00
admin a4a7de3d8f docs: v0.143.0 REPORT + CONTEXT + README (guest RAM resize UI, R-24; deployed + live-validated on demo) 2026-07-17 19:27:47 +02:00
admin f900c83eed docs: v0.142.0 REPORT + CONTEXT (offsite repo continuity A+C; live leg staged for the rehearsal; security-review Observation) 2026-07-17 10:55:30 +02:00
admin 1452dd2b17 docs: v0.141.0 REPORT + CONTEXT + README (F6 detached init job + format-status poll, F7; live-validated on demo scratch USB; security-review TOCTOU acknowledged) 2026-07-17 09:49:45 +02:00
admin 5be2449267 docs: v0.140.0 Direction-2 waiter — REPORT + CONTEXT (live: 240s no-annotation hold, 0.047s wake, restart no-storm) 2026-07-16 21:10:42 +02:00
admin f665bbed45 docs(report): v0.139.0 live verification — 2s save-to-hub round-trip proven on 9201
Out-of-cycle pushes at 17:42:19/17:42:34Z (quiet-window + min-interval
pacing exactly as designed, trailing edge carried the final state);
scheduled 15-min cycle unaffected (17:49:00Z tick on both ends).
Red-proof outcomes and the NOT-yet-live-validated list recorded.
2026-07-16 19:49:46 +02:00
admin 8f3564c137 docs(report): v0.138.0 live verification — 0.136→0.138 deployed, escrowed end-state confirmed
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017qDiBqKKQ5vPB5fXBqu7Kp
2026-07-16 18:48:00 +02:00
admin 120332103a feat(escrow): v0.138.0 — "awaiting hub confirmation" waiting state
After a completed escrow ceremony the Távoli mentés page showed the yellow
"Helyreállítási kód szükséges" card for ~15 min until the next hub-report ACK
flipped pending→escrowed. Phase-0 diagnosis (read-only) = verdict A (report-cycle
lag), already resolved on the demo box (escrow_state:"escrowed"); hub Hypothesis B
verified false (SaveHostEscrow ON CONFLICT already clears stale_at on upload) → no
hub change.

- settings.OffboxTarget.CeremonyCompletedAt: stamped on the recovery-code claim,
  zeroed on the auto-confirmer Flip + the deprecated manual confirm; persisted.
- web/handlers.go: offboxCeremonyWaitState + escrowCeremonyGraceWindow (35m).
- backups_remote.html: info "megerősítésre vár, legfeljebb 15 perc" card → warn
  "a megerősítés nem érkezett meg" past the window. Existing branches untouched.
- backups_escrow.html: "Mi történik ezután?" note on the wizard's final step.
- Test web/escrow_wait_state_test.go (truth table + red-proof recorded in REPORT).

No scheduler/agent/hub/endpoint changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017qDiBqKKQ5vPB5fXBqu7Kp
2026-07-16 18:44:13 +02:00
admin e99c675fe4 docs: v0.137.0 cleanup bundle — REPORT + CONTEXT (email-wipe guard + Parts 2-4 disposition) 2026-07-15 19:50:13 +02:00
admin 0ef6648e12 docs: REPORT — v0.136.0 deploy + SQ6 before/after live validation (sibling no longer rides along; radarr state-only; opt-in flips; manifest v1) 2026-07-15 11:39:24 +02:00
admin cf9ce01917 .fab exclusion scoping: classes in the manual export (Task 4, v0.136.0)
SQ6 over-capture FIXED for classified apps: the userdata root tar is exclude-scoped (keeps only
ancestors/descendants of a SELECTED bind relpath — R1-C, the tier2Reconcile keep-rule); no selected
userdata bind → no root tar (radarr state-only). New appbackup.ComputeFabBuckets (shared
resolveGuardCollapse pipeline; class buckets; guards over ALL classes; no cross-bucket containment).
appexport/fabplan.go: computeFabPlan + tarDirectoryExcluding + fabEstimateSplit. ExportRequest gains
DeselectOptional/OptInExcluded (both start handlers — two-call-site); mandatory is a server-side
floor. Manifest v1 + import UNTOUCHED; legacy apps byte-identical to v0.130.0. Estimate additive
class split; export UI: locked-mandatory/optional-checkboxes/excluded-opt-in + two-number warning.
All 6 §10 red-proofs verified. 6D Accept #1 now runs against this shape.
2026-07-15 11:28:40 +02:00
admin 5f216138e5 docs: REPORT — v0.135.0 deploy + §13 live validation (v2 tree, Part 0 opt-out-sticks, restore round-trip; leg-0 cause was transient not F-6C-1; leg-6 = unconfigured customer email) 2026-07-15 10:24:34 +02:00
admin 3603d1fc7f Tier-2 engine rework: class-driven legs, v2 layout, NAS-target exclusion (Task 3b, v0.135.0)
tier2_capture.go: classified apps get TierSecondary per-bind legs (paperless copy shrinks — export
drops); legacy apps keep the byte-identical resolver set. v2 relpath-mirroring layout
(backups/secondary/<stack>/{marker LAST, recovery-unit/, hdd/<rel>/, userdata/<rel>/}); N>1 native
(errTier2MultiDir/tier2AppDataName deleted). Migration=delete-and-rebuild + reconcile; all RemoveAll
via tier2SafeRemove (refuses outside backups/secondary/). SSD=state-only tier. selectTier2Target
never picks network storage (pinned+auto, F-6C-1). Restore reads v2 behind a marker gate.
Part 0: offbox_enlarge_blocked is a persisted one-time Load seed (opt-out sticks), not a getter
append. Part 0.5: offsite restore scratch prefers a local (non-network) path.
Full v2 test suite + all 10 §10 red-proofs verified. Destructive writes bounded to backups/secondary/.
2026-07-15 10:10:20 +02:00
admin 1245a6c46e docs: REPORT — §13 all 6 live legs PASS (credential was quote-stripping bug, not stale) 2026-07-15 09:15:05 +02:00
admin 483b2186cb docs: REPORT — v0.134.1 deploy + live validation (leg 2a/2b organic; sessions blocked by stale credential) 2026-07-15 08:02:57 +02:00
admin 0cfcc42464 Placement hardening (F-3a-1..4) + enlarge-blocked delivery chain (Task 3a-fix, v0.134.1)
PlaceOffsiteRestore: live target via raw GetStackHDDPath not AppNamespaceRoot (F-3a-1a: no SSD
merge; undeployed refused), placement headroom gate (F-3a-1b), stat pre-pass over all placements
before any copy (F-3a-4: no partial writes), scratch removed on success/kept on failure (F-3a-2).
mapOffsiteRestorePaths refuses the namespace root itself (F-3a-3).
Delivery chain: DefaultEnabledEvents + GetNotificationPrefs append-if-absent migration + settings
checkbox + handler slice; paired with hub v0.55.0 allowlist (no customerMessages entry — raw
dynamic message survives). +8 tests; all 6 controller §10 red-proofs verified.
2026-07-15 07:54:29 +02:00
admin 482d0d98e3 docs: REPORT — v0.134.0 deploy + read-only live validation (raw-data 710→271 MB proven, shape baseline) 2026-07-14 22:57:20 +02:00
admin 2d20859858 Offsite tier policy engine: mandatory userdata, raw-data quota, restore rework (Task 3a, v0.134.0)
Each toggled app's offsite push = one multi-path restic snapshot (recovery unit + TierOffsite
mandatory userdata via ComputeCaptureSet); legacy/undeployed stay unit-only. Loud capture gaps
(SP-3.4: restic 0.14.0 silently skips missing paths). Quota = stats --mode raw-data (SP-1;
displayed size drops once). Pre-push enlargement gate blocks the userdata enlargement over-quota
(unit-only push continues; EnlargedBlocked; edge-triggered notify). forget --group-by host,tags
on both sites (SP-2). Restore reworked: scratch off the rootfs + headroom gate (F-A1), unit-only
default via --include, size-first full, place-to-live missing-only merge (never --delete).
UI: unit/full-two-step/place actions + per-app blocked note; route POST /backup/offbox/place.
HUB FLAG: offbox_enlarge_blocked event needs hub allowlist for push delivery.
+13 tests; all 10 §10 red-proofs verified. No tier-2/.fab/hub/agent changes.
2026-07-14 22:51:54 +02:00
admin 0c6e151c1c docs: REPORT — v0.133.0 deploy + INERT-silence verification (guest 9201 healthy) 2026-07-14 21:55:10 +02:00
admin 2668ac4da3 Capture-set computation (INERT; Task 3-core, v0.133.0)
Pure appbackup.ComputeCaptureSet(binds, hasClassification, tier, hddPath) → CaptureSet
{HasClassification, Paths, Skipped}: legacy short-circuit → tier filter (§2) → structural
guards → equal-Abs collapse (mandatory>optional) → containment dedup → sort. Slash algebra,
no filepath/FS/log. Structural guards (traversal / bare HDD drive-root / reserved backups/)
are load-bearing (the compose parser does not reject ..). Pure CrossAppOverlaps advisory
(WARN wiring deferred to 3a/3b). INERT — no engine consumes it yet.

Tests: Groups A-F (appbackup) + F-S3 no-seam wiring (stacks); all 6 §10 red-proofs verified.
Docs: architecture §3 aligned (felhom.eu 8d85da7).
2026-07-14 21:53:05 +02:00
admin 95f3180ab4 docs: REPORT — v0.132.0 backup classification (INERT) deploy + live sync evidence
Both guests healthy on 0.132.0; catalog 21e8df1 (13 blocks) synced live
with ZERO backup-block rejections. 13-app cross-check table (every bind
resolves explicit). RP-1..RP-4 confirmed. audiobookshelf PENDING-VETO =
optional pending Viktor's ruling.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A45Qop8YY8tS94bz63LFne
2026-07-14 18:54:34 +02:00
admin af98c53c82 docs: REPORT — v0.131.0 F-S2/F-S3 deploy evidence + deferred live legs
Both guests live+healthy on 0.131.0. Live functional legs (paperless
deploy → tier-2 backup → marker restore → storage page → F-S3 migration)
deferred to Viktor's supervised session — paperless-ngx is undeployed on
the demo and the API is container-internal; documented with rationale.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A45Qop8YY8tS94bz63LFne
2026-07-14 18:01:12 +02:00
admin b42904bbab docs: REPORT — v0.130.0 live self-verify evidence (repro flipped: 2308 B -> 31.8 MB, both flags true, marker hashes byte-identical) 2026-07-14 15:40:34 +02:00
admin 3679a759ba docs: v0.130.0 — CHANGELOG + README export section + REUSE (2 helpers) + CONTEXT + REPORT 2026-07-14 15:33:05 +02:00
admin eb3bf4a391 @
docs: REPORT covers v0.129.0 (F-B/F-A/F-C fixes, red-proofs, both guests live 0.129.0)

Claude-Session: https://claude.ai/code/session_01LbMm4T7Ayzs1unB9pN6Uqd
@
2026-07-14 09:55:53 +02:00
admin 3c9de42c20 docs: REPORT + CONTEXT cover v0.128.1 + demo legacy dir-storage retirement (gates G1-G3, 4/4 verifications) 2026-07-13 21:51:06 +02:00
admin 61c1391ff6 docs: REPORT covers v0.128.0 (probe numbers, A-F results, red-proofs, both guests live) 2026-07-13 21:14:18 +02:00
admin 59e4ca70de docs: REPORT covers v0.127.1-.3 (live-code reveal copy; both guests on 0.127.3, healthy) 2026-07-13 20:46:56 +02:00
admin 900adf733c docs: REPORT covers v0.127.1+v0.127.2 (manual-only hide toggle per Viktor's live finding; both guests on 0.127.2, healthy) 2026-07-13 20:28:49 +02:00
admin 6f72e5e0c2 docs: v0.127.1 REPORT (polish deployed both guests, healthy; §10 red-proofs N/A — presentation-only; visual leg awaits Viktor) 2026-07-13 20:20:16 +02:00
admin a5041dac80 docs: v0.127.0 REPORT (Scenario F LIVE both boxes: stale warn fired at first ACK, drill blob repaired + flag cleared on the 17:23Z ACK, state never flipped; red-proofs 4/5; NOT-live-validated: full browser wizard leg — customer-owned password) + CONTEXT 2026-07-13 19:24:18 +02:00
admin 6136461de6 docs: REPORT — v0.126.3 wizard-CSRF section (root cause, latency-via-claim-arc, red-proof, deploy) 2026-07-13 13:53:09 +02:00
admin 93c95f0fb5 docs: v0.126.x REPORT overwrite (parts, 4 red-proofs, gate outputs, drill live-QA evidence incl. reversible gate-lift + restore, open demo human steps) + CONTEXT 2026-07-13 12:07:09 +02:00
admin e0618af438 docs: v0.125.0 path-strand fix — CHANGELOG + REPORT (probe transcript, red-proofs, round-trip evidence, Tier-1/2 mechanism) + CONTEXT + REUSE + README flows; hollow-bundle asymmetry recorded (containerized ≤0.124.0 exports suspect — re-export); floor note for the next train
Claude-Session: https://claude.ai/code/session_01GzammAMzsJTgpQHqxwM2bC
2026-07-13 10:58:19 +02:00
admin 811a0ef7a7 docs: v0.124.0 backups IA restructure — CHANGELOG + REPORT + CONTEXT (decisions 1-3) + README page map + REUSE; records the HIGH containerized-.fab volume-strand finding and the agent SystemDisks legacy-boot finding
Claude-Session: https://claude.ai/code/session_01GzammAMzsJTgpQHqxwM2bC
2026-07-13 10:17:58 +02:00
admin df7ad378f4 docs: v0.123.0 polish batch — CHANGELOG + REPORT + CONTEXT + REUSE (felhomConfirm pattern, new gates)
Claude-Session: https://claude.ai/code/session_01GzammAMzsJTgpQHqxwM2bC
2026-07-13 08:47:58 +02:00
admin d4641c221d docs: v0.122.0 customer-claim gate — REPORT + CONTEXT 2026-07-12 18:56:29 +02:00
admin dec6fef20d REPORT: v0.121.0 live-validation results (9201, claude-in-chrome a–g green) 2026-07-12 12:33:39 +02:00
admin 9d05fa5c35 controller v0.121.0: backups page truth pass — remove dead Részletek card, real Tier-3 off-box state, SQLite-honest DB messaging
MinAgent: 0.81.0 (unchanged). Controller-only; no agent-API change, no backup-engine
behavior change. Fixes the self-contradicting /backups page (v0.120.0 live):

- Remove the dead "Részletek" card (redundant; kills never-set Tier2DriveGroups/
  ResticPassword fields + restic-pw element + toggleTier/toggleResticPw/copyResticPw JS).
- Per-app "3. mentés" row shows real off-box state via pure tier3State
  (unconfigured/off/escrow_pending/active) — "Hamarosan" placeholder gone.
- SQLite-honest DB messaging via pure dbSectionState (dumps/pending/embedded).
- Populate Tier1LastRun/Tier1LastStatus from ListRestorePoints; Tier-1/Tier-2 labels
  via timeAgoStr (relative), confirm() dialog keeps raw timestamp.
- Terminology split: "Távoli mentés (3. mentés)" (off-box, +#offbox-section anchor)
  vs "Távoli rendszermentés" (PBS whole-CT).
- Deploy page: add "Mentési beállítások →" link.

+9 internal/web tests (pure helper tables + buildAppBackupRows wiring + template
renders), 4 companion red-proofs run→fail→revert.
2026-07-12 12:26:30 +02:00