Yieldpoint

Rules reference

Every rule the engine can emit. This page is generated from the code: a rule that exists but is undocumented, or documented but removed, fails the build and the test suite.

What the tests verify

The reason this project exists. Each of these is a statement about what a change took away, which is why no tool that grades the end state can report them.

assertion_monotonicityrepair

Assertion weakened

An assertion on some value got weaker: == 42 became is not None, a specific exception became a bare Exception, an exact count became a lower bound. The subject is still asserted, so the test still passes and coverage is unchanged.

disabled_assertionrepair

Assertion commented out or neutered

An assertion still present in the source but no longer executed — commented out, moved behind a condition that is never true, or swallowed by a bare except.

empty_testrepair

Test with nothing left in it

A test function whose body asserts nothing: a pass, a docstring, or setup with no check at the end. It runs, it is counted, it verifies nothing.

skip_markerrepair

Test newly skipped

A @skip, @skipif, @xfail or equivalent added to a test that did not have one. The suite goes green by not asking.

vacuous_assertionrepair

Assertion that cannot fail

assert True, assert [1], assert x or True — an assertion whose truth does not depend on the code under test.

weak_new_testrepair

New test that only checks existence

A test added by this change whose every assertion is a not-null or truthiness check. Monotonicity cannot see this — there is no earlier version to be weaker than — yet the test passes whatever value the code returns. This is the shape an agent produces when asked to add a feature with tests. Advisory by default: a smoke test that asserts a call returns something is legitimate.

Moves that did not land

A refactor is only correct if everything that pointed at the old thing now points at the new one. These catch the half-finished move.

boundary_violationrepair

Layer boundary crossed

An import that the project's declared zones forbid. Configured in .yieldpoint.json; mature tools exist for this, and it ships here for convenience rather than as a reason to adopt.

dangling_referencerepair

Reference to something that moved

A name is gone and something still points at it. The classic half-finished rename, where the tests that happen not to exercise that path stay green.

export_removedrepair

Public API removed

A name that was part of a module's public surface — in __all__, or imported elsewhere — is no longer there. Callers outside the change set cannot be seen by a diff, so this asks rather than assumes.

swallowed_exceptionrepair

A handler that catches everything and records nothing

A try block gained except Exception: pass — or a bare except:, or one whose body is only ..., continue or a bare return. Every failure on that path now looks like success, so a test covering it keeps passing while verifying nothing. Naming the exception you expect, logging, or re-raising are all fine; only silent breadth is reported, and only when this change introduced it.

The pipeline itself

The cheapest way to make a suite pass is to stop running it. These watch the machinery rather than the code.

ci_check_disabledescalate

CI step neutralised

A step is still there but can no longer fail: || true, continue-on-error, if: false. Reported as disabling the same step rather than as a removal plus an addition.

ci_check_removedescalate

CI step deleted

A step disappeared from a workflow file. Deleting the job that runs the tests is the most effective way to make the tests pass.

new_file_out_of_scoperepair

A new file, in a task that said it would add none

The same contract, for --no-new-files. Aimed at the habit of answering a question with a new module rather than the one that already covers the concern.

out_of_scope_editrepair

A file outside what this task said it would touch

Declared with yieldpoint task --touch. The only rule here that knows something the code cannot tell it: every other rule reads the source and concludes, this one compares what changed against what somebody said would change. Reported, never enforced — intent legitimately changes mid-task; what must not happen is the drift going unnoticed until review.

policy_weakenedrepair

The rules themselves were loosened

A limit raised, a severity lowered, a rule switched off, a path added to the exclusions, or the ledger disabled. Raising a threshold until a finding disappears is the same act as weakening a test until it passes — only the file being edited differs. Reported and never enforced, whatever structure.gates says: a project must be able to change its own standards without first defeating the tool that holds them.

Shape and size

Maintainability, not correctness. These are reported but do not fail a run: a commit refused because a function is fifty-one lines teaches people to reach for --no-verify, and that habit mutes the rules that matter too. Set structure.gates true to make them binding.

change_too_largerepair

Change too large to review

Added lines past the configured ceiling. Aimed at agents, which do not tire and will happily produce a forty-file diff nobody can read.

complexity_too_highrepair

Too many branches

Default 10.

duplicate_across_filesrepair

The same implementation in two files

A function structurally identical to one in another file changed by the same commit. Shape is compared, not text, so a copy-paste that renamed its variables is still found. The within-file case belongs to duplicate_implementation; this is the one neither reader can see.

duplicate_implementationrepair

Structurally identical code

Two functions with the same shape. Two copies drift apart, and a fix applied to one is a bug left in the other.

file_too_longrepair

File over the line limit

Default 300 lines of code, excluding blanks and comments.

function_too_longrepair

Function over the line limit

Default 50 lines.

generated_file_editedrepair

Generated file edited by hand

A file marked as generated was edited directly. The edit is lost on the next regeneration, which is a bug that appears later and somewhere else.

nesting_too_deeprepair

Nesting too deep

Default 4 levels.

sibling_module_shadows_packagerepair

New module named as a package it is not in

A new foo_bar.py written beside an existing foo/ package. The name says the code belongs to that package; the filesystem says it does not. Characteristic of code written by something that can see the file it is creating but not the directory it is creating it in. Only new files are reported.

too_many_parametersrepair

Too many parameters

Default 5.

utility_modulerepair

Module with no theme

A utils-shaped file: unrelated functions with nothing in common but the fact that nobody knew where else to put them.

Answering a rule

Every rule is sometimes right about the code and wrong about the intent. Say so in the source, with a reason, and the finding is suppressed for that line only — and counted, so suppression cannot rot quietly.

# yieldpoint: allow assertion_monotonicity - broadened to cover YAML clients
def test_every_client_resolves_a_path():
    ...

One rule per comment, a reason required, and the comment must sit on the line the finding points at or within two lines above it.

It answers the debt, not the growth. A file acknowledged at four hundred lines that reaches nine hundred is reported again — an acknowledgement that covered everything after it would be an off switch with a comment attached. Reported, never blocking: the point is that the growth is visible.

An acknowledgement may also name who owns the debt and when it should stop being acceptable:

# yieldpoint: allow file_too_long until 2026-12-01 owner=platform - owed a split, tracked in issue 12

An expiry never changes a verdict. If a passing date made an acknowledgement stop suppressing, the same commit would pass today and fail tomorrow with nothing changed — so every rule ignores it. yieldpoint allows lists them; yieldpoint allows --expired reads today’s date and fails when one has passed, and is the only command here that reads a clock. Run it on a schedule, not in a gate.