fix: add gateguard recovery escape hatch

This commit is contained in:
Affaan Mustafa
2026-04-30 10:45:43 -04:00
committed by Affaan Mustafa
parent 4c8499d509
commit cfe770a735
4 changed files with 85 additions and 2 deletions

View File

@@ -38,11 +38,25 @@ const READ_HEARTBEAT_MS = 60 * 1000;
const MAX_CHECKED_ENTRIES = 500;
const MAX_SESSION_KEYS = 50;
const ROUTINE_BASH_SESSION_KEY = '__bash_session__';
const LEGACY_DISABLE_VALUES = new Set(['1', 'true', 'yes', 'on']);
const ECC_DISABLE_VALUES = new Set(['0', 'false', 'off', 'disabled', 'disable']);
const DESTRUCTIVE_BASH = /\b(rm\s+-rf|git\s+reset\s+--hard|git\s+checkout\s+--|git\s+clean\s+-f|drop\s+table|delete\s+from|truncate|git\s+push\s+--force(?!-with-lease)|git\s+commit\s+--amend|dd\s+if=)\b/i;
// --- State management (per-session, atomic writes, bounded) ---
function normalizeEnvValue(value) {
return String(value || '').trim().toLowerCase();
}
function isGateGuardDisabled() {
if (LEGACY_DISABLE_VALUES.has(normalizeEnvValue(process.env.GATEGUARD_DISABLED))) {
return true;
}
return ECC_DISABLE_VALUES.has(normalizeEnvValue(process.env.ECC_GATEGUARD));
}
function sanitizeSessionKey(value) {
const raw = String(value || '').trim();
if (!raw) {
@@ -352,6 +366,14 @@ function routineBashMsg() {
].join('\n');
}
function withRecoveryHint(message) {
return [
message,
'',
'Recovery: if GateGuard is blocking setup or repair work, run this session with `ECC_GATEGUARD=off` or add `pre:edit-write:gateguard-fact-force` to `ECC_DISABLED_HOOKS`.'
].join('\n');
}
// --- Deny helper ---
function denyResult(reason) {
@@ -360,7 +382,7 @@ function denyResult(reason) {
hookSpecificOutput: {
hookEventName: 'PreToolUse',
permissionDecision: 'deny',
permissionDecisionReason: reason
permissionDecisionReason: withRecoveryHint(reason)
}
}),
exitCode: 0
@@ -383,6 +405,11 @@ function run(rawInput) {
} catch (_) {
return rawInput; // allow on parse error
}
if (isGateGuardDisabled()) {
return rawInput;
}
activeStateFile = null;
getStateFile(data);