Skip to content

fix(ai): make prompt drift a cache miss, bound the Ollama context, and attribute votes to the producing model (#9477, #9478) - #9513

Merged
JSONbored merged 2 commits into
mainfrom
fix/ai-cache-fidelity-and-fallback
Jul 28, 2026
Merged

fix(ai): make prompt drift a cache miss, bound the Ollama context, and attribute votes to the producing model (#9477, #9478)#9513
JSONbored merged 2 commits into
mainfrom
fix/ai-cache-fidelity-and-fallback

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

Three ways the AI review pipeline produced or preserved a verdict that did not reflect the current code, the current policy, or the model that actually decided.

Closes #9477
Closes #9478

#9477 — superseded verdicts replayed forever

getCachedAiReview reuses a cacheable=1 row with no maxAgeMs, replaying its findings verbatim — including a severity: "critical" ai_consensus_defect.

AI_REVIEW_CACHE_INPUT_VERSION is hand-bumped, and last moved for #8364. Since then #8789, #8791, #8833, #8845, #8961, #9035, #9074, #9087, #9114, #9145 and #9445 all changed prompt text or verdict logic without a bump. REVIEW_PROMPT_VERSION is still v1 despite its own doc instructing a bump on any verdict-surface change, which also silently no-ops #8222's counterfactual replay gate.

Concretely: a PR closed or held under the pre-#9074 "false consensus" rule, re-gated at the same head, hits an identical fingerprint and replays the old critical finding and its close rationale. The corrected logic never runs for any already-reviewed head.

The fingerprint now folds in REVIEW_PROMPT_VERSION and sha256(buildCanonicalJudgePrompt()). Both are pure and available before the call, so drift becomes an automatic miss rather than something a human has to remember — the mechanism that has already failed eleven times. Bumped to v7 to invalidate rows written under the incomplete fingerprint.

#9478a — the fallback got a prompt it could not fit

Ollama silently left-truncates anything past num_ctx (typically 4k–8k by default) and then answers confidently over whatever survived — which is the tail of the prompt, i.e. the context sections rather than the diff. The review path sends up to 120k chars of diff plus a 240k-char aggregate context budget.

So during a Claude outage a review could be produced from a fraction of the change while carrying the same blocker authority and the same confidence semantics against aiReviewCloseConfidence as the primary, with nothing in the verdict surfacing which provider decided.

An explicit num_ctx is now sent — for the ollama provider only, since other OpenAI-compatible servers may reject an unknown options key and only Ollama has this truncation behaviour. An explicit caller providerOptions still wins, so the vision path's own num_ctx is untouched. Overridable via OLLAMA_NUM_CTX, because the window trades GPU memory against how much of a large diff the model can see.

#9478b — votes attributed to the wrong model

runWorkersOpinion iterates [primary, fallback] internally, and ReviewerOpinionOutcome carried no model identity — so a fallback-produced opinion was recorded as a primary vote. Those votes become reviewer_vote audit events and feed #8229's evidence-weighted routing track records and scoreJudgmentAgreement's contribution to decision-record confidence, so the calibration data was quietly wrong whenever the primary failed over.

The existing doc claimed slot↔model is "unambiguous by construction". That holds for the tie-break slot swap; it does not hold for in-slot fallback. The outcome now carries producedBy.

Scope

Not closing #9478's "tier the fallback's authority" half. Routing a fallback-served lone blocker to hold_for_review instead of a one-shot close is a policy change to the gate's disposition, not a correctness fix, and it deserves its own decision — especially now that the context bound removes the truncation that made the fallback's verdict untrustworthy in the first place. Flagged on the issue rather than bundled in silently.

Validation

  • npx tsc --noEmit -p tsconfig.json — clean
  • 491 passed across ai-review-cache-input, ai-review, selfhost-ai
  • Patch coverage against this diff: 0 uncovered changed lines

Regressions:

  • A change to the canonical judge prompt changes the fingerprint (mocked, so it tests the mechanism rather than today's text).
  • A deliberate REVIEW_PROMPT_VERSION bump also invalidates.
  • A fallback-produced review is attributed to the fallback model, not the primary.
  • An explicit num_ctx is sent for ollama.

Invariants:

  • Identical inputs with an unchanged prompt still produce a stable fingerprint — the fix must not destroy the cache, or every review re-pays.
  • The version constant really was bumped, so pre-fix rows are dead.
  • A primary-produced review is still attributed to the primary.
  • Nothing is sent for openai/openai-compatible/unknown providers, and a caller's own providerOptions always wins.
  • Invalid/empty/zero/negative OLLAMA_NUM_CTX falls back above the truncation-prone stock defaults.

…d attribute votes to the producing model (#9477, #9478)

getCachedAiReview reuses a cacheable row with NO maxAgeMs and replays its findings verbatim,
including a severity:critical ai_consensus_defect. AI_REVIEW_CACHE_INPUT_VERSION was hand-bumped
and last moved for #8364, but #8789, #8791, #8833, #8845, #8961, #9035, #9074, #9087, #9114,
#9145 and #9445 all changed prompt text or verdict logic without one -- so a PR closed or held
under the pre-#9074 false-consensus rule re-gated at the same head to the SAME stale finding and
the corrected logic never ran. The fingerprint now folds in REVIEW_PROMPT_VERSION and a digest of
the canonical judge prompt, both pure and available before the call, so drift is an automatic
miss rather than something a human must remember. Bumped to v7 to kill rows written under the
incomplete fingerprint.

Ollama silently left-truncates past num_ctx (typically 4k-8k by default) and then answers
confidently over whatever survived -- the TAIL of the prompt, i.e. the context sections rather
than the diff. The review path sends up to 120k chars of diff plus a 240k-char context budget,
so on the fallback provider a review could come from a fraction of the change while carrying the
same blocker authority and confidence semantics as the primary. An explicit num_ctx is now sent
for the ollama provider only, since other OpenAI-compatible servers may reject an unknown
options key, and an explicit caller providerOptions still wins.

runWorkersOpinion iterates [primary, fallback] internally and its outcome carried no model
identity, so a fallback-produced review was recorded as a PRIMARY vote -- poisoning the
reviewer_vote audit events, #8229's routing track records, and scoreJudgmentAgreement's
contribution to decision-record confidence. The doc's claim that slot-to-model is unambiguous by
construction holds for the tie-break swap, not for in-slot fallback.
@loopover-orb

loopover-orb Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Important

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏳ LoopOver is waiting…

LoopOver has seen this pull request and is waiting on CI checks to finish before reviewing it. This comment will update once the review runs.

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

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Logic backtest

Replayed 0 historical case(s) for linked_issue_scope_mismatch through the base (d1c770c) and head (26e6ca5) 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 28, 2026

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
23000 1 22999 21
View the top 1 failed test(s) by shortest run time
test/unit/queue-4.test.ts > queue processors > hard-blocks a confirmed contributor on a dual-model AI consensus defect when aiReview: block is opted in
Stack Traces | 0.395s run time
AssertionError: expected 'ai-review-input:v7:04ea7ce096c5fdca89…' to match /^ai-review-input:v6:/

- Expected:
/^ai-review-input:v6:/

+ Received:
"ai-review-input:v7:04ea7ce096c5fdca892877a445f44652974d68157730b3c1a69a1c69445e832b"

 ❯ test/unit/queue-4.test.ts:1287:45

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 28, 2026
@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 28, 2026
@superagent-security

Copy link
Copy Markdown
Contributor

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

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 28, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
loopover-ui 26e6ca5 Commit Preview URL

Branch Preview URL
Jul 28 2026, 05:11 AM

@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 44 bytes (0.0%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
loopover-ui 7.64MB 44 bytes (0.0%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: loopover-ui

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/add-scalar-classes-CLKvvd5H.js (New) 2.16MB 2.16MB 100.0% 🚀
assets/tanstack-vendor-QLiz2HDq.js (New) 862.21kB 862.21kB 100.0% 🚀
assets/docs.fumadocs-spike-api-reference-vfgy-P7u.js (New) 443.45kB 443.45kB 100.0% 🚀
assets/AgentScalarChatInterface.vue-77nloJwa.js (New) 201.7kB 201.7kB 100.0% 🚀
assets/modal-5-Myr_YY.js (New) 184.5kB 184.5kB 100.0% 🚀
assets/client-S4Bggoa_.js (New) 151.47kB 151.47kB 100.0% 🚀
assets/self-hosting-configuration-Y8N2T175.js (New) 101.93kB 101.93kB 100.0% 🚀
assets/maintainer-panel-DnDCsfhP.js (New) 78.99kB 78.99kB 100.0% 🚀
assets/routes-DtOBFP-4.js (New) 35.96kB 35.96kB 100.0% 🚀
assets/owner-panel-Bx9s3273.js (New) 27.92kB 27.92kB 100.0% 🚀
assets/app-CK-JVufq.js (New) 25.78kB 25.78kB 100.0% 🚀
assets/ui-vendor-BNdBZYsj.js (New) 24.57kB 24.57kB 100.0% 🚀
assets/miner-panel-D7N7vnPZ.js (New) 20.24kB 20.24kB 100.0% 🚀
assets/app.runs-UfzylT2J.js (New) 20.22kB 20.22kB 100.0% 🚀
assets/api._op-jVt1MQ8R.js (New) 17.57kB 17.57kB 100.0% 🚀
assets/self-hosting-docs-audit-CX3MuWTa.js (New) 16.6kB 16.6kB 100.0% 🚀
assets/docs._slug-Cz6pKUqf.js (New) 15.52kB 15.52kB 100.0% 🚀
assets/playground-panel-Bb6bzrNN.js (New) 14.42kB 14.42kB 100.0% 🚀
assets/fairness-r5q8SP8o.js (New) 10.73kB 10.73kB 100.0% 🚀
assets/app.audit-DZbgtXQe.js (New) 10.08kB 10.08kB 100.0% 🚀
assets/app.config-generator-WXoUOCNC.js (New) 10.06kB 10.06kB 100.0% 🚀
assets/maintainers-D9fs1OOd.js (New) 8.06kB 8.06kB 100.0% 🚀
assets/miners-4R7d-jrK.js (New) 7.91kB 7.91kB 100.0% 🚀
assets/agents-CBBU1TU9.js (New) 7.74kB 7.74kB 100.0% 🚀
assets/commands-panel-CZhq60F4.js (New) 6.65kB 6.65kB 100.0% 🚀
assets/maintainer-workflow-DwcdepS_.js (New) 6.52kB 6.52kB 100.0% 🚀
assets/digest-panel-Be8Nej4_.js (New) 6.15kB 6.15kB 100.0% 🚀
assets/repos._owner._repo.quality-BfzVPvOY.js (New) 6.14kB 6.14kB 100.0% 🚀
assets/docs-nav-Cocb1O-8.js (New) 6.01kB 6.01kB 100.0% 🚀
assets/docs.index-eA589sXD.js (New) 5.95kB 5.95kB 100.0% 🚀
assets/api.index-yq6qEOD8.js (New) 4.7kB 4.7kB 100.0% 🚀
assets/docs-CTxSpY4a.js (New) 2.7kB 2.7kB 100.0% 🚀
assets/api-Chmd4jtl.js (New) 2.69kB 2.69kB 100.0% 🚀
assets/docs-page-N-Na610u.js (New) 2.1kB 2.1kB 100.0% 🚀
assets/table-_1XxBVl4.js (New) 1.75kB 1.75kB 100.0% 🚀
assets/app.workbench-9G2_e6Jw.js (New) 1.58kB 1.58kB 100.0% 🚀
assets/tabs-B07YVlrJ.js (New) 1.39kB 1.39kB 100.0% 🚀
assets/app.repos-WiN001RP.js (New) 1.07kB 1.07kB 100.0% 🚀
assets/input-CeXhAOAQ.js (New) 796 bytes 796 bytes 100.0% 🚀
assets/file-cog-hmJ7E5Lo.js (New) 758 bytes 758 bytes 100.0% 🚀
assets/app.maintainer-C0q98Bua.js (New) 502 bytes 502 bytes 100.0% 🚀
assets/app.owner-KqGYuks_.js (New) 474 bytes 474 bytes 100.0% 🚀
assets/app.commands-DwU6ERD9.js (New) 455 bytes 455 bytes 100.0% 🚀
assets/app.playground-CSIm7AZd.js (New) 442 bytes 442 bytes 100.0% 🚀
assets/index-Oykf2gS4.js (New) 438 bytes 438 bytes 100.0% 🚀
assets/app.digest-BhQQXV7W.js (New) 430 bytes 430 bytes 100.0% 🚀
assets/eye-off-B4UvJl2H.js (New) 430 bytes 430 bytes 100.0% 🚀
assets/app.miner-DajfDvJE.js (New) 422 bytes 422 bytes 100.0% 🚀
assets/key-round-CCJBmuxx.js (New) 355 bytes 355 bytes 100.0% 🚀
assets/bot-B9P-KopM.js (New) 328 bytes 328 bytes 100.0% 🚀
assets/trash-2-QQtS23lG.js (New) 328 bytes 328 bytes 100.0% 🚀
assets/save-BLjJTSkA.js (New) 327 bytes 327 bytes 100.0% 🚀
assets/git-pull-request-arrow-Bdyo4CeN.js (New) 321 bytes 321 bytes 100.0% 🚀
assets/list-checks-C3yC-p0q.js (New) 279 bytes 279 bytes 100.0% 🚀
assets/compass-CjBmvNte.js (New) 251 bytes 251 bytes 100.0% 🚀
assets/history-psoZNGp4.js (New) 237 bytes 237 bytes 100.0% 🚀
assets/message-square-BuGKZvdG.js (New) 233 bytes 233 bytes 100.0% 🚀
assets/lock-Df30sidf.js (New) 206 bytes 206 bytes 100.0% 🚀
assets/rotate-cw-C5kZl0C0.js (New) 201 bytes 201 bytes 100.0% 🚀
assets/play-Dz34vz1f.js (New) 190 bytes 190 bytes 100.0% 🚀
assets/circle-check-RmdbFPZO.js (New) 178 bytes 178 bytes 100.0% 🚀
assets/search-CsFvmwj6.js (New) 174 bytes 174 bytes 100.0% 🚀
assets/add-scalar-classes-DUQb7lQc.js (Deleted) -2.16MB 0 bytes -100.0% 🗑️
assets/tanstack-vendor-sUd4-iZs.js (Deleted) -862.21kB 0 bytes -100.0% 🗑️
assets/docs.fumadocs-spike-api-reference-C8dKd-fh.js (Deleted) -443.45kB 0 bytes -100.0% 🗑️
assets/AgentScalarChatInterface.vue-66cSI5DN.js (Deleted) -201.7kB 0 bytes -100.0% 🗑️
assets/modal-DiWKRGp8.js (Deleted) -184.5kB 0 bytes -100.0% 🗑️
assets/client-B15ImyKI.js (Deleted) -151.47kB 0 bytes -100.0% 🗑️
assets/self-hosting-configuration-BLECzfnN.js (Deleted) -101.89kB 0 bytes -100.0% 🗑️
assets/maintainer-panel-L5CmhE3s.js (Deleted) -78.99kB 0 bytes -100.0% 🗑️
assets/routes-DpL6IZHW.js (Deleted) -35.96kB 0 bytes -100.0% 🗑️
assets/owner-panel-BcPJ2s-l.js (Deleted) -27.92kB 0 bytes -100.0% 🗑️
assets/app-ssLhsjEQ.js (Deleted) -25.78kB 0 bytes -100.0% 🗑️
assets/ui-vendor-B6uo62Xa.js (Deleted) -24.57kB 0 bytes -100.0% 🗑️
assets/miner-panel-CHkigePk.js (Deleted) -20.24kB 0 bytes -100.0% 🗑️
assets/app.runs-DgDqQIiV.js (Deleted) -20.22kB 0 bytes -100.0% 🗑️
assets/api._op-Dhyx4jJi.js (Deleted) -17.57kB 0 bytes -100.0% 🗑️
assets/self-hosting-docs-audit-DJJYNi6h.js (Deleted) -16.6kB 0 bytes -100.0% 🗑️
assets/docs._slug-DK7uHo3Z.js (Deleted) -15.52kB 0 bytes -100.0% 🗑️
assets/playground-panel-CNGuSTYF.js (Deleted) -14.42kB 0 bytes -100.0% 🗑️
assets/fairness-BP-jqELb.js (Deleted) -10.73kB 0 bytes -100.0% 🗑️
assets/app.audit-Cj3Wa49F.js (Deleted) -10.08kB 0 bytes -100.0% 🗑️
assets/app.config-generator-BIHynSxb.js (Deleted) -10.06kB 0 bytes -100.0% 🗑️
assets/maintainers-CyuheKjv.js (Deleted) -8.06kB 0 bytes -100.0% 🗑️
assets/miners-g3S0DziV.js (Deleted) -7.91kB 0 bytes -100.0% 🗑️
assets/agents-DZAEolQ-.js (Deleted) -7.74kB 0 bytes -100.0% 🗑️
assets/commands-panel-Dc8E7qzz.js (Deleted) -6.65kB 0 bytes -100.0% 🗑️
assets/maintainer-workflow-Bp1botcD.js (Deleted) -6.52kB 0 bytes -100.0% 🗑️
assets/digest-panel-iJ70-HcL.js (Deleted) -6.15kB 0 bytes -100.0% 🗑️
assets/repos._owner._repo.quality-BNZ02dQd.js (Deleted) -6.14kB 0 bytes -100.0% 🗑️
assets/docs-nav-Cy97kWvg.js (Deleted) -6.01kB 0 bytes -100.0% 🗑️
assets/docs.index-zbb0LSvV.js (Deleted) -5.95kB 0 bytes -100.0% 🗑️
assets/api.index-DCPwDChq.js (Deleted) -4.7kB 0 bytes -100.0% 🗑️
assets/docs-D1foIej0.js (Deleted) -2.7kB 0 bytes -100.0% 🗑️
assets/api-9U9yD_ue.js (Deleted) -2.69kB 0 bytes -100.0% 🗑️
assets/docs-page-D4sOmPJr.js (Deleted) -2.1kB 0 bytes -100.0% 🗑️
assets/table-CbwZT2g3.js (Deleted) -1.75kB 0 bytes -100.0% 🗑️
assets/app.workbench-R1l9c0VC.js (Deleted) -1.58kB 0 bytes -100.0% 🗑️
assets/tabs-VkzrsDbD.js (Deleted) -1.39kB 0 bytes -100.0% 🗑️
assets/app.repos-D-rF86CY.js (Deleted) -1.07kB 0 bytes -100.0% 🗑️
assets/input-_Y89XwQE.js (Deleted) -796 bytes 0 bytes -100.0% 🗑️
assets/file-cog-D9Rm7Faq.js (Deleted) -758 bytes 0 bytes -100.0% 🗑️
assets/app.maintainer-CBojz_cq.js (Deleted) -502 bytes 0 bytes -100.0% 🗑️
assets/app.owner-n0s_W2UQ.js (Deleted) -474 bytes 0 bytes -100.0% 🗑️
assets/app.commands-BHZULm0o.js (Deleted) -455 bytes 0 bytes -100.0% 🗑️
assets/app.playground-DnV52G5B.js (Deleted) -442 bytes 0 bytes -100.0% 🗑️
assets/index-BmiKkSg0.js (Deleted) -438 bytes 0 bytes -100.0% 🗑️
assets/app.digest-De2IGhch.js (Deleted) -430 bytes 0 bytes -100.0% 🗑️
assets/eye-off-DM9IXLT5.js (Deleted) -430 bytes 0 bytes -100.0% 🗑️
assets/app.miner-JCRnvBKg.js (Deleted) -422 bytes 0 bytes -100.0% 🗑️
assets/key-round-zjwqfLjI.js (Deleted) -355 bytes 0 bytes -100.0% 🗑️
assets/bot-Da7Oy3zg.js (Deleted) -328 bytes 0 bytes -100.0% 🗑️
assets/trash-2-DPt7kVCf.js (Deleted) -328 bytes 0 bytes -100.0% 🗑️
assets/save-CTGBB9vf.js (Deleted) -327 bytes 0 bytes -100.0% 🗑️
assets/git-pull-request-arrow-D6xt49Y9.js (Deleted) -321 bytes 0 bytes -100.0% 🗑️
assets/list-checks-Cf9j1V8x.js (Deleted) -279 bytes 0 bytes -100.0% 🗑️
assets/compass-NrHQka4m.js (Deleted) -251 bytes 0 bytes -100.0% 🗑️
assets/history-al7sk1Zn.js (Deleted) -237 bytes 0 bytes -100.0% 🗑️
assets/message-square-D6f-PYjd.js (Deleted) -233 bytes 0 bytes -100.0% 🗑️
assets/lock-Bg3aGHXa.js (Deleted) -206 bytes 0 bytes -100.0% 🗑️
assets/rotate-cw-D8URfKp_.js (Deleted) -201 bytes 0 bytes -100.0% 🗑️
assets/play-BMh-2Bzy.js (Deleted) -190 bytes 0 bytes -100.0% 🗑️
assets/circle-check-BrZCp9vq.js (Deleted) -178 bytes 0 bytes -100.0% 🗑️
assets/search-BqH2vsyU.js (Deleted) -174 bytes 0 bytes -100.0% 🗑️

@JSONbored
JSONbored merged commit adc0936 into main Jul 28, 2026
9 of 10 checks passed
@JSONbored
JSONbored deleted the fix/ai-cache-fidelity-and-fallback branch July 28, 2026 05:17
JSONbored added a commit that referenced this pull request Jul 28, 2026
…r log, and cap the third advisory (#9489, #9491) (#9514)

* fix(ledger,drift): retry an unanchored tip, stop truncating the anchor log, and cap the third advisory (#9489, #9491)

loadLastLedgerAnchorAttempt deliberately returns the newest attempt regardless of status so the
scheduler advances to newer tips rather than hammering a stale checkpoint -- but that made a
FAILURE at a QUIET tip unrecoverable. Rekor 429s at seq N, the ledger goes quiet, and every
hourly tick then sees tipUnchanged and returns "unchanged", so the tip carries no valid external
anchor indefinitely: exactly the unanchored window the feature exists to bound. It was also
backend-blind, since the newest row won regardless of which backend wrote it, so git succeeding
masked rekor failing at the same seq. The scheduler now asks per backend whether THIS rowHash has
a successful anchor, and retries on the hourly tick when it does not.

loadDecisionLedgerTip read COUNT(*) and the tip row as two statements under Promise.all. The
seq/totalCount pair is precisely how a verifier detects truncation-and-rechaining, so a
concurrent append between them produced totalCount = seq + 1 beside the OLD rowHash -- an
internally inconsistent checkpoint that anchoring then signs and publishes to Rekor,
unretractably, as a FALSE tamper signal about the maintainer's own ledger. One statement now
reads both from a single snapshot.

For a file between 1 MB and 100 MB the Contents API returns content:"" with encoding:"none", and
because typeof "" === "string" the old code accepted that as the file's contents and rewrote the
whole anchor log to a single line while reporting ok. At ~300 bytes per line hourly that lands
4-5 months out; git history keeps the commits but the file a skeptic is told to read shrinks,
which is indistinguishable from tampering. It now refuses and records a failed attempt, leaving
the log untouched and the gap visible on the public attempt log.

The linked-issue satisfaction advisory was the one paid LLM call in its family with no per-PR
commit cap -- ai_slop and ai_review both stop past auto_pause_after_reviewed_commits -- so a
long-lived PR kept paying for a fresh assessment on every push after its siblings had stopped.

* fix(ci): unpin a hardcoded cache-input version that broke main, and cover the new ledger paths

queue-4 asserted /^ai-review-input:v6:/ against a literal, so the v6 -> v7 bump in #9513 broke it
on main. It now asserts against AI_REVIEW_CACHE_INPUT_VERSION itself: the property that matters
is that the fingerprint carries the CURRENT version, not which version that happens to be, so a
future bump cannot break it again.

Adds per-backend anchor-lookup coverage (a failed attempt is not anchored; one backend's success
does not mask another's failure; a success at a different rowHash does not anchor this tip), the
three Contents-API body shapes, and the commit-threshold cap regression. Two fail-open catches
are annotated: an unreadable counter must not SUPPRESS the advisory, and an unreadable anchors
table degrades to the pre-#9489 scheduling behaviour rather than forcing an anchor every tick.
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

1 participant