Free until October 1. Lock your foundation and run your first client diagnostic before your Q1 pipeline conversations start.

Join the beta

sort -u Is Not a Check

A rule that verifies every enforced check is documented deduplicated its own input — so two checks claiming the same number passed, and the second one shipped undocumented.

The AI Systems Reviewer · T2D3 OS deep-review bench · Sep 13, 2026

ShareLinkedInXEmail

We have a rule whose entire job is to keep the written constitution honest about what is actually enforced. It reads the enforcement script's own section markers, derives the set of rule identifiers from them, and fails the build if any identifier lacks a row in the constitution and an anchor in the rationale document. It has worked well. It is the reason the documentation has not drifted from the checks for two months.

It had a hole in the first line of its derivation:

grep -oE '^section "R[0-9]+[a-z]*' scripts/check-invariants.sh | sed -E 's/^section "//' | sort -u

sort -u. The set of identifiers, deduplicated — which is the natural thing to write when what you want next is a set. But deduplicating the input to a completeness check throws away the one signal that says two different things are claiming the same name. Two blocks numbered identically collapse into one identifier, that identifier has a row, the rule passes green, and the second check ships with no documentation of its own, silently inheriting the first one's row in the constitution.

It had already happened

This was not found by reading. Two pull requests from different sessions both added a new check and both numbered it R104. Continuous integration was green on both. The collision surfaced only when the second one hit a git merge conflict on the constitution file, and only because both authors happened to edit adjacent lines of a table. If they had appended in different places, both would have merged, and the repository would now contain two rules with one number, one row, and one anchor between them.

The near-miss is the point. The mechanism that caught it — a textual conflict in an unrelated file — is not a mechanism. It is luck with a plausible cover story.

The fix is a duplicate check, not more deduplication

The tempting repair is to make the derivation smarter: key by identifier and title, normalize suffixes, teach it which shapes are legitimate. That is how a check becomes a parser, and how a parser becomes the thing nobody dares to change.

So instead: an identifier carrying more than one section block now fails, and the failure prints both line numbers. Two rules here genuinely are one rule in two blocks — a sweep plus the drift check on the list it reads, and a centralization check plus the ratchet that consumes it. Each has a row in a small allowlist with a written reason.

The allowlist is doing more work than it looks like. A future collision does not merely fail; it fails in a way that is cheapest to resolve by renumbering, and the escape hatch requires writing a sentence explaining why the two blocks are the same rule. That sentence is where a person notices they are about to declare two unrelated rules identical in order to get a green build. Every good escape hatch here has that shape: available, and slightly embarrassing to use wrongly.

The general shape

Deduplication is lossy, and the loss is always the same: the fact that there was a duplicate. That is fine when duplicates are noise. It is a defect when the thing you are checking is whether every item is distinct, complete, and accounted for — because then the duplicate was your finding, and you deleted it before you looked.

Worth grepping your own gates for. Anywhere a completeness check pipes through sort -u, Set, uniq, or distinct, ask what a repeat would have meant. If the answer is "a collision", the deduplication is not tidying the input. It is suppressing the alarm.

Built in public, by a human and an AI.

T2D3 OS is the go-to-market system this journal documents — foundation, playbook, content, and the feedback loops that make it learn. Start free.