You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 9999bb3
Browse filesBrowse the repository at this point in the historyBrowse files
@@ -346,26 +346,26 @@ recovery, orphan adoption after a crash). Nothing new is invented for writes.
346
346
`ready_for_maintainer` requires all of, on the current head:
347
347
348
348
1. not draft, not parked, not stale;
349
-
2. every watched or required check green, `lifecycle.py` classification
350
-
`complete == True` (unknown required-set counts as not ready, as today);
349
+
2.`lifecycle.py` supplies `ready_verified == True` for this head: the
350
+
required-check set is known, required and watched checks are present,
351
+
complete and passing, pagination is complete, and required app identities
352
+
match.
353
+
Missing or pending evidence never counts as green;
351
354
3.`mergeable_state == "clean"`;
352
355
4. a completed review attempt on this head;
353
-
5.**no open blocker/major finding.** Blocker/major findings are carried
354
-
forward across heads: each one the bot posted stays on the PR's ledger of
355
-
open findings until it is explicitly closed. A finding closes only by one
356
-
of:
357
-
- a later head's re-review lists it in `finding_dispositions` as
358
-
`resolved_or_outdated`**with `head_recheck == "fixed"`**. The Direct
359
-
contract also allows `head_recheck == "still_affected"`
360
-
(`direct_routing.py:221`, `:893-900`); that value keeps the finding open.
361
-
A re-review that simply omits a carried finding does not close it — the
362
-
sweep's re-review prompt receives the carried list and must return a
363
-
disposition for every entry, and a missing entry counts as
364
-
`still_affected`;
365
-
- the author marked it disputed: a 👎 reaction on the bot's inline comment
366
-
or a reply in its thread. Disputed findings do not block; they are
367
-
counted and shown in the ready page ("2 findings disputed by the
368
-
author") so the maintainer arrives at exactly the disagreement.
356
+
5.**no undisputed open blocker/major finding.** Published blockers remain
357
+
in the findings ledger across heads. Only a complete, head-bound recheck
358
+
of the carried set with `outcome == "fixed"` closes a finding. A
359
+
`still_affected` or `unverified` answer leaves it unresolved; omission,
360
+
malformed answers and incomplete coverage cannot resolve it. The request
361
+
and result shapes are defined in [the SDK contract below](#sdk-boundary).
362
+
363
+
An author can dispute a finding with a 👎 reaction on its bot comment
364
+
or a reply in its thread. A dispute removes that finding from the ready
365
+
gate without proving it fixed. Disputed findings stay in the ledger and
366
+
are counted on the ready page so the maintainer sees the disagreement.
367
+
Review evidence and dispute state are stored separately; withdrawing a
368
+
dispute restores blocking status unless a valid explicit fix remains.
369
369
370
370
**Disputes are an evidence source with their own deadline, not a
371
371
by-product of the next review.** Thread replies arrive through the
@@ -447,19 +447,28 @@ review attempt, and enqueues reviews in this priority order:
447
447
2. PRs never reviewed, newest first;
448
448
3. PRs pushed since their last review (re-reviews reuse thread dispositions,
449
449
so they are the cheapest);
450
-
4. legacy backlog (open before the flag turned on), oldest last.
450
+
4. legacy backlog (open before the flag turned on), oldest first.
451
+
452
+
To prevent lower bands from waiting indefinitely, the sweep reserves
453
+
`max(1, budget // 5)` slots for eligible heads that have waited at least
454
+
one day since first eligibility or their last allocation of review capacity.
455
+
At the initial budget this is four slots. The remaining slots follow the
456
+
priority bands, and legacy-band work still respects the backfill quota.
457
+
The ledger preserves `first_eligible_at` and `last_selected_at` across
458
+
restarts and retries; a new head starts a new queue age. Queue eligibility
459
+
is refreshed outside the nightly window as well.
451
460
452
461
Capacity, from the live step medians (`llm` 290 s in Direct mode, `strict`
453
462
919 s in Strict mode, one Strict worker):
454
463
455
464
| Setting | Default | Rationale |
456
465
| --- | --- | --- |
457
466
|`AUTO_REVIEW_ENABLED`|`false`| shadow first, like every #116 flag |
458
-
|`AUTO_REVIEW_AT`|`04:00` (host TZ, UTC+8) | owner's choice; off-peak for CI and for people |
459
-
|`AUTO_REVIEW_WINDOW_HOURS`|`6`|sweep must finish before the working day; leftovers carry to the next night at the same priority|
460
-
|`AUTO_REVIEW_BUDGET`|`60`|≈48 new PRs/day plus re-reviews; at 5 min each with 2 Direct workers this is ~2.5 h|
467
+
|`AUTO_REVIEW_AT`|`04:00` (`Asia/Shanghai`) | fixed named timezone, independent of host timezone; off-peak for CI and for people |
468
+
|`AUTO_REVIEW_WINDOW_HOURS`|`6`|bounded nightly scheduling; unfinished eligible work carries forward with its queue age|
469
+
|`AUTO_REVIEW_BUDGET`|`20`|initial measured exposure; increase toward 60 only after at least three successful nights and review of queue, failure and latency measurements|
461
470
|`AUTO_REVIEW_MODE`|`direct`| automatic reviews run Direct only; the 50/50 Strict split stays on mention-triggered reviews so the experiment's sample is not swamped |
462
-
|`AUTO_REVIEW_BACKFILL_PER_NIGHT`|`10`| legacy backlog (1,037 non-draft open PRs today) drains slowly instead of flooding authors|
471
+
|`AUTO_REVIEW_BACKFILL_PER_NIGHT`|`10`| legacy-band reviews are bounded independently; accepted configuration range is 0–10|
463
472
464
473
The mention trigger stays exactly as it is, as the immediate manual path, and
465
474
a mention-triggered review counts against no nightly budget.
@@ -660,8 +669,10 @@ Reconciler contract:
660
669
re-run on the same SHA re-derives the same keys and is a no-op.
661
670
662
671
Existing evidence tables remain authoritative; additive migrations preserve claims and history. `workflow_jobs`, `review_attempts`,
663
-
`lifecycle_notes`, `stale_windows` and `applied_labels` remain the evidence;
664
-
`pr_state` is what the kanban, the pager and the clocks read.
672
+
`lifecycle_notes`, `stale_windows`, `idle_ladder_windows` and historical
673
+
`applied_labels` remain evidence. Current internal labels use
674
+
`inferred_labels`, and `auto_review_queue` retains eligibility/service age;
675
+
`pr_state` is the derived projection for the kanban, pager and clocks.
665
676
666
677
## Kanban
667
678
@@ -677,45 +688,67 @@ blocked, timed out, rerouted all land in a column).
| review verdict, severities, `finding_dispositions`, quality verdict, head binding — the per-head facts| this repo, via the SDK (`build_review_result`, `build_quality_result`) |
691
+
| review verdict, published `findings`, explicit `finding_rechecks`, quality verdict and head binding| this repo, via the SDK (`build_review_result`, `build_quality_result`) |
681
692
|`open_findings` / `disputed_findings` counts | the bot, because they combine SDK per-finding results with reaction and reply data only the bot reads |
682
693
683
-
**SDK change required (this repo, a contract version bump).** Today
684
-
`build_review_result` projects each disposition record onto three fields —
0 commit comments