{
  "schema_version": 1,
  "id": "refname-filename-metachar",
  "track": "coding",
  "name": "Block Risky Characters in File and Branch Names",
  "version": "0.1.5",
  "sha256": "dbab33cf859b0457faff6f0ba2f5212fa83274a55233c119810a3ad6daae9ee8",
  "sha256_v1": "6bc2236c299d840c74a8465d1954db71283928e4229b69b5743cc12b6c6acd0a",
  "keyword": "block",
  "word": "blocks",
  "says": "refuses a matched shell command before it runs. Blocks on an agent's file writes and at turn end",
  "description": "Refuses names a shell, CI step or git can misread. Paths a change adds or renames into (commit, agent writes), and branches and tags pushed (pre-push), with command substitution, an IFS expansion, a backtick, ; & | < >, a double quote, a backslash, a control or bidi character, a base64-decode shape, a leading dash or trailing space or dot in a segment, or a '..' segment; a ref also with a full commit id's shape. A guard refuses git and file commands creating such names. No waiver. Friction, not a boundary.",
  "misses": null,
  "where": [
    "command",
    "write",
    "turn-end"
  ],
  "groups": [
    "git-hygiene"
  ],
  "eval_cases": 43,
  "eval_executed": 43,
  "latest": {
    "version": "0.1.5",
    "date": "2026-10-27",
    "change": "Title wording only (IR-F40): \"Refname Filename Metachar\" is now \"Block Risky Characters in File and Branch Names\". The id, guard and tests are unchanged."
  },
  "agent_labels": {
    "claude-code": {
      "keyword": "block",
      "says": "refuses a matched shell command before it runs. Blocks on an agent's file writes and at turn end"
    },
    "cursor": {
      "keyword": "block",
      "says": "refuses a matched shell command before it runs. Blocks on an agent's file writes and at turn end"
    },
    "codex": {
      "keyword": "block",
      "says": "refuses a matched shell command before it runs. Blocks on an agent's file writes and at turn end. If the hook errors, the action goes through (not witnessed; the vendor's row is only partly live-run)"
    },
    "copilot": {
      "keyword": "block",
      "says": "refuses a matched shell command before it runs. Blocks at turn end only. It does not check a file write when it happens. If the hook errors, the action goes through (not witnessed; the vendor's row is only partly live-run)"
    },
    "devin": {
      "keyword": "block",
      "says": "refuses a matched shell command before it runs. Blocks at turn end only. It does not check a file write when it happens. If the hook errors, the action goes through (vendor docs only, not witnessed)"
    },
    "grok": {
      "keyword": "ungraded",
      "says": "Not graded yet for Grok"
    },
    "goose": {
      "keyword": "ungraded",
      "says": "Not graded yet for goose"
    },
    "antigravity": {
      "keyword": "ungraded",
      "says": "Not graded yet for Antigravity"
    },
    "openhands": {
      "keyword": "ungraded",
      "says": "Not graded yet for OpenHands"
    },
    "kimi-code": {
      "keyword": "ungraded",
      "says": "Not graded yet for Kimi Code"
    },
    "factory-droid": {
      "keyword": "ungraded",
      "says": "Not graded yet for Factory Droid"
    }
  },
  "source_url": "https://github.com/open-coder-ai/chock-catalog/tree/1e60d211c1bb767152c6ab0167932da06ab3a10f/base/refname-filename-metachar",
  "enforces": "enforced-at-commit",
  "examples": [
    {
      "word": "Refused",
      "prompt": "A change adds a file whose name carries command substitution that decodes and runs a payload.",
      "command": null
    },
    {
      "word": "Allowed",
      "prompt": "A change adds ordinary source files.",
      "command": null
    }
  ]
}
