fix(review): fail closed on incoherent AI verdicts - #1581
Conversation
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1581 +/- ##
=======================================
Coverage 95.45% 95.45%
=======================================
Files 202 202
Lines 21781 21783 +2
Branches 7866 7867 +1
=======================================
+ Hits 20791 20793 +2
Misses 414 414
Partials 576 576
🚀 New features to boost your workflow:
|
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review — held for maintainer review
⏸️ Held for maintainer review — Touches a guarded path — held for manual review Review summary
Nits — 6 non-blocking
Review context
Contributor next steps
Signal definitions
Review detailsGenerated from public PR metadata and the diff. Advisory only; deterministic signals remain authoritative. This PR correctly closes a real security-relevant fail-open: the AI was already instructed to emit a sentinel assessment on incoherent diffs, but `parseModelReview` only short-circuited on a completely empty assessment, so a sentinel response (non-empty `assessment`, empty arrays) parsed as a valid clean review and reached auto-merge. Extracting the sentinel into `INCOHERENT_DIFF_ASSESSMENT`, interpolating it into the system prompt, and inserting an exact-equality guard before the existing empty-check at `ai-review.ts:390` closes the gap cleanly. The DRY promotion means prompt and parser can never silently diverge on the sentinel string, which was the root of the bug. Nits (5)
🟩 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 Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
Motivation
Description
INCOHERENT_DIFF_ASSESSMENTand reference it in the system prompt via the existing prompt assembly (src/services/ai-review.ts).parseModelReviewto treat the sentinel assessment as unparseable (returnnull), so downstream combining logic will treat the reviewer slot as missing and produceinconclusive(hold) per existing fail-closed rules.nulland thatcombineReviews(..., { strategy: "consensus" })yieldsinconclusive: true.Testing
npx vitest run test/unit/ai-review.test.ts, and the tests passed (including the new sentinel regression test).npx vitest run test/unit/ai-review.test.ts -t incoherent, and it passed (the sentinel path is exercised).npm run test:coverage -- test/unit/ai-review.test.ts; the tests passed but local coverage remapping failed withTypeError: jsTokens is not a functionin the coverage remapper (local toolchain issue, not related to the logic change).npm run typechecksurfaced pre-existing unrelated TypeScript errors insrc/selfhost/sentry.ts(missing@sentry/nodetypes), andnpm run test:ciencountered environment/tooling failures (offlineactionlintsetup and label check) and did not fully complete; these are unrelated to the fix itself but block a full CI run in this environment.Codex Task