Evidence provenance (added 2026-08-22). The run-derived figures in this issue come from a
private scan that a reader cannot reproduce (raptor-e2e-20260818, a 9.85-hour run against
a Python target). They are reported for completeness, not as independently checkable evidence.
Every code claim below is pinned to public source at b5019628 and is checkable; where a
conclusion rests on the private numbers rather than on the code, treat it as my report of what
that run showed. This label was missing when the issue was filed.
Summary
Several per-unit counters branch on error versus everything else, but the pipeline has three
outcomes, not two: completed, incomplete (the loop never reached a verdict), and errored. The
incomplete case falls into the else and is counted as completed. On our run the verify checkpoint
summary reported 175 completed where only 41 verifications actually produced a verdict.
The same two-branch shape appears at five sites. Two correct three/four-way handlers already exist in
the repository to copy — one of them in the same module as one of the broken sites.
Evidence
Runtime proof
RUN=~/.openant/projects/gadievron/raptor-e2e-20260818/scans/7dbf9c691d7/python
cat $RUN/verify_checkpoints/_summary.json
{
"step": "Verify", "phase": "done", "total_units": 223,
"completed": 175,
"errors": 48,
"error_breakdown": { "api": 48 }
}
Ground truth, by enumerating the 223 per-unit checkpoint files and keying on the shape of their
verification object ({"incomplete": true} alone = errored; incomplete: true with a verdict =
incomplete; otherwise complete):
python3 - <<'PY'
import json, glob, os
cps = [c for c in glob.glob(os.path.expanduser("$RUN/verify_checkpoints/*.json"))
if os.path.basename(c) not in ("_summary.json", "_fingerprint.json")]
inc = err = comp = 0
for c in cps:
v = json.load(open(c)).get("verification") or {}
if set(v.keys()) == {"incomplete"}: err += 1
elif v.get("incomplete"): inc += 1
else: comp += 1
print("genuinely complete:", comp, "| incomplete:", inc, "| errored:", err, "| total:", comp+inc+err)
PY
genuinely complete: 41 | incomplete: 134 | errored: 48 | total: 223
completed: 175 is 41 + 134. Every incomplete verification was counted as a completion — a 4.3x
over-report of the number that produced a verdict.
The mechanism
libs/openant-core/utilities/finding_verifier.py:673-681 (excerpt — 1 interior line elided) (HEAD b501962):
def _summary_callback(detail, usage=None):
"""Update summary counters after each unit. Called from main thread."""
nonlocal _summary_completed, _summary_errors, _summary_error_breakdown
...
if detail == "error":
_summary_errors += 1
_summary_error_breakdown["api"] = _summary_error_breakdown.get("api", 0) + 1
else:
_summary_completed += 1
detail for an incomplete verification is a verdict string (e.g. disagreed:vulnerable->vulnerable),
not "error", so it increments _summary_completed.
The same shape, five sites
| site |
third state that lands in else |
what it corrupts |
utilities/finding_verifier.py:673-689 |
incomplete verification |
checkpoint _summary.json counts (proof above) |
utilities/context_enhancer.py:744-767 |
INCOMPLETE_CLASSIFICATION units |
enhance summary counts |
core/analyzer.py:598-613 |
inconclusive / insufficient_context |
analyze progress counts |
utilities/finding_verifier.py:740-751 |
incomplete verification |
the verification_note prose ("Changed from X to X") |
experiment.py:590-597 |
incomplete verification |
harness-only |
enhance shows the same divergence in its own artifacts: its checkpoint summary reports
errors: 0, completed: 5475 while enhance.report.json records 3 incomplete units.
Correct handlers already in-tree
core/verifier.py:274-330 buckets error / incomplete / verdict separately — the best template.
core/reporter.py:419-428 handles agree / incomplete / else, though it has no error bucket.
utilities/context_enhancer.py:978-1027 (_compute_agentic_stats) buckets incomplete correctly —
in the same module as the broken counter above, which is the strongest available evidence that
site is an oversight rather than a deliberate simplification.
Why it matters
These counters are what an operator watches during a long run and what the checkpoint summary
preserves afterwards. A verify phase that adjudicated 41 of 223 candidates reported 175 completed;
nothing in the summary distinguishes "reached a verdict" from "ran 20 iterations and gave up". The
error count is correct, so the summary looks internally consistent (175 + 48 = 223) while being wrong
about the number that matters.
Suggested fix
-
Give each counter a third bucket (incomplete / needs_review) and branch on the structured flag
the producer already writes (verification.incomplete, INCOMPLETE_CLASSIFICATION), not on the
detail string.
Added 2026-08-21 — this is not uniformly applicable, and the difference matters for scoping
the work. The structured flag is reachable at some of the cited sites but not all:
- Reachable.
utilities/context_enhancer.py:744 is def _update_summary(classification, unit)
and already reads through unit (:752, :758), so a flag on the unit can be consulted with
no signature change.
- Not reachable without a signature change.
core/analyzer.py:598 is
def _summary_callback(finding, usage=None) — it receives the verdict string and usage,
nothing else. Both call sites pass only that: :273 and :299 are
summary_callback(out["finding"], usage=out.get("usage")). The full result object exists at
those sites — :302 reads out["result"] two lines later — but is not handed to the callback.
So at the analyzer site this fix requires widening the callback signature and passing
out["result"] (or the flag off it) from :273 and :299. That is still small, but it is a
change to a call contract rather than a one-line branch, and I filed the item as though it were
the latter everywhere.
-
Emit the new bucket in write_summary so _summary.json carries completed / incomplete /
errors that sum to total_units with all three visible.
-
Copy the bucketing from core/verifier.py:274-330 rather than writing a fourth variant.
-
Add a test asserting completed + incomplete + errors == total_units and that an incomplete unit
does not increment completed.
What I am not claiming
- I am not claiming the counts are wrong in the step reports.
verify.report.json correctly
carries needs_review: 134 and error_count: 48; the defect is in the checkpoint summary and the
progress counters, which is why the two disagree.
- I have runtime evidence for the verify site only. The other four are established from source; the
enhance divergence above is corroborating but I did not enumerate its per-unit checkpoints.
experiment.py:590-597 is harness code and is listed for completeness, not as a product defect.
Summary
Several per-unit counters branch on
errorversus everything else, but the pipeline has threeoutcomes, not two: completed, incomplete (the loop never reached a verdict), and errored. The
incomplete case falls into the
elseand is counted as completed. On our run the verify checkpointsummary reported 175 completed where only 41 verifications actually produced a verdict.
The same two-branch shape appears at five sites. Two correct three/four-way handlers already exist in
the repository to copy — one of them in the same module as one of the broken sites.
Evidence
Runtime proof
{ "step": "Verify", "phase": "done", "total_units": 223, "completed": 175, "errors": 48, "error_breakdown": { "api": 48 } }Ground truth, by enumerating the 223 per-unit checkpoint files and keying on the shape of their
verificationobject ({"incomplete": true}alone = errored;incomplete: truewith a verdict =incomplete; otherwise complete):
completed: 175is41 + 134. Every incomplete verification was counted as a completion — a 4.3xover-report of the number that produced a verdict.
The mechanism
libs/openant-core/utilities/finding_verifier.py:673-681(excerpt — 1 interior line elided) (HEADb501962):detailfor an incomplete verification is a verdict string (e.g.disagreed:vulnerable->vulnerable),not
"error", so it increments_summary_completed.The same shape, five sites
elseutilities/finding_verifier.py:673-689_summary.jsoncounts (proof above)utilities/context_enhancer.py:744-767INCOMPLETE_CLASSIFICATIONunitscore/analyzer.py:598-613inconclusive/insufficient_contextutilities/finding_verifier.py:740-751verification_noteprose ("Changed from X to X")experiment.py:590-597enhanceshows the same divergence in its own artifacts: its checkpoint summary reportserrors: 0, completed: 5475whileenhance.report.jsonrecords 3 incomplete units.Correct handlers already in-tree
core/verifier.py:274-330bucketserror/incomplete/ verdict separately — the best template.core/reporter.py:419-428handlesagree/incomplete/ else, though it has no error bucket.utilities/context_enhancer.py:978-1027(_compute_agentic_stats) buckets incomplete correctly —in the same module as the broken counter above, which is the strongest available evidence that
site is an oversight rather than a deliberate simplification.
Why it matters
These counters are what an operator watches during a long run and what the checkpoint summary
preserves afterwards. A verify phase that adjudicated 41 of 223 candidates reported 175 completed;
nothing in the summary distinguishes "reached a verdict" from "ran 20 iterations and gave up". The
error count is correct, so the summary looks internally consistent (175 + 48 = 223) while being wrong
about the number that matters.
Suggested fix
Give each counter a third bucket (
incomplete/needs_review) and branch on the structured flagthe producer already writes (
verification.incomplete,INCOMPLETE_CLASSIFICATION), not on thedetail string.
Emit the new bucket in
write_summaryso_summary.jsoncarriescompleted/incomplete/errorsthat sum tototal_unitswith all three visible.Copy the bucketing from
core/verifier.py:274-330rather than writing a fourth variant.Add a test asserting
completed + incomplete + errors == total_unitsand that an incomplete unitdoes not increment
completed.What I am not claiming
verify.report.jsoncorrectlycarries
needs_review: 134anderror_count: 48; the defect is in the checkpoint summary and theprogress counters, which is why the two disagree.
enhance divergence above is corroborating but I did not enumerate its per-unit checkpoints.
experiment.py:590-597is harness code and is listed for completeness, not as a product defect.