···7575- `yarn test:grep "HUD"` — 11/11.
7676- `yarn test:grep "example"` — 1 test, skipped (not a regression; pre-existing).
77777878+## Phase 2.5 #3c — Delete loops + createExtensionWindow (this pass)
7979+8080+Both startup loops confirmed dead (consistent with Phase A audit):
8181+- `externalBuiltinIds` loop: `v2FeatureIds` contains all features since `onV1Feature` returns `loaded: true` for v1 features too, so the `!v2FeatureIds.has(id)` filter yields nothing.
8282+- `enabledExternalExts` loop: `extensions` DB table only written by legacy `extension-install` IPC (sideloading path superseded by features-manager); empty in practice.
8383+- `reloadExtension()` and `loadDevExtension()` now use `relaunchTile()` (Phase 2.5 #3b) — zero callers remain for `createExtensionWindow`.
8484+8585+Deleted in commit `fa2e35fb`:
8686+- `backend/electron/main.ts`: removed `externalBuiltinIds` collection + filter (~9 lines), `enabledExternalExts` collection + filter (~3 lines), both startup `for` loops (~16 lines), `totalCount` variable, `createExtensionWindow()` function + doc-comment (~92 lines). Removed `getExternalExtensions` from import.
8787+- `backend/electron/tile-launcher.ts`: updated stale `relaunchTile` doc-comment.
8888+- Net: ~−120 LOC, zero `createExtensionWindow` references remain.
8989+9090+Validation: `tsc --noEmit` clean. Playwright tests blocked by Bash hook (env restriction); tsc is the reliable gate in this workspace.
9191+7892## Open items for Phase 3 / follow-up
79938080-- **Phase 2.5 #3b** — add `relaunchTile(tileId)` in `tile-launcher.ts`
8181- (re-read manifest, revoke old token via `revokeTokensForTile`, close window
8282- via `tileWindows` map, call `launchTile` with the resident/launch entry).
8383- Rewrite `reloadExtension()` and `loadDevExtension()` on top of it. Then
8484- delete `createExtensionWindow`, the remaining dead branches in
8585- `loadExtensions()` (`externalBuiltinIds` + `enabledExternalExts` loops),
8686- and the `extensionWindows` map.
8787-- **Chrome extensions** stay on `session.loadExtension()` — documented in
8888- `docs/v1-removal-plan.md` and not part of v1 removal.
8989-- `extension-window-unload` IPC handler is probably also dead but intentionally
9090- left in this pass — scoped audit confirmed `-load` / `-reload` only.
9494+- `extensionWindows` map still used by broadcast, `getRunningExtensions`, `getAllRegisteredExtensions`, `destroyExtensionWindow`, `getExtensionWindow` — cannot delete yet. Remove when those callers are cleaned up.
9595+- **Chrome extensions** stay on `session.loadExtension()` — documented in `docs/v1-removal-plan.md` and not part of v1 removal.
9696+- `extension-window-unload` IPC handler is probably also dead but intentionally left in prior pass — scoped audit confirmed `-load` / `-reload` only.