docs← Back to article

Markdown for LLMs

Facts and evidence: pitfalls

The source Markdown for this article. Copy it into your assistant or download it as a text file.

Download this articlePlain text ↗
# Facts and evidence: pitfalls

Wrong forms, silent outcomes, `LDC-E` diagnostics, typical mistakes of
formalizers and AI agents, and how to detect them. Items marked
“confirmed by runs” were reproduced during this research on the installed
engine.

## 1. The fact exists but the rule stays silent

Three different causes with the same Not established, not refuted:

- the premise is Contradiction — a bare literal reads as established;
- the fact is not accepted: off-mode `origin` (`ASSERTION_NOT_ACCEPTED`,
  warning) or the `valid` window missing the law date
  (`ASSERTION_OUTSIDE_VALID`, info);
- the argument value mismatched (another region, another rate).

Detection: the why-not explanation names the conjunct; a guard test on
Not established, not refuted must record which of the three causes is meant. Confirmed by the
`research.facts.polarity` teaching package: the empty case gives Not established, not refuted for exactly the
third cause (the `licensed` premise is simply absent).

## 2. Two identical anonymous facts

`LDC-E1331` in 0.2: both share one preimage (the normalized fact with
`origin`, times, anchors), and the StableId would fork. Two
assertions of one fact on different grounds need distinct `id`, `origin`,
or `evidence`. The AI agent duplicates a fact “for reliability” —
reliability here is a compiler rejection.

## 3. A `valid` window in the future with today’s law date (confirmed by runs)

The fact is silently outside supports: Not established, not refuted and an info-issue.
Reproduction: the `research.facts.valid_window` teaching package at law date 2026-03-01 answers
Not established, not refuted on the same fact that at 2027-06-01 gives Established. A guard
test is `expect issue(ASSERTION_OUTSIDE_VALID)`, otherwise window Not established, not refuted
is indistinguishable from “no fact”. Remember half-openness:
`[@2027-01-01, infinity)` includes the first day.

## 4. A typo in `origin`

`LDC-E1374`, an error: the origin list is closed at six names
(`case_input`, `source_asserted`, `external_snapshot`, `derived`,
`adjudicated`, `assumed_for_simulation`). Assumptions are `assumed_for_simulation` in simulation mode, not
disguised as `case_input`: faking provenance is not “test simplification”
but a different fact meaning.

## 5. A rule in `given`

A case cannot carry law: the program is presented
separately, a test without it is rejected. The AI agent, used to “the test
holds everything”, puts a rule in the case — and gets a rejection instead
of a run. Fix: the rule goes in the package, `given` holds only facts,
documents, and context.

## 6. An `evidence` declaration in the package

`LDC-E1314` (warning): a document is a case input, not part of the
program; without a `status` field it is already a rejection `LDC-E1208`. The
core does not infer a document’s admissibility from a number —
dedicated rules express it. A document goes in `case` or `given`, the `evidence Name;`
reference in the fact.

## 7. A computation in a fact argument

`100 + 20` is `LDC-E1325`, a non-canonical Rational spelling (`10 / 4`) is
`LDC-E1324`: a fact is a value, not a term; write the result
(`120`, `5 / 2`). Arguments match on canonical values; the predicate must
be declared (`LDC-E2102`), arity (`LDC-E2103`) and types (`LDC-E2104`) must
match. In a transport-JSON case the same check gives runtime-issue
`TYPE_ERROR`.

## 8. Fact-group inclusion without context; swapped time order

Including a missing or non-public group, or including without an import
context, is `LDC-E1327`: a group materializes into the consumer’s
compiled output only with a presented context. `observed` later than `recorded` is
warning `LDC-E3101`: the file is accepted, but the order is broken
— first observed, then recorded.