Reading Evidence in a Codebase
A question came up: how many tables write the envelope’s kind column in their own fill body? A grep on the identifier answered four.
# The bad way: count the name, answer the question about the binding.git grep -l 'insertStm\[kind\]' -- '*Table.kt' # → 4 filesFour was right about the identifier and wrong about the question. Six tables carry a kind column; four bind it to the envelope’s own accessor and two declare their own. Of the four fill bodies the grep found, two were writing a column of their own, not the envelope’s. The number was twice the truth, and it looked like an answer.
This page is about searches, counts and claims that come out the same way whether or not they are right.
A search that could not have matched returns the same thing as a search that found nothing. A count of names is not a count of the thing the names refer to. Both produce a number, and a number invites a conclusion.
This page covers the instrument Checks That Cannot Fail does not: not a check written in code, but a search, a count, or a claim about a tree. The rule is the same. A measurement that cannot come out otherwise is not a measurement.
Verify that a negative is real
Section titled “Verify that a negative is real”“No match” and “no such thing” are indistinguishable in a search’s output. Before reporting a zero, make the pattern produce a hit somewhere — on a case you know exists, or on a deliberately planted string — and only then trust it on the case you care about.
Two ways a pattern silently cannot match:
The regex mode decides whether shorthand exists, and the mode is easy not to think about. In git grep, \b, \s, \d and \w work under -P (PCRE) and are not part of the syntax under -E (POSIX extended), where they match nothing rather than erroring. The default mode’s handling depends on the platform’s regex library, so it is not something to rely on either way. Measured on git 2.51.0: -E found nothing, -P found the match, and the default found it too — three answers from one pattern.
A tool can refuse to look and say nothing. Two forms, both seen here. A bounded-repetition context window too wide for ugrep makes the system grep error out and print nothing at all. And a pattern using a lookahead — not supported by that same tool — is rejected outright: a link check written to find unresolvable targets reported twenty-six links and none missing, when it had matched nothing at all. There were two. In both cases “not found” and “refused to look” render identically.
Both were found the same way — by a zero that turned out to be a fact about the pattern rather than about the tree.
An instrument answers the question it was configured to ask
Section titled “An instrument answers the question it was configured to ask”Four ways a check reports honestly about something other than what you asked it. They are one rule, and they are listed together because separately each looks like its own discovery.
A search returns what a missing thing returns
Section titled “A search returns what a missing thing returns”A finding was described in a registry using one set of words. Two people searched every review thread on two pull requests for those words and found nothing. The thread existed. Its own words were different — the registry row was a paraphrase, and nobody had checked that the search terms came from the artifact rather than from the description of it. A third party then concluded from those two honest zeros that the object was a different kind of thing entirely.
That second step is the expensive one: an empty search is evidence about the query, never about the world, until you have checked that the query could have matched. “I searched and it is not there” feels like a fact about the repository; it is a fact about the search.
The thread was in one searcher’s own broad listing, run before the conclusion, and read past because it did not contain the expected words. The narrow search was a bad instrument; the listing was a good instrument ignored.
So: search the artifact’s vocabulary, not the description’s; an object has an identifier before it has a characterisation, and a handover naming a kind without an identifier of that kind has not established the kind; and two failed searches are one witness, not two, when both use the same terms — they share the assumption that would make them both fail.
A field that is always empty
Section titled “A field that is always empty”A pull request’s approval state was in question, and a decision field came back empty rather than approved — offered as corroboration that no approval existed.
That field was empty on all eight open pull requests in the repository, including one carrying a recorded approval. It read identically whether a pull request was approved, unapproved, or approved at a superseded commit, so it distinguished nothing and never could have.
Before an empty result becomes evidence, establish that the source can be non-empty. Read the same field on a case that should differ — one record with the property and one without takes a second and settles it. This one is easier to miss than a bad search, because a field has a name describing what it would mean if populated. An unconfigured field and a genuine absence are the same JSON.
A status command compares against what it was configured to compare
Section titled “A status command compares against what it was configured to compare”git status -sb reports how far ahead of the configured upstream a branch is. For a branch with no upstream set it compares against something else and still prints a confident [ahead N]. It never answers “is this branch on the remote”. git ls-remote --heads origin <branch> does.
A pushed, open pull request was reported as unpushed on that evidence. The local tip matched the remote exactly, so nothing had diverged — only the report was wrong, which is the worse failure, because everything downstream of it stayed consistent.
An audit can condemn a working convention
Section titled “An audit can condemn a working convention”The identifier-versus-binding rule, in a process listing rather than a source tree. Build daemons started with an isolated user home still resolve their program through the shared distribution directory, so every daemon’s command line shows the default home. What the flag isolates is the registry. An audit by command line therefore concludes the isolation is broken when it is working.
This one ranks above the others because of what it costs when it fires. A wrong number gets contradicted by the next measurement. A false alarm about a working convention gets the convention abandoned by someone doing the responsible thing — and nothing later contradicts it, because the evidence stopped being generated. A wrong number lives in a stream of measurements that will eventually correct it. A false alarm ends the stream.
Match on the binding, not the identifier
Section titled “Match on the binding, not the identifier”A grep counts names. The question is almost never about names.
Six tables in operations carry a kind column. Four bind it to occurrenceKind(); two declare their own varchar("kind", 64). The question being asked was narrower than either number — which fill bodies write the envelope’s kind — and four fill bodies write insertStm[kind], of which two are writing their own column rather than the envelope’s.
So a pattern matching the identifier counted four fill bodies as envelope writers, and two of them were writing something else. The column and the binding that fills it are different facts, and the identifier is common to both.
Match on the verb or the binding, then classify what you found by its declared type. Where that is impractical, report the name-count as a name-count and say what it does not establish.
A related form: a pattern keyed on a receiver’s name — universe., a guessed variable — looks authoritative and misses demandUniverse., underTest, mockUniverse. It returns a confident false zero.
A fact is true at a ref, and “the stack” is not a ref
Section titled “A fact is true at a ref, and “the stack” is not a ref”A property measured at one commit and reported as a property of a branch, a stack, or “the code” is a claim about something that has no state.
One defect was described as two writers reaching the same envelope columns. Measured at b73b3020, one rung below the stack’s tip, both writers are there — the guard-bearing library is pinned and two modules each write three envelope columns in fill. Measured at e300a9b6, the tip, neither writes any. The property was real and transient mid-stack, and calling it a property of the stack made it unfalsifiable: whoever checked would check a different rung and get a different right answer.
State the ref a claim was measured at, and the artifact it was measured from, at the point the claim is made. main, “the branch” and “the stack” are not refs; they are names for whatever the reader’s tree happens to hold.
One thread from that measurement stayed open for about six hours, and its resolution is worth more than the question was.
The thread read: the guard should throw, the demand tests are green, and why was never found. The guard does throw. It always did. The tests were never green. CI ran the suite that had been assumed and returned 106 failures with a single distinct cause — the guard, refusing a write that supplied no occurrence to a table declaring occurrence columns. Ninety-six failures on one table, eleven on another, identical across three jobs.
The premise nobody measured was the one everybody reasoned from. “The demand tests are green” was never a measurement. It came from a model-checking gate whose output is SAT and UNSAT counts over model commands — no test suite had been run at all. One instrument’s number was read as another’s, and the two do not measure the same thing or even the same artifact.
Everything else in the contradiction had been checked and was correct: the guard in the library branch, the pin at every ref in the stack, the absence of a supply path, the ancestry. The false step was the one that felt too obvious to check, carried in a single unexamined word.
When a contradiction will not resolve, suspect the premise you did not measure before the ones you did. This one did not yield to more reading. It was closed by running the suite.
An absent declaration is not a declared absence
Section titled “An absent declaration is not a declared absence”A type system can make an absence unwriteable only when the absence is a decision. Silence is not a decision.
A recommendation was built on the phrase “two logs decline by the model’s word.” One half of that turned out to be a gloss of model silence — traced to an uncited line and confirmed as an assertion by its author rather than a reading of the model. The recommendation withdrew.
The line is streams/samwise/type-system-what-the-model-says.md:57. What made the gloss findable was that its neighbouring claims in the same section were all line-cited and that one was not.
“By the model’s word” needs the line. So does “the spec says,” “the type forbids it,” and “the schema requires it.” Cite the line, or say you are inferring.
The same rule applies to a vendor’s documentation, and the second witness came from one. The github/github-mcp-server README describes two ways to authenticate to the remote endpoint — a one-click OAuth login, and a personal access token in an Authorization header — and says nothing there about a GitHub App installation token. App authentication appears in that same README only under the local server’s non-interactive deployment section. So the omission is not unsupported: it is absent, in a document that discusses the method elsewhere. A session needing it against the remote endpoint minted a real credential and sent one initialize request rather than inferring from the gap in either direction. The request succeeded, and the method works whatever the page enumerates. (Read 2026-09-09.)
Two shapes hide behind “the docs are wrong”, and they need different work. The docs are silent on X is a gap, and a test closes it. The docs claim X and are wrong is a record, and a correction fixes it. Which one you face decides your next move, and “test it rather than trust the documentation” collapses them into advice that tells you nothing about what to do afterwards. Say which you found.
git add does not scope a commit
Section titled “git add does not scope a commit”The index is shared state in a shared checkout, so naming paths on git add says what to add, not what to commit. Anything already staged by another process — a hook, a concurrent session, an earlier abandoned attempt — commits alongside it.
Two instances, in different repositories and different tools. In the second, a stale staged copy of a generated manifest, eleven days old, was sitting in the index before the committing session touched the worktree; a path-limited git add would have carried it silently into an unrelated commit.
Commit with an explicit pathspec — git commit -- <paths> — and read git status --porcelain immediately before, not from memory of what you changed.
Sources
Section titled “Sources”Items one to four come from the five-verb universe contract design session on the Orders v2 Phase-III work; the submission is /workbooks/notebooks/domain-ontology/streams/spearhead/parmandil-submission-01-five-verb-contract.md. The inert-pattern and index-scoping material comes from the model-checking campaign recorded at /workbooks/notebooks/domain-ontology/streams/minesweeper/parmandil-submission-2026-09-09.md.
See also
Section titled “See also”- Checks That Cannot Fail — the same rule, applied to a check written in code.
- What a Green Run Proves — the same rule, applied to a gate or a suite.
Copyright: © Arda Systems 2025-2026, All rights reserved