{
  "schema_version": 1,
  "id": "protect-test-integrity",
  "track": "coding",
  "name": "Protect Test Integrity",
  "version": "0.0.3",
  "sha256": "37f62b136e6b0a8c7167c3f81594d30409b08edc7c3e7b4c8f6f1c8a067b96c3",
  "sha256_v1": "e5360d6e932054cb6e37e77eda3be6e81ed9000ff541b0bdd3f2ee9255d2e92f",
  "keyword": "block",
  "word": "blocks",
  "says": "blocks on an agent's file writes and at turn end",
  "description": "Blocks weakening tests to turn them green: a deleted test file (commit only), a net loss of assertions, or an added vacuous assertion (assert True, expect(true).toBe(true)). Added skips are block-test-skips. Runs: commit (incl. an agent's commit: CHOCK_AGENT_COMMIT, CLAUDECODE=1, AI_AGENT or agent_commit_env), agent write (vs disk), turn's end (vs HEAD). Waiver: 'chock: allow test-integrity' on an added line. Person's commit: honoured. Agent: only if already in HEAD; it asks a person.",
  "misses": null,
  "where": [
    "write",
    "turn-end"
  ],
  "groups": [
    "test-integrity"
  ],
  "eval_cases": 19,
  "eval_executed": 17,
  "latest": {
    "version": "0.0.3",
    "date": "2026-09-30",
    "change": "Wording fix, no behaviour change: the description and the gate message said a waiver is 'never honoured in the agent'. Since chock 0.14.0 a waiver already committed in HEAD counts in the agent (tool use, the turn's end, an agent's commit), the same as block-test-skips; a waiver on a new line does not. The description, the gate message, the tc-017 expect text and the same sentence in the 0.0.2 entry below are corrected. The description names where each check runs, and fits the 500-char budget."
  },
  "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/protect-test-integrity",
  "enforces": "enforced-at-commit",
  "examples": [
    {
      "word": "Refused",
      "prompt": "A failing test is made green by cutting two of its three assertions.",
      "command": null
    },
    {
      "word": "Allowed",
      "prompt": "A test is refactored: assertions are reworded and moved into a helper, and none is lost.",
      "command": null
    }
  ]
}
