From e161b1eae7718744fffa93972e8d500c07f072f2 Mon Sep 17 00:00:00 2001 From: Julien Calixte Date: Tue, 14 Jul 2026 09:35:35 +0200 Subject: [PATCH] =?UTF-8?q?docs(v0.7):=20close=20the=20version=20=E2=80=94?= =?UTF-8?q?=20run-3=20fast-forward=20pull=20verified?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pulled shape passed on device: apply_tree_diff 1271ms for 1 file, no crash, interning confirmed (0 KB internal on re-walk). Records run-3 timings, the reconcile 30s→5s session-resumption win, and the 1-byte-load/0-byte-save trailing-newline watch item. --- docs/v0.7-search-and-git.md | 55 +++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/docs/v0.7-search-and-git.md b/docs/v0.7-search-and-git.md index 879b9fe..a5c5bcd 100644 --- a/docs/v0.7-search-and-git.md +++ b/docs/v0.7-search-and-git.md @@ -3,17 +3,23 @@ > Part of the [Typoena macro plan](macroplan.md). Requirements and targets: > [qfd.md](qfd.md). Load-bearing decisions: [adr.md](adr.md). -**Status: feature-complete, one gate left.** `/` search is done and -panel-verified (case-insensitive since 2026-07-14; `n`/`N` confirmed -on-device). `:gl` is built end-to-end and three of its four shapes are -on-device verified; the **fast-forward (Pulled) shape is the closing gate** — -its first attempt (2026-07-14, run 2) crashed in libgit2's `checkout_tree` -(O(tree) workdir walk + internal-DRAM exhaustion + an esp-idf spi_master -NULL-deref on its own failed-alloc path), and the checkout has been rebuilt as -an O(changed) tree-diff apply plus three memory fixes (file-list interning, -64 KB DMA reserve, TLS session reuse). **Re-run the Mac-push → device `:gl` -test to close the version.** Run-1 bonus: the first on-device -rejected-push → reconcile → replay → push success (replay commit 59444a94). +**Status: CLOSED 2026-07-14.** `/` search is done and panel-verified +(smartcase + accent-folded; `n`/`N` confirmed on-device). `:gl` is verified +on-device in all four shapes: the **fast-forward (Pulled) closing gate passed +on run 3** — `main 17840720 → e738a6a1`, `apply_tree_diff` wrote the one +changed file in 1271 ms, internal DRAM never dropped below ~48 KB, and the +palette re-walk picked the new file up in the background (0 KB internal +consumed — interning confirmed). Run 2 had crashed there in libgit2's +`checkout_tree` (O(tree) workdir walk + internal-DRAM exhaustion + an esp-idf +spi_master NULL-deref on its own failed-alloc path); the rebuild as an +O(changed) tree-diff apply plus three memory fixes (file-list interning, +64 KB DMA reserve, TLS session reuse) is what run 3 verified. Run-1 bonus: +the first on-device rejected-push → reconcile → replay → push success; run 3 +repeated that cycle at 24 s total (was 59 s — the reconcile fetch fell from +~30 s to ~5 s with session resumption). Residual watch item from run 3: +boot loaded 1 byte from notes.md but `:w` saved 0 — possible trailing-newline +round-trip asymmetry on an empty-note buffer (host-test it; harmless here, +the tree was unchanged). - [x] `/` forward search, `n N` — core 2026-07-13, panel-verified 2026-07-14 (including `n`/`N`). Literal substring (no regex on-device), matched @@ -32,11 +38,13 @@ rejected-push → reconcile → replay → push success (replay commit 59444a94) (survives buffer switches, like vim's search register). `n`/`N` are motions (counts work, Visual extends over them); deliberately **not** operator targets (`dn` out of scope). -- [~] `:gl` — pull: fetch + **fast-forward only**, refuse on divergence and +- [x] `:gl` — pull: fetch + **fast-forward only**, refuse on divergence and surface it (renamed from the planned `:Gpull`). On-device 2026-07-14: - **UpToDate shape, dirty-journal gate, and the reconcile/replay path - verified**; the **Pulled (fast-forward) shape is rebuilt after the run-2 - crash and awaits its on-device pass** — the closing gate. How it works: + UpToDate shape, dirty-journal gate, and the reconcile/replay path + verified (runs 1 and 3); **Pulled (fast-forward) verified run 3** + (ls-refs 2792 ms, download 5136 ms, apply 1271 ms / 1 file, `:gl` total + 16.0 s — ~3 s of the total is still unaccounted connect/negotiation, + tracked with the publish gap below). How it works: - The git thread takes a `GitRequest::Pull` on the same channel as publish (shared `ensure_online` Wi-Fi/clock/TLS preamble). `pull_once` does **ls-refs first**: the ref advertisement alone answers "anything new?", so @@ -79,16 +87,21 @@ all three compose): SPIRAM-malloc threshold), a main contributor to the DMA-pool exhaustion. The walk now emits one newline-joined blob (seeded at 64 KB → PSRAM); the editor stores blob + sorted spans (`set_file_list_joined`) and the - palette reads slices. Expected walk log line now: ~0 KB internal - consumed — confirm on the next boot. + palette reads slices. **Confirmed run 3**: the post-pull re-walk logged + `0 KB consumed, blob 51 KB`. (The boot walk's "125 KB consumed" is a + measurement artifact — that window runs concurrently with USB attach and + other boot allocations; the quiescent re-walk is the clean reading.) - [x] **DMA reserve 32 → 64 KB** (`CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL`) — the esp-idf SPI driver crashes rather than errors on a failed DMA alloc, so the floor must be generous enough that it never sees one. - [x] **TLS session resumption + one-connection pull** — every git op paid a full multi-second handshake (a rejected-push `:sync` runs three). `esp_mbedtls_stream.c` (second vendor delta) caches the mbedTLS session - at stream close and offers it on the next connect to the same host; - measure as first-op vs second-op `ls-refs`/handshake time in a session. + at stream close and offers it on the next connect to the same host. + First same-session evidence (run 3): the reconcile fetch — always the + second connection of a rejected-push `:sync` — fell from ~30 s (run 1) + to ~5 s; a controlled first-op vs second-op `ls-refs` comparison is + still worth logging when convenient. Sync performance — inherited from the [real-repo-sync kaizen](kaizen/real-repo-sync.md) (closed 2026-07-13 at @@ -98,7 +111,9 @@ Sync performance — inherited from the and the ~7 s of repo-open/negotiation overhead are the next curves ([tradeoff analysis](tradeoff-curves/sync-commit-staging.md)). TLS session resumption (above) attacks the negotiation half; re-measure a - warm `:sync` before hunting further. + warm `:sync` before hunting further. Run-3 data point: a rejected-push + `:sync` (worst case, three connections) totalled 24.0 s vs 59 s in + run 1; a clean warm publish is still unmeasured. - [~] Instrument the residual ~360 ms/loose-write (suspect: FAT directory-op cost in the freshen/refresh path) — **instrumentation BUILT 2026-07-14, measurement run pending**: `sd_bench` grew a directory-entry-scaling