{
  "version": 1,
  "gates": [
    {
      "id": "local-only-git-writes",
      "layer": "Identity",
      "pattern": "^(git\\s+(add|commit|push|tag)|gh\\s+pr\\s+|gh\\s+release\\s+create|npm\\s+publish|yarn\\s+publish|pnpm\\s+publish)",
      "action": "block",
      "when": { "constraints": { "local_only": true } },
      "message": "User requested local-only work. Git writes, PR operations, and release actions are blocked.",
      "severity": "critical"
    },
    {
      "id": "raw-gh-auto-merge-blocked",
      "layer": "Execution",
      "toolNames": ["Bash"],
      "pattern": "gh\\s+pr\\s+merge\\b[^\\n]*--auto",
      "action": "block",
      "message": "Raw GitHub auto-merge is blocked. Use npm run pr:manage after all critical quality checks have terminal success.",
      "severity": "critical"
    },
    {
      "id": "task-scope-required",
      "layer": "Decisions",
      "toolNames": ["Bash"],
      "pattern": "^(git\\s+(add|commit|push)|gh\\s+pr\\s+(create|merge)|gh\\s+release\\s+create|git\\s+tag\\b|npm\\s+publish|yarn\\s+publish|pnpm\\s+publish)",
      "requireTaskScope": true,
      "action": "block",
      "message": "Git write, PR, release, and publish operations require an explicit task scope.",
      "severity": "critical"
    },
    {
      "id": "task-scope-edit-boundary",
      "layer": "Decisions",
      "toolNames": ["Edit", "Write", "MultiEdit"],
      "pattern": ".*",
      "requireTaskScope": true,
      "scopeMode": "declared-only",
      "action": "block",
      "message": "Edits outside the declared task scope are blocked once a task scope is active.",
      "severity": "critical"
    },
    {
      "id": "protected-file-approval-required",
      "layer": "Decisions",
      "toolNames": ["Edit", "Write", "MultiEdit", "Bash"],
      "pattern": ".*",
      "requireProtectedApproval": true,
      "protectedGlobs": [
        "AGENTS.md",
        "CLAUDE.md",
        "CLAUDE.local.md",
        "GEMINI.md",
        "README.md",
        ".gitignore",
        ".husky/**",
        ".claude/**",
        "skills/**",
        "SKILL.md",
        "config/gates/**"
      ],
      "action": "block",
      "message": "Protected files require explicit approval before editing or publishing.",
      "severity": "critical"
    },
    {
      "id": "gh-pr-create-restricted",
      "layer": "Identity",
      "pattern": "gh\\s+pr\\s+create",
      "action": "block",
      "unless": "pr_create_allowed",
      "message": "PR creation requires explicit 'pr_create_allowed' satisfaction with evidence of user permission.",
      "severity": "high"
    },
    {
      "id": "gh-pr-merge-restricted",
      "layer": "Identity",
      "pattern": "gh\\s+pr\\s+merge",
      "action": "block",
      "unless": "pr_merge_allowed",
      "message": "PR merging requires explicit 'pr_merge_allowed' satisfaction with evidence of user permission.",
      "severity": "high"
    },
    {
      "id": "branch-governance-required",
      "layer": "Decisions",
      "toolNames": ["Bash"],
      "pattern": "^(gh\\s+pr\\s+(create|merge)|gh\\s+release\\s+create|git\\s+tag\\b|npm\\s+publish|yarn\\s+publish|pnpm\\s+publish)",
      "requireBranchGovernance": true,
      "action": "block",
      "message": "PR, release, and publish actions require explicit branch governance.",
      "severity": "critical"
    },
    {
      "id": "release-readiness-required",
      "layer": "Execution",
      "toolNames": ["Bash"],
      "pattern": "^(gh\\s+release\\s+create|git\\s+tag\\b|npm\\s+publish|yarn\\s+publish|pnpm\\s+publish)",
      "requireReleaseReadiness": true,
      "action": "block",
      "message": "Release and publish actions require a releasable mainline commit and a matching version plan.",
      "severity": "critical"
    },
    {
      "id": "admin-merge-bypass-blocked",
      "layer": "Execution",
      "pattern": "gh\\s+pr\\s+merge.*--admin",
      "action": "block",
      "message": "Admin merge bypass is blocked. Use the merge queue or normal protected-branch flow.",
      "severity": "critical"
    },
    {
      "id": "loop-abuse-prevention",
      "layer": "Decisions",
      "pattern": "loop\\s+\\d+\\s+.*(curl|wget|rm\\s+-rf|git\\s+push|gh\\s+pr)",
      "action": "block",
      "message": "High-risk command detected inside a loop. Scheduled tasks must not perform egress or destructive writes without explicit approval.",
      "severity": "critical"
    },
    {
      "id": "push-without-thread-check",
      "layer": "Decisions",
      "trigger": "Bash:git_push",
      "pattern": "git\\s+push",
      "action": "block",
      "unless": "pr_threads_checked",
      "message": "Check PR review threads (reviewThreads first:50) before pushing. Use satisfy_gate('pr_threads_checked', 'evidence') to bypass.",
      "severity": "critical"
    },
    {
      "id": "package-lock-reset",
      "layer": "Execution",
      "trigger": "Bash:package_lock",
      "pattern": "git\\s+checkout\\s+\\S+\\s+--\\s+package-lock\\.json",
      "action": "block",
      "message": "Never reset package-lock.json from another branch. Run npm install instead.",
      "severity": "critical"
    },
    {
      "id": "force-push",
      "layer": "Execution",
      "trigger": "Bash:git_force_push",
      "pattern": "git\\s+push\\s+(--force|-f)",
      "action": "block",
      "message": "Force push blocked. This is destructive and irreversible.",
      "severity": "critical",
      "compliance": ["NIST-CM-5", "SOC2-CC8.1", "CWE-863"]
    },
    {
      "id": "git-reset-hard",
      "layer": "Execution",
      "trigger": "Bash:git_reset_hard",
      "toolNames": ["Bash"],
      "pattern": "(?:^|[;&|]\\s*)git\\s+reset\\s+--hard\\b",
      "action": "block",
      "message": "git reset --hard is blocked because it can destroy uncommitted work. Stash or use a non-destructive restore path with explicit user approval.",
      "severity": "critical",
      "compliance": ["NIST-CM-5", "SOC2-CC8.1", "CWE-863"]
    },
    {
      "id": "git-clean-force",
      "layer": "Execution",
      "trigger": "Bash:git_clean_force",
      "toolNames": ["Bash"],
      "pattern": "(?:^|[;&|]\\s*)git\\s+clean\\s+(?:-[^\\s]*f[^\\s]*|--force)\\b",
      "action": "block",
      "message": "git clean --force is blocked because it can delete untracked user work. Inventory files and get explicit approval before destructive cleanup.",
      "severity": "critical",
      "compliance": ["NIST-CM-5", "SOC2-CC8.1", "CWE-863"]
    },
    {
      "id": "protected-branch-push",
      "layer": "Execution",
      "trigger": "Bash:protected_push",
      "pattern": "git\\s+push\\s+(?:\\S+\\s+)?(?:develop|main|master)\\b",
      "action": "block",
      "message": "Direct push to protected branch. Use feature branches and PRs.",
      "severity": "critical"
    },
    {
      "id": "rm-rf-home-or-root",
      "layer": "Execution",
      "trigger": "Bash:rm_rf_home_or_root",
      "toolNames": ["Bash"],
      "pattern": "(?:^|[;&|]\\s*)rm\\s+-(?=[^\\s]*r)(?=[^\\s]*f)[^\\s]+\\s+(?:/|/\\*|~(?:/[^\\s]*)?|\\$HOME(?:/[^\\s]*)?)(?:\\s|$)",
      "action": "block",
      "message": "Broad rm -rf against root or home is blocked. Use a narrow, reviewed path and explicit approval for destructive deletes.",
      "severity": "critical",
      "compliance": ["NIST-CM-5", "SOC2-CC8.1", "CWE-732"]
    },
    {
      "id": "env-file-edit",
      "layer": "Cloud",
      "trigger": "Edit:env_file",
      "pattern": "\\.env",
      "action": "warn",
      "message": "Editing .env file — verify you are not deleting existing tokens",
      "severity": "medium",
      "compliance": ["NIST-IA-5", "SOC2-CC6.1", "CWE-798"]
    },
    {
      "id": "deny-network-egress",
      "layer": "Cloud",
      "pattern": "curl\\s|wget\\s|fetch\\(|https?://(?!github\\.com|registry\\.npmjs\\.org|api\\.anthropic\\.com)",
      "action": "warn",
      "unless": "egress_approved",
      "message": "Potential unauthorized network egress detected.",
      "severity": "medium",
      "compliance": ["NIST-SC-7", "SOC2-CC6.6", "OWASP-A10"]
    },
    {
      "id": "unverified-skill-use",
      "layer": "Supply Chain",
      "trigger": "Skill:load",
      "pattern": ".*",
      "when": { "constraints": { "THUMBGATE_DELEGATION_MODE": true } },
      "action": "warn",
      "unless": "skill_verified",
      "message": "Skill provenance check failed. Run 'npm run skill:verify' or satisfy 'skill_verified' with a valid signature to proceed.",
      "severity": "high"
    },
    {
      "id": "supply-chain-dep-add",
      "layer": "Supply Chain",
      "toolNames": ["Edit", "Write"],
      "pattern": "package\\.json$",
      "action": "warn",
      "message": "Dependency mutation detected in package.json. Security scanner will audit for typosquatting, wildcard versions, and suspicious install scripts.",
      "severity": "high",
      "compliance": ["NIST-SA-12", "OWASP-A06", "CWE-1357"]
    },
    {
      "id": "blocked-npx-content",
      "layer": "Supply Chain",
      "trigger": "Bash:exec",
      "pattern": ".*",
      "executable_hash": "237adf8f3747cad8b9b62fcfd0d9c8d509a64e550337707f55100afcb79e8900",
      "when": { "constraints": { "THUMBGATE_DELEGATION_MODE": true } },
      "action": "block",
      "message": "Blocked npx execution by content hash. Renaming the binary does not bypass this gate.",
      "severity": "critical"
    },
    {
      "id": "production-deploy-approval",
      "layer": "Execution",
      "toolNames": ["Bash"],
      "pattern": "(?:railway|fly|heroku|vercel|render|kubectl|helm)\\s+(?:deploy|up|apply|release|push|rollout)",
      "action": "approve",
      "message": "Production deploy detected. Human approval required before this action can proceed.",
      "severity": "high",
      "compliance": ["NIST-CM-3", "SOC2-CC8.1", "OWASP-A05"]
    },
    {
      "id": "schema-migration-approval",
      "layer": "Execution",
      "toolNames": ["Bash"],
      "pattern": "(?:npx\\s+(?:sequelize|typeorm|prisma|knex|drizzle|flyway|liquibase)|alembic\\s+upgrade|rails\\s+db:migrate|php\\s+artisan\\s+migrate)\\b",
      "action": "approve",
      "message": "Database schema migration detected. Human approval required before this action can proceed.",
      "severity": "high",
      "compliance": ["NIST-CM-3", "SOC2-CC8.1", "CWE-89"]
    },
    {
      "id": "permission-change-approval",
      "layer": "Execution",
      "toolNames": ["Bash"],
      "pattern": "(?:chmod|chown|setfacl|iam|policy|role|grant|revoke)\\s+",
      "action": "approve",
      "message": "Permission or IAM change detected. Human approval required before this action can proceed.",
      "severity": "high",
      "compliance": ["NIST-AC-6", "SOC2-CC6.1", "CWE-732"]
    },
    {
      "id": "style-violation-log",
      "layer": "Decisions",
      "toolNames": ["Edit", "Write", "MultiEdit"],
      "pattern": ".*",
      "action": "log",
      "when": { "constraints": { "THUMBGATE_STYLE_AUDIT": true } },
      "message": "Style audit mode active. Action recorded for review but allowed to proceed.",
      "severity": "low"
    },
    {
      "id": "large-file-creation-log",
      "layer": "Execution",
      "toolNames": ["Write"],
      "pattern": ".*",
      "action": "log",
      "when": { "constraints": { "THUMBGATE_LARGE_FILE_AUDIT": true } },
      "message": "Large file write detected. Action recorded for audit trail but allowed to proceed.",
      "severity": "low"
    },
    {
      "id": "non-critical-warning-log",
      "layer": "Decisions",
      "toolNames": ["Bash"],
      "pattern": "(?:console\\.log|debugger|TODO|FIXME|HACK|XXX)",
      "action": "log",
      "message": "Non-critical code pattern detected. Action recorded for audit trail but allowed to proceed.",
      "severity": "low"
    },
    {
      "id": "mcp-sql-delete-block",
      "layer": "Execution",
      "toolNames": ["delete_record"],
      "pattern": ".*",
      "requireTaskScope": true,
      "action": "block",
      "message": "SQL MCP delete_record requires explicit task scope. Destructive database operations must be scoped to prevent accidental data loss.",
      "severity": "critical",
      "compliance": ["NIST-AC-3", "SOC2-CC6.1", "CWE-89"]
    },
    {
      "id": "mcp-sql-execute-warn",
      "layer": "Execution",
      "toolNames": ["execute_entity"],
      "pattern": "(?:drop|truncate|alter|grant|revoke)",
      "action": "warn",
      "message": "SQL MCP execute_entity matches a potentially destructive DDL pattern. Review before proceeding.",
      "severity": "high"
    },
    {
      "id": "mcp-sql-bulk-update-warn",
      "layer": "Execution",
      "toolNames": ["update_record"],
      "pattern": "(?:WHERE\\s+1\\s*=\\s*1|WHERE\\s+true|WITHOUT\\s+WHERE)",
      "action": "block",
      "message": "SQL MCP bulk update without a safe WHERE clause. This could modify all records in the table.",
      "severity": "critical",
      "compliance": ["NIST-AC-3", "CWE-89"]
    },
    {
      "id": "self-protect-config",
      "layer": "Execution",
      "toolNames": ["Edit", "Write", "MultiEdit"],
      "pattern": "(?:config/gates/|config/budget\\.json|\\.thumbgate/|thumbgate\\.json)",
      "action": "block",
      "message": "Self-protection: agent cannot modify ThumbGate configuration, gate rules, or budget settings.",
      "severity": "critical",
      "compliance": ["NIST-AC-3", "OWASP-A01", "SOC2-CC6.1"]
    },
    {
      "id": "self-protect-kill",
      "layer": "Execution",
      "toolNames": ["Bash"],
      "pattern": "(?:kill|pkill|killall)\\s+.*(?:thumbgate|gates-engine|budget-enforcer)",
      "action": "block",
      "message": "Self-protection: agent cannot terminate ThumbGate processes.",
      "severity": "critical",
      "compliance": ["NIST-AC-3", "OWASP-A01"]
    },
    {
      "id": "self-protect-env-override",
      "layer": "Execution",
      "toolNames": ["Bash"],
      "pattern": "(?:export|unset)\\s+(?:THUMBGATE_|LANEKEEP_)",
      "action": "block",
      "message": "Self-protection: agent cannot modify ThumbGate environment variables.",
      "severity": "critical",
      "compliance": ["NIST-AC-3", "SOC2-CC6.1"]
    },
    {
      "id": "self-protect-hooks-disable",
      "layer": "Execution",
      "toolNames": ["Edit", "Write", "Bash"],
      "pattern": "(?:settings\\.json|settings\\.local\\.json).*(?:hooks|PreToolUse|PostToolUse)",
      "action": "block",
      "message": "Self-protection: agent cannot modify hook registrations.",
      "severity": "critical",
      "compliance": ["NIST-AC-3", "OWASP-A01", "SOC2-CC6.1"]
    }
  ]
}
