nisse-review marks a reply that settles its thread; the PR's author resolves it #169

Merged
dev-agent merged 2 commits from review-settled into main 2026-10-19 23:40:27 +00:00
4 changed files with 24 additions and 2 deletions
Showing only changes of commit 0694b47c34 - Show all commits

No files matched your search

+2 -1
View File
@@ -693,7 +693,8 @@ of earlier points, replies on threads, the round cap and its reset, `stop` and
change). A settled reply carries `<!-- nisse-review: settled -->`. Being change). A settled reply carries `<!-- nisse-review: settled -->`. Being
read-only (R3), the reviewer can't resolve the thread, so the PR's author read-only (R3), the reviewer can't resolve the thread, so the PR's author
does: nisse-dev resolves every comment on that thread's line when it next does: nisse-dev resolves every comment on that thread's line when it next
watches the PR and takes the settled reply as no point to answer; watches the PR and takes the settled reply as no point to answer (nor one
posted top-level, which has no thread to resolve);
`scripts/resolve_settled.py` does the same for PRs made by hand. `scripts/resolve_settled.py` does the same for PRs made by hand.
- **Sign-off:** `sign_off` posts a short review when there is nothing to raise; - **Sign-off:** `sign_off` posts a short review when there is nothing to raise;
while it stays happy, a later review offers `still_happy`, which posts nothing while it stays happy, a later review offers `still_happy`, which posts nothing
+3 -1
View File
@@ -97,7 +97,9 @@ SETTLED_MARKER = "<!-- nisse-review: settled -->"
def to_resolve(notes: list[ReviewNote]) -> list[int]: def to_resolve(notes: list[ReviewNote]) -> list[int]:
"""The ids of the unresolved line comments in threads a settled reply """The ids of the unresolved line comments in threads a settled reply
closed: every comment on that path:line, as Gitea groups a thread.""" closed: every comment on that path:line, as Gitea groups a thread.
Gitea resolves one comment at a time (seen on 28.2: the rest of the
thread still reports no resolver), and resolving one again is a 204."""
settled = { settled = {
n.where for n in notes if n.key.startswith("line-") and SETTLED_MARKER in n.body n.where for n in notes if n.key.startswith("line-") and SETTLED_MARKER in n.body
} }
2
+2
View File
@@ -1111,6 +1111,8 @@ class LoopAgent:
loop = replace(loop, comments=comment.id) loop = replace(loop, comments=comment.id)
if comment.author == self._account: if comment.author == self._account:
continue # its own replies continue # its own replies
if SETTLED_MARKER in comment.body:
continue # a settled reply posted top-level: nothing to answer
if comment.author not in self._gitea_operators: if comment.author not in self._gitea_operators:
point = f"c{comment.id}" point = f"c{comment.id}"
loop = self._peer_point( loop = self._peer_point(
+17
View File
@@ -293,3 +293,20 @@ def test_a_refused_resolve_leaves_the_thread_and_is_tried_again(
forge.refuse_resolve = False forge.refuse_resolve = False
agent.watch() agent.watch()
assert forge.resolved == [11, 12, 13] assert forge.resolved == [11, 12, 13]
def test_a_settled_reply_posted_top_level_is_not_a_point(
world: dict[str, Any],
) -> None:
"""One quoting a top-level point, or Gitea refused on its line: there's
no thread to resolve, and answering it would start the loop again."""
forge: Forge = world["forge"]
agent, _, pr = published(world)
forge.comments[pr] = [
Comment(
15, REVIEWER, f"> nisse-dev:\n> Done.\n\nThanks.\n{SETTLED_MARKER}", "t"
)
]
agent.watch()
loop = loop_of(the_item(world))
assert (the_item(world).position, loop.points) == (WAITING, ())