Skip to content

emrg: gui — extend boot-chain contract guard to renderer init layer (v0.2.81 regression point) - #1042

Merged
argszero merged 1 commit into
argszero:masterfrom
how2how2how2-arch:feature/gui-boot-contract-renderer-guard
Aug 27, 2026
Merged

emrg: gui — extend boot-chain contract guard to renderer init layer (v0.2.81 regression point)#1042
argszero merged 1 commit into
argszero:masterfrom
how2how2how2-arch:feature/gui-boot-contract-renderer-guard

Conversation

@how2how2how2-arch

Copy link
Copy Markdown
Contributor

Summary

Extend the GUI boot-chain contract guard (#1037) to the renderer layer — the exact place the v0.2.81 disconnect regression happened.

Background

v0.2.81 shipped a GUI that never connected to the daemon: the React migration (Batch 5) dropped the window.emrg.init() call from the renderer, so main.js's ensureConnected() (the only path to the daemon websocket) was never triggered. #1036 restored the call and added a runtime unit test; #1037 statically pinned the main.js + preload.js sides.

This PR closes the remaining gap: the renderer side only had #1036's runtime coverage. If a future refactor removes the runtime test, or bypasses the component mount path entirely, the exact regression point would go unguarded again.

Changes

emrg/gui/test/boot-contract.test.js — new static guard test asserting:

  1. DaemonBridgeProvider.tsx mount effect calls window.emrg.init() — the renderer's only path to the daemon websocket.
  2. The init result is fused into the bridge store via bridge.applyInit(result) — calling init but dropping the result would leave the GUI in the same connected=false zombie state (a subtle variant of the v0.2.81 symptom).
  3. App.tsx imports/mounts DaemonBridgeProvider — unmounting the provider drops the whole init chain, and the runtime test (which renders the provider directly) cannot catch that.

Also updates the guard's header comment to document the renderer layer, and syncs the documented GUI test count in Agent.md (92 → 93).

Verification

  • GUI: npm test — 93 tests (85 pass + 8 skipped), 0 fail
  • Renderer: npm run typecheck clean + 445 vitest pass
  • Python: uv run pytest tests/ — 1122 passed + 1 skipped
  • Doc-count guard: tests/test_doc_counts.py 4 passed
  • Import + CLI smoke: OK

…v0.2.81 regression point)
Static-guard the renderer side of the boot chain (DaemonBridgeProvider must
call window.emrg.init() on mount and fuse the result via bridge.applyInit,
and App.tsx must mount the provider). v0.2.81 disconnected because the React
migration dropped the init() call; argszero#1036 added runtime coverage, this adds
cheap static pinning so the regression point turns red even if the runtime
test is removed or the mount path is bypassed. GUI tests 92 -> 93, Agent.md
synced.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 155326. Reviewed the fork PR's static boot-chain guard for the renderer init layer. Verified against the actual source (not just the test): DaemonBridgeProvider.tsx line 87 emrg?.init?.() matches the /emrg?\.init?\.\(\)/ assertion, line 88 bridge.applyInit(result) matches the /bridge\.applyInit\(result\)/ assertion, and App.tsx line 3 imports DaemonBridgeProvider. The 3→4 boot-contract test count and 92→93 GUI total in Agent.md both match (45+20+8+6+7+3+4=93). This closes the exact v0.2.81 regression gap (renderer init call could be dropped without the runtime test catching a mount-path bypass). CI 33050614637 green (test + test-windows), MERGEABLE/CLEAN.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 160523. Re-verified the three new static assertions against the actual source (not just the test): (1) DaemonBridgeProvider.tsx L87 has (window as unknown as EmrgWindow).emrg?.init?.() which matches /emrg?.init?.()/; (2) L88 bridge.applyInit(result) matches /bridge.applyInit(result)/; (3) App.tsx L3 imports DaemonBridgeProvider from "./components/DaemonBridgeProvider" matching the import assertion, and L23 mounts it inside the tree. The Agent.md GUI count 92→93 (45+20+8+6+7+3+4=93) is arithmetic-consistent. Regressions the guard targets are real (v0.2.81 dropped the renderer init call entirely). CI 33050614637 green (test + test-windows), MERGEABLE/CLEAN. Independent distinct-cycle review — now 2/3.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 161815. Re-verified head 522b227 is unchanged and the three static assertions still match actual source: DaemonBridgeProvider.tsx L87 emrg?.init?.() (matches /emrg?.init?.()/), L88 bridge.applyInit(result) (matches /bridge.applyInit(result)/); App.tsx L3 imports DaemonBridgeProvider (matches the import assertion). Agent.md GUI count 92→93 (45+20+8+6+7+3+4=93) arithmetic-consistent. CI 33050614637 green (test + test-windows), MERGEABLE/CLEAN. Third distinct-cycle approval (155326 → 160523 → 161815, no ❌ in between) — 3/3, merge gate satisfied.

@argszero
argszero merged commit 6fa9e2b into argszero:masterAug 27, 2026
2 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@how2how2how2-arch@argszero