From e78308862acfa7c34bb4b704fc5ccd5c0d2a9b3f Mon Sep 17 00:00:00 2001 From: Teleo Agents Date: Wed, 13 May 2026 04:29:54 +0000 Subject: [PATCH] fix(activity-feed): emit Forgejo pr_url fallback so every event has a clickthrough Previously _github_pr_url() only returned a URL when prs.github_pr was populated. That field is set on only 3 of 4094 merged PRs (the rare cases mirrored to the public GitHub repo), so pr_url was null for ~100% of the feed. The frontend whole-row PR overlay (livingip-web PR #30) renders only when pr_url is non-null, so until now no rows had the overlay. Pipeline-attributed events (reweave/*, ingestion/*) are the most visible victim: their /contributors/pipeline link lands on a sparse stub, with no way to reach the actual commit/PR they refer to. Fix: rename _github_pr_url -> _pr_url and fall back to the canonical Forgejo URL (git.livingip.xyz/teleo/teleo-codex/pulls/{number}) when no GitHub mirror exists. Verified 200 OK against a sample (#10568). GitHub URL still wins when available. Result: 1972/1972 events in _build_events now carry a pr_url. Whole-row overlay starts working for everything including pipeline events. --- diagnostics/activity_feed_api.py | 34 +++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/diagnostics/activity_feed_api.py b/diagnostics/activity_feed_api.py index c901ee7..54422dc 100644 --- a/diagnostics/activity_feed_api.py +++ b/diagnostics/activity_feed_api.py @@ -123,10 +123,21 @@ def _claim_target_url(claim_slug): return f"/claims/{claim_slug}" -def _github_pr_url(github_pr): - if not github_pr: - return None - return f"https://github.com/living-ip/teleo-codex/pull/{github_pr}" +# Canonical clickthrough URL for an activity-feed event. +# +# Every merged PR in the pipeline.db `prs` table lives on Forgejo at +# git.livingip.xyz/teleo/teleo-codex/pulls/{number}. A small subset (3 of +# 4094 as of 2026-05-13) was additionally mirrored to GitHub and has +# prs.github_pr populated. Prefer GitHub when available (more public-facing +# surface), fall back to Forgejo so every row has a real destination +# instead of None (which makes the frontend whole-row overlay no-op and +# leaves pipeline-attributed events looking dead-on-click). +def _pr_url(pr_number, github_pr): + if github_pr: + return f"https://github.com/living-ip/teleo-codex/pull/{github_pr}" + if pr_number: + return f"https://git.livingip.xyz/teleo/teleo-codex/pulls/{pr_number}" + return None # Canonicalize contributor labels so frontend links resolve to real @@ -225,6 +236,15 @@ def _build_events(): continue contributor = _normalize_contributor(row["submitted_by"], row["agent"]) + # Hide pipeline-attributed events (reweave/*, ingestion/*) from the + # public activity feed. They're automation maintenance, not + # contributions — the daemon re-knits the graph nightly and ingests + # external sources. Internal diagnostics + CI math still see these + # rows in prs / contribution_events; only the public timeline drops + # them. Mirrors the existing _FEED_COMMIT_TYPES filter (which hides + # commit_type='pipeline') along the contributor axis. + if contributor == "pipeline": + continue merged_at = row["merged_at"] or "" domain = row["domain"] or "unknown" kind = _KIND_MAP.get(event_type, event_type) @@ -255,7 +275,7 @@ def _build_events(): "ci_earned": round(ci_earned, 2), "summary": summary_text, "pr_number": row["number"], - "pr_url": _github_pr_url(row["github_pr"]), + "pr_url": _pr_url(row["number"], row["github_pr"]), "source_channel": row["source_channel"] or "unknown", }) continue @@ -276,7 +296,7 @@ def _build_events(): "ci_earned": round(ci_earned, 2), "summary": summary_text, "pr_number": row["number"], - "pr_url": _github_pr_url(row["github_pr"]), + "pr_url": _pr_url(row["number"], row["github_pr"]), "source_channel": row["source_channel"] or "unknown", }) continue @@ -315,7 +335,7 @@ def _build_events(): "ci_earned": round(ci_earned, 2), "summary": summary_text, "pr_number": row["number"], - "pr_url": _github_pr_url(row["github_pr"]), + "pr_url": _pr_url(row["number"], row["github_pr"]), "source_channel": row["source_channel"] or "unknown", })