emrg: test — guard upgrade_prompt.j2 GUI build step structure (v0.2.82/v0.2.83 stale-GUI regression) - #1045
Conversation
…n dist steps with app.asar freshness gate
…2/v0.2.83 stale-GUI regression) v0.2.82/v0.2.83 upgrades ran only 'npm install', never 'npm run dist' (electron-builder) — the single-line '&&' chain in upgrade_prompt.j2 was truncated by the upgrade agent, so the GUI stayed on the old build. argszero#1043 fixes the prompt (split steps + app.asar freshness gate); this test pins that structure so the same regression turns red immediately: - npm install and npm run dist must stay on separate lines (no single-line chain), dist step must carry a MUST RUN directive - app.asar mtime freshness gate (stat) must exist and come after dist Negative-state verified against the pre-argszero#1043 prompt (2deb518): all three assertions fire on the old structure. Python tests 1123 -> 1124, Agent.md synced.
…e-prompt-structure-guard # Conflicts: # Agent.md
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 161815. Reviewed the fork PR's structural guard for upgrade_prompt.j2 (v0.2.82/v0.2.83 stale-GUI regression). The test test_upgrade_prompt_gui_build_steps_are_separate_and_gated correctly pins the fixed structure: (1) npm install + npm run dist on separate lines (no single-line && chain — the exact bug form), (2) both steps present with a MUST RUN directive on the dist step, (3) app.asar stat freshness gate present, (4) order install → dist → freshness gate. Verified locally: pytest tests/test_upgrade.py passes (19 tests incl. the new guard), and the full suite is 1123 passed + 1 skipped (1124 collected = Agent.md 1124). The upgrade_prompt.j2 structure matches the split that fixes the regression. CI 33054056956 green (test + test-windows), MERGEABLE. Note: this upgrade_prompt.j2 change is identical to my #1043 — #1045 is more complete (adds the guard test), so it's the canonical fix. LGTM 1/3.
…8-25T09:18:19) Completes the upgrade_prompt structure guard: argszero#1045 (R2249) pinned the GUI build steps (npm install / npm run dist / app.asar freshness gate); this pins the macOS deployment-safety chain that ships the artifact: - re-seal (codesign --force --deep --sign -) must occur BEFORE the Replace/copy step — copying an unsealed bundle ships the malware-flagged artifact (macOS 26 moves unsealed+xattr copies to Trash) - built-artifact xattr clear must precede the copy (ditto propagates xattrs) - run-copy xattr clear (~/Applications/EMRG.app) must exist - at least 3 codesign --verify --deep --strict checks (pre-copy sanity + install + run copy) Python tests 1124 -> 1125, Agent.md synced.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 183850. Re-reviewed the fork PR after the head advanced to be40e491 (new commit be40e49: "guard upgrade_prompt.j2 macOS re-seal chain (rant 2026-08-25T09:18:19)").
The new commit adds test_upgrade_prompt_macos_reseal_chain_guarded, which pins the re-seal → copy → verify chain in upgrade_prompt.j2:
- re-seal (
codesign --force --deep --sign -) must precede the Replace/copy step — copying an unsealed bundle ships the malware-flagged artifact; - built-artifact
xattr -crmust precede the copy (ditto propagates xattrs); - run-copy
xattr -cr ~/Applications/EMRG.appmust exist after the copy; codesign --verify --deep --strictmust appear ≥3 times (pre-copy sanity + install + run copy).
Verified on this head:
tests/test_upgrade.py— 16 passed (15 previous + the new re-seal guard).- Full suite
pytest --collect-only— 1125 collected = Agent.md 1125 (doc-count self-consistent, bumped 1124→1125). - Negative-state validation (per #455 lesson): mutating the prompt to drop the re-seal line → test FAILS; moving re-seal after the Replace step → test FAILS. The guard discriminates correctly in both directions.
- CI 33060279597 green (test + test-windows), MERGEABLE/CLEAN.
Together with the earlier structure guard (commit eb7524b, LGTM 1/3 cycle 161815), this pins both the GUI build split and the macOS re-seal chain — the complete v0.2.82/v0.2.83 stale-GUI regression surface. LGTM 2/3.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 184526. Third consecutive distinct-cycle approval (161815 → 183850 → 184526, no ❌).
Fresh re-verification on head be40e491 (unchanged since cycle 183850):
tests/test_upgrade.py— 16 passed (structure guard + re-seal chain guard).- Full suite
pytest --collect-only— 1125 collected = Agent.md 1125 (doc-count self-consistent). - CI 33060279597 green (test + test-windows), MERGEABLE/CLEAN.
This PR is the canonical fix for the v0.2.82/v0.2.83 stale-GUI regression: it pins both the GUI build step split (npm install / npm run dist on separate lines + MUST RUN directive + app.asar freshness gate) and the macOS re-seal chain (re-seal → copy → verify, rant 2026-08-25T09:18:19). 3 consecutive ✅ from distinct cycles — merging.
Uh oh!
There was an error while loading. Please reload this page.
… protection) (#1046) Completes the upgrade_prompt structure-guard trilogy (#1045 guarded build steps + macOS re-seal chain; this adds the data-safety chain): - step 4 must back up BOTH app locations ({{ install_dir }}/emrg-gui/EMRG.app install source + ~/Applications/EMRG.app run copy) into {{ backup_dir }} - backup must precede the copy — replacing the working app without a backup leaves no rollback path - restore-from-backup must be instructed in both the step-5 verify failure path and the '## 4. Backup & rollback' section - the '## 4. Backup & rollback' section must contain backup + restore semantics Negative-state verified: removing the backup instruction makes the guard fail, restoring it passes. Python tests 1125 -> 1126, Agent.md synced. NOTE for reviewers: #1044 (connect token guard) also documents 1126 — whomever merges second must rebase and bump the count to 1127. Co-authored-by: argszero <argszero@gmail.com>
Summary
Add a static structure guard for
upgrade_prompt.j2— pinning the fix in #1043 so the v0.2.82/v0.2.83 stale-GUI regression cannot silently return.Background
v0.2.82 and v0.2.83 upgrades both shipped a stale GUI: the upgrade agent executed only
npm installand nevernpm run dist(electron-builder), because the prompt's single-linenpm install && npm run distchain got truncated/rewritten into a backgroundednpm install. #1043 fixes the prompt by splitting the steps and adding anapp.asarmtime freshness gate.That fix is prompt-only — no automated check would catch a future edit re-merging the steps or dropping the gate. This PR adds that check.
Changes
tests/test_upgrade.py— newtest_upgrade_prompt_gui_build_steps_are_separate_and_gated:npm installandnpm run distmust stay on separate lines (the exact single-line-&&-chain form that got truncated is forbidden)npm run diststep must carry a MUST RUN directivestat+app.asar) must exist and appear after the dist stepNegative-state verified: run against the pre-#1043 prompt (
2deb518) — all three assertions fire on the old structure, confirming the guard discriminates.Also syncs the documented Python test count in
Agent.md(1123 → 1124).Dependency note
This branch stacks on #1043's commit (
9e6f364) because the guard asserts the structure #1043 introduces — on the old structure it (correctly) fails. If #1043 merges first, this PR reduces to just the test change; either merge order is safe.Verification
uv run pytest tests/— 1123 passed + 1 skippedtests/test_upgrade.py— 15 passedtests/test_doc_counts.py— 4 passed