From 17fcd166d7ca34f1ed5766c24528a50ae1204acb Mon Sep 17 00:00:00 2001 From: Glenn Gore Date: Wed, 5 Aug 2026 13:15:36 +0200 Subject: [PATCH] feat(consent): log where the consent window was opened #106 made a window that cannot be created a logged denial. The remaining blind spot is the opposite case: creation succeeds, a window id comes back, and the user still sees nothing. Those two are indistinguishable from the outside -- "no popup, no errors" -- and that ambiguity is exactly what made the silent hang take days to find. A window id proves creation succeeded; it does not prove the window is visible. consentWindowBounds derives left/top from chrome.windows.getLastFocused(), so a minimised window, a second display, or an undocked DevTools window can place the prompt somewhere the user never looks. Logging the id and the computed bounds makes "I see no popup" answerable: either no line (never reached creation), the #106 error (creation failed), or a line naming coordinates that can be checked against the actual displays. Logging only; no behaviour change. Both consent surfaces. Signed-off-by: Glenn Gore --- packages/extension/src/background.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packages/extension/src/background.ts b/packages/extension/src/background.ts index 043f036..7beeacd 100644 --- a/packages/extension/src/background.ts +++ b/packages/extension/src/background.ts @@ -592,6 +592,18 @@ async function requestConsent(args: { settle(false, false); return; } + // A window id proves creation succeeded; it does NOT prove the window is + // visible. `consentWindowBounds` derives left/top from + // `chrome.windows.getLastFocused()`, so a minimised window, a second + // display, or an undocked DevTools window can place the prompt somewhere + // the user never looks — and that is indistinguishable from no prompt at + // all, which is precisely the ambiguity that made the silent hang above + // so hard to find. Log where it went so "I see no popup" is answerable. + console.info( + "[pnm consent] consent window opened", + "id=", winId, + "bounds=", JSON.stringify(bounds), + ); // Closing the window without a decision is a denial. const onClosed = (closedId: number) => { if (closedId === winId) { @@ -678,6 +690,18 @@ async function requestTaskConsent( settle(false); return; } + // A window id proves creation succeeded; it does NOT prove the window is + // visible. `consentWindowBounds` derives left/top from + // `chrome.windows.getLastFocused()`, so a minimised window, a second + // display, or an undocked DevTools window can place the prompt somewhere + // the user never looks — and that is indistinguishable from no prompt at + // all, which is precisely the ambiguity that made the silent hang above + // so hard to find. Log where it went so "I see no popup" is answerable. + console.info( + "[pnm consent] consent window opened", + "id=", winId, + "bounds=", JSON.stringify(bounds), + ); // Closing the window without deciding is a denial. Never assent: silence // is not agreement, and a task-consent prompt that timed out into an // approval would be the single worst bug in this system.