Skip to main content
Wildo.ai Coming soon

Build and repository checks

Code-conduct checkers

Rules that no type system can express are enforced by dedicated checks, each of which can prove it is not broken.

What it is
Tool — something you run.
What it does
A family of small checks that read the working tree directly — no build, no install — and refuse to let a decision stay implicit.
Where it stops
Most are advisory about intent and strict only about visibility.
refuse driftrefuse drift

Source

Compile

Publish

Checkers

An application installs it

Drawn for Build and repository checks, the area this capability belongs to.

Some of the rules a framework depends on cannot be written as types. An end-to-end assertion must reach the database through the adapter-neutral seam or say out loud that one dialect is its subject. A package subpath must be the only door onto its surface. A closed vocabulary must have one named home. Each of those has a dedicated script under code-conduct, thirty-six of them, and almost all of them ship a self-test that plants each failure shape and asserts it is caught.

The problem it solves

The rules that matter most in a framework are usually the ones a compiler cannot see. They are properties of how code is arranged rather than of what it evaluates to: which package a symbol is reachable through, whether a string is a vocabulary or a wire value, whether a security-relevant action emits a record. A type system has no opinion on any of them, so the fallback is review, and review is what authoring speed outruns. One of these checkers was written after a measurement that makes the point exactly: around a hundred call sites had been converted to a store-neutral seam, and by the time the conversion was reviewed, ten new sites of the old kind had arrived in code written during it. A sweep fixes the population that exists today; the population refills.

There is a second, sharper reason these are scripts rather than conventions. A convention is enforced by whoever remembers it, and nobody remembers thirty-six of them.

What it does

A family of small checks that read the working tree directly — no build, no install — and refuse to let a decision stay implicit.

What most of them deliberately do NOT do is decide what is correct. A check cannot tell a deliberate exception from an unconverted one, so the guarantee on offer is weaker and honest: it refuses to let the answer stay unstated. A site that genuinely needs the exception carries a marker naming its reason, in a comment beside the code — visible in review, surviving a file move, and unable to drift from what it explains.

They are not text matching where text matching would be wrong in both directions. One check runs a real tokeniser, because its own source discusses the forbidden call in prose that must not be counted, and because the target appears inside string templates that must not be either. That was learned the expensive way: the first live run reported twenty-six sites where a plain search found sixty-one, because a pattern containing a quotation mark opened a string that swallowed the rest of one file — and every short fixture had passed.

Why a check proves it is not broken

This answers a failure with no symptom. A check reports findings; when it reports none, that reads as a clean repository — and there is nothing in the output to distinguish that from a check whose discovery has silently stopped matching anything. A widened directory layout, a renamed extension, a tokeniser that lost half the file: both print the same thing. So a broken check is not merely useless, it is worse than absent, because its silence is taken as evidence.

The answer is that a check carries fixtures of both kinds and asserts both directions: each planted bad input must be reported, and each good input must not. The second half is what makes it a test rather than a demonstration — detection without a clean control proves only that something fires, not that it discriminates. Several go further and check themselves against the live tree, so a tokeniser regression that stops seeing a file becomes a red run naming that file.

Shrink-only baselines, and what a check should refuse

A baseline is a different design decision from a gate, and the two answer different questions about a rule that is right and a codebase that does not yet satisfy it.

A gate refuses the state outright. That is correct for a rule with no pre-existing population.

A baseline is for the other case: the rule is correct, the population predates it, and converting everything before the rule can be enforced means the rule is not enforced for as long as the conversion takes — which is when the population grows. So a baseline records what exists as a per-file ceiling and enforces one thing only: that the ceiling never rises. Converting a site lowers the count, the row is deleted at zero, and the self-test refuses a row naming a file with nothing left to convert, so the ledger cannot rot into a list of resolved entries.

The rule the baselines carry in their own text is what keeps this from becoming an allowlist: never raise a count to silence a new finding. A new occurrence is the defect the check exists to catch, and the answer is to fix it or to declare it at the site with a marker naming the reason. A marker is visible in review; a raised number is not. The steady state of every one of these files is empty.

Limits

Most are advisory about intent and strict only about visibility. A check that reports a site is saying the site has not declared what it is, not that it is wrong.

Two of the thirty-six carry no self-test, so their discovery is unverified. One is reachable from neither a named command nor a pipeline, so nothing runs it on a change.

They do not all gate. Roughly a third are reachable only by running them deliberately.

Building a B2B product or an internal tool?

Wildo is not self-service yet. Tell us what you have in mind and we will say plainly whether it fits, and what happens next.