From 7f7249d3d2698a2af65c2caccd99c8a8cca9bad8 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Mon, 20 Apr 2026 07:17:16 +0800 Subject: [PATCH] fix(security): make GSTACK_SECURITY_OFF a real kill switch Docs promised env var would disable ML classifier load. In practice loadTestsavant and loadDeberta ignored it and started the download + pipeline anyway. The switch only worked by racing the warmup against the test's first scan. Add an explicit early-return on the env value. Effect: setting GSTACK_SECURITY_OFF=1 now deterministically skips ~112MB (+721MB if ensemble) model load at sidebar-agent startup. Canary layer and content-security layers stay active. Co-Authored-By: Claude Opus 4.7 (1M context) --- browse/src/security-classifier.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/browse/src/security-classifier.ts b/browse/src/security-classifier.ts index f934d5da..a0a6ab06 100644 --- a/browse/src/security-classifier.ts +++ b/browse/src/security-classifier.ts @@ -174,6 +174,11 @@ async function ensureTestsavantStaged(onProgress?: (msg: string) => void): Promi let loadPromise: Promise | null = null; export function loadTestsavant(onProgress?: (msg: string) => void): Promise { + if (process.env.GSTACK_SECURITY_OFF === '1') { + testsavantState = 'failed'; + testsavantLoadError = 'GSTACK_SECURITY_OFF=1 — ML classifier kill switch engaged'; + return Promise.resolve(); + } if (testsavantState === 'loaded') return Promise.resolve(); if (loadPromise) return loadPromise; testsavantState = 'loading'; @@ -299,6 +304,7 @@ async function ensureDebertaStaged(onProgress?: (msg: string) => void): Promise< let debertaLoadPromise: Promise | null = null; export function loadDeberta(onProgress?: (msg: string) => void): Promise { + if (process.env.GSTACK_SECURITY_OFF === '1') return Promise.resolve(); if (!isDebertaEnabled()) return Promise.resolve(); if (debertaState === 'loaded') return Promise.resolve(); if (debertaLoadPromise) return debertaLoadPromise;