thumbgate 1.26.3 → 1.26.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thumbgate",
3
- "version": "1.26.3",
3
+ "version": "1.26.4",
4
4
  "description": "ThumbGate self-improving agent governance: thumbs-up/down turns every mistake into a prevention rule and blocks repeat patterns. 36 pre-action checks, budget enforcement, and self-protection for Claude Code, Cursor, Codex, Gemini CLI, and Amp.",
5
5
  "homepage": "https://thumbgate.ai",
6
6
  "repository": {
@@ -1061,6 +1061,13 @@ function isBreakGlassSettingsBypass(gate, affectedFiles) {
1061
1061
  return Array.isArray(affectedFiles) && affectedFiles.length > 0 && affectedFiles.every(isAgentHookSettingsFile);
1062
1062
  }
1063
1063
 
1064
+ function isBreakGlassSettingsRecoveryAction(toolName, toolInput = {}) {
1065
+ if (!EDIT_LIKE_TOOLS.has(toolName)) return false;
1066
+ if (!isConditionSatisfied(BREAK_GLASS_CONDITION)) return false;
1067
+ const affectedFiles = extractAffectedFiles(toolName, toolInput).files;
1068
+ return affectedFiles.length > 0 && affectedFiles.every(isAgentHookSettingsFile);
1069
+ }
1070
+
1064
1071
  function formatFileList(files, limit = 5) {
1065
1072
  const items = Array.isArray(files) ? files.filter(Boolean) : [];
1066
1073
  if (items.length === 0) return 'none';
@@ -1601,6 +1608,18 @@ async function evaluateGatesAsync(toolName, toolInput, configPath) {
1601
1608
  if (localOnlyRemoteSideEffectGate) {
1602
1609
  return recordStructuralGateBlock(toolName, toolInput, localOnlyRemoteSideEffectGate);
1603
1610
  }
1611
+ if (isBreakGlassSettingsRecoveryAction(toolName, toolInput)) {
1612
+ recordAuditEvent({
1613
+ toolName,
1614
+ toolInput,
1615
+ decision: 'allow',
1616
+ gateId: BREAK_GLASS_CONDITION,
1617
+ message: 'Break-glass recovery allowed hook settings edit',
1618
+ severity: 'high',
1619
+ source: 'gates-engine',
1620
+ });
1621
+ return null;
1622
+ }
1604
1623
 
1605
1624
  const pendingThreadResolutionGate = evaluatePendingPrThreadResolutionGate(toolName, toolInput);
1606
1625
  if (pendingThreadResolutionGate) {
@@ -1815,6 +1834,18 @@ function evaluateGates(toolName, toolInput, configPath) {
1815
1834
  if (localOnlyRemoteSideEffectGate) {
1816
1835
  return recordStructuralGateBlock(toolName, toolInput, localOnlyRemoteSideEffectGate);
1817
1836
  }
1837
+ if (isBreakGlassSettingsRecoveryAction(toolName, toolInput)) {
1838
+ recordAuditEvent({
1839
+ toolName,
1840
+ toolInput,
1841
+ decision: 'allow',
1842
+ gateId: BREAK_GLASS_CONDITION,
1843
+ message: 'Break-glass recovery allowed hook settings edit',
1844
+ severity: 'high',
1845
+ source: 'gates-engine',
1846
+ });
1847
+ return null;
1848
+ }
1818
1849
 
1819
1850
  const pendingThreadResolutionGate = evaluatePendingPrThreadResolutionGate(toolName, toolInput);
1820
1851
  if (pendingThreadResolutionGate) {
@@ -2850,6 +2881,7 @@ module.exports = {
2850
2881
  isRemoteSideEffectCommand,
2851
2882
  evaluateLocalOnlyRemoteSideEffectGate,
2852
2883
  isAgentHookSettingsFile,
2884
+ isBreakGlassSettingsRecoveryAction,
2853
2885
  PR_THREAD_RESOLUTION_ACTION,
2854
2886
  buildBlockActionProCta,
2855
2887
  applyDailyBlockCap,