nisse-review: later reviews, replies, rounds, stop and review (M7.5)
Back on a PR it reviewed: a new head gets a later review of the commits since (each one's diff, through the API) and of its earlier points; what was said since gets replies, answered where it was said or skipped with a reason. It signs off once and stays quiet while still happy. Past tuning.review.max_rounds it sums up for the operator and goes quiet, until a push or someone other than the PR's author joins in. An operator's `stop` quiets it; `review` asks for a fresh review. Reviews carry numbered markers and replies their point's key, so recovery posts nothing twice. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J5Utyfzw7gF7UhjRDEtjTk
This commit is contained in:
1 parent
7e73b8fb37
commit
37bbac7e72
14 files changed
+1268
-157
No files matched your search
@@ -9,15 +9,23 @@ from nisse_core.state import store
|
||||
from nisse_core.state.store import WorkItem
|
||||
|
||||
# A review item's positions.
|
||||
READY = "ready" # to review
|
||||
RUNNING = "running" # a review run is under way; on boot, interrupted
|
||||
REVIEWED = "reviewed" # reviewed at its head; later events are M7.5's
|
||||
READY = "ready" # a run is due: a review, a later review, or replies
|
||||
RUNNING = "running" # a run is under way; on boot, interrupted
|
||||
REVIEWED = "reviewed" # nothing due: watching for pushes and comments
|
||||
WAITING = "waiting" # not ready: a draft or work in progress
|
||||
FAILED = "failed" # reviews kept failing; said so on the PR
|
||||
FAILED = "failed" # runs kept failing; said so on the PR
|
||||
CAPPED = "capped" # the round cap: summed up for the operator, quiet (R2)
|
||||
STOPPED = "stopped" # an operator said `stop` on the PR; `review` resumes (R5)
|
||||
CLOSED = "closed"
|
||||
|
||||
POST_REVIEW = "post_review" # the intent around posting one (L8)
|
||||
|
||||
# What a run is, from the item (``Scheduler._kind``).
|
||||
FIRST = "first" # the whole PR: its first review, or one asked for
|
||||
LATER = "later" # what changed since its last review, and its earlier points
|
||||
REPLIES = "replies" # answering what was said since, at the same head
|
||||
SUMMARY = "summary" # the round cap: what is still open, for the operator
|
||||
|
||||
|
||||
class StateStore(store.StateStore):
|
||||
AGENT = "nisse-review"
|
||||
@@ -31,9 +39,17 @@ class PR:
|
||||
repo: str # owner/name
|
||||
number: int
|
||||
head: str = "" # the commit last seen at the PR's head
|
||||
reviewed: str = "" # the commit its review was posted on
|
||||
reviewed: str = "" # the commit its last review was posted on
|
||||
attempts: int = 0 # failed runs at this head
|
||||
seen_at: float = 0.0 # when this head was first seen (the CI wait)
|
||||
# M7.5: the discussion.
|
||||
seen: tuple[str, ...] = () # keys of everything said on it, taken in
|
||||
fresh: tuple[str, ...] = () # keys said since its last run, to answer
|
||||
rounds: int = 0 # reviews and reply sets since the last reset (R2)
|
||||
posts: int = 0 # reviews it posted on the PR: their markers' numbers
|
||||
happy: bool = False # its last review signed off: no repeats while so
|
||||
full: bool = False # an operator asked for a fresh review (`review`)
|
||||
run: str = "" # the kind of run under way, for recovery
|
||||
|
||||
|
||||
def item_id(repo: str, number: int) -> str:
|
||||
@@ -41,7 +57,12 @@ def item_id(repo: str, number: int) -> str:
|
||||
|
||||
|
||||
def pr_of(item: WorkItem) -> PR:
|
||||
return PR(**item.data["pr"])
|
||||
raw = dict(item.data["pr"])
|
||||
for key in ("seen", "fresh"):
|
||||
raw[key] = tuple(raw.get(key) or ())
|
||||
if "posts" not in raw and raw.get("reviewed"):
|
||||
raw["posts"] = 1 # reviewed before M7.5, which numbered them
|
||||
return PR(**raw)
|
||||
|
||||
|
||||
def data(pr: PR) -> dict[str, Any]:
|
||||
|
||||
Reference in new issue
Block a user