fix(pm-agent): take the newest comment by list order, not by comparing timestamp strings
last_activity() is the whole trigger: the PM acts iff the newest thing in a thread was not written by it. It found that newest comment by comparing Gitea's RFC 3339 created_at STRINGS, which is only correct while every offset is identical — true today, silently wrong after a server timezone change, and the failure would be the PM answering its own last comment forever. The comments endpoint returns them in creation order, so the last element IS the newest. Using that removes the dependency entirely. Found by self-review, before anything ran. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
1 parent
c5b5b8672a
commit
54418363aa
2 files changed
+18
-9
No files matched your search
@@ -599,19 +599,22 @@ def render_thread(cfg: Config, issue: dict, comments, pr: dict, status: dict,
|
||||
|
||||
|
||||
def last_activity(issue: dict, comments) -> tuple:
|
||||
"""Who wrote the newest thing in this thread, and when.
|
||||
"""Who wrote the newest thing in this thread, and when. THE TRIGGER DEPENDS ON THIS.
|
||||
|
||||
Deliberately NOT `issue.updated_at`: that moves when a label is added or the title is
|
||||
edited, which would re-trigger the PM for a change nobody asked it about.
|
||||
|
||||
And deliberately NOT a comparison of the timestamp STRINGS. Gitea returns RFC 3339 with
|
||||
a timezone offset, and lexicographic order over such strings is only correct while every
|
||||
offset is identical — true today, silently wrong after a server timezone change, and the
|
||||
failure would be the PM answering its own last comment in a loop. The comments endpoint
|
||||
returns them in creation order, so the last element IS the newest; that is one less thing
|
||||
to be right about.
|
||||
"""
|
||||
actor = (issue.get("user") or {}).get("login")
|
||||
when = issue.get("created_at") or ""
|
||||
for c in comments:
|
||||
ts = c.get("created_at") or ""
|
||||
if ts >= when:
|
||||
when = ts
|
||||
actor = (c.get("user") or {}).get("login")
|
||||
return actor, when
|
||||
if comments:
|
||||
newest = comments[-1]
|
||||
return (newest.get("user") or {}).get("login"), newest.get("created_at") or ""
|
||||
return (issue.get("user") or {}).get("login"), issue.get("created_at") or ""
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- job
|
||||
|
||||
Reference in new issue
Block a user