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
@@ -90,6 +90,12 @@ All offline, in the pinned toolbox (`./infra/devcontainer/dev.sh run`), never on
|
||||
kustomization, because the kustomization's comment named it by filename. Correctly
|
||||
refused: the distance between a filename in a comment and a line under `resources:` is
|
||||
one careless edit. The comment now points at it in prose.
|
||||
- **A self-review of the trigger found and fixed one real defect** before any of this ran:
|
||||
`last_activity()` compared RFC 3339 timestamp STRINGS to find the newest comment, which is
|
||||
only correct while every offset Gitea returns is identical — and the failure mode is the
|
||||
worst available one, the PM answering its own last comment in a loop. It now takes the last
|
||||
element of the comments list, which is the order the endpoint returns, so there is nothing
|
||||
about timezones to be right about.
|
||||
- **`check-jsonschema --schemafile schemas/servicedefinition.schema.json catalog/gitea.yaml`
|
||||
→ ok.**
|
||||
- **The golden reproduces:** `python3 catalog/render.py --all catalog -o apps --wave-layout
|
||||
|
||||
@@ -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