From a921bcd9ef1d8945879b1ee5b6d2a45016c18267 Mon Sep 17 00:00:00 2001 From: Jason Matthew Suhari Date: Thu, 19 Mar 2026 14:47:13 +0800 Subject: [PATCH] fix(core): don't persist browser consent sentinel in non-interactive mode (#23073) --- packages/core/src/utils/browserConsent.test.ts | 10 ++++------ packages/core/src/utils/browserConsent.ts | 6 ++++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/core/src/utils/browserConsent.test.ts b/packages/core/src/utils/browserConsent.test.ts index f145632068..307921293e 100644 --- a/packages/core/src/utils/browserConsent.test.ts +++ b/packages/core/src/utils/browserConsent.test.ts @@ -47,7 +47,7 @@ describe('browserConsent', () => { expect(emitSpy).not.toHaveBeenCalled(); }); - it('should auto-accept in non-interactive mode (no listeners)', async () => { + it('should auto-accept in non-interactive mode (no listeners) without persisting consent', async () => { // Consent file does not exist vi.mocked(fs.access).mockRejectedValue(new Error('ENOENT')); // No listeners registered @@ -56,11 +56,9 @@ describe('browserConsent', () => { const result = await getBrowserConsentIfNeeded(); expect(result).toBe(true); - // Should persist the consent - expect(fs.writeFile).toHaveBeenCalledWith( - expect.stringContaining('browser-consent-acknowledged.txt'), - expect.stringContaining('consent acknowledged'), - ); + // Should NOT persist the consent — an interactive user on the same machine + // must still see the dialog the first time they use the browser agent. + expect(fs.writeFile).not.toHaveBeenCalled(); }); it('should request consent interactively and return true when accepted', async () => { diff --git a/packages/core/src/utils/browserConsent.ts b/packages/core/src/utils/browserConsent.ts index 097c3b683e..8a651e0694 100644 --- a/packages/core/src/utils/browserConsent.ts +++ b/packages/core/src/utils/browserConsent.ts @@ -42,9 +42,11 @@ export async function getBrowserConsentIfNeeded(): Promise { void 0; } - // Non-interactive mode (no UI listeners): auto-accept. + // Non-interactive mode (no UI listeners): skip the dialog for this session + // only. Do NOT persist the sentinel file — an interactive user on the same + // machine should still see the consent dialog the first time they use the + // browser agent. if (coreEvents.listenerCount(CoreEvent.ConsentRequest) === 0) { - await markConsentAsAcknowledged(consentFilePath); return true; }