Skip to content

fix(knowledge): gradeFor refuses a passing check for having a precise expectation #1006

Description

@drewstone

Summary

gradeFor refuses an expectation carrying three or more key=value tokens and returns uncheckableafter the check has already run and exited 0, and before the output is compared. A check whose output matches its expectation byte for byte is therefore discarded as ungraded.

Measured on @tangle-network/agent-knowledge@10.7.0, 2026-08-23: 173 of 1001 rung≥4 claims with an expectation (17.3%) are refused this way.

The rule

function expectationRefusalNote(expect) {
  if (!expect?.trim()) return NO_EXPECTATION_NOTE
  if (expect.includes("\n") || expect.includes("\r")) return MULTILINE_EXPECTATION_NOTE
  if (expect.trim().split(/\s+/).filter((token) => token.includes("=")).length >= 3) return MULTI_VALUE_EXPECTATION_NOTE
}

Called from gradeFor at a point where execution.exitCode === 0 is already established:

if (mustBeCheckable) {
  const note = expectationRefusalNote(evidence.expect)
  if (note) return { verdict: "uncheckable", note }
}
if (evidence.expect && !output.includes(evidence.expect)) return { verdict: ... }
return { verdict: "verified" }

The refusal sits directly above the comparison that would have passed.

Worked example

A formally certified code-distance result. The check runs drat-trim over two UNSAT proofs and re-verifies two witness words with numpy:

expect:     SMALL_MITTEN_CERTIFIED proofs_verified=true dZ_lb=10 dX_lb=10 dZ_witness=10OK dX_witness=10OK
outputTail: SMALL_MITTEN_CERTIFIED proofs_verified=true dZ_lb=10 dX_lb=10 dZ_witness=10OK dX_witness=10OK
verdict:    uncheckable

Re-executed independently: same output, exit 0, 7 m 15 s. output.includes(expect) is true. The verdict is uncheckable solely because five tokens contain =.

Why the rule inverts its own intent

A guard against vague expectations should reject expectations that are easy to satisfy accidentally. This rejects the opposite. Ranked by how hard they are to match by chance, the refused expectations are the strongest in our corpus:

GRID OK cells=8 WIN=1 PARETO=6 NEGATIVE=1
CELL steane7|pL=0.10 delta=-8 disc=(9,1) p=0.021484 -> WIN
SCORE cells=4 verdict=MIXED detail=150-30-10:no-loss:NEGATIVE;...

Each names several independent quantities at once, so a false pass requires every one of them to coincide. Meanwhile expect: OK — one token, no = — sails through and is satisfied by any output containing "OK" anywhere.

The rule makes a claim less gradable the more precisely it is stated, which is backwards, and the effect is silent: the verdict is uncheckable, the same word used for a claim that carries no check at all, so a fleet operator reading a grade summary cannot tell "the author never wrote a check" from "the check ran and passed".

Suggested fix

Compare first, refuse second. If output.includes(expect) the claim is verified regardless of token shape — a passing exact-match is not a vague expectation.

If a guard against kitchen-sink expectations is still wanted, it should key on something that actually indicates weakness (an expectation shorter than N characters, or one that matches a large fraction of arbitrary outputs), not on the count of = characters. And if such an expectation must be refused, please give it a distinct verdict from "no check exists" — those are opposite failures.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions