Skip to content

fix(review): stop truncation-induced false 'missing evidence' closes - #8980

Merged
JSONbored merged 1 commit into
mainfrom
fix/truncation-evidence-facts
Jul 26, 2026
Merged

fix(review): stop truncation-induced false 'missing evidence' closes#8980
JSONbored merged 1 commit into
mainfrom
fix/truncation-evidence-facts

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Closes #8961.

The review prompt slices PR descriptions at PR_BODY_PROMPT_LIMIT (2,000 chars). When the cut fell before a Screenshots section, reviewers concluded required visual evidence was absent and the gate closed compliant PRs — a confirmed production failure class found by the 2026-07-26 decision-audit backfill (metagraphed#4640: closed at confidence 0.5 for "missing screenshots" while the body verifiably carries 6 image attachments past the cut; adjudicated incorrect / policy_misapplied).

Model/fact boundary treatment, same doctrine as #8833's CI-claim demotion:

  1. The fact: countBodyAttachments counts markdown images, user-attachments links, <img> tags, and bare media URLs over the FULL body. A truncated description line now reads Description (TRUNCATED at 2000 chars — the FULL body contains N image/video attachment(s) beyond what you can see; NEVER claim screenshots or visual evidence are missing).
  2. The guarantee: demoteEvidenceAbsenceBlockers demotes visual-evidence-absence blockers to annotated nits at BOTH parse sites (Workers + provider paths) whenever the body was truncated — absence of evidence inside a truncated window is not evidence of absence. Untruncated bodies are untouched: there the model saw everything and the claim is a legitimate judgment. Demotions log ai_review_evidence_absence_demoted for prompt-regression monitoring.
  3. bodyTruncated is computed from the SAME promptInput.body the prompt slicer saw, so the demotion can never disagree with the prompt about whether the description was cut.

Tests: pure coverage of the counter (all four attachment forms), the pattern (both phrasing directions, non-visual absence claims excluded), both demotion arms including zero-demotion object identity; the issue's required regression — long body with images beyond the cut produces zero evidence-absence blockers — on the Workers path directly and the BYOK provider path end-to-end. Changed-line coverage: 71/71 lines, all branches.

The review prompt slices PR descriptions at 2,000 chars; when the cut fell
before a Screenshots section, reviewers concluded the required visual
evidence was absent and the gate closed compliant PRs (confirmed live:
metagraphed#4640 closed with 6 attachments beyond the cut). Attachment
presence is a deterministic fact, not a judgment: the prompt now carries
the full-body attachment count whenever the description is truncated, and
a parse-time guard demotes evidence-absence blockers to nits on truncated
bodies at both parse sites, mirroring the CI-claim demotion. Untruncated
bodies are untouched — there the claim is a legitimate judgment.
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@github-actions

Copy link
Copy Markdown
Contributor

Logic backtest

Replayed 0 historical case(s) for linked_issue_scope_mismatch through the base (0bf4b39) and head (77a0b02) versions of its detection logic (corpus checksum 4f53cda18c2b).

Backtest comparison: linked_issue_scope_mismatch

Verdict: unchanged — no comparable axis moved.

Advisory only — this check never blocks merge (#8105).

@codecov

codecov Bot commented Jul 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.64%. Comparing base (266b07d) to head (77a0b02).
⚠️ Report is 13 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8980      +/-   ##
==========================================
+ Coverage   90.56%   92.64%   +2.08%     
==========================================
  Files          96      807     +711     
  Lines       22490    80379   +57889     
  Branches     3884    24366   +20482     
==========================================
+ Hits        20367    74468   +54101     
- Misses       1945     4841    +2896     
- Partials      178     1070     +892     
Flag Coverage Δ
backend 93.45% <100.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/services/ai-review.ts 97.29% <100.00%> (ø)

... and 710 files with indirect coverage changes

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 26, 2026
@loopover-orb

loopover-orb Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Caution

🛑 LoopOver review result - fixes required

Review updated: 2026-07-26 15:21:05 UTC

2 files · 1 AI reviewer · no blockers · CI failing · unstable

🛑 Suggested Action - Manual Review

Review summary
This PR adds a deterministic guard so the AI reviewer never claims screenshots/visual evidence are missing when the PR body was truncated for the prompt, mirroring the #8833 CI-claim demotion pattern: `countBodyAttachments` counts image/video references over the FULL body, `demoteEvidenceAbsenceBlockers` demotes matching blockers to annotated nits at both the Workers and BYOK provider parse sites, and `bodyTruncated` is derived from the same `promptInput.body` the prompt slicer used so the fact and the prompt can never disagree. The wiring is threaded correctly through all call sites in `runLoopOverAiReview` (advisory, dual, and single-reviewer paths all pass `bodyTruncated`), and tests cover the counter, the pattern (both phrasing directions), zero-demotion object identity, and end-to-end regressions on both the Workers and provider paths. The two 'FAILED (no detail provided)' checks (validate, validate-tests) cannot be attributed to a defect visible in this diff; the branch is 7 commits behind the default branch, which is a verified, more likely explanation than a content-level bug.

Nits — 5 non-blocking
  • `EVIDENCE_ABSENCE_PATTERN` in src/services/ai-review.ts:808-810 is a broad regex with a 0-80 char gap; verify it doesn't also fire on non-visual absence claims phrased similarly (e.g. 'lacking test evidence for the screenshot upload endpoint') since the pattern only excludes non-visual nouns, not adjacent unrelated clauses.
  • The console.warn calls at src/services/ai-review.ts:1409 and :1749 for `ai_review_evidence_absence_demoted` duplicate the exact shape of the adjacent `ai_review_ci_claim_demoted` warn — consider a small shared helper to avoid the copy-paste, though this is purely stylistic.
  • The new `runWorkersOpinion`/`runProviderReview` signatures take an added trailing `bodyTruncated = false` positional boolean after an existing optional `images` param, and every call site now must pass an explicit `undefined` placeholder for `images` (e.g. src/services/ai-review.ts:2577-2578) — this is a bit fragile for future edits; consider an options object instead of stacking positional params, though this is a style preference not a defect.
  • Consider consolidating the two now-nearly-identical `console.warn(JSON.stringify({...}))` demotion-logging blocks (CI-claim and evidence-absence) into one small logger function to reduce duplication across both runWorkersOpinion and runProviderReview.
  • Consider naming the `2000`-derived `PR_BODY_PROMPT_LIMIT` reference alongside a comment noting it must track any future change to the prompt's own slice point (already partially done via the exported constant, which is good practice).

CI checks failing

  • validate
  • validate-tests

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #8961
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 13 registered-repo PR(s), 13 merged, 293 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 13 PR(s), 293 issue(s).
Improvement ✅ Minor risk: clean · value: minor
Linked issue satisfaction

Addressed
The PR adds a deterministic attachment_count fact computed from the full untruncated body injected into the prompt with an explicit 'never claim missing' instruction, and adds demoteEvidenceAbsenceBlockers to force-demote evidence-absence blockers to nits at both Workers and provider parse sites whenever bodyTruncated is true, matching all three stated requirements. Tests cover the counter across

Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, TypeScript, Ruby, Go, MDX, Shell, Solidity, JavaScript
  • Official Gittensor activity: 13 PR(s), 293 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Start here: Treat this as maintainer-lane context rather than normal contributor-lane activity.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask &lt;question&gt; answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat &lt;question&gt; answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

Decision record
  • action: hold · clause: success
  • config: 03a7f8b529a9 · pack: oss-anti-slop
  • record: 931853f6ce4b (schema v2, head 77a0b02)

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 26, 2026
@JSONbored
JSONbored merged commit f5e457e into main Jul 26, 2026
8 of 10 checks passed
@JSONbored
JSONbored deleted the fix/truncation-evidence-facts branch July 26, 2026 15:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Review-input truncation causes false 'missing screenshot evidence' closes

1 participant