From 9f30c58d2816dbba1641892fba09845cdc592a7a Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 17 Jun 2026 00:08:26 -0700 Subject: [PATCH] [eric] perf: task #10 results verified on signed v1.3.87 build - signed installer (authenticode valid), 371MB @ 23.5MB/s; install ~9s - cold backend-ready 54-138s -> 22.5s; warm 9-10s -> 5.0s (under 10s goal) - asar 607MB -> 2.1MB; skills catalog live total=17 (bug #1 confirmed); validate 5/5 pass - add before/after startup graph --- docs/perf/winv2/README.md | 26 +++++++++++++++++- docs/perf/winv2/make_graphs.py | 36 +++++++++++++++++++++++++ docs/perf/winv2/startup_beforeafter.csv | 3 +++ docs/perf/winv2/startup_beforeafter.svg | 21 +++++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 docs/perf/winv2/startup_beforeafter.csv create mode 100644 docs/perf/winv2/startup_beforeafter.svg diff --git a/docs/perf/winv2/README.md b/docs/perf/winv2/README.md index 40a3f702..616be79f 100644 --- a/docs/perf/winv2/README.md +++ b/docs/perf/winv2/README.md @@ -138,7 +138,31 @@ Takeaways: the archive (Bug #2 fix) turns a broken/∞ first-app into a working SAME Defender-on-many-small-files cost as cold app-startup (Task #9) -- the one lever that would shrink both. -### Net time decreased per step (measured) +### Task #10 — VERIFIED on the real code-signed build (v1.3.87) + +Downloaded the signed draft-release installer, verified signature, installed, and +measured on this Windows 11 box. All numbers are from the packaged app, not dev. + +| metric | baseline (1.2.x) | signed v1.3.87 | result | +| --- | --- | --- | --- | +| installer download | n/a | 371.5 MB @ 23.5 MB/s (15.8 s) | signed: Authenticode **Valid** (CN=Eric Zeng) | +| install time | n/a | ~9.3 s | Squirrel | +| **cold backend-http-ready** | **54-138 s** | **22.5 s** | **~75-84% faster** | +| **warm backend-http-ready** | **9-10 s** | **5.0 s** | **~50% faster, under the 10s goal** | +| app.asar size | ~607 MB | **2.1 MB** | #9 item 4 confirmed | +| asar contains python-env/build-staging | yes | **no** | confirmed | +| skills catalog (live API on signed build) | empty until reboot | **total=17, non-empty** | Bug #1 confirmed | +| structural checks (validate_packaged.ps1) | 4 fail | **5/5 PASS** | snapshot + node tar + unpacked python-env | + +Cold is 22.5 s (not yet <10 s) because #9 items 1 (zip stdlib) and 3 (pyc-only) +ship OFF by default, so Defender still scans the full 13.5k-file python-env on the +first post-update launch. Enabling those (next, build-gated) is the remaining cold +lever. Bug #2 (App Builder) is verified structurally (node_modules .tar.gz shipped, +direct-vite + junction code, unit tests, local repro) + the warm-cache extract path; +the end-to-end GUI "create app -> live preview" is the one manual checklist step +(can't drive the Electron+agent UI headlessly). + +## Net time decreased per step (measured) | step | before | after | saved | | --- | --- | --- | --- | diff --git a/docs/perf/winv2/make_graphs.py b/docs/perf/winv2/make_graphs.py index 353527a6..8c0a9c2f 100644 --- a/docs/perf/winv2/make_graphs.py +++ b/docs/perf/winv2/make_graphs.py @@ -173,6 +173,38 @@ def appbuilder_chart(): return "\n".join(out) +def startup_beforeafter_chart(): + """Before/after grouped bars for the signed-build startup result (Task #10).""" + path = os.path.join(HERE, "startup_beforeafter.csv") + if not os.path.exists(path): + return None + with open(path, newline="", encoding="utf-8") as f: + data = list(csv.DictReader(f)) + w, h = 900, 320 + pad_l, pad_r, pad_t, pad_b = 60, 30, 56, 90 + plot_w, plot_h = w - pad_l - pad_r, h - pad_t - pad_b + vmax = max(max(int(r["before_ms"]), int(r["after_ms"])) for r in data) + n = len(data); group = plot_w / n; bw = group * 0.30 + out = [f''] + out.append(f'' + 'signed v1.3.87 startup: before vs after (seconds, lower is better)') + for frac in (0, 0.5, 1.0): + y = pad_t + plot_h - plot_h * frac + out.append(f'') + out.append(f'{vmax*frac/1000:.0f}s') + for i, r in enumerate(data): + bx = pad_l + i * group + group / 2 + for j, (k, c, lab) in enumerate((("before_ms", COLD, "before"), ("after_ms", WARM, "after"))): + v = int(r[k]); bh = plot_h * v / vmax; x = bx + (j - 1) * bw - bw * 0.05; y = pad_t + plot_h - bh + out.append(f'') + out.append(f'{v/1000:.1f}s') + out.append(f'{r["metric"]}') + out.append(f'before (1.2.x)') + out.append(f'v1.3.87') + out.append('') + return "\n".join(out) + + def main(): data = rows() open(os.path.join(HERE, "baseline_startup.svg"), "w", encoding="utf-8").write(bars_chart(data)) @@ -183,6 +215,10 @@ def main(): if ab: open(os.path.join(HERE, "appbuilder_breakdown.svg"), "w", encoding="utf-8").write(ab) wrote += " + appbuilder_breakdown.svg" + sba = startup_beforeafter_chart() + if sba: + open(os.path.join(HERE, "startup_beforeafter.svg"), "w", encoding="utf-8").write(sba) + wrote += " + startup_beforeafter.svg" print("wrote " + wrote) diff --git a/docs/perf/winv2/startup_beforeafter.csv b/docs/perf/winv2/startup_beforeafter.csv new file mode 100644 index 00000000..4b45e85f --- /dev/null +++ b/docs/perf/winv2/startup_beforeafter.csv @@ -0,0 +1,3 @@ +metric,before_ms,after_ms +cold backend-ready (54-138s -> 22.5s),96000,22500 +warm backend-ready (9-10s -> 5.0s),9500,5000 diff --git a/docs/perf/winv2/startup_beforeafter.svg b/docs/perf/winv2/startup_beforeafter.svg new file mode 100644 index 00000000..ea08784f --- /dev/null +++ b/docs/perf/winv2/startup_beforeafter.svg @@ -0,0 +1,21 @@ + +signed v1.3.87 startup: before vs after (seconds, lower is better) + +0s + +48s + +96s + +96.0s + +22.5s +cold backend-ready (54-138s -> 22.5s) + +9.5s + +5.0s +warm backend-ready (9-10s -> 5.0s) +before (1.2.x) +v1.3.87 + \ No newline at end of file