Skip to content

Evidence

The failure mode of an AI writing about your codebase is the confident paragraph about code nobody opened. tldrx's answer is mechanical: a claim without a source is not written down.

Every bullet a stage writes into its handoff has to end with a source token. If one does not, the stage is refused — before the gate, not after.

markdown
## Findings
- Hunt completion already emits a HuntCompleted event [src: api:src/Hunts/Hunt.cs:184]
- The lab SDK is generated, so a DTO change is a two-repo change [src: F003]

## Unknowns
- Retention period for historical rankings [src: absent:.tldrx/memory/facts.yml]

## Evidence ledger
- Contract project builds clean [src: $ dotnet build → exit 0]

The kinds of source

Looks likeMeans
api:src/Hunts/Hunt.cs:184a file and a line — the file must exist and the line must be in range
F003an answer you gave, from .tldrx/memory/facts.yml
Q6a question asked in this run
$ dotnet build → exit 0a command that was run — only commands your workspace.yml declares, and only in the Evidence ledger
https://…a document; http:// is rejected
graph:<node>a node in the code map
absent:path/to/filewe looked here and found nothing
aidlc:intents/260821/design.md:14a line in the AI-DLC intent folder a run new --from distilled — or #Q3, one of its answered questions. Recorded, never resolved: that folder sits outside the workspace and may be gone by the time anyone reads the handoff

absent: is the one that makes honesty cheap. "There is no retry policy" is a claim, and this is how it gets sourced. It is refused on a positive claim outside the Unknowns section — you cannot cite an empty directory as proof that something exists.

A command that was refused gets no $ … → exit <n> citation at all. That shape needs an exit code, and a Definition-of-Done command your workspace.yml does not declare — or one that needs a shell, which the gate never opens — never ran, so there is none to write. It is not recorded as exit 126 either. The Evidence ledger says was REFUSED and never ran, quotes the gate's own sentence, and cites the story's review log instead. A refusal and a red build are different facts, and only one of them is a measurement.

Three outcomes, not two

Each source resolves to ok, refused, or unverified.

  • refused — the file does not exist, the line is out of range, the fact id is not in facts.yml, the command is not one your workspace declared. The stage fails.
  • unverified — nobody could check it. There is no facts.yml yet; the workspace declares no commands; nothing in the workspace cites that URL. This is not a lie and it does not fail the stage — but it does stop an auto gate from closing, because a citation nothing can check is exactly the one a person should read.

This distinction was earned. Before it existed, six of the eight kinds returned ok unconditionally, and a handoff citing an invented fact id, an invented question and an invented graph node to assert "we removed the auth check from /admin" validated clean, closed its own auto gate, and advanced the cursor. That was a measured probe, not a hypothetical.

What the checker will and will not tell you

It checks that the citation resolves. Whether the cited line actually supports the sentence is a separate question, and a human at a gate is still the one answering it. The checker's job is to make the cheap failures impossible so your attention goes to the expensive ones.

Two small rules worth knowing, both from real refusals:

  • The token must be the last thing on the line. Trailing punctuation is fine; wrapping the citation in backticks is not — a real first run was refused with "9 unsourced bullets" when all nine carried a citation inside backticks. That case now reports malformed citation instead, because the two need different advice.
  • A section with nothing in it is written as - none [src: absent:<what was looked at>], never as a prose sentence. "No unknowns that we can see" is precisely the claim that most needs a source.

A decision says who made it, or says it does not

An answer you record is a fact, and a fact is the artefact that gets quoted back to every later stage. So it carries who decided it, which is not the same as who typed it.

bash
tldrx answer Q4 "B — rankings are global" --decided-by owner --repo api

--decided-by owner|driver is optional on answer and required on tldrx facts add, and the difference is honest rather than tidy: the same code path also runs from the answer-capture hook, which fires on an agent's own edit and on yours alike, so it cannot say which of the two answered. When nothing said, the fact says not stated — never owner — and the command prints that on stdout rather than leaving you to notice it later. Every close of the run, and the Build handoff's header, then say how many of the run's decisions name a decider and how many do not.

--repo scopes the fact, so a decision about one repo stops appearing in prompts about the others. Without it the scope comes from the question's own affects: line when an entry there names a repo, and from nothing otherwise — an empty scope means no repo was named, never every repo. A --repo your workspace.yml does not declare is refused before anything is written.

A contradiction becomes a question, not two live facts

When an answer lexically contradicts a fact already on record, the answer is still recorded — and tldrx raises a question asking which of the two holds, in the same file you just answered in, with the options supersede the old one, supersede the new one, or write the correction. The new fact also carries conflicts_with, so a prompt that quotes it says so.

It raises; it never refuses. The check is lexical — the same word-overlap rule the no-re-ask hook uses — so it can miss two differently-worded answers that disagree, and it can fire on two that do not. Refusing on that would let a word count deadlock an unattended run. For the same reason the raised question is marked advisory: and stops nothing that runs unattended — not an auto gate, not a stage waiting on answers, not a skip rule: the gate says how many it skipped, and every reader that LISTS questions shows this one exactly like any other. Nothing is retired, nothing is reconciled, and the absence of conflicts_with on a fact means no contradiction was detected — never checked and agreed.

The same rule applies to money

Every dollar tldrx cost prints was reported by the model provider and read off an event in the run's log. No token count is ever multiplied by a price. Work whose cost was never observed is reported as UNMETERED, not as $0.00 — a missing number and a free turn are different claims. See budgets.

The grammar, the resolution rules and every refusal are specified in docs/spec.md §2.8.

MIT licensed. Beta software — the file formats are frozen.