Commit Graph
21 Commits
Author SHA1 Message Date
Nirav Patel 6b131e1427 Merge pull request 'fix(verdict): findings resolved by the change under review never block' (#5) from fix/resolved-findings-dont-block into main 2026-08-22 14:44:49 -04:00
nirpaandClaude Fable 5 a76221578c fix(verdict): findings resolved by the change under review never block
The review model routinely narrates the pre-existing bug a PR fixes as a
critical/confirmed correctness finding; deriveVerdict then failed the very
change that fixes it (three consecutive A-grade reviews of shreai#188
verdicted fail this way). Findings now carry resolved_by_this_change
(prompted, schema'd, normalized); resolved findings are excluded from
fail/warn derivation, and a model-level warn whose findings are all
resolved normalizes to pass. Introduced-or-remaining defects still block.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01AD1cPDz563Fyppc7T4ibhU
2026-08-22 14:44:32 -04:00
Claude 0dec11b5ed Disable router fallbacks for local reviews 2026-08-21 19:55:50 -04:00
Claude 6478ce2bfa Reject local review model drift 2026-08-21 19:49:45 -04:00
Claude c648a5a6da Track running Granthi review queue jobs 2026-08-21 18:04:35 -04:00
Nirav Patel 10bbd598f3 Merge pull request 'fix: diff-fetch fallback chain — stop failing open on compare 404' (#4) from fix/diff-fetch-fallback into main 2026-08-19 12:01:42 -04:00
Claude ad8c1256d8 fix: dual-review round-2 — partial diffs cap the verdict, bounded fallback chain, URL-safe paths
Codex adversarial review of the fallback chain found 1 P1 + 3 P2:
- P1: head-only and incomplete per-commit fallbacks could present a SUBSET
  diff as a full passing review. fetchDiff now returns {diff, partial, note};
  review.js caps partial reviews at 'warn' (same contract as truncation) and
  labels the status 'partial review (<reason>)'.
- getRepo default-branch lookup swallows only 404; auth/5xx propagate.
- per-commit reconstruction dedupes + validates shas (40-hex) and hard-caps
  at 20 requests; capped/short coverage marks the result partial; the
  all-sources-failed message is bounded to 1500 chars.
- gitea.js URL-encodes every webhook-supplied path segment (owner/repo/ref/
  sha) — branch names with '/' or '#' can no longer distort request paths.

Tests: 61 pass (2 new: sha cap/dedupe, getRepo 401 propagation).

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-19 11:58:59 -04:00
Claude a531323865 fix: diff-fetch fallback chain — stop failing open on compare 404
~23% of reviews were failing open with `diff fetch failed: gitea GET
/{owner}/{repo}/compare/{before}...{after}.diff -> 404`. Probing the live
forge (Gitea 1.27.1) showed the web compare route answers 404 for ALL refs
on private repos — it does not honor `Authorization: token` and resolves as
anonymous — while the API compare (JSON) and per-commit
/git/commits/{sha}.diff endpoints succeed for the exact same sha pairs.
It also 404s legitimately when `before` is unknown (force-push, rebase).

fetchDiff now walks a fallback chain instead of failing open on the first
404 (any non-404 error still propagates immediately):

  PR job:     pulls/{n}.diff -> git/commits/{head}.diff
  range push: web compare {before}...{after}.diff
              -> web compare {defaultBranch}...{after}.diff
              -> API compare commit list (falls back to the webhook's
                 commitShas) -> concatenated per-commit git/commits/{sha}.diff,
                 stopping past maxDiffBytes so the existing truncation cap
                 (verdict capped at 'warn') kicks in
              -> git/commits/{after}.diff alone
  new branch: git/commits/{after}.diff (unchanged)

Only when every source is exhausted does the review fail open, and the log
line now lists every URL tried. Webhook jobs carry the repo default_branch
so the fallback needs no extra API call; getRepo() covers recovered jobs
persisted before this change.

Verified against the live forge for the exact failing pair from today's
service.log (Nirlabinc/shreai 481d8663...46696b50): the chain recovers a
full-range 8,993-byte diff via 2/2 per-commit diffs.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-19 11:48:06 -04:00
Nirav Patel d0b21927e7 Merge pull request 'fix: review hardening — full push-range diff, fail-closed diff fetch, crash-safe queue, 403 self-heal' (#3) from fix/review-hardening into main 2026-08-19 09:15:41 -04:00
Nirav PatelandClaude Fable 5 e32c600215 fix: review hardening — full push-range diff, fail-closed diff fetch, crash-safe queue, 403 self-heal
- push reviews now fetch ONE compare diff (before...after) instead of
  slicing to the first 20 commits under a head-sha status; new-branch
  pushes (zero before-sha) fall back to the head commit diff
- truncated diffs can no longer yield a clean pass: verdict capped at
  warn and status description prefixed 'partial review (diff truncated)'
- any diff-fetch failure (throw / empty body on a non-empty push or PR)
  short-circuits to status 'warning' ('review unavailable — diff fetch
  failed (not blocking)') with a ledger row; a diffless prompt is never
  sent to the model
- accepted jobs persist to sqlite (queue_jobs) before the pending status
  posts; startup re-enqueues rows that never reached a final state, so
  restarts no longer strand shas at 'pending'
- 403 on status/comment posts self-heals: admin-scoped token (config
  admin_token) adds shre-reviewer as collaborator (write), retries once
- scripts/wire-repos.mjs: idempotent estate-wide webhook + collaborator
  wiring over GET /repos/search
- tests: 32 -> 51 (truncation cap, persisted-queue reconciliation,
  collab-retry stubs, fetchDiff routing)

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-19 09:12:10 -04:00
Nirav Patel f35a75f787 merge README docs 2026-08-19 00:04:07 -04:00
Nirav PatelandClaude Fable 5 9f2927c33e docs: deployment reality — webhook coverage, router bypass flags, v1 limitations
Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-19 00:04:06 -04:00
Nirav Patel aa6f2c8715 Merge pull request 'test: live review smoke' (#1) from test/live-review-smoke into main 2026-08-19 00:02:49 -04:00
Nirav PatelandClaude Fable 5 7d7b69e4e4 test: final e2e verification run
Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-19 00:01:05 -04:00
Nirav PatelandClaude Fable 5 f7b56297a8 fix: raw:true bypass for router keyword fast-paths + c-suite fallback agent
Two live-observed router hijack modes on diff content: (1) retail/store
fast-paths (store-resolver, arm:sales) intercepting prompts whose diffs
mention sales/store-ish words, (2) domain preflight 400 agent_mismatch
when the intent classifier confidently misclassifies a diff. raw:true
(_bypassToolRouting) disables the keyword intercepts; attempt 2 retries
as the configurable c-suite fallback agent (architect) which bypasses
the tier-gated domain preflight.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-19 00:00:37 -04:00
Nirav PatelandClaude Fable 5 7416df88c9 feat: pull PR commits for Co-Authored-By attribution on PR reviews
PR webhooks only carry title/body; fetch /pulls/{i}/commits so the
trailer ledger and per-agent digests attribute PR reviews correctly.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-18 23:52:43 -04:00
Nirav PatelandClaude Fable 5 ed4b347cab fix: send tools:false to the router so skill fast-paths cannot hijack reviews
The router's current-info briefing fast-path (enableToolsEffective gate)
was intercepting review prompts whose diffs mention GitHub-like terms and
returning a trending-repos digest instead of the model's review. Reviews
need pure model reasoning; body.tools=false disables the tool layer.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-18 23:41:09 -04:00
Nirav PatelandClaude Fable 5 74222a1631 fix: handle OpenAI-style router responses + log unparseable model output
The router's response shape varies by upstream: some backends return
.message.content, some choices[0].message.content, some only top-level
.content. Prefer them in that order. Record the actually-served model
(_shre.model) in the ledger and log a snippet of unparseable output for
diagnosis.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-18 23:35:12 -04:00
Nirav PatelandClaude Fable 5 e3ad9c25fc test: retrigger review webhooks
Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-18 23:27:50 -04:00
Nirav PatelandClaude Fable 5 bd148c4b50 test: live-review smoke marker
Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-18 23:25:58 -04:00
Nirav PatelandClaude Fable 5 9ffd810943 granthi-review v1: estate-wide AI code review service
Webhook-driven central review service for Granthi forges: HMAC-verified
push/pull_request webhooks, per-repo serialization with global LLM
concurrency 1, shre-router powered rubric review (8 axes, strict JSON,
tolerant extractor + retry), commit statuses + PR scorecard comments,
sqlite attribution ledger with Co-Authored-By trailer parsing, per-repo
HTML history dashboard, nightly per-agent digests, fail-open-with-
visibility when the router is unavailable.

Posture: BLOCK on confirmed critical/high correctness+security findings;
admin merge is the human override.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-18 23:24:27 -04:00