{
  "schema_version": 1,
  "id": "pin-github-actions",
  "track": "coding",
  "name": "Pin GitHub Actions",
  "version": "0.0.7",
  "sha256": "ef86d2b0c6a1b7f143ed6a4f85eb48821c901b08013cb5853a776b8858388424",
  "sha256_v1": "168d6e9463249309abd4022adc176b8d97ab1fdb16f4ca5967f5c4ca858569ec",
  "keyword": "block",
  "word": "blocks",
  "says": "blocks on an agent's file writes and at turn end",
  "description": "Blocks uses: of an action/reusable workflow at a movable ref (not a lowercase 40-hex SHA) and a docker:// image without @sha256, quoted, JSON or flow; an alias, escape or value off the uses line is refused. Local ./ passes. Scope: .github/workflows/, .github/actions/, action.y*ml. Line regex, no YAML parse: container image tags, impostor SHAs, a tag named as 40 hex pass. Waiver: 'pragma: allowlist unpinned-action' same line. Person's commit: honoured. Agent: only if in HEAD; MCP gateway: never.",
  "misses": null,
  "where": [
    "write",
    "turn-end"
  ],
  "groups": [
    "ci-pipeline"
  ],
  "eval_cases": 63,
  "eval_executed": 63,
  "latest": {
    "version": "0.0.7",
    "date": "2026-10-07",
    "change": "Promoted from draft to production: every test case ran and passed, and no bug report was open. Behaviour unchanged."
  },
  "agent_labels": {
    "claude-code": {
      "keyword": "block",
      "says": "blocks on an agent's file writes and at turn end"
    },
    "cursor": {
      "keyword": "block",
      "says": "blocks on an agent's file writes and at turn end"
    },
    "codex": {
      "keyword": "block",
      "says": "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": "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": "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/pin-github-actions",
  "enforces": "enforced-at-commit",
  "examples": [
    {
      "word": "Refused",
      "prompt": "A staged workflow references an action by a major version tag.",
      "command": null
    },
    {
      "word": "Allowed",
      "prompt": "A staged workflow pins the action to a full commit SHA.",
      "command": null
    }
  ]
}
