v0.128.0: chunked browser .fab upload on /import (tunnel-proof)

Cloudflare edge caps request bodies (~100 MB, probed live: 120 MiB -> edge 413,
80 MiB -> origin), so the client slices the file into 64 MiB strictly-sequential
chunks; the server streams each to a .part file in the default drive's exports
dir and finalize renames atomically. Scan/validate/import pipeline untouched.
upload/{init,chunk,finalize,abort} inside ServeExportAPI (inherits auth+CSRF);
single-flight; offset==received or 409+echo; free-space gate; collision ->
lowest-free "name (N).fab"; startup GC of *.part-*; 15-min idle abort.
appexport.DiskFree exported (seam web.uploadDiskFree). Scenarios A-F tested,
red-proofs run (traversal / out-of-order / overwrite).
This commit is contained in:
2026-07-13 21:09:20 +02:00
parent 59e4ca70de
commit db16371f47
11 changed files with 1055 additions and 8 deletions
+16 -1
View File
@@ -7,7 +7,22 @@
>
> Ask Claude Code: "Please update CONTEXT.md with what we did today"
Last updated: 2026-07-13 eve (v0.127.0 — escrow ceremony wizard LIVE drill+demo)
Last updated: 2026-07-13 night (v0.128.0 — browser .fab upload on /import)
> **2026-07-13 night — v0.128.0: CHUNKED BROWSER .FAB UPLOAD on /import (ruling F3: chunked).**
> Step-0 probe on the real tunnel PROVED the Cloudflare edge cap (120 MiB POST → edge 413 with
> `Server: cloudflare` on Content-Length alone; 80 MiB → origin 302 /login; local DNS overrides
> the hostname to the LAN guest, probe needed `--resolve` onto CF's public IP). Design: JS
> `File.slice` 64 MiB strictly-sequential chunks → `POST /api/export/upload/{init,chunk,finalize,
> abort}` inside `ServeExportAPI` (inherits RequireAuth+CsrfProtect; single-flight; offset must
> equal received else 409+echo; 96 MiB request cap; free-space gate size+1 GiB; finalize =
> exact-size + fsync + atomic rename, collision → lowest-free `"name (N).fab"`). Lands in the
> DEFAULT drive's exports dir — scan/validate/import pipeline untouched. No client hash
> (deliberate: .fab self-validates). In-memory state: startup GC of `*.part-*`, 15-min idle
> abort. §7 AF tested + 3 red-proofs. `appexport.DiskFree` exported (REUSE.md row).
> **NOT live-validated: the end-to-end multi-GB browser upload through the real tunnel needs a
> dashboard login → Viktor's 5-minute leg (export an app to .fab, download, re-upload, import —
> full circle).** Possible follow-up if it itches: per-drive target picker (v1 = default drive only).
> **2026-07-13 eve — v0.127.0: CUSTOMER-FACING ESCROW CEREMONY WIZARD (/backup/escrow) +
> Scenario-F stale-blob re-check. MinAgent 0.88.0 (wizard only). LIVE on demo 9201 + drill guest