jev-style-demo / guard_config.json
chaoliangUNSW's picture
Jev-Style v3 demo: ten tabs on ZeroGPU
411ac01 verified
Raw History Blame Contribute Delete
8.04 kB
{
"_about": "MacJev guard settings. Keys starting with '_' are notes and are ignored. Environment overrides: MACJEV_GUARD_CONFIG (another file), MACJEV_GUARD_URL, MACJEV_GUARD_LOG, MACJEV_GUARD_DRY_RUN=1, MACJEV_GUARD_DISABLE=1.",
"server_url": "http://127.0.0.1:8765",
"_server_url": "Only loopback hosts are accepted unless allow_remote_server is true, because the full command is sent to the server.",
"allow_remote_server": false,
"api_key_env": "MACJEV_API_KEY",
"timeout_s": 8,
"dry_run": false,
"_dry_run": "true = compute and log the verdict, print nothing (Claude Code behaves as if the hook were absent).",
"emit_allow": false,
"_emit_allow": "false = an 'allow' verdict prints nothing, so Claude Code's normal permission prompts still apply. true = the guard auto-approves calls it judges safe.",
"on_error": "ask",
"_on_error": "Verdict when the server is down, times out, or rejects the request: 'ask' or 'deny' (never 'allow').",
"log_path": "~/.local/state/macjev-guard/guard.jsonl",
"log_preview_chars": 300,
"max_field_chars": 0,
"_max_field_chars": "0 (default) = never shorten: the whole call is sent, and a call too big for the model's 25,600-token context comes back as input_budget_exceeded, which becomes 'ask'. A positive value shortens longer strings with a visible marker, and any shortened call is raised to at least 'ask' because the model did not see all of it.",
"drop_fields": {
"Bash": [
"description"
]
},
"_drop_fields": "Top-level argument names hidden from the model, per tool ('*' = every tool). Bash's description is the agent's own account of the command and must not talk the guard into anything. Nested keys are never dropped.",
"skip_tools": [
"Glob",
"Grep",
"LS",
"TodoWrite",
"TodoRead",
"Task",
"ExitPlanMode"
],
"skip_tools_regex": [
"^mcp__.*macjev"
],
"thresholds": {
"_about": "noul answers are P(true) in [0,1]; 'risk' is the expected level index in [0,4] (none, low, moderate, high, severe). A value at or above 'deny' denies, else at or above 'ask' asks. null disables a bound. The strictest verdict across questions wins.",
"destructive": {
"ask": 0.5,
"deny": 0.93
},
"exfiltration": {
"ask": 0.5,
"deny": 0.93
},
"outside_project": {
"ask": 0.6,
"deny": null
},
"secrets": {
"ask": 0.5,
"deny": 0.95
},
"risk": {
"ask": 2.0,
"deny": 3.4
}
},
"_hard_rules": "Regexes checked in code before the model (on the Bash command, or on the JSON arguments for other tools; 'tools' omitted = every tool). They can only make a verdict stricter, never looser.",
"hard_rules": [
{
"name": "wipe-root-or-home",
"decision": "deny",
"tools": [
"Bash"
],
"pattern": "\\brm\\s+(?=(?:-[-a-zA-Z]+\\s+)*(?:-[a-zA-Z]*[rR]|--recursive\\b))(?:-[-a-zA-Z]+\\s+)*[\"']?(?:/|~|\\$HOME|\\$\\{HOME\\})/?\\*?[\"']?(?=\\s|$|[;&|)])",
"reason": "recursive delete of / or the home directory"
},
{
"name": "wipe-system-dir",
"decision": "deny",
"tools": [
"Bash"
],
"pattern": "\\brm\\s+(?=(?:-[-a-zA-Z]+\\s+)*(?:-[a-zA-Z]*[rR]|--recursive\\b))(?:-[-a-zA-Z]+\\s+)*[\"']?/(?:etc|usr|bin|sbin|System|Library|Applications|Users|home|var|opt|private)/?\\*?[\"']?(?=\\s|$|[;&|)])",
"reason": "recursive delete of a top-level system folder"
},
{
"name": "delete-in-home",
"decision": "ask",
"tools": [
"Bash"
],
"pattern": "\\brm\\s+(?=(?:-[-a-zA-Z]+\\s+)*(?:-[a-zA-Z]*[rR]|--recursive\\b))(?:-[-a-zA-Z]+\\s+)*[\"']?(?:~|\\$HOME|\\$\\{HOME\\})/[^\\s;&|]+",
"reason": "recursive delete inside the home directory"
},
{
"name": "find-delete-root",
"decision": "deny",
"tools": [
"Bash"
],
"pattern": "\\bfind\\s+[\"']?/[\"']?\\s[^;&|\\n]*(?:-delete\\b|-exec\\s+rm\\b)",
"reason": "find ... -delete over the whole disk"
},
{
"name": "find-delete-home",
"decision": "ask",
"tools": [
"Bash"
],
"pattern": "\\bfind\\s+[\"']?(?:~|\\$HOME|\\$\\{HOME\\})[^\\s;&|]*\\s[^;&|\\n]*(?:-delete\\b|-exec\\s+rm\\b)",
"reason": "find ... -delete inside the home directory"
},
{
"name": "recursive-chmod-root-or-home",
"decision": "deny",
"tools": [
"Bash"
],
"pattern": "\\b(?:chmod|chown|chgrp)\\s+(?:-[-a-zA-Z]+\\s+)*(?:-[a-zA-Z]*R[a-zA-Z]*|--recursive)\\s+(?:-[-a-zA-Z]+\\s+)*\\S+\\s+[\"']?(?:/|~|\\$HOME|\\$\\{HOME\\})/?[\"']?(?=\\s|$|[;&|)])",
"reason": "recursive permission change on / or the home directory"
},
{
"name": "format-disk",
"decision": "deny",
"tools": [
"Bash"
],
"pattern": "\\b(mkfs(\\.\\w+)?|diskutil\\s+(erase\\w*|zeroDisk|secureErase))\\b|\\bdd\\b[^|;&]*\\bof=/dev/",
"reason": "formats or overwrites a disk"
},
{
"name": "fork-bomb",
"decision": "deny",
"tools": [
"Bash"
],
"pattern": ":\\(\\)\\s*\\{\\s*:\\|:&\\s*\\}\\s*;\\s*:",
"reason": "fork bomb"
},
{
"name": "force-push-main",
"decision": "deny",
"tools": [
"Bash"
],
"pattern": "\\bgit\\b[^;&|\\n]*?\\spush\\b(?=[^;&|\\n]*\\s(?:--force(?:-with-lease)?(?:=\\S*)?|-[a-zA-Z]*f[a-zA-Z]*)(?=\\s|$))(?=[^;&|\\n]*[\\s:](?:main|master)(?=\\s|$|[;&|]))|\\bgit\\b[^;&|\\n]*?\\spush\\b[^;&|\\n]*\\s\\+(?:\\S*:)?(?:main|master)(?=\\s|$|[;&|])",
"reason": "force-pushes main or master"
},
{
"name": "force-push",
"decision": "ask",
"tools": [
"Bash"
],
"pattern": "\\bgit\\b[^;&|\\n]*?\\spush\\b[^;&|\\n]*\\s(?:--force(?:-with-lease)?(?:=\\S*)?|-[a-zA-Z]*f[a-zA-Z]*|\\+\\S+)(?=\\s|$|[;&|])",
"reason": "force-push rewrites remote history"
},
{
"name": "private-key-read",
"decision": "deny",
"tools": [
"Bash"
],
"pattern": "(?:\\b(?:cat|less|more|head|tail|bat|cp|mv|scp|rsync|base64|xxd|od|hexdump|strings|tar|zip|gzip|curl|wget|nc|ncat|pbcopy|openssl|gpg|python3?|node|perl|ruby)\\b[^;&|\\n]*|<\\s*|@)[\"']?[^\\s;&|\"']*\\.ssh/id_[A-Za-z0-9_-]+(?![A-Za-z0-9_.-])",
"reason": "reads or sends an SSH private key"
},
{
"name": "private-key-file-tool",
"decision": "deny",
"tools": [
"Read",
"Write",
"Edit",
"MultiEdit",
"NotebookEdit"
],
"pattern": "\\.ssh/id_[A-Za-z0-9_-]+(?![A-Za-z0-9_.-])",
"reason": "opens an SSH private key"
},
{
"name": "browser-cookies-or-passwords",
"decision": "deny",
"pattern": "(?i)(?:Cookies\\.binarycookies|/(?:Cookies|Login Data|Web Data)(?=[\"'\\s]|$)|cookies\\.sqlite|logins\\.json|key4\\.db|\\bsecurity\\s+(?:find-generic-password|find-internet-password|dump-keychain)\\b[^;&|\\n]*\\s-[a-z]*[gw])",
"reason": "reads browser cookies, saved passwords or keychain secrets"
},
{
"name": "credential-store",
"decision": "ask",
"pattern": "(?:~|\\$HOME|\\$\\{HOME\\}|/(?:Users|home)/[^/\\s\"']+)/\\.(?:aws|ssh|gnupg|kube|docker|netrc|pypirc|npmrc|git-credentials|config/gcloud|config/gh)(?![A-Za-z0-9_-])",
"reason": "touches a credential store in the home directory"
},
{
"name": "dotenv",
"decision": "ask",
"pattern": "(?:^|[\\s/\"'=@<:])\\.env(?!\\.(?:example|sample|template|dist)\\b)(?:\\.[\\w-]+)?(?=$|[\\s\"';&|)])",
"reason": "touches a .env file"
},
{
"name": "pipe-download-to-shell",
"decision": "ask",
"tools": [
"Bash"
],
"pattern": "\\b(curl|wget)\\b[^|;&]*\\|\\s*(sudo\\s+)?(ba|z|da)?sh\\b",
"reason": "runs a downloaded script"
},
{
"name": "sudo",
"decision": "ask",
"tools": [
"Bash"
],
"pattern": "(^|[;&|]\\s*)sudo\\s",
"reason": "runs as root"
}
]
}