Chock.sh Build your plugin
Blocksv0.1.0 preset: Test integrity

Block Test Skips

Blocks on an agent's file writes and at turn end.

Acts on

File write · Turn end

When

Before the file write · at turn end

Tested

89 of 90 pass

In a git repo

At commit

What it does

Blocks newly added test skips, focus markers and runner options that hide tests: pytest/unittest skips, non-strict xfail, importorskip; JS skip/only/todo/fixme, x/f prefixes; JUnit Disabled/Assume; Go Skip, Short(); Rust ignore; RSpec, PHPUnit, C#, Swift skips; --deselect/-k not, collect_ignore, jest testPathIgnorePatterns. Runs: commit, agent write, turn's end; only additions judged. Friction: computed names evade it. Waiver: 'chock: allow test-skip' same line; agent: only if in HEAD.

Chock adds friction. It is not a security boundary.

Its label on each agent

The catalog grades each policy on each agent. Pick an agent to build with this policy:

  • Claude Code TestedBlocks Blocks on an agent's file writes and at turn endBuild →
  • Cursor TestedBlocks Blocks on an agent's file writes and at turn endBuild →
  • Codex TestedBlocks 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)Build →
  • GitHub Copilot TestedBlocks 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)Build →
  • Devin TestedBlocks 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)Build →
  • Grok Tested Not graded yet for GrokBuild →
  • goose Tested Not graded yet for gooseBuild →
  • Antigravity Tested Not graded yet for AntigravityBuild →
  • OpenHands Untested Not graded yet for OpenHandsBuild →
  • Kimi Code Untested Not graded yet for Kimi CodeBuild →
  • Factory Droid Untested Not graded yet for Factory DroidBuild →

See it in action

Refused

A failing pytest test is marked @pytest.mark.skip.

Allowed

A doc page about testing shows @pytest.mark.skip in an example.

Both examples are this policy's own test cases.

What it misses

This policy does not state what it misses.

Latest change

0.1.0 · · V2 (roadmap HP07). Python is read from the syntax tree, with imports resolved: markers anywhere (decorator, pytestmark, pytest.param(marks=...), add_marker), skipif, xfail unless strict=True without run=False, runtime pytest.skip/xfail/importorskip (module level included), skipTest, SkipTest, unittest.skip*/expectedFailure, aliases (from pytest import mark as m, from unittest import skip as later) and getattr(..., 'skip'). A file that does not parse is read as text. Other languages by extension: JS/TS skip/only/todo/fixme/skipIf/runIf on any it/describe/test chain (it.concurrent.skip, describe.skip.each), .each(table).skip matched as a group, it/test.fails, x/f prefixes (xtest, fit, fdescribe), mocha this.skip(); JVM @Disabled*, @Ignore*, @EnabledIf/On/For*, Assume*/assume*/assumingThat, TestNG enabled = false/SkipException, Kotest xtest/config(enabled = false); Go .Skip*() on a testing receiver and testing.Short() guards that return or skip; Rust #[ignore] and cfg_attr(..., ignore) in every .rs file (the attribute only marks tests); Ruby statement-initial x/f prefixes, skip, pending, and :skip/skip:/focus: example metadata; PHPUnit markTestSkipped/Incomplete; C# [Fact/Theory(Skip=)], [Ignore], [Explicit], Skip.If, Assert.Ignore/Inconclusive, Assume.*; Swift XCTSkip*, XCTExpectFailure, .disabled(. String literals are blanked first, so a title that says skip is not one. A test-path file with any other extension keeps v1's pattern. Runner configs anywhere by base name: pytest.ini, pytest.toml, pyproject.toml, setup.cfg, tox.ini lines (in a pytest section, or running pytest) with --deselect, --ignore/--ignore-glob (not --ignore-installed) or -k ... not; conftest.py collect_ignore/collect_ignore_glob entries, pytest_ignore_collect, and item removal or pytest_deselected in pytest_collection_modifyitems; jest.config.* and package.json testPathIgnorePatterns, one finding per entry (Jest's default /node_modules/ aside), the whole list when an entry is not a string. Test paths widen beyond protect-test-integrity's (kept as TEST_PATH) to [Tt]ests/, [Ss]pecs/, e2e/, cypress/, playwright/, *_spec.rb, *_test.rb, *Test(s).java/kt/kts/groovy/scala/cs/php/swift, *.test.*, *.spec.*. Keys stay rule + enclosing test + detail: the normalized line, a Python skip's whole decorator or statement behind its guards, a list entry's value, so a moved skip or a reordered pattern is old. Eval cases tc-027 to tc-075.